roosterjs-content-model-core 9.15.0 → 9.16.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/createModelFromHtml/createDomToModelContextForSanitizing.js +2 -0
- package/lib/command/createModelFromHtml/createDomToModelContextForSanitizing.js.map +1 -1
- package/lib/command/createModelFromHtml/createModelFromHtml.js +2 -4
- package/lib/command/createModelFromHtml/createModelFromHtml.js.map +1 -1
- package/lib/command/paste/mergePasteContent.d.ts +1 -1
- package/lib/command/paste/mergePasteContent.js +2 -2
- package/lib/command/paste/mergePasteContent.js.map +1 -1
- package/lib/command/paste/paste.js +7 -6
- package/lib/command/paste/paste.js.map +1 -1
- package/lib/coreApi/restoreUndoSnapshot/restoreSnapshotHTML.js +3 -3
- package/lib/coreApi/restoreUndoSnapshot/restoreSnapshotHTML.js.map +1 -1
- package/lib/corePlugin/format/applyDefaultFormat.js +36 -34
- package/lib/corePlugin/format/applyDefaultFormat.js.map +1 -1
- package/lib/editor/Editor.d.ts +10 -2
- package/lib/editor/Editor.js +10 -0
- package/lib/editor/Editor.js.map +1 -1
- package/lib/editor/core/createEditorCore.d.ts +0 -4
- package/lib/editor/core/createEditorCore.js +6 -9
- package/lib/editor/core/createEditorCore.js.map +1 -1
- package/lib/override/pasteWhiteSpaceFormatParser.d.ts +5 -0
- package/lib/override/pasteWhiteSpaceFormatParser.js +15 -0
- package/lib/override/pasteWhiteSpaceFormatParser.js.map +1 -0
- package/lib/utils/domCreator.d.ts +17 -0
- package/lib/utils/domCreator.js +40 -0
- package/lib/utils/domCreator.js.map +1 -0
- package/lib-amd/command/createModelFromHtml/createDomToModelContextForSanitizing.js +2 -1
- package/lib-amd/command/createModelFromHtml/createDomToModelContextForSanitizing.js.map +1 -1
- package/lib-amd/command/createModelFromHtml/createModelFromHtml.js +2 -5
- package/lib-amd/command/createModelFromHtml/createModelFromHtml.js.map +1 -1
- package/lib-amd/command/paste/mergePasteContent.d.ts +1 -1
- package/lib-amd/command/paste/mergePasteContent.js +2 -2
- package/lib-amd/command/paste/mergePasteContent.js.map +1 -1
- package/lib-amd/command/paste/paste.js +7 -6
- package/lib-amd/command/paste/paste.js.map +1 -1
- package/lib-amd/coreApi/restoreUndoSnapshot/restoreSnapshotHTML.js +3 -3
- package/lib-amd/coreApi/restoreUndoSnapshot/restoreSnapshotHTML.js.map +1 -1
- package/lib-amd/corePlugin/format/applyDefaultFormat.js +36 -34
- package/lib-amd/corePlugin/format/applyDefaultFormat.js.map +1 -1
- package/lib-amd/editor/Editor.d.ts +10 -2
- package/lib-amd/editor/Editor.js +10 -0
- package/lib-amd/editor/Editor.js.map +1 -1
- package/lib-amd/editor/core/createEditorCore.d.ts +0 -4
- package/lib-amd/editor/core/createEditorCore.js +6 -10
- package/lib-amd/editor/core/createEditorCore.js.map +1 -1
- package/lib-amd/override/pasteWhiteSpaceFormatParser.d.ts +5 -0
- package/lib-amd/override/pasteWhiteSpaceFormatParser.js +17 -0
- package/lib-amd/override/pasteWhiteSpaceFormatParser.js.map +1 -0
- package/lib-amd/utils/domCreator.d.ts +17 -0
- package/lib-amd/utils/domCreator.js +42 -0
- package/lib-amd/utils/domCreator.js.map +1 -0
- package/lib-mjs/command/createModelFromHtml/createDomToModelContextForSanitizing.js +2 -0
- package/lib-mjs/command/createModelFromHtml/createDomToModelContextForSanitizing.js.map +1 -1
- package/lib-mjs/command/createModelFromHtml/createModelFromHtml.js +2 -4
- package/lib-mjs/command/createModelFromHtml/createModelFromHtml.js.map +1 -1
- package/lib-mjs/command/paste/mergePasteContent.d.ts +1 -1
- package/lib-mjs/command/paste/mergePasteContent.js +2 -2
- package/lib-mjs/command/paste/mergePasteContent.js.map +1 -1
- package/lib-mjs/command/paste/paste.js +7 -6
- package/lib-mjs/command/paste/paste.js.map +1 -1
- package/lib-mjs/coreApi/restoreUndoSnapshot/restoreSnapshotHTML.js +3 -3
- package/lib-mjs/coreApi/restoreUndoSnapshot/restoreSnapshotHTML.js.map +1 -1
- package/lib-mjs/corePlugin/format/applyDefaultFormat.js +37 -35
- package/lib-mjs/corePlugin/format/applyDefaultFormat.js.map +1 -1
- package/lib-mjs/editor/Editor.d.ts +10 -2
- package/lib-mjs/editor/Editor.js +10 -0
- package/lib-mjs/editor/Editor.js.map +1 -1
- package/lib-mjs/editor/core/createEditorCore.d.ts +0 -4
- package/lib-mjs/editor/core/createEditorCore.js +5 -7
- package/lib-mjs/editor/core/createEditorCore.js.map +1 -1
- package/lib-mjs/override/pasteWhiteSpaceFormatParser.d.ts +5 -0
- package/lib-mjs/override/pasteWhiteSpaceFormatParser.js +11 -0
- package/lib-mjs/override/pasteWhiteSpaceFormatParser.js.map +1 -0
- package/lib-mjs/utils/domCreator.d.ts +17 -0
- package/lib-mjs/utils/domCreator.js +33 -0
- package/lib-mjs/utils/domCreator.js.map +1 -0
- package/package.json +3 -3
|
@@ -10,6 +10,7 @@ var getRootComputedStyleForContext_1 = require("../../coreApi/createEditorContex
|
|
|
10
10
|
var pasteCopyBlockEntityParser_1 = require("../../override/pasteCopyBlockEntityParser");
|
|
11
11
|
var pasteDisplayFormatParser_1 = require("../../override/pasteDisplayFormatParser");
|
|
12
12
|
var pasteTextProcessor_1 = require("../../override/pasteTextProcessor");
|
|
13
|
+
var pasteWhiteSpaceFormatParser_1 = require("../../override/pasteWhiteSpaceFormatParser");
|
|
13
14
|
var DefaultSanitizingOption = {
|
|
14
15
|
processorOverride: {},
|
|
15
16
|
formatParserOverride: {},
|
|
@@ -32,6 +33,7 @@ function createDomToModelContextForSanitizing(document, defaultFormat, defaultOp
|
|
|
32
33
|
},
|
|
33
34
|
formatParserOverride: {
|
|
34
35
|
display: pasteDisplayFormatParser_1.pasteDisplayFormatParser,
|
|
36
|
+
whiteSpace: pasteWhiteSpaceFormatParser_1.pasteWhiteSpaceFormatParser,
|
|
35
37
|
},
|
|
36
38
|
additionalFormatParsers: {
|
|
37
39
|
container: [containerSizeFormatParser_1.containerSizeFormatParser],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createDomToModelContextForSanitizing.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/command/createModelFromHtml/createDomToModelContextForSanitizing.ts"],"names":[],"mappings":";;;;AAAA,sFAAqF;AACrF,2EAAsE;AACtE,4EAAiF;AACjF,8EAAmF;AACnF,mHAAkH;AAClH,wFAAmF;AACnF,oFAAmF;AACnF,wEAAuE;
|
|
1
|
+
{"version":3,"file":"createDomToModelContextForSanitizing.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/command/createModelFromHtml/createDomToModelContextForSanitizing.ts"],"names":[],"mappings":";;;;AAAA,sFAAqF;AACrF,2EAAsE;AACtE,4EAAiF;AACjF,8EAAmF;AACnF,mHAAkH;AAClH,wFAAmF;AACnF,oFAAmF;AACnF,wEAAuE;AACvE,0FAAyF;AAQzF,IAAM,uBAAuB,GAAkC;IAC3D,iBAAiB,EAAE,EAAE;IACrB,oBAAoB,EAAE,EAAE;IACxB,uBAAuB,EAAE,EAAE;IAC3B,qBAAqB,EAAE,EAAE;IACzB,wBAAwB,EAAE,EAAE;IAC5B,eAAe,EAAE,EAAE;IACnB,mBAAmB,EAAE,EAAE;CAC1B,CAAC;AAEF;;GAEG;AACH,SAAgB,oCAAoC,CAChD,QAAkB,EAClB,aAAyC,EACzC,aAAgC,EAChC,0BAAmE;IAEnE,IAAM,gBAAgB,mDACf,uBAAuB,GACvB,0BAA0B,CAChC,CAAC;IAEF,OAAO,IAAA,qDAAuB,gDAEtB,aAAa,eAAA,IACV,IAAA,+DAA8B,EAAC,QAAQ,CAAC,KAC3C,oBAAoB,EAAE,EAAE,KAE5B,aAAa,EACb;QACI,iBAAiB,EAAE;YACf,OAAO,EAAE,uCAAkB;YAC3B,MAAM,EAAE,IAAA,iDAA0B,EAAC,gBAAgB,CAAC;YACpD,GAAG,EAAE,IAAA,mDAA2B,EAAC,gBAAgB,CAAC;SACrD;QACD,oBAAoB,EAAE;YAClB,OAAO,EAAE,mDAAwB;YACjC,UAAU,EAAE,yDAA2B;SAC1C;QACD,uBAAuB,EAAE;YACrB,SAAS,EAAE,CAAC,qDAAyB,CAAC;YACtC,MAAM,EAAE,CAAC,mDAAsB,CAAC;SACnC;KACJ,EACD,gBAAgB,CACnB,CAAC;AACN,CAAC;AAnCD,oFAmCC","sourcesContent":["import { containerSizeFormatParser } from '../../override/containerSizeFormatParser';\nimport { createDomToModelContext } from 'roosterjs-content-model-dom';\nimport { createPasteEntityProcessor } from '../../override/pasteEntityProcessor';\nimport { createPasteGeneralProcessor } from '../../override/pasteGeneralProcessor';\nimport { getRootComputedStyleForContext } from '../../coreApi/createEditorContext/getRootComputedStyleForContext';\nimport { pasteBlockEntityParser } from '../../override/pasteCopyBlockEntityParser';\nimport { pasteDisplayFormatParser } from '../../override/pasteDisplayFormatParser';\nimport { pasteTextProcessor } from '../../override/pasteTextProcessor';\nimport { pasteWhiteSpaceFormatParser } from '../../override/pasteWhiteSpaceFormatParser';\nimport type {\n ContentModelSegmentFormat,\n DomToModelContext,\n DomToModelOption,\n DomToModelOptionForSanitizing,\n} from 'roosterjs-content-model-types';\n\nconst DefaultSanitizingOption: DomToModelOptionForSanitizing = {\n processorOverride: {},\n formatParserOverride: {},\n additionalFormatParsers: {},\n additionalAllowedTags: [],\n additionalDisallowedTags: [],\n styleSanitizers: {},\n attributeSanitizers: {},\n};\n\n/**\n * @internal\n */\nexport function createDomToModelContextForSanitizing(\n document: Document,\n defaultFormat?: ContentModelSegmentFormat,\n defaultOption?: DomToModelOption,\n additionalSanitizingOption?: Partial<DomToModelOptionForSanitizing>\n): DomToModelContext {\n const sanitizingOption: DomToModelOptionForSanitizing = {\n ...DefaultSanitizingOption,\n ...additionalSanitizingOption,\n };\n\n return createDomToModelContext(\n {\n defaultFormat,\n ...getRootComputedStyleForContext(document),\n experimentalFeatures: [],\n },\n defaultOption,\n {\n processorOverride: {\n '#text': pasteTextProcessor,\n entity: createPasteEntityProcessor(sanitizingOption),\n '*': createPasteGeneralProcessor(sanitizingOption),\n },\n formatParserOverride: {\n display: pasteDisplayFormatParser,\n whiteSpace: pasteWhiteSpaceFormatParser,\n },\n additionalFormatParsers: {\n container: [containerSizeFormatParser],\n entity: [pasteBlockEntityParser],\n },\n },\n sanitizingOption\n );\n}\n"]}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.createModelFromHtml = void 0;
|
|
4
4
|
var convertInlineCss_1 = require("./convertInlineCss");
|
|
5
|
+
var domCreator_1 = require("../../utils/domCreator");
|
|
5
6
|
var createDomToModelContextForSanitizing_1 = require("./createDomToModelContextForSanitizing");
|
|
6
7
|
var roosterjs_content_model_dom_1 = require("roosterjs-content-model-dom");
|
|
7
8
|
/**
|
|
@@ -12,10 +13,7 @@ var roosterjs_content_model_dom_1 = require("roosterjs-content-model-dom");
|
|
|
12
13
|
* @returns A Content Model Document object that contains the Content Model from the give HTML, or undefined if failed to parse the source HTML
|
|
13
14
|
*/
|
|
14
15
|
function createModelFromHtml(html, options, trustedHTMLHandler, defaultSegmentFormat) {
|
|
15
|
-
var
|
|
16
|
-
var doc = html
|
|
17
|
-
? new DOMParser().parseFromString((_a = trustedHTMLHandler === null || trustedHTMLHandler === void 0 ? void 0 : trustedHTMLHandler(html)) !== null && _a !== void 0 ? _a : html, 'text/html')
|
|
18
|
-
: null;
|
|
16
|
+
var doc = html ? (0, domCreator_1.createDOMCreator)(trustedHTMLHandler).htmlToDOM(html) : null;
|
|
19
17
|
if (doc === null || doc === void 0 ? void 0 : doc.body) {
|
|
20
18
|
var context = (0, createDomToModelContextForSanitizing_1.createDomToModelContextForSanitizing)(doc, defaultSegmentFormat, undefined /*defaultOptions*/, options);
|
|
21
19
|
var cssRules = doc ? (0, convertInlineCss_1.retrieveCssRules)(doc) : [];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createModelFromHtml.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/command/createModelFromHtml/createModelFromHtml.ts"],"names":[],"mappings":";;;AAAA,uDAAwE;AACxE,+FAA8F;AAC9F,2EAA+F;AAQ/F;;;;;;GAMG;AACH,SAAgB,mBAAmB,CAC/B,IAAY,EACZ,OAAgD,EAChD,kBAAuC,EACvC,oBAAgD
|
|
1
|
+
{"version":3,"file":"createModelFromHtml.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/command/createModelFromHtml/createModelFromHtml.ts"],"names":[],"mappings":";;;AAAA,uDAAwE;AACxE,qDAA0D;AAC1D,+FAA8F;AAC9F,2EAA+F;AAQ/F;;;;;;GAMG;AACH,SAAgB,mBAAmB,CAC/B,IAAY,EACZ,OAAgD,EAChD,kBAAuC,EACvC,oBAAgD;IAEhD,IAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,IAAA,6BAAgB,EAAC,kBAAkB,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAE/E,IAAI,GAAG,aAAH,GAAG,uBAAH,GAAG,CAAE,IAAI,EAAE;QACX,IAAM,OAAO,GAAG,IAAA,2EAAoC,EAChD,GAAG,EACH,oBAAoB,EACpB,SAAS,CAAC,kBAAkB,EAC5B,OAAO,CACV,CAAC;QACF,IAAM,QAAQ,GAAG,GAAG,CAAC,CAAC,CAAC,IAAA,mCAAgB,EAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAElD,IAAA,mCAAgB,EAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;QAChC,IAAA,yCAAW,EAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,aAAa,CAAC,cAAc,EAAE,OAAO,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;QAE5F,OAAO,IAAA,+CAAiB,EAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;KAC/C;SAAM;QACH,OAAO,IAAA,8CAAgB,EAAC,oBAAoB,CAAC,CAAC;KACjD;AACL,CAAC;AAxBD,kDAwBC","sourcesContent":["import { convertInlineCss, retrieveCssRules } from './convertInlineCss';\nimport { createDOMCreator } from '../../utils/domCreator';\nimport { createDomToModelContextForSanitizing } from './createDomToModelContextForSanitizing';\nimport { createEmptyModel, domToContentModel, parseFormat } from 'roosterjs-content-model-dom';\nimport type {\n ContentModelDocument,\n ContentModelSegmentFormat,\n DomToModelOptionForSanitizing,\n TrustedHTMLHandler,\n} from 'roosterjs-content-model-types';\n\n/**\n * Create Content Model from HTML string\n * @param html The source HTML string\n * @param options Options for DOM to Content Model conversion\n * @param trustedHTMLHandler A string handler to convert string to trusted string\n * @returns A Content Model Document object that contains the Content Model from the give HTML, or undefined if failed to parse the source HTML\n */\nexport function createModelFromHtml(\n html: string,\n options?: Partial<DomToModelOptionForSanitizing>,\n trustedHTMLHandler?: TrustedHTMLHandler,\n defaultSegmentFormat?: ContentModelSegmentFormat\n): ContentModelDocument {\n const doc = html ? createDOMCreator(trustedHTMLHandler).htmlToDOM(html) : null;\n\n if (doc?.body) {\n const context = createDomToModelContextForSanitizing(\n doc,\n defaultSegmentFormat,\n undefined /*defaultOptions*/,\n options\n );\n const cssRules = doc ? retrieveCssRules(doc) : [];\n\n convertInlineCss(doc, cssRules);\n parseFormat(doc.body, context.formatParsers.segmentOnBlock, context.segmentFormat, context);\n\n return domToContentModel(doc.body, context);\n } else {\n return createEmptyModel(defaultSegmentFormat);\n }\n}\n"]}
|
|
@@ -6,4 +6,4 @@ export declare function cloneModelForPaste(model: ReadonlyContentModelDocument):
|
|
|
6
6
|
/**
|
|
7
7
|
* @internal
|
|
8
8
|
*/
|
|
9
|
-
export declare function mergePasteContent(editor: IEditor, eventResult: BeforePasteEvent): void;
|
|
9
|
+
export declare function mergePasteContent(editor: IEditor, eventResult: BeforePasteEvent, isFirstPaste: boolean): void;
|
|
@@ -18,10 +18,10 @@ exports.cloneModelForPaste = cloneModelForPaste;
|
|
|
18
18
|
/**
|
|
19
19
|
* @internal
|
|
20
20
|
*/
|
|
21
|
-
function mergePasteContent(editor, eventResult) {
|
|
21
|
+
function mergePasteContent(editor, eventResult, isFirstPaste) {
|
|
22
22
|
var fragment = eventResult.fragment, domToModelOption = eventResult.domToModelOption, customizedMerge = eventResult.customizedMerge, pasteType = eventResult.pasteType, clipboardData = eventResult.clipboardData, containsBlockElements = eventResult.containsBlockElements;
|
|
23
23
|
editor.formatContentModel(function (model, context) {
|
|
24
|
-
if (clipboardData.modelBeforePaste) {
|
|
24
|
+
if (!isFirstPaste && clipboardData.modelBeforePaste) {
|
|
25
25
|
var clonedModel = cloneModelForPaste(clipboardData.modelBeforePaste);
|
|
26
26
|
model.blocks = clonedModel.blocks;
|
|
27
27
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mergePasteContent.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/command/paste/mergePasteContent.ts"],"names":[],"mappings":";;;;AAAA,oHAAmH;AACnH,2EAQqC;AAarC,IAAM,UAAU,GAAG,YAAY,CAAC;AAEhC,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;;GAEG;AACH,SAAgB,kBAAkB,CAAC,KAAmC;IAClE,OAAO,IAAA,wCAAU,EAAC,KAAK,EAAE,WAAW,CAAC,CAAC;AAC1C,CAAC;AAFD,gDAEC;AAED;;GAEG;AACH,SAAgB,iBAAiB,
|
|
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 cloneModel,\n domToContentModel,\n getSegmentTextFormat,\n getSelectedSegments,\n mergeModel,\n} from 'roosterjs-content-model-dom';\nimport type {\n BeforePasteEvent,\n CloneModelOptions,\n ContentModelDocument,\n ContentModelSegmentFormat,\n IEditor,\n MergeModelOption,\n PasteType,\n ReadonlyContentModelDocument,\n ShallowMutableContentModelDocument,\n} from 'roosterjs-content-model-types';\n\nconst BlackColor = 'rgb(0,0,0)';\n\nconst CloneOption: CloneModelOptions = {\n includeCachedElement: (node, type) => (type == 'cache' ? undefined : node),\n};\n\n/**\n * @internal\n */\nexport function cloneModelForPaste(model: ReadonlyContentModelDocument) {\n return cloneModel(model, CloneOption);\n}\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 );\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"]}
|
|
@@ -16,15 +16,16 @@ function paste(editor, clipboardData, pasteTypeOrGetter) {
|
|
|
16
16
|
var _a;
|
|
17
17
|
if (pasteTypeOrGetter === void 0) { pasteTypeOrGetter = 'normal'; }
|
|
18
18
|
editor.focus();
|
|
19
|
-
var
|
|
19
|
+
var isFirstPaste = false;
|
|
20
20
|
if (!clipboardData.modelBeforePaste) {
|
|
21
|
+
isFirstPaste = true;
|
|
21
22
|
editor.formatContentModel(function (model) {
|
|
22
23
|
clipboardData.modelBeforePaste = (0, mergePasteContent_1.cloneModelForPaste)(model);
|
|
23
24
|
return false;
|
|
24
25
|
});
|
|
25
26
|
}
|
|
26
27
|
// 1. Prepare variables
|
|
27
|
-
var doc = createDOMFromHtml(clipboardData.rawHtml,
|
|
28
|
+
var doc = createDOMFromHtml(clipboardData.rawHtml, editor.getDOMCreator());
|
|
28
29
|
var pasteType = typeof pasteTypeOrGetter == 'function'
|
|
29
30
|
? pasteTypeOrGetter(doc, clipboardData)
|
|
30
31
|
: pasteTypeOrGetter;
|
|
@@ -33,16 +34,16 @@ function paste(editor, clipboardData, pasteTypeOrGetter) {
|
|
|
33
34
|
// 3. Create target fragment
|
|
34
35
|
var sourceFragment = (0, createPasteFragment_1.createPasteFragment)(editor.getDocument(), clipboardData, pasteType, (_a = (clipboardData.rawHtml == clipboardData.html
|
|
35
36
|
? doc
|
|
36
|
-
: createDOMFromHtml(clipboardData.html,
|
|
37
|
+
: createDOMFromHtml(clipboardData.html, editor.getDOMCreator()))) === null || _a === void 0 ? void 0 : _a.body);
|
|
37
38
|
// 4. Trigger BeforePaste event to allow plugins modify the fragment
|
|
38
39
|
var eventResult = (0, generatePasteOptionFromPlugins_1.generatePasteOptionFromPlugins)(editor, clipboardData, sourceFragment, htmlFromClipboard, pasteType);
|
|
39
40
|
// 5. Convert global CSS to inline CSS
|
|
40
41
|
(0, convertInlineCss_1.convertInlineCss)(eventResult.fragment, htmlFromClipboard.globalCssRules);
|
|
41
42
|
// 6. Merge pasted content into main Content Model
|
|
42
|
-
(0, mergePasteContent_1.mergePasteContent)(editor, eventResult);
|
|
43
|
+
(0, mergePasteContent_1.mergePasteContent)(editor, eventResult, isFirstPaste);
|
|
43
44
|
}
|
|
44
45
|
exports.paste = paste;
|
|
45
|
-
function createDOMFromHtml(html,
|
|
46
|
-
return html ?
|
|
46
|
+
function createDOMFromHtml(html, domCreator) {
|
|
47
|
+
return html ? domCreator.htmlToDOM(html) : null;
|
|
47
48
|
}
|
|
48
49
|
//# sourceMappingURL=paste.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paste.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/command/paste/paste.ts"],"names":[],"mappings":";;;AAAA,yDAA4E;AAC5E,4EAA2E;AAC3E,6DAA4D;AAC5D,mFAAkF;AAClF,uDAAsD;AAQtD;;;;;GAKG;AACH,SAAgB,KAAK,CACjB,MAAe,EACf,aAA4B,EAC5B,iBAA+C;;IAA/C,kCAAA,EAAA,4BAA+C;IAE/C,MAAM,CAAC,KAAK,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"paste.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/command/paste/paste.ts"],"names":[],"mappings":";;;AAAA,yDAA4E;AAC5E,4EAA2E;AAC3E,6DAA4D;AAC5D,mFAAkF;AAClF,uDAAsD;AAQtD;;;;;GAKG;AACH,SAAgB,KAAK,CACjB,MAAe,EACf,aAA4B,EAC5B,iBAA+C;;IAA/C,kCAAA,EAAA,4BAA+C;IAE/C,MAAM,CAAC,KAAK,EAAE,CAAC;IACf,IAAI,YAAY,GAAG,KAAK,CAAC;IAEzB,IAAI,CAAC,aAAa,CAAC,gBAAgB,EAAE;QACjC,YAAY,GAAG,IAAI,CAAC;QAEpB,MAAM,CAAC,kBAAkB,CAAC,UAAA,KAAK;YAC3B,aAAa,CAAC,gBAAgB,GAAG,IAAA,sCAAkB,EAAC,KAAK,CAAC,CAAC;YAE3D,OAAO,KAAK,CAAC;QACjB,CAAC,CAAC,CAAC;KACN;IAED,uBAAuB;IACvB,IAAM,GAAG,GAAG,iBAAiB,CAAC,aAAa,CAAC,OAAO,EAAE,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC;IAC7E,IAAM,SAAS,GACX,OAAO,iBAAiB,IAAI,UAAU;QAClC,CAAC,CAAC,iBAAiB,CAAC,GAAG,EAAE,aAAa,CAAC;QACvC,CAAC,CAAC,iBAAiB,CAAC;IAE5B,gCAAgC;IAChC,IAAM,iBAAiB,GAAG,IAAA,mCAAgB,EAAC,GAAG,EAAE,aAAa,CAAC,CAAC;IAE/D,4BAA4B;IAC5B,IAAM,cAAc,GAAG,IAAA,yCAAmB,EACtC,MAAM,CAAC,WAAW,EAAE,EACpB,aAAa,EACb,SAAS,EACT,MAAA,CAAC,aAAa,CAAC,OAAO,IAAI,aAAa,CAAC,IAAI;QACxC,CAAC,CAAC,GAAG;QACL,CAAC,CAAC,iBAAiB,CAAC,aAAa,CAAC,IAAI,EAAE,MAAM,CAAC,aAAa,EAAE,CAAC,CAClE,0CAAE,IAAI,CACV,CAAC;IAEF,oEAAoE;IACpE,IAAM,WAAW,GAAG,IAAA,+DAA8B,EAC9C,MAAM,EACN,aAAa,EACb,cAAc,EACd,iBAAiB,EACjB,SAAS,CACZ,CAAC;IAEF,sCAAsC;IACtC,IAAA,mCAAgB,EAAC,WAAW,CAAC,QAAQ,EAAE,iBAAiB,CAAC,cAAc,CAAC,CAAC;IAEzE,kDAAkD;IAClD,IAAA,qCAAiB,EAAC,MAAM,EAAE,WAAW,EAAE,YAAY,CAAC,CAAC;AACzD,CAAC;AArDD,sBAqDC;AAED,SAAS,iBAAiB,CACtB,IAA+B,EAC/B,UAAsB;IAEtB,OAAO,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACpD,CAAC","sourcesContent":["import { cloneModelForPaste, mergePasteContent } from './mergePasteContent';\nimport { convertInlineCss } from '../createModelFromHtml/convertInlineCss';\nimport { createPasteFragment } from './createPasteFragment';\nimport { generatePasteOptionFromPlugins } from './generatePasteOptionFromPlugins';\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 doc = createDOMFromHtml(clipboardData.rawHtml, editor.getDOMCreator());\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, editor.getDOMCreator())\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"]}
|
|
@@ -6,10 +6,10 @@ var roosterjs_content_model_dom_1 = require("roosterjs-content-model-dom");
|
|
|
6
6
|
* @internal
|
|
7
7
|
*/
|
|
8
8
|
function restoreSnapshotHTML(core, snapshot) {
|
|
9
|
-
var _a
|
|
9
|
+
var _a;
|
|
10
10
|
var physicalRoot = core.physicalRoot, entityMap = core.entity.entityMap;
|
|
11
11
|
var refNode = physicalRoot.firstChild;
|
|
12
|
-
var body =
|
|
12
|
+
var body = core.domCreator.htmlToDOM(snapshot.html).body;
|
|
13
13
|
for (var currentNode = body.firstChild; currentNode;) {
|
|
14
14
|
var next = currentNode.nextSibling;
|
|
15
15
|
var originalEntityElement = tryGetEntityElement(entityMap, currentNode);
|
|
@@ -41,7 +41,7 @@ function restoreSnapshotHTML(core, snapshot) {
|
|
|
41
41
|
}
|
|
42
42
|
while (refNode) {
|
|
43
43
|
var next = refNode.nextSibling;
|
|
44
|
-
(
|
|
44
|
+
(_a = refNode.parentNode) === null || _a === void 0 ? void 0 : _a.removeChild(refNode);
|
|
45
45
|
refNode = next;
|
|
46
46
|
}
|
|
47
47
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"restoreSnapshotHTML.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/coreApi/restoreUndoSnapshot/restoreSnapshotHTML.ts"],"names":[],"mappings":";;;AAAA,2EAOqC;AAGrC;;GAEG;AACH,SAAgB,mBAAmB,CAAC,IAAgB,EAAE,QAAkB;;IAEhE,IAAA,YAAY,GAEZ,IAAI,aAFQ,EACF,SAAS,GACnB,IAAI,iBADe,CACd;IACT,IAAI,OAAO,GAAgB,YAAY,CAAC,UAAU,CAAC;IAEnD,IAAM,IAAI,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"restoreSnapshotHTML.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/coreApi/restoreUndoSnapshot/restoreSnapshotHTML.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n getAllEntityWrappers,\n isBlockEntityContainer,\n isEntityElement,\n isNodeOfType,\n parseEntityFormat,\n reuseCachedElement,\n} from 'roosterjs-content-model-dom';\nimport type { Snapshot, EditorCore, KnownEntityItem } from 'roosterjs-content-model-types';\n\n/**\n * @internal\n */\nexport function restoreSnapshotHTML(core: EditorCore, snapshot: Snapshot) {\n const {\n physicalRoot,\n entity: { entityMap },\n } = core;\n let refNode: Node | null = physicalRoot.firstChild;\n\n const body = core.domCreator.htmlToDOM(snapshot.html).body;\n\n for (let currentNode = body.firstChild; currentNode; ) {\n const next = currentNode.nextSibling;\n const originalEntityElement = tryGetEntityElement(entityMap, currentNode);\n\n if (originalEntityElement) {\n refNode = reuseCachedElement(physicalRoot, originalEntityElement, refNode);\n } else {\n physicalRoot.insertBefore(currentNode, refNode);\n\n if (isNodeOfType(currentNode, 'ELEMENT_NODE')) {\n const childEntities = getAllEntityWrappers(currentNode);\n\n childEntities.forEach(element => {\n const wrapper = tryGetEntityElement(entityMap, element);\n\n if (wrapper) {\n if (wrapper == refNode) {\n // In case the node we are moving is just the ref node,\n // We create a temporary clone and insert it before the refNode, and use this cloned node as refNode\n // After replaceChild(), the original refNode will be moved away\n const markerNode = wrapper.cloneNode();\n\n physicalRoot.insertBefore(markerNode, refNode);\n refNode = markerNode;\n }\n\n element.parentNode?.replaceChild(wrapper, element);\n }\n });\n }\n }\n currentNode = next;\n }\n\n while (refNode) {\n const next = refNode.nextSibling;\n\n refNode.parentNode?.removeChild(refNode);\n refNode = next;\n }\n}\n\nfunction tryGetEntityElement(\n entityMap: Record<string, KnownEntityItem>,\n node: Node\n): HTMLElement | null {\n let result: HTMLElement | null = null;\n\n if (isNodeOfType(node, 'ELEMENT_NODE')) {\n if (isEntityElement(node)) {\n const format = parseEntityFormat(node);\n\n result = getEntityWrapperForReuse(entityMap, format.id);\n } else if (isBlockEntityContainer(node)) {\n result = tryGetEntityFromContainer(node, entityMap);\n }\n }\n\n return result;\n}\n\nfunction tryGetEntityFromContainer(\n element: HTMLElement,\n entityMap: Record<string, KnownEntityItem>\n): HTMLElement | null {\n for (let node = element.firstChild; node; node = node.nextSibling) {\n if (isEntityElement(node) && isNodeOfType(node, 'ELEMENT_NODE')) {\n const format = parseEntityFormat(node);\n const parent = getEntityWrapperForReuse(entityMap, format.id)?.parentElement;\n\n return isNodeOfType(parent, 'ELEMENT_NODE') && isBlockEntityContainer(parent)\n ? parent\n : null;\n }\n }\n\n return null;\n}\n\nfunction getEntityWrapperForReuse(\n entityMap: Record<string, KnownEntityItem>,\n entityId: string | undefined\n): HTMLElement | null {\n const entry = entityId ? entityMap[entityId] : undefined;\n\n return entry?.canPersist ? entry.element : null;\n}\n"]}
|
|
@@ -10,41 +10,43 @@ var roosterjs_content_model_dom_1 = require("roosterjs-content-model-dom");
|
|
|
10
10
|
* @param defaultFormat The default segment format to apply
|
|
11
11
|
*/
|
|
12
12
|
function applyDefaultFormat(editor, defaultFormat) {
|
|
13
|
-
editor.
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
(0, roosterjs_content_model_dom_1.
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
13
|
+
var selection = editor.getDOMSelection();
|
|
14
|
+
if ((selection === null || selection === void 0 ? void 0 : selection.type) == 'range' && selection.range.collapsed) {
|
|
15
|
+
editor.formatContentModel(function (model, context) {
|
|
16
|
+
(0, roosterjs_content_model_dom_1.iterateSelections)(model, function (path, _, paragraph, segments) {
|
|
17
|
+
var marker = segments === null || segments === void 0 ? void 0 : segments[0];
|
|
18
|
+
if ((paragraph === null || paragraph === void 0 ? void 0 : paragraph.blockType) == 'Paragraph' &&
|
|
19
|
+
(marker === null || marker === void 0 ? void 0 : marker.segmentType) == 'SelectionMarker') {
|
|
20
|
+
var blocks = path[0].blocks;
|
|
21
|
+
var blockCount = blocks.length;
|
|
22
|
+
var blockIndex = blocks.indexOf(paragraph);
|
|
23
|
+
if (paragraph.isImplicit &&
|
|
24
|
+
paragraph.segments.length == 1 &&
|
|
25
|
+
paragraph.segments[0] == marker &&
|
|
26
|
+
blockCount > 0 &&
|
|
27
|
+
blockIndex == blockCount - 1) {
|
|
28
|
+
// Focus is in the last paragraph which is implicit and there is not other segments.
|
|
29
|
+
// This can happen when focus is moved after all other content under current block group.
|
|
30
|
+
// We need to check if browser will merge focus into previous paragraph by checking if
|
|
31
|
+
// previous block is block. If previous block is paragraph, browser will most likely merge
|
|
32
|
+
// the input into previous paragraph, then nothing need to do here. Otherwise we need to
|
|
33
|
+
// apply pending format since this input event will start a new real paragraph.
|
|
34
|
+
var previousBlock = blocks[blockIndex - 1];
|
|
35
|
+
if ((previousBlock === null || previousBlock === void 0 ? void 0 : previousBlock.blockType) != 'Paragraph') {
|
|
36
|
+
context.newPendingFormat = getNewPendingFormat(editor, defaultFormat, marker.format);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
else if (paragraph.segments.every(function (x) { return x.segmentType != 'Text'; })) {
|
|
40
|
+
context.newPendingFormat = getNewPendingFormat(editor, defaultFormat, marker.format);
|
|
41
|
+
}
|
|
39
42
|
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
});
|
|
43
|
+
// Stop searching more selection
|
|
44
|
+
return true;
|
|
45
|
+
});
|
|
46
|
+
// We didn't do any change but just apply default format to pending format, so no need to write back
|
|
47
|
+
return false;
|
|
48
|
+
});
|
|
49
|
+
}
|
|
48
50
|
}
|
|
49
51
|
exports.applyDefaultFormat = applyDefaultFormat;
|
|
50
52
|
function getNewPendingFormat(editor, defaultFormat, markerFormat) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"applyDefaultFormat.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/corePlugin/format/applyDefaultFormat.ts"],"names":[],"mappings":";;;;AAAA,
|
|
1
|
+
{"version":3,"file":"applyDefaultFormat.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/corePlugin/format/applyDefaultFormat.ts"],"names":[],"mappings":";;;;AAAA,2EAAgE;AAGhE;;;;;GAKG;AACH,SAAgB,kBAAkB,CAAC,MAAe,EAAE,aAAwC;IACxF,IAAM,SAAS,GAAG,MAAM,CAAC,eAAe,EAAE,CAAC;IAE3C,IAAI,CAAA,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,IAAI,KAAI,OAAO,IAAI,SAAS,CAAC,KAAK,CAAC,SAAS,EAAE;QACzD,MAAM,CAAC,kBAAkB,CAAC,UAAC,KAAK,EAAE,OAAO;YACrC,IAAA,+CAAiB,EAAC,KAAK,EAAE,UAAC,IAAI,EAAE,CAAC,EAAE,SAAS,EAAE,QAAQ;gBAClD,IAAM,MAAM,GAAG,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAG,CAAC,CAAC,CAAC;gBAC7B,IACI,CAAA,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,SAAS,KAAI,WAAW;oBACnC,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,WAAW,KAAI,iBAAiB,EAC1C;oBACE,IAAM,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;oBAC9B,IAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC;oBACjC,IAAM,UAAU,GAAG,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;oBAE7C,IACI,SAAS,CAAC,UAAU;wBACpB,SAAS,CAAC,QAAQ,CAAC,MAAM,IAAI,CAAC;wBAC9B,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,MAAM;wBAC/B,UAAU,GAAG,CAAC;wBACd,UAAU,IAAI,UAAU,GAAG,CAAC,EAC9B;wBACE,oFAAoF;wBACpF,yFAAyF;wBACzF,sFAAsF;wBACtF,0FAA0F;wBAC1F,wFAAwF;wBACxF,+EAA+E;wBAC/E,IAAM,aAAa,GAAG,MAAM,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC;wBAE7C,IAAI,CAAA,aAAa,aAAb,aAAa,uBAAb,aAAa,CAAE,SAAS,KAAI,WAAW,EAAE;4BACzC,OAAO,CAAC,gBAAgB,GAAG,mBAAmB,CAC1C,MAAM,EACN,aAAa,EACb,MAAM,CAAC,MAAM,CAChB,CAAC;yBACL;qBACJ;yBAAM,IAAI,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,UAAA,CAAC,IAAI,OAAA,CAAC,CAAC,WAAW,IAAI,MAAM,EAAvB,CAAuB,CAAC,EAAE;wBAC/D,OAAO,CAAC,gBAAgB,GAAG,mBAAmB,CAC1C,MAAM,EACN,aAAa,EACb,MAAM,CAAC,MAAM,CAChB,CAAC;qBACL;iBACJ;gBAED,gCAAgC;gBAChC,OAAO,IAAI,CAAC;YAChB,CAAC,CAAC,CAAC;YAEH,oGAAoG;YACpG,OAAO,KAAK,CAAC;QACjB,CAAC,CAAC,CAAC;KACN;AACL,CAAC;AAtDD,gDAsDC;AAED,SAAS,mBAAmB,CACxB,MAAe,EACf,aAAwC,EACxC,YAAuC;IAEvC,6EACO,aAAa,GACb,MAAM,CAAC,gBAAgB,EAAE,GACzB,YAAY,EACjB;AACN,CAAC","sourcesContent":["import { iterateSelections } from 'roosterjs-content-model-dom';\nimport type { ContentModelSegmentFormat, IEditor } from 'roosterjs-content-model-types';\n\n/**\n * @internal\n * When necessary, set default format as current pending format so it will be applied when Input event is fired\n * @param editor The editor object\n * @param defaultFormat The default segment format to apply\n */\nexport function applyDefaultFormat(editor: IEditor, defaultFormat: ContentModelSegmentFormat) {\n const selection = editor.getDOMSelection();\n\n if (selection?.type == 'range' && selection.range.collapsed) {\n editor.formatContentModel((model, context) => {\n iterateSelections(model, (path, _, paragraph, segments) => {\n const marker = segments?.[0];\n if (\n paragraph?.blockType == 'Paragraph' &&\n marker?.segmentType == 'SelectionMarker'\n ) {\n const blocks = path[0].blocks;\n const blockCount = blocks.length;\n const blockIndex = blocks.indexOf(paragraph);\n\n if (\n paragraph.isImplicit &&\n paragraph.segments.length == 1 &&\n paragraph.segments[0] == marker &&\n blockCount > 0 &&\n blockIndex == blockCount - 1\n ) {\n // Focus is in the last paragraph which is implicit and there is not other segments.\n // This can happen when focus is moved after all other content under current block group.\n // We need to check if browser will merge focus into previous paragraph by checking if\n // previous block is block. If previous block is paragraph, browser will most likely merge\n // the input into previous paragraph, then nothing need to do here. Otherwise we need to\n // apply pending format since this input event will start a new real paragraph.\n const previousBlock = blocks[blockIndex - 1];\n\n if (previousBlock?.blockType != 'Paragraph') {\n context.newPendingFormat = getNewPendingFormat(\n editor,\n defaultFormat,\n marker.format\n );\n }\n } else if (paragraph.segments.every(x => x.segmentType != 'Text')) {\n context.newPendingFormat = getNewPendingFormat(\n editor,\n defaultFormat,\n marker.format\n );\n }\n }\n\n // Stop searching more selection\n return true;\n });\n\n // We didn't do any change but just apply default format to pending format, so no need to write back\n return false;\n });\n }\n}\n\nfunction getNewPendingFormat(\n editor: IEditor,\n defaultFormat: ContentModelSegmentFormat,\n markerFormat: ContentModelSegmentFormat\n): ContentModelSegmentFormat {\n return {\n ...defaultFormat,\n ...editor.getPendingFormat(),\n ...markerFormat,\n };\n}\n"]}
|
package/lib/editor/Editor.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ContentModelDocument, ContentModelFormatter, ContentModelSegmentFormat, DarkColorHandler, DOMEventRecord, DOMHelper, DOMSelection, EditorEnvironment, FormatContentModelOptions, IEditor, PluginEventData, PluginEventFromType, PluginEventType, Snapshot, SnapshotsManager, EditorCore, EditorOptions,
|
|
1
|
+
import type { ContentModelDocument, ContentModelFormatter, ContentModelSegmentFormat, DarkColorHandler, DOMEventRecord, DOMHelper, DOMSelection, EditorEnvironment, FormatContentModelOptions, IEditor, PluginEventData, PluginEventFromType, PluginEventType, Snapshot, SnapshotsManager, EditorCore, EditorOptions, Rect, EntityState, DomToModelOptionForCreateModel, AnnounceData, ExperimentalFeature, LegacyTrustedHTMLHandler, DOMCreator } from 'roosterjs-content-model-types';
|
|
2
2
|
/**
|
|
3
3
|
* The main editor class based on Content Model
|
|
4
4
|
*/
|
|
@@ -139,12 +139,20 @@ export declare class Editor implements IEditor {
|
|
|
139
139
|
*/
|
|
140
140
|
getColorManager(): DarkColorHandler;
|
|
141
141
|
/**
|
|
142
|
+
* @deprecated
|
|
142
143
|
* Get a function to convert HTML string to trusted HTML string.
|
|
143
144
|
* By default it will just return the input HTML directly. To override this behavior,
|
|
144
145
|
* pass your own trusted HTML handler to EditorOptions.trustedHTMLHandler
|
|
145
146
|
* See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/trusted-types
|
|
146
147
|
*/
|
|
147
|
-
getTrustedHTMLHandler():
|
|
148
|
+
getTrustedHTMLHandler(): LegacyTrustedHTMLHandler;
|
|
149
|
+
/**
|
|
150
|
+
* Get a function to convert HTML string to a trust Document.
|
|
151
|
+
* By default it will just convert the original HTML string into a Document object directly.
|
|
152
|
+
* To override, pass your own trusted HTML handler to EditorOptions.trustedHTMLHandler
|
|
153
|
+
* See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/trusted-types
|
|
154
|
+
*/
|
|
155
|
+
getDOMCreator(): DOMCreator;
|
|
148
156
|
/**
|
|
149
157
|
* Get the scroll container of the editor
|
|
150
158
|
*/
|
package/lib/editor/Editor.js
CHANGED
|
@@ -267,6 +267,7 @@ var Editor = /** @class */ (function () {
|
|
|
267
267
|
return this.getCore().darkColorHandler;
|
|
268
268
|
};
|
|
269
269
|
/**
|
|
270
|
+
* @deprecated
|
|
270
271
|
* Get a function to convert HTML string to trusted HTML string.
|
|
271
272
|
* By default it will just return the input HTML directly. To override this behavior,
|
|
272
273
|
* pass your own trusted HTML handler to EditorOptions.trustedHTMLHandler
|
|
@@ -275,6 +276,15 @@ var Editor = /** @class */ (function () {
|
|
|
275
276
|
Editor.prototype.getTrustedHTMLHandler = function () {
|
|
276
277
|
return this.getCore().trustedHTMLHandler;
|
|
277
278
|
};
|
|
279
|
+
/**
|
|
280
|
+
* Get a function to convert HTML string to a trust Document.
|
|
281
|
+
* By default it will just convert the original HTML string into a Document object directly.
|
|
282
|
+
* To override, pass your own trusted HTML handler to EditorOptions.trustedHTMLHandler
|
|
283
|
+
* See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/trusted-types
|
|
284
|
+
*/
|
|
285
|
+
Editor.prototype.getDOMCreator = function () {
|
|
286
|
+
return this.getCore().domCreator;
|
|
287
|
+
};
|
|
278
288
|
/**
|
|
279
289
|
* Get the scroll container of the editor
|
|
280
290
|
*/
|
package/lib/editor/Editor.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Editor.js","sourceRoot":"","sources":["../../../../packages/roosterjs-content-model-core/lib/editor/Editor.ts"],"names":[],"mappings":"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","sourcesContent":["import { createEditorCore } from './core/createEditorCore';\nimport {\n createEmptyModel,\n ChangeSource,\n cloneModel,\n transformColor,\n createDomToModelContextWithConfig,\n domToContentModel,\n} from 'roosterjs-content-model-dom';\nimport type {\n ContentModelDocument,\n ContentModelFormatter,\n ContentModelSegmentFormat,\n DarkColorHandler,\n DOMEventRecord,\n DOMHelper,\n DOMSelection,\n EditorEnvironment,\n FormatContentModelOptions,\n IEditor,\n PluginEventData,\n PluginEventFromType,\n PluginEventType,\n Snapshot,\n SnapshotsManager,\n EditorCore,\n EditorOptions,\n TrustedHTMLHandler,\n Rect,\n EntityState,\n CachedElementHandler,\n DomToModelOptionForCreateModel,\n AnnounceData,\n ExperimentalFeature,\n} from 'roosterjs-content-model-types';\n\n/**\n * The main editor class based on Content Model\n */\nexport class Editor implements IEditor {\n private core: EditorCore | null = null;\n\n /**\n * Creates an instance of Editor\n * @param contentDiv The DIV HTML element which will be the container element of editor\n * @param options An optional options object to customize the editor\n */\n constructor(contentDiv: HTMLDivElement, options: EditorOptions = {}) {\n this.core = createEditorCore(contentDiv, options);\n\n const initialModel = options.initialModel ?? createEmptyModel(options.defaultSegmentFormat);\n\n this.core.api.setContentModel(\n this.core,\n initialModel,\n { ignoreSelection: true },\n undefined /*onNodeCreated*/,\n true /*isInitializing*/\n );\n this.core.plugins.forEach(plugin => plugin.initialize(this));\n }\n\n /**\n * Dispose this editor, dispose all plugins and custom data\n */\n dispose() {\n const core = this.getCore();\n\n for (let i = core.plugins.length - 1; i >= 0; i--) {\n const plugin = core.plugins[i];\n\n try {\n plugin.dispose();\n } catch (e) {\n // Cache the error and pass it out, then keep going since dispose should always succeed\n core.disposeErrorHandler?.(plugin, e as Error);\n }\n }\n\n core.darkColorHandler.reset();\n\n this.core = null;\n }\n\n /**\n * Get whether this editor is disposed\n * @returns True if editor is disposed, otherwise false\n */\n isDisposed(): boolean {\n return !this.core;\n }\n\n /**\n * Create Content Model from DOM tree in this editor\n * @param mode What kind of Content Model we want. Currently we support the following values:\n * - disconnected: Returns a disconnected clone of Content Model from editor which you can do any change on it and it won't impact the editor content.\n * If there is any entity in editor, the returned object will contain cloned copy of entity wrapper element.\n * If editor is in dark mode, the cloned entity will be converted back to light mode.\n * - clean: Similar with disconnected, this will return a disconnected model, the difference is \"clean\" mode will not include any selection info.\n * This is usually used for exporting content\n */\n getContentModelCopy(mode: 'connected' | 'disconnected' | 'clean'): ContentModelDocument {\n const core = this.getCore();\n\n switch (mode) {\n case 'connected': // Get a connected model is deprecated. Now we will always return disconnected model\n case 'disconnected':\n return cloneModel(\n core.api.createContentModel(core, {\n tryGetFromCache: false,\n }),\n {\n includeCachedElement: this.cloneOptionCallback,\n }\n );\n\n case 'clean':\n const domToModelContext = createDomToModelContextWithConfig(\n core.environment.domToModelSettings.calculated,\n core.api.createEditorContext(core, false /*saveIndex*/)\n );\n\n return cloneModel(domToContentModel(core.physicalRoot, domToModelContext), {\n includeCachedElement: this.cloneOptionCallback,\n });\n }\n }\n\n /**\n * Get current running environment, such as if editor is running on Mac\n */\n getEnvironment(): EditorEnvironment {\n return this.getCore().environment;\n }\n\n /**\n * Get current DOM selection\n */\n getDOMSelection(): DOMSelection | null {\n const core = this.getCore();\n\n return core.api.getDOMSelection(core);\n }\n\n /**\n * Set DOMSelection into editor content.\n * @param selection The selection to set\n */\n setDOMSelection(selection: DOMSelection | null) {\n const core = this.getCore();\n\n core.api.setDOMSelection(core, selection);\n }\n\n /**\n * Set a new logical root (most likely due to focus change)\n * @param logicalRoot The new logical root (has to be child of physicalRoot)\n */\n setLogicalRoot(logicalRoot: HTMLDivElement) {\n const core = this.getCore();\n\n core.api.setLogicalRoot(core, logicalRoot);\n }\n\n /**\n * The general API to do format change with Content Model\n * It will grab a Content Model for current editor content, and invoke a callback function\n * to do format change. Then according to the return value, write back the modified content model into editor.\n * If there is cached model, it will be used and updated.\n * @param formatter Formatter function, see ContentModelFormatter\n * @param options More options, see FormatContentModelOptions\n */\n formatContentModel(\n formatter: ContentModelFormatter,\n options?: FormatContentModelOptions,\n domToModelOptions?: DomToModelOptionForCreateModel\n ): void {\n const core = this.getCore();\n\n core.api.formatContentModel(core, formatter, options, domToModelOptions);\n }\n\n /**\n * Get pending format of editor if any, or return null\n */\n getPendingFormat(): ContentModelSegmentFormat | null {\n return this.getCore().format.pendingFormat?.format ?? null;\n }\n\n /**\n * Get a DOM Helper object to help access DOM tree in editor\n */\n getDOMHelper(): DOMHelper {\n return this.getCore().domHelper;\n }\n\n /**\n * Add a single undo snapshot to undo stack\n * @param entityState @optional State for entity if we want to add entity state for this snapshot\n */\n takeSnapshot(entityState?: EntityState): Snapshot | null {\n const core = this.getCore();\n\n return core.api.addUndoSnapshot(\n core,\n false /*canUndoByBackspace*/,\n entityState ? [entityState] : undefined\n );\n }\n\n /**\n * Restore an undo snapshot into editor\n * @param snapshot The snapshot to restore\n */\n restoreSnapshot(snapshot: Snapshot): void {\n const core = this.getCore();\n\n core.api.restoreUndoSnapshot(core, snapshot);\n }\n\n /**\n * Get document which contains this editor\n * @returns The HTML document which contains this editor\n */\n getDocument(): Document {\n return this.getCore().physicalRoot.ownerDocument;\n }\n\n /**\n * Focus to this editor, the selection was restored to where it was before, no unexpected scroll.\n */\n focus() {\n const core = this.getCore();\n core.api.focus(core);\n }\n\n /**\n * Check if focus is in editor now\n * @returns true if focus is in editor, otherwise false\n */\n hasFocus(): boolean {\n const core = this.getCore();\n return core.domHelper.hasFocus();\n }\n\n /**\n * Trigger an event to be dispatched to all plugins\n * @param eventType Type of the event\n * @param data data of the event with given type, this is the rest part of PluginEvent with the given type\n * @param broadcast indicates if the event needs to be dispatched to all plugins\n * True means to all, false means to allow exclusive handling from one plugin unless no one wants that\n * @returns the event object which is really passed into plugins. Some plugin may modify the event object so\n * the result of this function provides a chance to read the modified result\n */\n triggerEvent<T extends PluginEventType>(\n eventType: T,\n data: PluginEventData<T>,\n broadcast: boolean = false\n ): PluginEventFromType<T> {\n const core = this.getCore();\n const event = ({\n eventType,\n ...data,\n } as any) as PluginEventFromType<T>;\n core.api.triggerEvent(core, event, broadcast);\n\n return event;\n }\n\n /**\n * Attach a DOM event to the editor content DIV\n * @param eventMap A map from event name to its handler\n */\n attachDomEvent(eventMap: Record<string, DOMEventRecord>): () => void {\n const core = this.getCore();\n return core.api.attachDomEvent(core, eventMap);\n }\n\n /**\n * Get undo snapshots manager\n */\n getSnapshotsManager(): SnapshotsManager {\n const core = this.getCore();\n\n return core.undo.snapshotsManager;\n }\n\n /**\n * Check if the editor is in dark mode\n * @returns True if the editor is in dark mode, otherwise false\n */\n isDarkMode(): boolean {\n return this.getCore().lifecycle.isDarkMode;\n }\n\n /**\n * Set the dark mode state and transforms the content to match the new state.\n * @param isDarkMode The next status of dark mode. True if the editor should be in dark mode, false if not.\n */\n setDarkModeState(isDarkMode?: boolean) {\n const core = this.getCore();\n\n if (!!isDarkMode != core.lifecycle.isDarkMode) {\n transformColor(\n core.physicalRoot,\n false /*includeSelf*/,\n isDarkMode ? 'lightToDark' : 'darkToLight',\n core.darkColorHandler\n );\n\n core.lifecycle.isDarkMode = !!isDarkMode;\n\n core.api.triggerEvent(\n core,\n {\n eventType: 'contentChanged',\n source: isDarkMode\n ? ChangeSource.SwitchToDarkMode\n : ChangeSource.SwitchToLightMode,\n },\n true\n );\n }\n }\n\n /**\n * Check if editor is in Shadow Edit mode\n */\n isInShadowEdit() {\n return !!this.getCore().lifecycle.shadowEditFragment;\n }\n\n /**\n * Make the editor in \"Shadow Edit\" mode.\n * In Shadow Edit mode, all format change will finally be ignored.\n * This can be used for building a live preview feature for format button, to allow user\n * see format result without really apply it.\n * This function can be called repeated. If editor is already in shadow edit mode, we can still\n * use this function to do more shadow edit operation.\n */\n startShadowEdit() {\n const core = this.getCore();\n core.api.switchShadowEdit(core, true /*isOn*/);\n }\n\n /**\n * Leave \"Shadow Edit\" mode, all changes made during shadow edit will be discarded\n */\n stopShadowEdit() {\n const core = this.getCore();\n core.api.switchShadowEdit(core, false /*isOn*/);\n }\n\n /**\n * Get a color manager object for this editor.\n */\n getColorManager(): DarkColorHandler {\n return this.getCore().darkColorHandler;\n }\n\n /**\n * Get a function to convert HTML string to trusted HTML string.\n * By default it will just return the input HTML directly. To override this behavior,\n * pass your own trusted HTML handler to EditorOptions.trustedHTMLHandler\n * See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/trusted-types\n */\n getTrustedHTMLHandler(): TrustedHTMLHandler {\n return this.getCore().trustedHTMLHandler;\n }\n\n /**\n * Get the scroll container of the editor\n */\n getScrollContainer(): HTMLElement {\n return this.getCore().domEvent.scrollContainer;\n }\n\n /**\n * Retrieves the rect of the visible viewport of the editor.\n */\n getVisibleViewport(): Rect | null {\n return this.getCore().api.getVisibleViewport(this.getCore());\n }\n\n /**\n * Add CSS rules for editor\n * @param key A string to identify the CSS rule type. When set CSS rules with the same key again, existing rules with the same key will be replaced.\n * @param cssRule The CSS rule string, must be a valid CSS rule string, or browser may throw exception. Pass null to clear existing rules\n * @param subSelectors @optional If the rule is used for child element under editor, use this parameter to specify the child elements. Each item will be\n * combined with root selector together to build a separate rule.\n */\n setEditorStyle(\n key: string,\n cssRule: string | null,\n subSelectors?: 'before' | 'after' | string[]\n ): void {\n const core = this.getCore();\n\n core.api.setEditorStyle(core, key, cssRule, subSelectors);\n }\n\n /**\n * Announce the given data\n * @param announceData Data to announce\n */\n announce(announceData: AnnounceData): void {\n const core = this.getCore();\n\n core.api.announce(core, announceData);\n }\n\n /**\n * Check if a given feature is enabled\n * @param featureName The name of feature to check\n */\n isExperimentalFeatureEnabled(featureName: ExperimentalFeature | string): boolean {\n return this.getCore().experimentalFeatures.indexOf(featureName) >= 0;\n }\n\n /**\n * @returns the current EditorCore object\n * @throws a standard Error if there's no core object\n */\n protected getCore(): EditorCore {\n if (!this.core) {\n throw new Error('Editor is already disposed');\n }\n return this.core;\n }\n\n private cloneOptionCallback: CachedElementHandler = (node, type) => {\n if (type == 'cache') {\n return undefined;\n }\n\n const result = node.cloneNode(true /*deep*/) as HTMLElement;\n\n if (this.isDarkMode()) {\n const colorHandler = this.getColorManager();\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\n return result;\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"Editor.js","sourceRoot":"","sources":["../../../../packages/roosterjs-content-model-core/lib/editor/Editor.ts"],"names":[],"mappings":"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","sourcesContent":["import { createEditorCore } from './core/createEditorCore';\nimport {\n createEmptyModel,\n ChangeSource,\n cloneModel,\n transformColor,\n createDomToModelContextWithConfig,\n domToContentModel,\n} from 'roosterjs-content-model-dom';\nimport type {\n ContentModelDocument,\n ContentModelFormatter,\n ContentModelSegmentFormat,\n DarkColorHandler,\n DOMEventRecord,\n DOMHelper,\n DOMSelection,\n EditorEnvironment,\n FormatContentModelOptions,\n IEditor,\n PluginEventData,\n PluginEventFromType,\n PluginEventType,\n Snapshot,\n SnapshotsManager,\n EditorCore,\n EditorOptions,\n Rect,\n EntityState,\n CachedElementHandler,\n DomToModelOptionForCreateModel,\n AnnounceData,\n ExperimentalFeature,\n LegacyTrustedHTMLHandler,\n DOMCreator,\n} from 'roosterjs-content-model-types';\n\n/**\n * The main editor class based on Content Model\n */\nexport class Editor implements IEditor {\n private core: EditorCore | null = null;\n\n /**\n * Creates an instance of Editor\n * @param contentDiv The DIV HTML element which will be the container element of editor\n * @param options An optional options object to customize the editor\n */\n constructor(contentDiv: HTMLDivElement, options: EditorOptions = {}) {\n this.core = createEditorCore(contentDiv, options);\n\n const initialModel = options.initialModel ?? createEmptyModel(options.defaultSegmentFormat);\n\n this.core.api.setContentModel(\n this.core,\n initialModel,\n { ignoreSelection: true },\n undefined /*onNodeCreated*/,\n true /*isInitializing*/\n );\n this.core.plugins.forEach(plugin => plugin.initialize(this));\n }\n\n /**\n * Dispose this editor, dispose all plugins and custom data\n */\n dispose() {\n const core = this.getCore();\n\n for (let i = core.plugins.length - 1; i >= 0; i--) {\n const plugin = core.plugins[i];\n\n try {\n plugin.dispose();\n } catch (e) {\n // Cache the error and pass it out, then keep going since dispose should always succeed\n core.disposeErrorHandler?.(plugin, e as Error);\n }\n }\n\n core.darkColorHandler.reset();\n\n this.core = null;\n }\n\n /**\n * Get whether this editor is disposed\n * @returns True if editor is disposed, otherwise false\n */\n isDisposed(): boolean {\n return !this.core;\n }\n\n /**\n * Create Content Model from DOM tree in this editor\n * @param mode What kind of Content Model we want. Currently we support the following values:\n * - disconnected: Returns a disconnected clone of Content Model from editor which you can do any change on it and it won't impact the editor content.\n * If there is any entity in editor, the returned object will contain cloned copy of entity wrapper element.\n * If editor is in dark mode, the cloned entity will be converted back to light mode.\n * - clean: Similar with disconnected, this will return a disconnected model, the difference is \"clean\" mode will not include any selection info.\n * This is usually used for exporting content\n */\n getContentModelCopy(mode: 'connected' | 'disconnected' | 'clean'): ContentModelDocument {\n const core = this.getCore();\n\n switch (mode) {\n case 'connected': // Get a connected model is deprecated. Now we will always return disconnected model\n case 'disconnected':\n return cloneModel(\n core.api.createContentModel(core, {\n tryGetFromCache: false,\n }),\n {\n includeCachedElement: this.cloneOptionCallback,\n }\n );\n\n case 'clean':\n const domToModelContext = createDomToModelContextWithConfig(\n core.environment.domToModelSettings.calculated,\n core.api.createEditorContext(core, false /*saveIndex*/)\n );\n\n return cloneModel(domToContentModel(core.physicalRoot, domToModelContext), {\n includeCachedElement: this.cloneOptionCallback,\n });\n }\n }\n\n /**\n * Get current running environment, such as if editor is running on Mac\n */\n getEnvironment(): EditorEnvironment {\n return this.getCore().environment;\n }\n\n /**\n * Get current DOM selection\n */\n getDOMSelection(): DOMSelection | null {\n const core = this.getCore();\n\n return core.api.getDOMSelection(core);\n }\n\n /**\n * Set DOMSelection into editor content.\n * @param selection The selection to set\n */\n setDOMSelection(selection: DOMSelection | null) {\n const core = this.getCore();\n\n core.api.setDOMSelection(core, selection);\n }\n\n /**\n * Set a new logical root (most likely due to focus change)\n * @param logicalRoot The new logical root (has to be child of physicalRoot)\n */\n setLogicalRoot(logicalRoot: HTMLDivElement) {\n const core = this.getCore();\n\n core.api.setLogicalRoot(core, logicalRoot);\n }\n\n /**\n * The general API to do format change with Content Model\n * It will grab a Content Model for current editor content, and invoke a callback function\n * to do format change. Then according to the return value, write back the modified content model into editor.\n * If there is cached model, it will be used and updated.\n * @param formatter Formatter function, see ContentModelFormatter\n * @param options More options, see FormatContentModelOptions\n */\n formatContentModel(\n formatter: ContentModelFormatter,\n options?: FormatContentModelOptions,\n domToModelOptions?: DomToModelOptionForCreateModel\n ): void {\n const core = this.getCore();\n\n core.api.formatContentModel(core, formatter, options, domToModelOptions);\n }\n\n /**\n * Get pending format of editor if any, or return null\n */\n getPendingFormat(): ContentModelSegmentFormat | null {\n return this.getCore().format.pendingFormat?.format ?? null;\n }\n\n /**\n * Get a DOM Helper object to help access DOM tree in editor\n */\n getDOMHelper(): DOMHelper {\n return this.getCore().domHelper;\n }\n\n /**\n * Add a single undo snapshot to undo stack\n * @param entityState @optional State for entity if we want to add entity state for this snapshot\n */\n takeSnapshot(entityState?: EntityState): Snapshot | null {\n const core = this.getCore();\n\n return core.api.addUndoSnapshot(\n core,\n false /*canUndoByBackspace*/,\n entityState ? [entityState] : undefined\n );\n }\n\n /**\n * Restore an undo snapshot into editor\n * @param snapshot The snapshot to restore\n */\n restoreSnapshot(snapshot: Snapshot): void {\n const core = this.getCore();\n\n core.api.restoreUndoSnapshot(core, snapshot);\n }\n\n /**\n * Get document which contains this editor\n * @returns The HTML document which contains this editor\n */\n getDocument(): Document {\n return this.getCore().physicalRoot.ownerDocument;\n }\n\n /**\n * Focus to this editor, the selection was restored to where it was before, no unexpected scroll.\n */\n focus() {\n const core = this.getCore();\n core.api.focus(core);\n }\n\n /**\n * Check if focus is in editor now\n * @returns true if focus is in editor, otherwise false\n */\n hasFocus(): boolean {\n const core = this.getCore();\n return core.domHelper.hasFocus();\n }\n\n /**\n * Trigger an event to be dispatched to all plugins\n * @param eventType Type of the event\n * @param data data of the event with given type, this is the rest part of PluginEvent with the given type\n * @param broadcast indicates if the event needs to be dispatched to all plugins\n * True means to all, false means to allow exclusive handling from one plugin unless no one wants that\n * @returns the event object which is really passed into plugins. Some plugin may modify the event object so\n * the result of this function provides a chance to read the modified result\n */\n triggerEvent<T extends PluginEventType>(\n eventType: T,\n data: PluginEventData<T>,\n broadcast: boolean = false\n ): PluginEventFromType<T> {\n const core = this.getCore();\n const event = ({\n eventType,\n ...data,\n } as any) as PluginEventFromType<T>;\n core.api.triggerEvent(core, event, broadcast);\n\n return event;\n }\n\n /**\n * Attach a DOM event to the editor content DIV\n * @param eventMap A map from event name to its handler\n */\n attachDomEvent(eventMap: Record<string, DOMEventRecord>): () => void {\n const core = this.getCore();\n return core.api.attachDomEvent(core, eventMap);\n }\n\n /**\n * Get undo snapshots manager\n */\n getSnapshotsManager(): SnapshotsManager {\n const core = this.getCore();\n\n return core.undo.snapshotsManager;\n }\n\n /**\n * Check if the editor is in dark mode\n * @returns True if the editor is in dark mode, otherwise false\n */\n isDarkMode(): boolean {\n return this.getCore().lifecycle.isDarkMode;\n }\n\n /**\n * Set the dark mode state and transforms the content to match the new state.\n * @param isDarkMode The next status of dark mode. True if the editor should be in dark mode, false if not.\n */\n setDarkModeState(isDarkMode?: boolean) {\n const core = this.getCore();\n\n if (!!isDarkMode != core.lifecycle.isDarkMode) {\n transformColor(\n core.physicalRoot,\n false /*includeSelf*/,\n isDarkMode ? 'lightToDark' : 'darkToLight',\n core.darkColorHandler\n );\n\n core.lifecycle.isDarkMode = !!isDarkMode;\n\n core.api.triggerEvent(\n core,\n {\n eventType: 'contentChanged',\n source: isDarkMode\n ? ChangeSource.SwitchToDarkMode\n : ChangeSource.SwitchToLightMode,\n },\n true\n );\n }\n }\n\n /**\n * Check if editor is in Shadow Edit mode\n */\n isInShadowEdit() {\n return !!this.getCore().lifecycle.shadowEditFragment;\n }\n\n /**\n * Make the editor in \"Shadow Edit\" mode.\n * In Shadow Edit mode, all format change will finally be ignored.\n * This can be used for building a live preview feature for format button, to allow user\n * see format result without really apply it.\n * This function can be called repeated. If editor is already in shadow edit mode, we can still\n * use this function to do more shadow edit operation.\n */\n startShadowEdit() {\n const core = this.getCore();\n core.api.switchShadowEdit(core, true /*isOn*/);\n }\n\n /**\n * Leave \"Shadow Edit\" mode, all changes made during shadow edit will be discarded\n */\n stopShadowEdit() {\n const core = this.getCore();\n core.api.switchShadowEdit(core, false /*isOn*/);\n }\n\n /**\n * Get a color manager object for this editor.\n */\n getColorManager(): DarkColorHandler {\n return this.getCore().darkColorHandler;\n }\n\n /**\n * @deprecated\n * Get a function to convert HTML string to trusted HTML string.\n * By default it will just return the input HTML directly. To override this behavior,\n * pass your own trusted HTML handler to EditorOptions.trustedHTMLHandler\n * See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/trusted-types\n */\n getTrustedHTMLHandler(): LegacyTrustedHTMLHandler {\n return this.getCore().trustedHTMLHandler;\n }\n\n /**\n * Get a function to convert HTML string to a trust Document.\n * By default it will just convert the original HTML string into a Document object directly.\n * To override, pass your own trusted HTML handler to EditorOptions.trustedHTMLHandler\n * See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/trusted-types\n */\n getDOMCreator(): DOMCreator {\n return this.getCore().domCreator;\n }\n\n /**\n * Get the scroll container of the editor\n */\n getScrollContainer(): HTMLElement {\n return this.getCore().domEvent.scrollContainer;\n }\n\n /**\n * Retrieves the rect of the visible viewport of the editor.\n */\n getVisibleViewport(): Rect | null {\n return this.getCore().api.getVisibleViewport(this.getCore());\n }\n\n /**\n * Add CSS rules for editor\n * @param key A string to identify the CSS rule type. When set CSS rules with the same key again, existing rules with the same key will be replaced.\n * @param cssRule The CSS rule string, must be a valid CSS rule string, or browser may throw exception. Pass null to clear existing rules\n * @param subSelectors @optional If the rule is used for child element under editor, use this parameter to specify the child elements. Each item will be\n * combined with root selector together to build a separate rule.\n */\n setEditorStyle(\n key: string,\n cssRule: string | null,\n subSelectors?: 'before' | 'after' | string[]\n ): void {\n const core = this.getCore();\n\n core.api.setEditorStyle(core, key, cssRule, subSelectors);\n }\n\n /**\n * Announce the given data\n * @param announceData Data to announce\n */\n announce(announceData: AnnounceData): void {\n const core = this.getCore();\n\n core.api.announce(core, announceData);\n }\n\n /**\n * Check if a given feature is enabled\n * @param featureName The name of feature to check\n */\n isExperimentalFeatureEnabled(featureName: ExperimentalFeature | string): boolean {\n return this.getCore().experimentalFeatures.indexOf(featureName) >= 0;\n }\n\n /**\n * @returns the current EditorCore object\n * @throws a standard Error if there's no core object\n */\n protected getCore(): EditorCore {\n if (!this.core) {\n throw new Error('Editor is already disposed');\n }\n return this.core;\n }\n\n private cloneOptionCallback: CachedElementHandler = (node, type) => {\n if (type == 'cache') {\n return undefined;\n }\n\n const result = node.cloneNode(true /*deep*/) as HTMLElement;\n\n if (this.isDarkMode()) {\n const colorHandler = this.getColorManager();\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\n return result;\n };\n}\n"]}
|
|
@@ -5,10 +5,6 @@ import type { EditorCore, EditorOptions } from 'roosterjs-content-model-types';
|
|
|
5
5
|
* @param options Editor options
|
|
6
6
|
*/
|
|
7
7
|
export declare function createEditorCore(contentDiv: HTMLDivElement, options: EditorOptions): EditorCore;
|
|
8
|
-
/**
|
|
9
|
-
* @internal export for test only
|
|
10
|
-
*/
|
|
11
|
-
export declare function defaultTrustHtmlHandler(html: string): string;
|
|
12
8
|
/**
|
|
13
9
|
* @internal Export for test only
|
|
14
10
|
* A fallback function, always return original color
|