Skip to content

Commit

Permalink
Publish 8.37.0 with 4 changes (#1430)
Browse files Browse the repository at this point in the history
* Fix a list color issue in dark mode (#1428) (#1429)

* Fix a list color issue in dark mode

* fix test

* Add test

* Improve shadow edit behavior when there is entity in editor (#1408)

* Move mergeFragmentWithEntity to roosterjs

* Shadow edit with entity

* 8.37.0

* Merge pull request #1425 from microsoft/u/juliaroldi/auto-format-list-special-char

Valid numbering

* Merge pull request #1426 from microsoft/u/juliaroldi/previous-line-bug

Fix cursor jump bug.

Co-authored-by: Julia Roldi <[email protected]>
  • Loading branch information
2 people authored and BryanValverdeU committed Feb 10, 2023
1 parent b9c5f37 commit 2c0add2
Show file tree
Hide file tree
Showing 22 changed files with 76 additions and 661 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ const initialState: BuildInPluginState = {
ExperimentalFeatures.ListItemAlignment,
ExperimentalFeatures.PendingStyleBasedFormat,
ExperimentalFeatures.DefaultFormatInSpan,
ExperimentalFeatures.AutoFormatList,
],
isRtl: false,
};
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "roosterjs",
"version": "8.36.0",
"version": "8.37.0",
"description": "Framework-independent javascript editor",
"repository": {
"type": "git",
Expand Down
9 changes: 1 addition & 8 deletions packages/roosterjs-content-model/lib/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
export { default as domToContentModel } from './publicApi/domToContentModel';
export { default as contentModelToDom } from './publicApi/contentModelToDom';
export {
default as mergeFragmentWithEntity,
preprocessEntitiesFromContentModel,
} from './publicApi/mergeFragmentWithEntity';
export { default as insertTable } from './publicApi/table/insertTable';
export { default as formatTable } from './publicApi/table/formatTable';
export { default as setTableCellShade } from './publicApi/table/setTableCellShade';
Expand Down Expand Up @@ -123,10 +119,7 @@ export {
ContentModelHandlerTypeMap,
DefaultImplicitSegmentFormatMap,
} from './publicTypes/context/ModelToDomSettings';
export {
ModelToDomEntityContext,
EntityPlaceholderPair,
} from './publicTypes/context/ModelToDomEntityContext';
export { ModelToDomEntityContext } from './publicTypes/context/ModelToDomEntityContext';
export { ElementProcessor } from './publicTypes/context/ElementProcessor';
export { ContentModelHandler } from './publicTypes/context/ContentModelHandler';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { ContentModelDocument } from '../publicTypes/group/ContentModelDocument'
import { createModelToDomContext } from '../modelToDom/context/createModelToDomContext';
import { createRange, Position, toArray } from 'roosterjs-editor-dom';
import { EditorContext } from '../publicTypes/context/EditorContext';
import { EntityPlaceholderPair } from '../publicTypes/context/ModelToDomEntityContext';
import { isNodeOfType } from '../domUtils/isNodeOfType';
import { ModelToDomBlockAndSegmentNode } from '../publicTypes/context/ModelToDomSelectionContext';
import { ModelToDomContext } from '../publicTypes/context/ModelToDomContext';
Expand Down Expand Up @@ -31,7 +30,7 @@ export default function contentModelToDom(
model: ContentModelDocument,
editorContext: EditorContext,
option?: ModelToDomOption
): [DocumentFragment, SelectionRangeEx | null, EntityPlaceholderPair[]] {
): [DocumentFragment, SelectionRangeEx | null, Record<string, HTMLElement>] {
const fragment = model.document.createDocumentFragment();
const modelToDomContext = createModelToDomContext(editorContext, option);

Expand All @@ -42,7 +41,7 @@ export default function contentModelToDom(

fragment.normalize();

return [fragment, range, modelToDomContext.entityPairs];
return [fragment, range, modelToDomContext.entities];
}

function extractSelectionRange(context: ModelToDomContext): SelectionRangeEx | null {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,10 @@ export function createModelToDomContext(
...defaultImplicitSegmentFormatMap,
...(options?.defaultImplicitSegmentFormatOverride || {}),
},
entityPairs: [],
entities: {},

defaultModelHandlers: defaultContentModelHandlers,
defaultFormatAppliers: defaultFormatAppliers,
doNotReuseEntityDom: !!options?.doNotReuseEntityDom,
};
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { applyFormat } from '../utils/applyFormat';
import { commitEntity, getObjectKeys } from 'roosterjs-editor-dom';
import { commitEntity, createEntityPlaceholder, getObjectKeys } from 'roosterjs-editor-dom';
import { ContentModelEntity } from '../../publicTypes/entity/ContentModelEntity';
import { ContentModelHandler } from '../../publicTypes/context/ContentModelHandler';
import { ModelToDomContext } from '../../publicTypes/context/ModelToDomContext';
Expand All @@ -18,12 +18,6 @@ export const handleEntity: ContentModelHandler<ContentModelEntity> = (
// Commit the entity attributes in case there is any change
commitEntity(wrapper, type, isReadonly, id);

// Create a comment as placeholder and insert into DOM tree.
// If the entity DOM can be reused, the original DOM node will be preserved without any change
// so that in case there is something that is sensitive to its DOM path (e.g. IFRAME), no need to cause it reloaded.
// For entity that is not directly under root, later we will replace the comment with its original DOM node
const placeholder = doc.createComment('Entity:' + id);

if (getObjectKeys(format).length > 0) {
const span = doc.createElement('span');

Expand All @@ -32,11 +26,16 @@ export const handleEntity: ContentModelHandler<ContentModelEntity> = (
parent = span;
}

parent.appendChild(placeholder);
if (context.doNotReuseEntityDom) {
parent.appendChild(wrapper);
} else {
// Create a comment as placeholder and insert into DOM tree.
// If the entity DOM can be reused, the original DOM node will be preserved without any change
// so that in case there is something that is sensitive to its DOM path (e.g. IFRAME), no need to cause it reloaded.
// For entity that is not directly under root, later we will replace the comment with its original DOM node
parent.appendChild(createEntityPlaceholder(entityModel));

// Save the entity DOM wrapper node and its placeholder into context so that later we know how to handle it
context.entityPairs.push({
entityWrapper: wrapper,
placeholder: placeholder,
});
// Save the entity DOM wrapper node and its placeholder into context so that later we know how to handle it
context.entities[id] = wrapper;
}
};

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import { mergeTableCells } from '../../modelApi/table/mergeTableCells';
import { mergeTableColumn } from '../../modelApi/table/mergeTableColumn';
import { mergeTableRow } from '../../modelApi/table/mergeTableRow';
import { normalizeTable } from '../../modelApi/table/normalizeTable';
import { preprocessEntitiesFromContentModel } from '../mergeFragmentWithEntity';
import { splitTableCellHorizontally } from '../../modelApi/table/splitTableCellHorizontally';
import { splitTableCellVertically } from '../../modelApi/table/splitTableCellVertically';
import { TableOperation } from 'roosterjs-editor-types';
Expand Down Expand Up @@ -110,8 +109,8 @@ export default function editTable(editor: IContentModelEditor, operation: TableO
editor.focus();
if (model && table) {
editor.setContentModel(model, {
mergingCallback: (fragment, _, entityPairs) => {
preprocessEntitiesFromContentModel(entityPairs);
doNotReuseEntityDom: true,
mergingCallback: fragment => {
editor.replaceNode(table, fragment);
},
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { applyTableFormat } from '../../modelApi/table/applyTableFormat';
import { ChangeSource } from 'roosterjs-editor-types';
import { IExperimentalContentModelEditor } from '../../publicTypes/IExperimentalContentModelEditor';
import { preprocessEntitiesFromContentModel } from '../mergeFragmentWithEntity';
import { TableMetadataFormat } from '../../publicTypes/format/formatParts/TableMetadataFormat';

/**
Expand All @@ -26,8 +25,8 @@ export default function formatTable(
editor.focus();
if (model && table) {
editor.setContentModel(model, {
mergingCallback: (fragment, _, entityPairs) => {
preprocessEntitiesFromContentModel(entityPairs);
doNotReuseEntityDom: true,
mergingCallback: fragment => {
editor.replaceNode(table, fragment);
},
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { formatWithContentModel } from '../utils/formatWithContentModel';
import { IContentModelEditor } from '../../publicTypes/IContentModelEditor';
import { mergeModel } from '../../modelApi/common/mergeModel';
import { normalizeTable } from '../../modelApi/table/normalizeTable';
import { preprocessEntitiesFromContentModel } from '../mergeFragmentWithEntity';
import { TableMetadataFormat } from '../../publicTypes/format/formatParts/TableMetadataFormat';

/**
Expand Down Expand Up @@ -43,8 +42,8 @@ export default function insertTable(
editor.addUndoSnapshot(
() => {
editor.setContentModel(doc, {
mergingCallback: (fragment, _, entityPairs) => {
preprocessEntitiesFromContentModel(entityPairs);
doNotReuseEntityDom: true,
mergingCallback: fragment => {
editor.insertNode(fragment);
},
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { formatWithContentModel } from '../utils/formatWithContentModel';
import { getFirstSelectedTable } from '../../modelApi/selection/collectSelections';
import { IContentModelEditor } from '../../publicTypes/IContentModelEditor';
import { normalizeTable } from '../../modelApi/table/normalizeTable';
import { preprocessEntitiesFromContentModel } from '../mergeFragmentWithEntity';
import { setTableCellBackgroundColor } from '../../modelApi/table/setTableCellBackgroundColor';

/**
Expand All @@ -23,8 +22,8 @@ export default function setTableCellShade(editor: IContentModelEditor, color: st
editor.focus();
if (model && table) {
editor.setContentModel(model, {
mergingCallback: (fragment, _, entityPairs) => {
preprocessEntitiesFromContentModel(entityPairs);
doNotReuseEntityDom: true,
mergingCallback: fragment => {
editor.replaceNode(table, fragment);
},
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { ContentModelDocument } from './group/ContentModelDocument';
import { EditorContext } from './context/EditorContext';
import { EntityPlaceholderPair } from './context/ModelToDomEntityContext';
import { IEditor, SelectionRangeEx } from 'roosterjs-editor-types';
import {
ContentModelHandlerMap,
Expand Down Expand Up @@ -65,14 +64,19 @@ export interface ModelToDomOption {
* A callback to specify how to merge DOM tree generated from Content Model in to existing container
* @param source Source document fragment that is generated from Content Model
* @param target Target container, usually to be editor root container
* @param entityPairs An array of entity wrapper - placeholder pairs, used for reuse existing DOM structure for entity
* @param entities An array of entity wrapper - placeholder pairs, used for reuse existing DOM structure for entity
*/
mergingCallback?: (
source: DocumentFragment,
target: HTMLElement,
entityPairs: EntityPlaceholderPair[]
entities: Record<string, HTMLElement>
) => void;

/**
* When set to true, directly put entity DOM nodes into the result DOM tree when doing Content Model to DOM conversion and do not use placeholder
*/
doNotReuseEntityDom?: boolean;

/**
* Overrides default format appliers
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,14 @@
/**
* Represent an object pair of Entity DOM node and placeholder comment node
* Represents context for entity
*/
export interface EntityPlaceholderPair {
export interface ModelToDomEntityContext {
/**
* Wrapper element of element
* When set to true, directly put entity DOM nodes into the result DOM tree when doing Content Model to DOM conversion and do not use placeholder
*/
entityWrapper: HTMLElement;
doNotReuseEntityDom: boolean;

/**
* Placeholder comment node
* Entities collected during DOM tree generation, used for reusing existing DOM structure of entities
*/
placeholder: Comment;
}

/**
* Represents context for entity
*/
export interface ModelToDomEntityContext {
entityPairs: EntityPlaceholderPair[];
entities: Record<string, HTMLElement>;
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,10 @@ describe('createModelToDomContext', () => {
formatAppliers: getFormatAppliers(),
modelHandlers: defaultContentModelHandlers,
defaultImplicitSegmentFormatMap: defaultImplicitSegmentFormatMap,
entityPairs: [],
entities: {},
defaultModelHandlers: defaultContentModelHandlers,
defaultFormatAppliers: defaultFormatAppliers,
doNotReuseEntityDom: false,
};
it('no param', () => {
const context = createModelToDomContext();
Expand Down Expand Up @@ -96,7 +97,7 @@ describe('createModelToDomContext', () => {
]);
expect(context.modelHandlers.br).toBe(mockedBrHandler);
expect(context.defaultImplicitSegmentFormatMap.a).toEqual(mockedAStyle);
expect(context.entityPairs).toEqual([]);
expect(context.entities).toEqual({});
expect(context.defaultModelHandlers).toEqual(defaultContentModelHandlers);
expect(context.defaultFormatAppliers).toEqual(defaultFormatAppliers);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,10 @@ describe('handleEntity', () => {

handleEntity(document, parent, entityModel, context);

expect(parent.innerHTML).toBe('<!--Entity:entity_1-->');
expect(context.entityPairs).toEqual([
{
entityWrapper: div,
placeholder: parent.firstChild as Comment,
},
]);
expect(parent.innerHTML).toBe('<entity-placeholder id="entity_1"></entity-placeholder>');
expect(context.entities).toEqual({
entity_1: div,
});
expect(div.outerHTML).toBe(
'<div class="_Entity _EType_entity _EId_entity_1 _EReadonly_1" contenteditable="false"></div>'
);
Expand Down
Loading

0 comments on commit 2c0add2

Please sign in to comment.