Skip to content

Commit 83a7588

Browse files
Merge pull request #3150 from flyingbee2012/u/biwu/versionbump912
Version bump to 9.36.1
2 parents 9bbe91a + 08761bc commit 83a7588

File tree

15 files changed

+859
-563
lines changed

15 files changed

+859
-563
lines changed

packages/roosterjs-content-model-core/lib/coreApi/restoreUndoSnapshot/restoreSnapshotLogicalRoot.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,5 @@ export function restoreSnapshotLogicalRoot(core: EditorCore, snapshot: Snapshot)
1111
if (restoredLogicalRoot !== core.logicalRoot) {
1212
core.api.setLogicalRoot(core, restoredLogicalRoot);
1313
}
14-
} else {
15-
core.api.setLogicalRoot(core, null);
1614
}
1715
}

packages/roosterjs-content-model-core/lib/coreApi/restoreUndoSnapshot/restoreUndoSnapshot.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ export const restoreUndoSnapshot: RestoreUndoSnapshot = (core, snapshot) => {
2424
try {
2525
core.undo.isRestoring = true;
2626

27+
// Force clear logical root before restoring snapshot, so the whole editor is editable.
28+
// Without changing logical root, browser may want to maintain the scroll position of current logical root,
29+
// which may cause the editor to scroll to a wrong position after content is changed.
30+
core.api.setLogicalRoot(core, null /* logicalRoot */);
31+
2732
restoreSnapshotHTML(core, snapshot);
2833
restoreSnapshotLogicalRoot(core, snapshot);
2934
restoreSnapshotSelection(core, snapshot);

packages/roosterjs-content-model-core/lib/corePlugin/domEvent/DOMEventPlugin.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,8 @@ class DOMEventPlugin implements PluginWithState<DOMEventPluginState> {
172172
event.stopPropagation();
173173

174174
const isAndroid = this.editor?.getEnvironment()?.isAndroid ?? false;
175-
const isComposing = !isAndroid && ((event as InputEvent).isComposing || this.state.isInIME);
175+
const isComposing =
176+
!isAndroid && ((event as InputEvent).isComposing || this.state.isInIME);
176177

177178
if (this.editor && !isComposing) {
178179
this.editor.triggerEvent('input', {

packages/roosterjs-content-model-core/lib/corePlugin/selection/SelectionPlugin.ts

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import type {
2121
ParsedTable,
2222
TableSelectionInfo,
2323
TableCellCoordinate,
24+
DOMEventRecord,
2425
} from 'roosterjs-content-model-types';
2526

2627
const MouseLeftButton = 0;
@@ -48,6 +49,7 @@ class SelectionPlugin implements PluginWithState<SelectionPluginState> {
4849
private isSafari = false;
4950
private isMac = false;
5051
private scrollTopCache: number = 0;
52+
private pointerEvent: PointerEvent | null = null;
5153

5254
constructor(options: EditorOptions) {
5355
this.state = {
@@ -99,18 +101,15 @@ class SelectionPlugin implements PluginWithState<SelectionPluginState> {
99101
this.isSafari = !!env.isSafari;
100102
this.isMac = !!env.isMac;
101103
document.addEventListener('selectionchange', this.onSelectionChange);
102-
if (this.isSafari) {
103-
this.disposer = this.editor.attachDomEvent({
104-
focus: { beforeDispatch: this.onFocus },
105-
drop: { beforeDispatch: this.onDrop },
106-
});
107-
} else {
108-
this.disposer = this.editor.attachDomEvent({
109-
focus: { beforeDispatch: this.onFocus },
110-
blur: { beforeDispatch: this.onBlur },
111-
drop: { beforeDispatch: this.onDrop },
112-
});
113-
}
104+
const eventHandlers: Partial<
105+
{ [P in keyof HTMLElementEventMap]: DOMEventRecord<HTMLElementEventMap[P]> }
106+
> = {
107+
focus: { beforeDispatch: this.onFocus },
108+
drop: { beforeDispatch: this.onDrop },
109+
blur: this.isSafari ? undefined : { beforeDispatch: this.onBlur },
110+
pointerdown: { beforeDispatch: (event: PointerEvent) => this.onPointerDown(event) },
111+
};
112+
this.disposer = this.editor.attachDomEvent(<Record<string, DOMEventRecord>>eventHandlers);
114113
}
115114

116115
dispose() {
@@ -246,6 +245,10 @@ class SelectionPlugin implements PluginWithState<SelectionPluginState> {
246245
},
247246
});
248247
}
248+
249+
if (rawEvent.defaultPrevented) {
250+
this.pointerEvent = null;
251+
}
249252
}
250253

251254
private onMouseMove = (event: Event) => {
@@ -310,12 +313,27 @@ class SelectionPlugin implements PluginWithState<SelectionPluginState> {
310313

311314
private onMouseUp() {
312315
this.detachMouseEvent();
316+
if (this.pointerEvent && this.pointerEvent.pointerType === 'touch') {
317+
requestAnimationFrame(() => {
318+
if (this.editor && this.pointerEvent) {
319+
// Handle touch selection here since the cursor position is updated
320+
// Work-in-progress
321+
}
322+
this.pointerEvent = null;
323+
});
324+
}
313325
}
314326

315327
private onDrop = () => {
316328
this.detachMouseEvent();
317329
};
318330

331+
private onPointerDown = (e: PointerEvent) => {
332+
if (e.pointerType === 'touch' || e.pointerType === 'pen') {
333+
this.pointerEvent = e;
334+
}
335+
};
336+
319337
private onKeyDown(editor: IEditor, rawEvent: KeyboardEvent) {
320338
const key = rawEvent.key;
321339
const selection = editor.getDOMSelection();

packages/roosterjs-content-model-plugins/lib/autoFormat/list/getListTypeStyle.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,9 +131,10 @@ const getPreviousListLevel = (
131131
};
132132

133133
const getPreviousListStyle = (list?: ContentModelListItem) => {
134-
if (list?.levels[0].dataset) {
135-
return updateListMetadata(list.levels[0])?.orderedStyleType;
134+
if (!list || list.levels.length < 1) {
135+
return undefined;
136136
}
137+
return updateListMetadata(list.levels[0])?.orderedStyleType;
137138
};
138139

139140
const bulletListType: Map<string, number> = new Map<string, number>([

packages/roosterjs-content-model-plugins/lib/edit/keyboardInput.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,11 @@ export function keyboardInput(editor: IEditor, rawEvent: KeyboardEvent) {
6969
function shouldInputWithContentModel(selection: DOMSelection | null, rawEvent: KeyboardEvent) {
7070
if (!selection) {
7171
return false; // Nothing to delete
72-
} else if (!isModifierKey(rawEvent) && (rawEvent.key == 'Space' || rawEvent.key.length == 1)) {
72+
} else if (
73+
!isModifierKey(rawEvent) &&
74+
rawEvent.key &&
75+
(rawEvent.key == 'Space' || rawEvent.key.length == 1)
76+
) {
7377
return selection.type != 'range' || !selection.range.collapsed;
7478
} else {
7579
return false;

packages/roosterjs-content-model-plugins/lib/imageEdit/ImageEditPlugin.ts

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -240,11 +240,7 @@ export class ImageEditPlugin implements ImageEditor, EditorPlugin {
240240
event.rawEvent.button !== MouseRightButton &&
241241
!this.isCropMode
242242
) {
243-
this.applyFormatWithContentModel(
244-
editor,
245-
this.isCropMode,
246-
this.shadowSpan === event.rawEvent.target
247-
);
243+
this.applyFormatWithContentModel(editor, this.isCropMode);
248244
}
249245
}
250246

@@ -339,7 +335,7 @@ export class ImageEditPlugin implements ImageEditor, EditorPlugin {
339335
protected applyFormatWithContentModel(
340336
editor: IEditor,
341337
isCropMode: boolean,
342-
shouldSelectImage: boolean,
338+
shouldSelectImage?: boolean,
343339
isApiOperation?: boolean
344340
) {
345341
let editingImageModel: ContentModelImage | undefined;
@@ -389,9 +385,10 @@ export class ImageEditPlugin implements ImageEditor, EditorPlugin {
389385
if (this.wasImageResized || changeState == 'FullyChanged') {
390386
context.skipUndoSnapshot = false;
391387
}
392-
393-
image.isSelected = shouldSelectImage;
394-
image.isSelectedAsImageSelection = shouldSelectImage;
388+
const isSameImage =
389+
previousSelectedImage?.image === editingImage?.image;
390+
image.isSelected = isSameImage || shouldSelectImage;
391+
image.isSelectedAsImageSelection = isSameImage || shouldSelectImage;
395392
image.format.imageState = undefined;
396393

397394
if (selection?.type == 'range' && !selection.range.collapsed) {
@@ -508,6 +505,7 @@ export class ImageEditPlugin implements ImageEditor, EditorPlugin {
508505
if (!this.imageEditInfo) {
509506
this.imageEditInfo = getSelectedImageMetadata(editor, image);
510507
}
508+
511509
this.imageHTMLOptions = getHTMLImageOptions(editor, this.options, this.imageEditInfo);
512510
this.lastSrc = image.getAttribute('src');
513511

packages/roosterjs-content-model-plugins/lib/paste/WordDesktop/processPastedContentFromWordDesktop.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,11 @@ const listLevelParser: FormatParser<ContentModelListItemLevelFormat> = (
8080
format.marginBottom = undefined;
8181
};
8282

83-
const wordTableParser: FormatParser<ContentModelTableFormat> = (format): void => {
83+
const wordTableParser: FormatParser<ContentModelTableFormat> = (format, element): void => {
8484
if (format.marginLeft?.startsWith('-')) {
8585
delete format.marginLeft;
8686
}
87+
if (format.htmlAlign) {
88+
delete format.htmlAlign;
89+
}
8790
};

packages/roosterjs-content-model-plugins/lib/paste/WordDesktop/processWordLists.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -227,10 +227,10 @@ function wordListPaddingParser(
227227
format: ContentModelListItemLevelFormat,
228228
element: HTMLElement
229229
): void {
230-
if (element.style.marginLeft && element.style.marginLeft != '0in') {
230+
if (element.style.marginLeft && parseInt(element.style.marginLeft) != 0) {
231231
format.paddingLeft = '0px';
232232
}
233-
if (element.style.marginRight && element.style.marginRight != '0in') {
233+
if (element.style.marginRight && parseInt(element.style.marginRight) != 0) {
234234
format.paddingRight = '0px';
235235
}
236236
}

packages/roosterjs-content-model-plugins/test/autoFormat/list/getListTypeStyleTest.ts

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1356,4 +1356,59 @@ describe('getListTypeStyle', () => {
13561356
index: 3,
13571357
});
13581358
});
1359+
1360+
it('should create a new list', () => {
1361+
const model: ContentModelDocument = {
1362+
blockGroupType: 'Document',
1363+
blocks: [
1364+
{
1365+
formatHolder: {
1366+
isSelected: false,
1367+
segmentType: 'SelectionMarker',
1368+
format: {},
1369+
},
1370+
levels: [],
1371+
blockType: 'BlockGroup',
1372+
format: {},
1373+
blockGroupType: 'ListItem',
1374+
blocks: [
1375+
{
1376+
segments: [
1377+
{
1378+
segmentType: 'Br',
1379+
format: {},
1380+
},
1381+
],
1382+
segmentFormat: {},
1383+
blockType: 'Paragraph',
1384+
format: {},
1385+
},
1386+
],
1387+
},
1388+
{
1389+
segments: [
1390+
{
1391+
text: '1.',
1392+
segmentType: 'Text',
1393+
format: {},
1394+
},
1395+
{
1396+
isSelected: true,
1397+
segmentType: 'SelectionMarker',
1398+
format: {},
1399+
},
1400+
],
1401+
segmentFormat: {},
1402+
blockType: 'Paragraph',
1403+
format: {},
1404+
},
1405+
],
1406+
format: {},
1407+
};
1408+
runTest(model, {
1409+
listType: 'OL',
1410+
styleType: NumberingListType.Decimal,
1411+
index: undefined,
1412+
});
1413+
});
13591414
});

0 commit comments

Comments
 (0)