Skip to content

Commit

Permalink
Merge pull request #2769 from microsoft/u/juliaroldi/bump-9.9.1
Browse files Browse the repository at this point in the history
Bump RoosterJS 9.9.1
  • Loading branch information
juliaroldi authored Aug 19, 2024
2 parents 658c4c2 + 6fef89e commit c711390
Show file tree
Hide file tree
Showing 14 changed files with 392 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import type {

// During IME input, KeyDown event will have "Process" as key
const ProcessKey = 'Process';
// For some Android IME, KeyDown event will have "Unidentified" as key
const UnidentifiedKey = 'Unidentified';
const DefaultStyleKeyMap: Record<
keyof (FontFamilyFormat & FontSizeFormat & TextColorFormat & BackgroundColorFormat),
keyof CSSStyleDeclaration
Expand Down Expand Up @@ -116,12 +118,16 @@ class FormatPlugin implements PluginWithState<FormatPluginState> {
break;

case 'keyDown':
const isAndroidIME =
this.editor.getEnvironment().isAndroid && event.rawEvent.key == UnidentifiedKey;
if (isCursorMovingKey(event.rawEvent)) {
this.clearPendingFormat();
this.lastCheckedNode = null;
} else if (
this.defaultFormatKeys.size > 0 &&
(isCharacterValue(event.rawEvent) || event.rawEvent.key == ProcessKey) &&
(isAndroidIME ||
isCharacterValue(event.rawEvent) ||
event.rawEvent.key == ProcessKey) &&
this.shouldApplyDefaultFormat(this.editor)
) {
applyDefaultFormat(this.editor, this.state.defaultFormat);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,13 @@ class SelectionPlugin implements PluginWithState<SelectionPluginState> {
key == Up ? td.childNodes.length : 0,
this.editor
);
} else if (!td && (lastCo.row == -1 || lastCo.row <= parsedTable.length)) {
this.selectBeforeOrAfterElement(
this.editor,
table,
change == 1 /* after */,
change != 1 /* setSelectionInNextSiblingElement */
);
}
} else if (key == 'TabLeft' || key == 'TabRight') {
const reverse = key == 'TabLeft';
Expand Down Expand Up @@ -568,15 +575,30 @@ class SelectionPlugin implements PluginWithState<SelectionPluginState> {
}
}

private selectBeforeOrAfterElement(editor: IEditor, element: HTMLElement, after?: boolean) {
private selectBeforeOrAfterElement(
editor: IEditor,
element: HTMLElement,
after?: boolean,
setSelectionInNextSiblingElement?: boolean
) {
const doc = editor.getDocument();
const parent = element.parentNode;
const index = parent && toArray(parent.childNodes).indexOf(element);
let sibling: Element | undefined | null;

if (parent && index !== null && index >= 0) {
const range = doc.createRange();
range.setStart(parent, index + (after ? 1 : 0));
range.collapse();
if (
setSelectionInNextSiblingElement &&
(sibling = after ? element.nextElementSibling : element.previousElementSibling) &&
isNodeOfType(sibling, 'ELEMENT_NODE')
) {
range.selectNodeContents(sibling);
range.collapse(false /* toStart */);
} else {
range.setStart(parent, index + (after ? 1 : 0));
range.collapse();
}

this.setDOMSelection(
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ describe('FormatPlugin', () => {
const editor = ({
cacheContentModel: () => {},
isDarkMode: () => false,
getEnvironment: () => ({}),
} as any) as IEditor;
const plugin = createFormatPlugin({});
plugin.initialize(editor);
Expand Down Expand Up @@ -101,6 +102,7 @@ describe('FormatPlugin', () => {
const editor = ({
createContentModel: () => model,
cacheContentModel: () => {},
getEnvironment: () => ({}),
} as any) as IEditor;

const plugin = createFormatPlugin({});
Expand Down Expand Up @@ -243,6 +245,7 @@ describe('FormatPlugin for default format', () => {
cacheContentModel: cacheContentModelSpy,
takeSnapshot: takeSnapshotSpy,
formatContentModel: formatContentModelSpy,
getEnvironment: () => ({}),
} as any) as IEditor;
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1788,6 +1788,205 @@ describe('SelectionPlugin handle table selection', () => {
});
});

it('From Range, Press Down in the last row and move focus outside of table.', () => {
getDOMSelectionSpy.and.returnValue({
type: 'range',
range: {
startContainer: td3,
startOffset: 0,
endContainer: td3,
endOffset: 0,
commonAncestorContainer: tr2,
},
isReverted: false,
});

requestAnimationFrameSpy.and.callFake((func: Function) => {
getDOMSelectionSpy.and.returnValue({
type: 'range',
range: {
startContainer: td4,
startOffset: 0,
endContainer: td4,
endOffset: 0,
commonAncestorContainer: tr2,
collapsed: true,
},
isReverted: false,
});

func();
});

const setStartSpy = jasmine.createSpy('setStart');
const collapseSpy = jasmine.createSpy('collapse');
const mockedRange = {
setStart: setStartSpy,
collapse: collapseSpy,
} as any;

createRangeSpy.and.returnValue(mockedRange);

plugin.onPluginEvent!({
eventType: 'keyDown',
rawEvent: {
key: 'ArrowDown',
} as any,
});

expect(requestAnimationFrameSpy).toHaveBeenCalledTimes(1);
expect(plugin.getState()).toEqual({
selection: null,
tableSelection: null,
imageSelectionBorderColor: DEFAULT_SELECTION_BORDER_COLOR,
imageSelectionBorderColorDark: DEFAULT_SELECTION_BORDER_COLOR,
tableCellSelectionBackgroundColor: DEFAULT_TABLE_CELL_SELECTION_BACKGROUND_COLOR,
tableCellSelectionBackgroundColorDark: DEFAULT_TABLE_CELL_SELECTION_BACKGROUND_COLOR,
});
expect(setDOMSelectionSpy).toHaveBeenCalledTimes(1);
expect(setDOMSelectionSpy).toHaveBeenCalledWith({
type: 'range',
range: mockedRange,
isReverted: false,
});
expect(setStartSpy).toHaveBeenCalledWith(table.parentElement, 1);
});

it('From Range, Press Up in the first row and move focus outside of table, select before table as there are no elements before table.', () => {
getDOMSelectionSpy.and.returnValue({
type: 'range',
range: {
startContainer: td2,
startOffset: 0,
endContainer: td2,
endOffset: 0,
commonAncestorContainer: tr1,
},
isReverted: false,
});

requestAnimationFrameSpy.and.callFake((func: Function) => {
getDOMSelectionSpy.and.returnValue({
type: 'range',
range: {
startContainer: td1,
startOffset: 0,
endContainer: td1,
endOffset: 0,
commonAncestorContainer: tr1,
collapsed: true,
},
isReverted: false,
});

func();
});

const setStartSpy = jasmine.createSpy('setStart');
const collapseSpy = jasmine.createSpy('collapse');
const mockedRange = {
setStart: setStartSpy,
collapse: collapseSpy,
} as any;

createRangeSpy.and.returnValue(mockedRange);

plugin.onPluginEvent!({
eventType: 'keyDown',
rawEvent: {
key: 'ArrowUp',
} as any,
});

expect(requestAnimationFrameSpy).toHaveBeenCalledTimes(1);
expect(plugin.getState()).toEqual({
selection: null,
tableSelection: null,
imageSelectionBorderColor: DEFAULT_SELECTION_BORDER_COLOR,
imageSelectionBorderColorDark: DEFAULT_SELECTION_BORDER_COLOR,
tableCellSelectionBackgroundColor: DEFAULT_TABLE_CELL_SELECTION_BACKGROUND_COLOR,
tableCellSelectionBackgroundColorDark: DEFAULT_TABLE_CELL_SELECTION_BACKGROUND_COLOR,
});
expect(setDOMSelectionSpy).toHaveBeenCalledTimes(1);
expect(setDOMSelectionSpy).toHaveBeenCalledWith({
type: 'range',
range: mockedRange,
isReverted: false,
});
expect(setStartSpy).toHaveBeenCalledWith(table.parentElement, 0);
});

it('From Range, Press Up in the first row and move focus outside of table, select before table as there are no elements before table.', () => {
getDOMSelectionSpy.and.returnValue({
type: 'range',
range: {
startContainer: td2,
startOffset: 0,
endContainer: td2,
endOffset: 0,
commonAncestorContainer: tr1,
},
isReverted: false,
});

requestAnimationFrameSpy.and.callFake((func: Function) => {
getDOMSelectionSpy.and.returnValue({
type: 'range',
range: {
startContainer: td1,
startOffset: 0,
endContainer: td1,
endOffset: 0,
commonAncestorContainer: tr1,
collapsed: true,
},
isReverted: false,
});

func();
});

const setStartSpy = jasmine.createSpy('setStart');
const collapseSpy = jasmine.createSpy('collapse');
const selectNodeContentsSpy = jasmine.createSpy('selectNodeContents');

const mockedRange = {
setStart: setStartSpy,
collapse: collapseSpy,
selectNodeContents: selectNodeContentsSpy,
} as any;

const div = document.createElement('div');
table.parentElement?.insertBefore(div, table);
createRangeSpy.and.returnValue(mockedRange);

plugin.onPluginEvent!({
eventType: 'keyDown',
rawEvent: {
key: 'ArrowUp',
} as any,
});

expect(requestAnimationFrameSpy).toHaveBeenCalledTimes(1);
expect(plugin.getState()).toEqual({
selection: null,
tableSelection: null,
imageSelectionBorderColor: DEFAULT_SELECTION_BORDER_COLOR,
imageSelectionBorderColorDark: DEFAULT_SELECTION_BORDER_COLOR,
tableCellSelectionBackgroundColor: DEFAULT_TABLE_CELL_SELECTION_BACKGROUND_COLOR,
tableCellSelectionBackgroundColorDark: DEFAULT_TABLE_CELL_SELECTION_BACKGROUND_COLOR,
});
expect(setDOMSelectionSpy).toHaveBeenCalledTimes(1);
expect(setDOMSelectionSpy).toHaveBeenCalledWith({
type: 'range',
range: mockedRange,
isReverted: false,
});
expect(setStartSpy).not.toHaveBeenCalledWith(table.parentElement, 0);
expect(selectNodeContentsSpy).toHaveBeenCalledWith(div);
expect(collapseSpy).toHaveBeenCalledWith(false);
});

it('From Range, Press Shift+Up', () => {
getDOMSelectionSpy.and.returnValue({
type: 'range',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ export const listLevelThreadFormatHandler: FormatHandler<ListThreadFormat> = {
const depth = levels.length;

if (
typeof threadItemCounts[depth] === 'number' &&
element.start != threadItemCounts[depth] + 1
element.start == 1 ||
(typeof threadItemCounts[depth] === 'number' &&
element.start != threadItemCounts[depth] + 1)
) {
format.startNumberOverride = element.start;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -453,7 +453,15 @@ describe('childProcessor', () => {
{
blockType: 'BlockGroup',
blockGroupType: 'ListItem',
levels: [{ listType: 'OL', format: {}, dataset: {} }],
levels: [
{
listType: 'OL',
format: {
startNumberOverride: 1,
},
dataset: {},
},
],
formatHolder: { segmentType: 'SelectionMarker', isSelected: false, format: {} },
blocks: [
{
Expand Down
Loading

0 comments on commit c711390

Please sign in to comment.