Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimize cache for mutation under entity #2691

Closed
wants to merge 135 commits into from
Closed
Changes from all commits
Commits
Show all changes
135 commits
Select commit Hold shift + click to select a range
c30c84a
KeyboardEnter
JiuqingSong Apr 29, 2024
9865552
fix comment
JiuqingSong Apr 30, 2024
a8af367
fix test
JiuqingSong Apr 30, 2024
ac1a2c1
improve
JiuqingSong May 1, 2024
18ac906
Merge branch 'master' into u/jisong/keyboardenter
JiuqingSong May 1, 2024
bc99d9d
Let Content Model cache handle child list change
JiuqingSong May 2, 2024
fc1d4ea
pushMerge branch 'u/jisong/keyboardenter' into u/jisong/reconcilechi…
JiuqingSong May 2, 2024
817530f
Merge branch 'master' into u/jisong/keyboardenter
JiuqingSong May 2, 2024
0b3b22b
Merge branch 'master' into u/jisong/reconcilechildlist
JiuqingSong May 2, 2024
bccb2ed
Merge branch 'master' into u/jisong/keyboardenter
JiuqingSong May 6, 2024
8304dc9
Scroll caret into view when call formatContentModel
JiuqingSong May 6, 2024
6506a6e
Merge branch 'u/jisong/scrollintoview' into u/jisong/keyboardenter
JiuqingSong May 6, 2024
65913c0
scroll caret into view
JiuqingSong May 6, 2024
844e1f7
Merge branch 'master' into u/jisong/keyboardenter
JiuqingSong May 6, 2024
7468a88
Merge branch 'master' into u/jisong/keyboardenter
JiuqingSong May 7, 2024
34f7b06
Merge branch 'master' into u/jisong/keyboardenter
JiuqingSong May 10, 2024
7cc5a1b
Readonly types (3rd try
JiuqingSong May 13, 2024
3ff0779
Improve
JiuqingSong May 14, 2024
950a4ae
fix build
JiuqingSong May 14, 2024
2574fe2
Improve
JiuqingSong May 14, 2024
0180d29
Merge branch 'master' into u/jisong/readonlytype0513
JiuqingSong May 14, 2024
47b21f3
improve
JiuqingSong May 14, 2024
bd6b0cb
Improve
JiuqingSong May 14, 2024
cf3ea78
Add shallow mutable type
JiuqingSong May 14, 2024
e14e506
improve
JiuqingSong May 14, 2024
9a2d449
Improve
JiuqingSong May 14, 2024
719f5ed
improve
JiuqingSong May 14, 2024
caf7ef1
improve
JiuqingSong May 15, 2024
29495db
Merge branch 'master' into u/jisong/readonlytype0513
JiuqingSong May 16, 2024
0230a26
add test
JiuqingSong May 16, 2024
46fbe45
Readonly types step 2
JiuqingSong May 16, 2024
5f9b88b
Readonly types step 3
JiuqingSong May 16, 2024
4fa3138
Merge branch 'u/jisong/readonlytypes_step_2' into u/jisong/readonlyty…
JiuqingSong May 16, 2024
ce2e31a
Readonly type step 4
JiuqingSong May 16, 2024
2afcf38
add test
JiuqingSong May 16, 2024
b2a3f6c
Merge branch 'u/jisong/readonlytypes_step_2' into u/jisong/readonlyty…
JiuqingSong May 16, 2024
adb26a0
Improve
JiuqingSong May 16, 2024
b77e4b0
Merge branch 'u/jisong/readonlytypes_step_2' into u/jisong/readonlyty…
JiuqingSong May 16, 2024
85b50f2
improve
JiuqingSong May 17, 2024
e91e1a8
Merge branch 'master' into u/jisong/readonlytype0513
JiuqingSong May 17, 2024
6dbd78b
improve
JiuqingSong May 17, 2024
d0ee665
Merge branch 'u/jisong/readonlytype0513' into u/jisong/readonlytypes_…
JiuqingSong May 17, 2024
6d7d041
Merge branch 'u/jisong/readonlytype0513' into u/jisong/readonlytypes_…
JiuqingSong May 17, 2024
6c35a70
Merge branch 'u/jisong/readonlytypes_step_2' into u/jisong/readonlyty…
JiuqingSong May 17, 2024
1e157b1
Merge branch 'u/jisong/readonlytypes_step_3' into u/jisong/readonlyty…
JiuqingSong May 17, 2024
c92c7db
Readonly types step 5: dom package
JiuqingSong May 17, 2024
719c917
add change
JiuqingSong May 17, 2024
3ec1ec0
Merge branch 'master' into u/jisong/readonlytypes_step_5
JiuqingSong May 18, 2024
f659ca9
Merge branch 'master' into u/jisong/readonlytypes_step_2
JiuqingSong May 19, 2024
acceb1d
improve
JiuqingSong May 19, 2024
d5b159d
Merge branch 'u/jisong/readonlytypes_step_2' into u/jisong/readonlyty…
JiuqingSong May 19, 2024
93b0247
Merge branch 'u/jisong/readonlytypes_step_4' into u/jisong/readonlyty…
JiuqingSong May 19, 2024
f7384a4
Readonly types step 6
JiuqingSong May 20, 2024
7bd493a
fix build
JiuqingSong May 20, 2024
a69738f
Merge branch 'master' into u/jisong/readonlytype0513
JiuqingSong May 20, 2024
b4ab134
improve
JiuqingSong May 20, 2024
dea9f7f
Merge branch 'u/jisong/readonlytype0513' into u/jisong/readonlytypes_…
JiuqingSong May 20, 2024
6d9fe1e
Merge branch 'u/jisong/readonlytype0513' into u/jisong/readonlytypes_…
JiuqingSong May 20, 2024
124559c
Merge branch 'u/jisong/readonlytypes_step_2' into u/jisong/readonlyty…
JiuqingSong May 20, 2024
df68a71
Merge branch 'u/jisong/readonlytypes_step_3' into u/jisong/readonlyty…
JiuqingSong May 20, 2024
9301264
Merge branch 'u/jisong/readonlytypes_step_4' into u/jisong/readonlyty…
JiuqingSong May 20, 2024
289e3f9
Merge branch 'u/jisong/readonlytypes_step_5' into u/jisong/readonlyty…
JiuqingSong May 20, 2024
f745036
Merge branch 'master' into u/jisong/readonlytypes_step_2
JiuqingSong May 20, 2024
806a1d3
Improve
JiuqingSong May 20, 2024
fa84daa
Merge branch 'master' into u/jisong/readonlytypes_step_3
JiuqingSong May 20, 2024
de8ca0d
improve
JiuqingSong May 20, 2024
149b315
Merge branch 'u/jisong/readonlytypes_step_2' into u/jisong/readonlyty…
JiuqingSong May 20, 2024
1de55bb
Merge branch 'u/jisong/readonlytypes_step_3' into u/jisong/readonlyty…
JiuqingSong May 20, 2024
588864e
Merge branch 'u/jisong/readonlytypes_step_4' into u/jisong/readonlyty…
JiuqingSong May 20, 2024
7a6b43f
fix test
JiuqingSong May 20, 2024
bd9661d
Merge branch 'u/jisong/readonlytypes_step_2' into u/jisong/readonlyty…
JiuqingSong May 20, 2024
cc17fdb
Merge branch 'u/jisong/readonlytypes_step_4' into u/jisong/readonlyty…
JiuqingSong May 20, 2024
62e491f
Improve
JiuqingSong May 20, 2024
1a43582
Merge branch 'u/jisong/readonlytypes_step_5' into u/jisong/readonlyty…
JiuqingSong May 20, 2024
5f3027f
Improve
JiuqingSong May 20, 2024
829e6ca
fix build
JiuqingSong May 20, 2024
2bc734b
improve
JiuqingSong May 20, 2024
5e72761
improve
JiuqingSong May 20, 2024
3f36928
Merge branch 'u/jisong/readonlytypes_step_2' into u/jisong/readonlyty…
JiuqingSong May 20, 2024
a8cc329
Merge branch 'u/jisong/readonlytypes_step_4' into u/jisong/readonlyty…
JiuqingSong May 20, 2024
fffd11c
Merge branch 'u/jisong/readonlytypes_step_5' into u/jisong/readonlyty…
JiuqingSong May 20, 2024
71f3ba8
Readonly types step 7: Port all other files
JiuqingSong May 20, 2024
5062a70
improve
JiuqingSong May 20, 2024
4bc4412
Readonly type steps 8: Finally enable readonly type
JiuqingSong May 20, 2024
c717e24
fix test
JiuqingSong May 20, 2024
732d153
improve
JiuqingSong May 21, 2024
cd6fe10
Merge branch 'master' into u/jisong/keyboardenter
JiuqingSong May 23, 2024
fe31c04
Merge branch 'master' into u/jisong/readonlytypes_step_6
JiuqingSong May 24, 2024
37b5abe
improve
JiuqingSong May 24, 2024
fedf510
Merge branch 'master' into u/jisong/readonlytypes_step_6
JiuqingSong May 24, 2024
8d6ace8
Merge branch 'u/jisong/readonlytypes_step_6' into u/jisong/readonlyty…
JiuqingSong May 24, 2024
edf9445
Merge branch 'master' into u/jisong/readonlytypes_step_6
JiuqingSong May 28, 2024
bdd5f1b
Merge branch 'u/jisong/readonlytypes_step_6' into u/jisong/readonlyty…
JiuqingSong May 28, 2024
9ac9e08
Merge branch 'u/jisong/readonlytypes_step_7' into u/jisong/readonlyty…
JiuqingSong May 28, 2024
96a4a48
fix build
JiuqingSong May 28, 2024
87ab530
fix build
JiuqingSong May 28, 2024
2edbc0a
fix build
JiuqingSong May 28, 2024
e269e91
Merge branch 'master' into u/jisong/readonlytypes_step_7
JiuqingSong May 29, 2024
c3b766d
Merge branch 'u/jisong/readonlytypes_step_7' into u/jisong/readonlyty…
JiuqingSong May 29, 2024
66db4cd
Merge branch 'master' into u/jisong/keyboardenter
JiuqingSong May 29, 2024
115bf03
Merge branch 'u/jisong/keyboardenter' into u/jisong/reconcilechildlist
JiuqingSong May 29, 2024
a5ef968
Fix build
JiuqingSong May 29, 2024
840cb8d
Merge branch 'u/jisong/keyboardenter' into u/jisong/reconcilechildlist
JiuqingSong May 29, 2024
dd1171c
fix build
JiuqingSong May 29, 2024
472436e
Merge branch 'master' into u/jisong/keyboardenter
JiuqingSong May 29, 2024
09938f2
 'master' into u/jisong/keyboardenter
JiuqingSong May 30, 2024
ad9feeb
improve
JiuqingSong May 30, 2024
3a7d92e
fix build
JiuqingSong May 31, 2024
2bc4b5a
Merge branch 'master' into u/jisong/readonlytypes_step_8
JiuqingSong May 31, 2024
6ae3bb0
Add experimental features
JiuqingSong May 31, 2024
21a0bb0
Merge branch 'master' into u/jisong/keyboardenter
JiuqingSong May 31, 2024
c0a41f8
Merge branch 'u/jisong/keyboardenter' into u/jisong/reconcilechildlist
JiuqingSong May 31, 2024
becf627
Merge branch 'u/jisong/readonlytypes_step_8' into u/jisong/reconcilec…
JiuqingSong May 31, 2024
fa4c2ff
Merge branch 'master' into u/jisong/keyboardenter
JiuqingSong Jun 3, 2024
0698c39
Improve
JiuqingSong Jun 3, 2024
f1dfe80
fix test
JiuqingSong Jun 3, 2024
37f6b4b
add test
JiuqingSong Jun 3, 2024
1f90c24
add test
JiuqingSong Jun 4, 2024
5491860
Merge branch 'u/jisong/keyboardenter' into u/jisong/reconcilechildlist
JiuqingSong Jun 5, 2024
82d4ce3
Merge branch 'master' into u/jisong/keyboardenter
JiuqingSong Jun 5, 2024
aaa58f6
improve
JiuqingSong Jun 5, 2024
280345f
do not scroll caret into view for now
JiuqingSong Jun 5, 2024
ff29216
Merge branch 'master' into u/jisong/keyboardenter
JiuqingSong Jun 5, 2024
8be7099
Merge branch 'u/jisong/keyboardenter' into u/jisong/reconcilechildlist
JiuqingSong Jun 5, 2024
6077ae6
Merge branch 'master' into u/jisong/reconcilechildlist
JiuqingSong Jun 6, 2024
a8e46cd
improve
JiuqingSong Jun 6, 2024
ac47a4d
fix test
JiuqingSong Jun 6, 2024
9443a20
Merge branch 'master' into u/jisong/reconcilechildlist
JiuqingSong Jun 7, 2024
30455ff
Improve
JiuqingSong Jun 10, 2024
b296c39
fix test
JiuqingSong Jun 10, 2024
c46cd18
add test cases
JiuqingSong Jun 10, 2024
b8ca862
Handle mutation in entity
JiuqingSong Jun 11, 2024
77033e1
Merge branch 'master' into u/jisong/handleentity
JiuqingSong Jun 12, 2024
d6c2413
Merge branch 'master' into u/jisong/handleentity
JiuqingSong Jun 12, 2024
a5f60a2
Merge branch 'master' into u/jisong/handleentity
JiuqingSong Jun 12, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { areSameSelection } from './areSameSelection';
import { createTextMutationObserver } from './textMutationObserver';
import { DomIndexerImpl } from './domIndexerImpl';
import { findClosestEntityWrapper, getSelectionRootNode } from 'roosterjs-content-model-dom';
import { updateCachedSelection } from './updateCachedSelection';
import type {
CachePluginState,
@@ -9,6 +10,7 @@ import type {
PluginWithState,
EditorOptions,
ContentModelDocument,
DOMHelper,
} from 'roosterjs-content-model-types';

/**
@@ -17,6 +19,7 @@ import type {
class CachePlugin implements PluginWithState<CachePluginState> {
private editor: IEditor | null = null;
private state: CachePluginState;
private logicalRoot: HTMLElement | null = null;

/**
* Construct a new instance of CachePlugin class
@@ -38,7 +41,8 @@ class CachePlugin implements PluginWithState<CachePluginState> {
contentDiv,
domIndexer,
this.onMutation,
this.onSkipMutation
this.onSkipMutation,
this.areNodesUnderEntity
),
};
}
@@ -71,6 +75,7 @@ class CachePlugin implements PluginWithState<CachePluginState> {
*/
dispose() {
this.state.textMutationObserver?.stopObserving();
this.logicalRoot = null;

if (this.editor) {
this.editor
@@ -99,6 +104,10 @@ class CachePlugin implements PluginWithState<CachePluginState> {
}

switch (event.eventType) {
case 'logicalRootChanged':
this.logicalRoot = event.logicalRoot;
break;

case 'keyDown':
case 'input':
if (!this.state.textMutationObserver) {
@@ -159,28 +168,47 @@ class CachePlugin implements PluginWithState<CachePluginState> {
const cachedSelection = this.state.cachedSelection;
this.state.cachedSelection = undefined; // Clear it to force getDOMSelection() retrieve the latest selection range

const newRangeEx = editor.getDOMSelection() || undefined;
const selection = editor.getDOMSelection() || undefined;
const model = this.state.cachedModel;
const isSelectionChanged =
forceUpdate ||
!cachedSelection ||
!newRangeEx ||
!areSameSelection(newRangeEx, cachedSelection);
!selection ||
!areSameSelection(selection, cachedSelection);

if (isSelectionChanged) {
if (
!model ||
!newRangeEx ||
!this.state.domIndexer?.reconcileSelection(model, newRangeEx, cachedSelection)
!selection ||
(!this.state.domIndexer?.reconcileSelection(model, selection, cachedSelection) &&
!this.isNodeUnderEntity(editor.getDOMHelper(), getSelectionRootNode(selection)))
) {
this.invalidateCache();
} else {
updateCachedSelection(this.state, newRangeEx);
updateCachedSelection(this.state, selection);
}
} else {
this.state.cachedSelection = cachedSelection;
}
}

private areNodesUnderEntity = (nodes: Node[]) => {
const domHelper = this.editor?.getDOMHelper();

return !!domHelper && nodes.every(node => this.isNodeUnderEntity(domHelper, node));
};

private isNodeUnderEntity(domHelper: DOMHelper, node: Node | undefined) {
const entity = node && findClosestEntityWrapper(node, domHelper);

if (!entity) {
return false;
} else if (this.logicalRoot) {
return this.logicalRoot.contains(node);
} else {
return domHelper.isNodeInEditor(node);
}
}
}

/**
Original file line number Diff line number Diff line change
@@ -11,7 +11,8 @@ class TextMutationObserverImpl implements TextMutationObserver {
private contentDiv: HTMLDivElement,
private domIndexer: DomIndexer,
private onMutation: (isTextChangeOnly: boolean) => void,
private onSkipMutation: (newModel: ContentModelDocument) => void
private onSkipMutation: (newModel: ContentModelDocument) => void,
private areNodesUnderEntity: (nodes: Node[]) => boolean
) {
this.observer = new MutationObserver(this.onMutationInternal);
}
@@ -47,6 +48,12 @@ class TextMutationObserverImpl implements TextMutationObserver {
let removedNodes: Node[] = [];
let reconcileText = false;

const nodeSet = new Set<Node>(mutations.map(x => x.target));

if (this.areNodesUnderEntity(Array.from(nodeSet))) {
return;
}

for (let i = 0; i < mutations.length && canHandle; i++) {
const mutation = mutations[i];

@@ -103,7 +110,14 @@ export function createTextMutationObserver(
contentDiv: HTMLDivElement,
domIndexer: DomIndexer,
onMutation: (isTextChangeOnly: boolean) => void,
onSkipMutation: (newModel: ContentModelDocument) => void
onSkipMutation: (newModel: ContentModelDocument) => void,
areNodesUnderEntity: (nodes: Node[]) => boolean
): TextMutationObserver {
return new TextMutationObserverImpl(contentDiv, domIndexer, onMutation, onSkipMutation);
return new TextMutationObserverImpl(
contentDiv,
domIndexer,
onMutation,
onSkipMutation,
areNodesUnderEntity
);
}
Original file line number Diff line number Diff line change
@@ -20,7 +20,9 @@ export function getDOMInsertPointRect(doc: Document, pos: DOMInsertPoint): Rect
return rect;
}

// 2) try to get rect using range.getClientRects
// 2) Normalize this selection and try again
// If selection is at beginning of a TEXT node, we will get node=text.parentNode and offset=0
// This will move it down to the real text node
while (node.lastChild) {
if (offset == node.childNodes.length) {
node = node.lastChild;
@@ -31,24 +33,19 @@ export function getDOMInsertPointRect(doc: Document, pos: DOMInsertPoint): Rect
}
}

const rects = range.getClientRects && range.getClientRects();
rect = rects && rects.length == 1 ? normalizeRect(rects[0]) : null;
range.setStart(node, offset);
range.setEnd(node, offset);
rect = normalizeRect(range.getBoundingClientRect());

if (rect) {
return rect;
}

// 3) if node is text node, try inserting a SPAN and get the rect of SPAN for others
if (isNodeOfType(node, 'TEXT_NODE')) {
const span = node.ownerDocument.createElement('span');

span.textContent = '\u200b';
range.insertNode(span);
rect = normalizeRect(span.getBoundingClientRect());
span.parentNode?.removeChild(span);

if (rect) {
return rect;
}
// 3) try to get rect using range.getClientRects
const rects = range.getClientRects && range.getClientRects();
rect = rects && rects.length == 1 ? normalizeRect(rects[0]) : null;
if (rect) {
return rect;
}

// 4) try getBoundingClientRect on element
Loading