Skip to content

Commit

Permalink
Bump Rooster main to 9.8.0 (#2746)
Browse files Browse the repository at this point in the history
* Export DefaultSanitizers to be available in roosterjs-content-model-plugins package #2739

* Fix #2741 by changing Id selectors from `#{id}` to `[id="{id}"]` (#2742)

* init

* Fix build

* fix selection

* fix

* fixes

* remove console.log

* fix test

* Fix #2734 by Setting List Metadata `applyListStyleFromLevel: true` when toggling a list (#2743)

* init

* Tests

* add missing file

* crop alternative

* Fix #2733 by changing the approach to announce repeated announce messages (#2745)

* init

* move string to constant

* bump version

---------

Co-authored-by: vhuseinova-msft <[email protected]>
Co-authored-by: Bryan Valverde U <[email protected]>
Co-authored-by: Julia Roldi (from Dev Box) <[email protected]>
Co-authored-by: Julia Roldi <[email protected]>
  • Loading branch information
5 people authored Jul 15, 2024
1 parent 288231d commit db0ac97
Show file tree
Hide file tree
Showing 19 changed files with 397 additions and 79 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
mutateBlock,
normalizeContentModel,
setParagraphNotImplicit,
updateListMetadata,
} from 'roosterjs-content-model-dom';
import type {
ContentModelListItem,
Expand Down Expand Up @@ -121,6 +122,17 @@ export function setListType(

mutateBlock(parent).blocks.splice(index, 1, newListItem);
existingListItems.push(newListItem);

const levelIndex = newListItem.levels.length - 1;
const level = mutateBlock(newListItem).levels[levelIndex];

if (level) {
updateListMetadata(level, metadata =>
Object.assign({}, metadata, {
applyListStyleFromLevel: true,
})
);
}
} else {
existingListItems.forEach(
x => (mutateBlock(x).levels[0].format.marginBottom = '0px')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ describe('indent', () => {
marginTop: undefined,
textAlign: undefined,
},
dataset: {},
dataset: { editingInfo: '{"applyListStyleFromLevel":true}' },
},
],
blocks: [para],
Expand Down Expand Up @@ -138,7 +138,9 @@ describe('indent', () => {
marginTop: '0px',
textAlign: undefined,
},
dataset: {},
dataset: {
editingInfo: '{"applyListStyleFromLevel":true}',
},
},
],
blocks: [para],
Expand Down Expand Up @@ -364,7 +366,7 @@ describe('indent', () => {
marginTop: undefined,
textAlign: undefined,
},
dataset: {},
dataset: { editingInfo: '{"applyListStyleFromLevel":true}' },
},
],
blocks: [para3],
Expand Down Expand Up @@ -420,7 +422,7 @@ describe('indent', () => {
levels: [
{
listType: 'OL',
dataset: {},
dataset: { editingInfo: '{"applyListStyleFromLevel":true}' },
format: {
startNumberOverride: 1,
direction: 'rtl',
Expand Down Expand Up @@ -500,7 +502,7 @@ describe('indent', () => {
levels: [
{
listType: 'OL',
dataset: {},
dataset: { editingInfo: '{"applyListStyleFromLevel":true}' },
format: {
startNumberOverride: 1,
direction: undefined,
Expand Down Expand Up @@ -529,7 +531,7 @@ describe('indent', () => {
levels: [
{
listType: 'OL',
dataset: {},
dataset: { editingInfo: '{"applyListStyleFromLevel":true}' },
format: {
direction: undefined,
marginBottom: undefined,
Expand Down Expand Up @@ -584,7 +586,7 @@ describe('indent', () => {
levels: [
{
listType: 'OL',
dataset: {},
dataset: { editingInfo: '{"applyListStyleFromLevel":true}' },
format: {
startNumberOverride: 1,
direction: undefined,
Expand Down Expand Up @@ -641,7 +643,7 @@ describe('indent', () => {
levels: [
{
listType: 'OL',
dataset: {},
dataset: { editingInfo: '{"applyListStyleFromLevel":true}' },
format: {
startNumberOverride: 1,
direction: undefined,
Expand Down Expand Up @@ -669,7 +671,7 @@ describe('indent', () => {
levels: [
{
listType: 'OL',
dataset: {},
dataset: { editingInfo: '{"applyListStyleFromLevel":true}' },
format: {
startNumberOverride: undefined,
direction: undefined,
Expand Down Expand Up @@ -697,7 +699,7 @@ describe('indent', () => {
levels: [
{
listType: 'OL',
dataset: {},
dataset: { editingInfo: '{"applyListStyleFromLevel":true}' },
format: {
direction: undefined,
marginBottom: undefined,
Expand Down Expand Up @@ -779,7 +781,7 @@ describe('indent', () => {
marginTop: undefined,
textAlign: undefined,
},
dataset: {},
dataset: { editingInfo: '{"applyListStyleFromLevel":true}' },
},
],
formatHolder: {
Expand Down Expand Up @@ -809,7 +811,7 @@ describe('indent', () => {
marginTop: undefined,
textAlign: undefined,
},
dataset: {},
dataset: { editingInfo: '{"applyListStyleFromLevel":true}' },
},
],
formatHolder: {
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 { IEditor } from 'roosterjs-content-model-types';
import { toggleNumbering } from '../../../lib/publicApi/list/toggleNumbering';

import {
ContentModelDocument,
ContentModelFormatter,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { createAriaLiveElement } from '../../utils/createAriaLiveElement';
import type { Announce } from 'roosterjs-content-model-types';

const DOT_STRING = '.';

/**
* @internal
* Announce the given data
Expand All @@ -10,16 +13,16 @@ export const announce: Announce = (core, announceData) => {
const { text, defaultStrings, formatStrings = [] } = announceData;
const { announcerStringGetter } = core.lifecycle;
const template = defaultStrings && announcerStringGetter?.(defaultStrings);
const textToAnnounce = formatString(template || text, formatStrings);

if (textToAnnounce) {
let announceContainer = core.lifecycle.announceContainer;
let textToAnnounce = formatString(template || text, formatStrings);

if (!announceContainer || textToAnnounce == announceContainer.textContent) {
announceContainer?.parentElement?.removeChild(announceContainer);
announceContainer = createAriaLiveElement(core.physicalRoot.ownerDocument);
if (!core.lifecycle.announceContainer) {
core.lifecycle.announceContainer = createAriaLiveElement(core.physicalRoot.ownerDocument);
}

core.lifecycle.announceContainer = announceContainer;
if (textToAnnounce && core.lifecycle.announceContainer) {
const { announceContainer } = core.lifecycle;
if (textToAnnounce == announceContainer.textContent) {
textToAnnounce += DOT_STRING;
}

if (announceContainer) {
Expand All @@ -41,20 +44,3 @@ function formatString(text: string | undefined, formatStrings: string[]) {

return text;
}

function createAriaLiveElement(document: Document): HTMLDivElement {
const div = document.createElement('div');

div.style.clip = 'rect(0px, 0px, 0px, 0px)';
div.style.clipPath = 'inset(100%)';
div.style.height = '1px';
div.style.overflow = 'hidden';
div.style.position = 'absolute';
div.style.whiteSpace = 'nowrap';
div.style.width = '1px';
div.ariaLive = 'assertive';

document.body.appendChild(div);

return div;
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export function ensureUniqueId(element: HTMLElement, idPrefix: string): string {
const doc = element.ownerDocument;
let i = 0;

while (!element.id || doc.querySelectorAll('#' + element.id).length > 1) {
while (!element.id || doc.querySelectorAll(`[id="${element.id}"]`).length > 1) {
element.id = idPrefix + '_' + i++;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { ChangeSource, getObjectKeys, setColor } from 'roosterjs-content-model-dom';
import { createAriaLiveElement } from '../../utils/createAriaLiveElement';
import type {
IEditor,
LifecyclePluginState,
Expand Down Expand Up @@ -74,6 +75,9 @@ class LifecyclePlugin implements PluginWithState<LifecyclePluginState> {

// Let other plugins know that we are ready
this.editor.triggerEvent('editorReady', {}, true /*broadcast*/);

// Initialize the Announce container.
this.state.announceContainer = createAriaLiveElement(editor.getDocument());
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/**
* @internal
*/
export function createAriaLiveElement(document: Document): HTMLDivElement {
const div = document.createElement('div');

div.style.clip = 'rect(0px, 0px, 0px, 0px)';
div.style.clipPath = 'inset(100%)';
div.style.height = '1px';
div.style.overflow = 'hidden';
div.style.position = 'absolute';
div.style.whiteSpace = 'nowrap';
div.style.width = '1px';
div.ariaLive = 'assertive';

document.body.appendChild(div);

return div;
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,16 @@ describe('announce', () => {
});

it('announce empty string', () => {
const mockedDiv = {
style: {},
} as any;
createElementSpy.and.returnValue(mockedDiv);

announce(core, {});
expect(createElementSpy).not.toHaveBeenCalled();
expect(appendChildSpy).not.toHaveBeenCalled();

expect(createElementSpy).toHaveBeenCalled();
expect(appendChildSpy).toHaveBeenCalled();
expect(mockedDiv.textContent).toBeUndefined();
});

it('announce a given string', () => {
Expand Down Expand Up @@ -180,39 +187,18 @@ describe('announce', () => {
});

it('already has div with same text', () => {
const removeChildSpy = jasmine.createSpy('removeChild');
const mockedDiv = {
textContent: 'test',
parentElement: {
removeChild: removeChildSpy,
},
} as any;
const mockedDiv2 = {
style: {},
} as any;

core.lifecycle.announceContainer = mockedDiv;
createElementSpy.and.returnValue(mockedDiv2);

announce(core, {
text: 'test',
});

expect(removeChildSpy).toHaveBeenCalledWith(mockedDiv);
expect(createElementSpy).toHaveBeenCalledWith('div');
expect(appendChildSpy).toHaveBeenCalledWith(mockedDiv2);
expect(mockedDiv2).toEqual({
style: {
clip: 'rect(0px, 0px, 0px, 0px)',
clipPath: 'inset(100%)',
height: '1px',
overflow: 'hidden',
position: 'absolute',
whiteSpace: 'nowrap',
width: '1px',
},
ariaLive: 'assertive',
textContent: 'test',
expect(mockedDiv).toEqual({
textContent: 'test.',
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -529,7 +529,7 @@ describe('setDOMSelection', () => {
createRangeSpy.and.returnValue(mockedRange);

querySelectorAllSpy.and.callFake(selector => {
return selector == '#image_0' ? ['', ''] : [''];
return selector == '[id="image_0"]' ? ['', ''] : [''];
});
hasFocusSpy.and.returnValue(false);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,52 @@ describe('ensureUniqueId', () => {
id: 'dup',
} as any;
querySelectorAllSpy.and.callFake((selector: string) =>
selector == '#dup' ? [{}, {}] : []
selector == '[id="dup"]' ? [{}, {}] : []
);
const result = ensureUniqueId(element, 'prefix');

expect(result).toBe('dup_0');
});

it('Should not throw when element id starts with number', () => {
const element = {
ownerDocument: doc,
id: '0',
} as any;

let isFirst = true;
querySelectorAllSpy.and.callFake((_selector: string) => {
if (isFirst) {
isFirst = false;
return [{}, {}];
}
return [{}];
});

ensureUniqueId(element, 'prefix');

expect(querySelectorAllSpy).toHaveBeenCalledWith('[id="0"]');
expect(element.id).toEqual('0_0');
});

it('Should not throw when element id starts with hyphen', () => {
const element = {
ownerDocument: doc,
id: '-',
} as any;

let isFirst = true;
querySelectorAllSpy.and.callFake((_selector: string) => {
if (isFirst) {
isFirst = false;
return [{}, {}];
}
return [{}];
});

ensureUniqueId(element, 'prefix');

expect(querySelectorAllSpy).toHaveBeenCalledWith('[id="-"]');
expect(element.id).toEqual('-_0');
});
});
Loading

0 comments on commit db0ac97

Please sign in to comment.