fix: Various compounding memory leaks in editor (#5950)
This commit is contained in:
@@ -302,6 +302,7 @@ export class Editor extends React.PureComponent<
|
||||
|
||||
public componentWillUnmount(): void {
|
||||
window.removeEventListener("theme-changed", this.dispatchThemeChanged);
|
||||
this.view.destroy();
|
||||
this.mutationObserver?.disconnect();
|
||||
}
|
||||
|
||||
@@ -349,27 +350,26 @@ export class Editor extends React.PureComponent<
|
||||
private createNodeViews() {
|
||||
return this.extensions.extensions
|
||||
.filter((extension: ReactNode) => extension.component)
|
||||
.reduce((nodeViews, extension: ReactNode) => {
|
||||
const nodeView = (
|
||||
node: ProsemirrorNode,
|
||||
view: EditorView,
|
||||
getPos: () => number,
|
||||
decorations: Decoration[]
|
||||
) =>
|
||||
new ComponentView(extension.component, {
|
||||
editor: this,
|
||||
extension,
|
||||
node,
|
||||
view,
|
||||
getPos,
|
||||
decorations,
|
||||
});
|
||||
|
||||
return {
|
||||
.reduce(
|
||||
(nodeViews, extension: ReactNode) => ({
|
||||
...nodeViews,
|
||||
[extension.name]: nodeView,
|
||||
};
|
||||
}, {});
|
||||
[extension.name]: (
|
||||
node: ProsemirrorNode,
|
||||
view: EditorView,
|
||||
getPos: () => number,
|
||||
decorations: Decoration[]
|
||||
) =>
|
||||
new ComponentView(extension.component, {
|
||||
editor: this,
|
||||
extension,
|
||||
node,
|
||||
view,
|
||||
getPos,
|
||||
decorations,
|
||||
}),
|
||||
}),
|
||||
{}
|
||||
);
|
||||
}
|
||||
|
||||
private createCommands() {
|
||||
|
||||
@@ -171,7 +171,7 @@
|
||||
"prosemirror-state": "^1.4.3",
|
||||
"prosemirror-tables": "^1.3.2",
|
||||
"prosemirror-transform": "^1.7.3",
|
||||
"prosemirror-view": "^1.31.3",
|
||||
"prosemirror-view": "^1.32.0",
|
||||
"query-string": "^7.1.3",
|
||||
"quoted-printable": "^1.0.1",
|
||||
"randomstring": "1.2.3",
|
||||
|
||||
@@ -29,10 +29,10 @@ const Image = (props: Props) => {
|
||||
const [loaded, setLoaded] = React.useState(false);
|
||||
const [naturalWidth, setNaturalWidth] = React.useState(node.attrs.width);
|
||||
const [naturalHeight, setNaturalHeight] = React.useState(node.attrs.height);
|
||||
const documentBounds = useComponentSize(props.view.dom);
|
||||
const containerBounds = useComponentSize(
|
||||
document.body.querySelector("#full-width-container")
|
||||
);
|
||||
const documentBounds = props.view.dom.getBoundingClientRect();
|
||||
const maxWidth = layoutClass
|
||||
? documentBounds.width / 3
|
||||
: documentBounds.width;
|
||||
|
||||
@@ -14,48 +14,44 @@ const defaultRect = {
|
||||
export default function useComponentSize(
|
||||
element: HTMLElement | null
|
||||
): DOMRect | typeof defaultRect {
|
||||
const [size, setSize] = useState(element?.getBoundingClientRect());
|
||||
const [size, setSize] = useState(() => element?.getBoundingClientRect());
|
||||
|
||||
useEffect(() => {
|
||||
const sizeObserver = new ResizeObserver((entries) => {
|
||||
entries.forEach(({ target }) => {
|
||||
const rect = target?.getBoundingClientRect();
|
||||
setSize((state) =>
|
||||
state?.width === rect?.width &&
|
||||
state?.height === rect?.height &&
|
||||
state?.x === rect?.x &&
|
||||
state?.y === rect?.y
|
||||
? state
|
||||
: rect
|
||||
);
|
||||
});
|
||||
const sizeObserver = new ResizeObserver(() => {
|
||||
element?.dispatchEvent(new CustomEvent("resize"));
|
||||
});
|
||||
|
||||
if (element) {
|
||||
sizeObserver.observe(element);
|
||||
}
|
||||
|
||||
return () => sizeObserver.disconnect();
|
||||
}, [element]);
|
||||
|
||||
useEffect(() => {
|
||||
const handleResize = () => {
|
||||
const rect = element?.getBoundingClientRect();
|
||||
setSize((state) =>
|
||||
state?.width === rect?.width &&
|
||||
state?.height === rect?.height &&
|
||||
state?.x === rect?.x &&
|
||||
state?.y === rect?.y
|
||||
? state
|
||||
: rect
|
||||
);
|
||||
setSize((state: DOMRect) => {
|
||||
const rect = element?.getBoundingClientRect();
|
||||
|
||||
if (
|
||||
rect &&
|
||||
Math.round(state.width) === Math.round(rect.width) &&
|
||||
Math.round(state.height) === Math.round(rect.height) &&
|
||||
Math.round(state.x) === Math.round(rect.x) &&
|
||||
Math.round(state.y) === Math.round(rect.y)
|
||||
) {
|
||||
return state;
|
||||
}
|
||||
return rect;
|
||||
});
|
||||
};
|
||||
|
||||
window.addEventListener("click", handleResize);
|
||||
window.addEventListener("resize", handleResize);
|
||||
element?.addEventListener("resize", handleResize);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener("click", handleResize);
|
||||
window.removeEventListener("resize", handleResize);
|
||||
element?.removeEventListener("resize", handleResize);
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
@@ -10848,10 +10848,10 @@ prosemirror-transform@^1.0.0, prosemirror-transform@^1.1.0, prosemirror-transfor
|
||||
dependencies:
|
||||
prosemirror-model "^1.0.0"
|
||||
|
||||
prosemirror-view@^1.0.0, prosemirror-view@^1.1.0, prosemirror-view@^1.13.3, prosemirror-view@^1.27.0, prosemirror-view@^1.31.0, prosemirror-view@^1.31.3:
|
||||
version "1.31.3"
|
||||
resolved "https://registry.yarnpkg.com/prosemirror-view/-/prosemirror-view-1.31.3.tgz#cfe171c4e50a577526d0235d9ec757cdddf6017d"
|
||||
integrity sha512-UYDa8WxRFZm0xQLXiPJUVTl6H08Fn0IUVDootA7ZlQwzooqVWnBOXLovJyyTKgws1nprfsPhhlvWgt2jo4ZA6g==
|
||||
prosemirror-view@^1.0.0, prosemirror-view@^1.1.0, prosemirror-view@^1.13.3, prosemirror-view@^1.27.0, prosemirror-view@^1.31.0, prosemirror-view@^1.32.0:
|
||||
version "1.32.0"
|
||||
resolved "https://registry.yarnpkg.com/prosemirror-view/-/prosemirror-view-1.32.0.tgz#2022538d02932c0901232d1e0430c064f79a8ea2"
|
||||
integrity sha512-HwW7IWgca6ehiW2PA48H/8yl0TakA0Ms5LgN5Krc97oar7GfjIKE/NocUsLe74Jq4mwyWKUNoBljE8WkXKZwng==
|
||||
dependencies:
|
||||
prosemirror-model "^1.16.0"
|
||||
prosemirror-state "^1.0.0"
|
||||
|
||||
Reference in New Issue
Block a user