Skip to content

Commit

Permalink
Merge branch 'bug-fixes' of https://github.com/KWizCom/roosterjs into…
Browse files Browse the repository at this point in the history
… bug-fixes
  • Loading branch information
shaipetel committed Jan 12, 2023
2 parents e799014 + ac738d0 commit ea977bd
Show file tree
Hide file tree
Showing 25 changed files with 234 additions and 67 deletions.
30 changes: 24 additions & 6 deletions demo/scripts/controls/editor/ExperimentalContentModelEditor.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
import { Editor } from 'roosterjs-editor-core';
import { EditorOptions, SelectionRangeTypes } from 'roosterjs-editor-types';
import {
getComputedStyles,
Position,
restoreContentWithEntityPlaceholder,
} from 'roosterjs-editor-dom';
import {
EditorContext,
ContentModelDocument,
ContentModelSegmentFormat,
contentModelToDom,
domToContentModel,
DomToModelOption,
EditorContext,
IExperimentalContentModelEditor,
ModelToDomOption,
} from 'roosterjs-content-model';
import {
getComputedStyles,
Position,
restoreContentWithEntityPlaceholder,
} from 'roosterjs-editor-dom';

/**
* !!! This is a temporary interface and will be removed in the future !!!
Expand All @@ -23,6 +24,7 @@ import {
export default class ExperimentalContentModelEditor extends Editor
implements IExperimentalContentModelEditor {
private getDarkColor: ((lightColor: string) => string) | undefined;
private pendingFormat: ContentModelSegmentFormat | null = null;

/**
* Creates an instance of ExperimentalContentModelEditor
Expand Down Expand Up @@ -88,4 +90,20 @@ export default class ExperimentalContentModelEditor extends Editor
this.select(range);
}
}

/**
* Get current pending format if any. A pending format is a format that user set when selection is collapsed,
* it will be applied when next time user input something
*/
getPendingFormat(): ContentModelSegmentFormat | null {
return this.pendingFormat;
}

/**
* Set current pending format if any. A pending format is a format that user set when selection is collapsed,
* it will be applied when next time user input something
*/
setPendingFormat(format: ContentModelSegmentFormat | null) {
this.pendingFormat = format;
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ContentModelSegment } from '../../publicTypes/segment/ContentModelSegment';
import { ContentModelSegmentFormat } from '../../publicTypes/format/ContentModelSegmentFormat';
import { FontSizeFormat } from '../../publicTypes/format/formatParts/FontSizeFormat';
import { FormatParser } from '../../publicTypes/context/DomToModelSettings';
import { formatSegmentWithContentModel } from '../utils/formatSegmentWithContentModel';
Expand Down Expand Up @@ -26,7 +26,7 @@ export default function changeFontSize(
formatSegmentWithContentModel(
editor,
'changeFontSize',
segment => changeFontSizeInternal(segment, change),
format => changeFontSizeInternal(format, change),
undefined /* segmentHasStyleCallback*/,
true /*includingFormatHandler*/,
{
Expand All @@ -45,14 +45,17 @@ const fontSizeHandler: FormatParser<FontSizeFormat> = (format, element, context,
}
};

function changeFontSizeInternal(segment: ContentModelSegment, change: 'increase' | 'decrease') {
if (segment.format.fontSize) {
let sizeNumber = parseFloat(segment.format.fontSize);
function changeFontSizeInternal(
format: ContentModelSegmentFormat,
change: 'increase' | 'decrease'
) {
if (format.fontSize) {
let sizeNumber = parseFloat(format.fontSize);

if (sizeNumber > 0) {
const newSize = getNewFontSize(sizeNumber, change == 'increase' ? 1 : -1, FONT_SIZES);

segment.format.fontSize = newSize + 'pt';
format.fontSize = newSize + 'pt';
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export default function setBackgroundColor(
editor: IExperimentalContentModelEditor,
backgroundColor: string
) {
formatSegmentWithContentModel(editor, 'setBackgroundColor', segment => {
segment.format.backgroundColor = backgroundColor;
formatSegmentWithContentModel(editor, 'setBackgroundColor', format => {
format.backgroundColor = backgroundColor;
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ export default function setFontName(editor: IExperimentalContentModelEditor, fon
formatSegmentWithContentModel(
editor,
'setFontName',
segment => {
segment.format.fontFamily = fontName;
format => {
format.fontFamily = fontName;
},
undefined /* segmentHasStyleCallback*/,
true /*includingFormatHandler*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ export default function setFontSize(editor: IExperimentalContentModelEditor, fon
formatSegmentWithContentModel(
editor,
'setFontSize',
segment => {
segment.format.fontSize = fontSize;
format => {
format.fontSize = fontSize;
},
undefined /* segmentHasStyleCallback*/,
true /*includingFormatHandler*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ export default function setTextColor(editor: IExperimentalContentModelEditor, te
formatSegmentWithContentModel(
editor,
'setTextColor',
segment => {
segment.format.textColor = textColor;
format => {
format.textColor = textColor;
},
undefined /* segmentHasStyleCallback*/,
true /*includingFormatHandler*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,17 @@ export default function toggleBold(editor: IExperimentalContentModelEditor) {
formatSegmentWithContentModel(
editor,
'toggleBold',
(segment, isTurningOn) => {
segment.format.fontWeight = isTurningOn ? 'bold' : undefined;
(format, isTurningOn) => {
format.fontWeight = isTurningOn ? 'bold' : undefined;
},
segment => isBold(segment.format.fontWeight)
format => isBold(format.fontWeight)
);
}

function isBold(boldStyle?: string): boolean {
/**
* @internal
*/
export function isBold(boldStyle?: string): boolean {
return (
!!boldStyle && (boldStyle == 'bold' || boldStyle == 'bolder' || parseInt(boldStyle) >= 600)
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ export default function toggleItalic(editor: IExperimentalContentModelEditor) {
formatSegmentWithContentModel(
editor,
'toggleItalic',
(segment, isTurningOn) => {
segment.format.italic = !!isTurningOn;
(format, isTurningOn) => {
format.italic = !!isTurningOn;
},
segment => !!segment.format.italic
format => !!format.italic
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ export default function toggleStrikethrough(editor: IExperimentalContentModelEdi
formatSegmentWithContentModel(
editor,
'toggleStrikethrough',
(segment, isTurningOn) => {
segment.format.strikethrough = !!isTurningOn;
(format, isTurningOn) => {
format.strikethrough = !!isTurningOn;
},
segment => !!segment.format.strikethrough
format => !!format.strikethrough
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ export default function toggleSubscript(editor: IExperimentalContentModelEditor)
formatSegmentWithContentModel(
editor,
'toggleSubscript',
(segment, isTurningOn) => {
segment.format.superOrSubScriptSequence = isTurningOn ? 'sub' : '';
(format, isTurningOn) => {
format.superOrSubScriptSequence = isTurningOn ? 'sub' : '';
},
segment => segment.format.superOrSubScriptSequence?.split(' ').pop() == 'sub'
format => format.superOrSubScriptSequence?.split(' ').pop() == 'sub'
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ export default function toggleSuperscript(editor: IExperimentalContentModelEdito
formatSegmentWithContentModel(
editor,
'toggleSuperscript',
(segment, isTurningOn) => {
segment.format.superOrSubScriptSequence = isTurningOn ? 'super' : '';
(format, isTurningOn) => {
format.superOrSubScriptSequence = isTurningOn ? 'super' : '';
},
segment => segment.format.superOrSubScriptSequence?.split(' ').pop() == 'super'
format => format.superOrSubScriptSequence?.split(' ').pop() == 'super'
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ export default function toggleUnderline(editor: IExperimentalContentModelEditor)
formatSegmentWithContentModel(
editor,
'toggleUnderline',
(segment, isTurningOn) => {
segment.format.underline = !!isTurningOn;
(format, isTurningOn) => {
format.underline = !!isTurningOn;
},
segment => !!segment.format.underline
format => !!format.underline
);
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ContentModelSegment } from '../../publicTypes/segment/ContentModelSegment';
import { ContentModelSegmentFormat } from '../../publicTypes/format/ContentModelSegmentFormat';
import { formatWithContentModel } from './formatWithContentModel';
import { getSelectedSegments } from '../../modelApi/selection/collectSelections';
import {
Expand All @@ -12,8 +12,8 @@ import {
export function formatSegmentWithContentModel(
editor: IExperimentalContentModelEditor,
apiName: string,
toggleStyleCallback: (segment: ContentModelSegment, isTuringOn: boolean) => void,
segmentHasStyleCallback?: (segment: ContentModelSegment) => boolean,
toggleStyleCallback: (format: ContentModelSegmentFormat, isTuringOn: boolean) => void,
segmentHasStyleCallback?: (format: ContentModelSegmentFormat) => boolean,
includingFormatHolder?: boolean,
domToModelOptions?: DomToModelOption
) {
Expand All @@ -22,17 +22,30 @@ export function formatSegmentWithContentModel(
apiName,
model => {
const segments = getSelectedSegments(model, !!includingFormatHolder);
const pendingFormat = editor.getPendingFormat();
const formats = pendingFormat
? [pendingFormat]
: segments.map(segment => segment.format);

const isTurningOff = segmentHasStyleCallback
? segments.every(segmentHasStyleCallback)
? formats.every(format => segmentHasStyleCallback(format))
: false;

segments.forEach(segment => toggleStyleCallback(segment, !isTurningOff));
formats.forEach(format => toggleStyleCallback(format, !isTurningOff));

return (
segments.length > 1 ||
(!!segments[0] && segments[0].segmentType != 'SelectionMarker')
);
const isCollapsedSelection =
segments.length == 1 && segments[0].segmentType == 'SelectionMarker';

if (!pendingFormat && isCollapsedSelection) {
editor.setPendingFormat(segments[0].format);
}

if (isCollapsedSelection) {
editor.focus();
return false;
} else {
return formats.length > 0;
}
},
domToModelOptions
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { ContentModelDocument } from './group/ContentModelDocument';
import { ContentModelSegmentFormat } from './format/ContentModelSegmentFormat';
import { EditorContext } from './context/EditorContext';
import { IEditor, SelectionRangeEx } from 'roosterjs-editor-types';
import {
Expand Down Expand Up @@ -123,4 +124,16 @@ export interface IExperimentalContentModelEditor extends IEditor {
* @param option Additional options to customize the behavior of Content Model to DOM conversion
*/
setContentModel(model: ContentModelDocument, option?: ModelToDomOption): void;

/**
* Get current pending format if any. A pending format is a format that user set when selection is collapsed,
* it will be applied when next time user input something
*/
getPendingFormat(): ContentModelSegmentFormat | null;

/**
* Set current pending format if any. A pending format is a format that user set when selection is collapsed,
* it will be applied when next time user input something
*/
setPendingFormat(format: ContentModelSegmentFormat | null): void;
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { ContentModelDocument } from '../../../lib/publicTypes/group/ContentModelDocument';
import { ContentModelSegmentFormat } from '../../../lib/publicTypes/format/ContentModelSegmentFormat';
import { IExperimentalContentModelEditor } from '../../../lib/publicTypes/IExperimentalContentModelEditor';

export function paragraphTestCommon(
Expand All @@ -23,6 +24,8 @@ export function paragraphTestCommon(
addUndoSnapshot,
focus: jasmine.createSpy(),
setContentModel,
getPendingFormat: (): ContentModelSegmentFormat | null => null,
setPendingFormat: () => {},
} as any) as IExperimentalContentModelEditor;

executionCallback(editor);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as formatWithContentModel from '../../../lib/publicApi/utils/formatWithContentModel';
import * as setModelIndentation from '../../../lib/modelApi/block/setModelIndentation';
import setIndentation from '../../../lib/publicApi/block/setIndentation';
import { ContentModelSegmentFormat } from '../../../lib/publicTypes/format/ContentModelSegmentFormat';
import { IExperimentalContentModelEditor } from '../../../lib/publicTypes/IExperimentalContentModelEditor';

describe('setIndentation', () => {
Expand All @@ -10,6 +11,8 @@ describe('setIndentation', () => {
beforeEach(() => {
editor = ({
createContentModel: () => fakeModel,
getPendingFormat: (): ContentModelSegmentFormat | null => null,
setPendingFormat: () => {},
} as any) as IExperimentalContentModelEditor;
});

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as formatWithContentModel from '../../../lib/publicApi/utils/formatWithContentModel';
import * as toggleModelBlockQuote from '../../../lib/modelApi/block/toggleModelBlockQuote';
import toggleBlockQuote from '../../../lib/publicApi/block/toggleBlockQuote';
import { ContentModelSegmentFormat } from '../../../lib/publicTypes/format/ContentModelSegmentFormat';
import { IExperimentalContentModelEditor } from '../../../lib/publicTypes/IExperimentalContentModelEditor';

describe('toggleBlockQuote', () => {
Expand All @@ -10,6 +11,8 @@ describe('toggleBlockQuote', () => {
beforeEach(() => {
editor = ({
createContentModel: () => fakeModel,
getPendingFormat: (): ContentModelSegmentFormat | null => null,
setPendingFormat: () => {},
} as any) as IExperimentalContentModelEditor;
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import * as readFile from 'roosterjs-editor-dom/lib/utils/readFile';
import insertImage from '../../../lib/publicApi/insert/insertImage';
import { addSegment } from '../../../lib/modelApi/common/addSegment';
import { ContentModelDocument } from '../../../lib/publicTypes/group/ContentModelDocument';
import { ContentModelSegmentFormat } from '../../../lib/publicTypes/format/ContentModelSegmentFormat';
import { createContentModelDocument } from '../../../lib/modelApi/creators/createContentModelDocument';
import { createSelectionMarker } from '../../../lib/modelApi/creators/createSelectionMarker';
import { IExperimentalContentModelEditor } from '../../../lib/publicTypes/IExperimentalContentModelEditor';
Expand Down Expand Up @@ -35,6 +36,8 @@ describe('insertImage', () => {
setContentModel,
isDisposed: () => false,
getDocument: () => document,
getPendingFormat: (): ContentModelSegmentFormat | null => null,
setPendingFormat: () => {},
} as any) as IExperimentalContentModelEditor;

executionCallback(editor);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as setListType from '../../../lib/modelApi/list/setListType';
import toggleBullet from '../../../lib/publicApi/list/toggleBullet';
import { ContentModelDocument } from '../../../lib/publicTypes/group/ContentModelDocument';
import { ContentModelSegmentFormat } from '../../../lib/publicTypes/format/ContentModelSegmentFormat';
import { IExperimentalContentModelEditor } from '../../../lib/publicTypes/IExperimentalContentModelEditor';

describe('toggleBullet', () => {
Expand All @@ -24,6 +25,8 @@ describe('toggleBullet', () => {
addUndoSnapshot,
createContentModel,
setContentModel,
getPendingFormat: (): ContentModelSegmentFormat | null => null,
setPendingFormat: () => {},
} as any) as IExperimentalContentModelEditor;

spyOn(setListType, 'setListType').and.returnValue(true);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as setListType from '../../../lib/modelApi/list/setListType';
import toggleNumbering from '../../../lib/publicApi/list/toggleNumbering';
import { ContentModelDocument } from '../../../lib/publicTypes/group/ContentModelDocument';
import { ContentModelSegmentFormat } from '../../../lib/publicTypes/format/ContentModelSegmentFormat';
import { IExperimentalContentModelEditor } from '../../../lib/publicTypes/IExperimentalContentModelEditor';

describe('toggleNumbering', () => {
Expand All @@ -24,6 +25,8 @@ describe('toggleNumbering', () => {
addUndoSnapshot,
createContentModel,
setContentModel,
getPendingFormat: (): ContentModelSegmentFormat | null => null,
setPendingFormat: () => {},
} as any) as IExperimentalContentModelEditor;

spyOn(setListType, 'setListType').and.returnValue(true);
Expand Down
Loading

0 comments on commit ea977bd

Please sign in to comment.