mirror of
https://github.com/microsoft/playwright.git
synced 2024-12-12 20:03:03 +03:00
chore: fix leaking event listeners (#22562)
Fixes https://github.com/microsoft/playwright/issues/22348
This commit is contained in:
parent
f6aa9f49ce
commit
becb072703
@ -104,6 +104,12 @@ export const Recorder: React.FC<RecorderProps> = ({
|
|||||||
return () => document.removeEventListener('keydown', handleKeyDown);
|
return () => document.removeEventListener('keydown', handleKeyDown);
|
||||||
}, [paused]);
|
}, [paused]);
|
||||||
|
|
||||||
|
const onEditorChange = React.useCallback((text: string) => {
|
||||||
|
setLocator(text);
|
||||||
|
const source = sources.find(s => s.id === fileId);
|
||||||
|
window.dispatch({ event: 'selectorUpdated', params: { selector: text, language: source?.language || 'javascript' } });
|
||||||
|
}, [sources, fileId]);
|
||||||
|
|
||||||
return <div className='recorder'>
|
return <div className='recorder'>
|
||||||
<Toolbar>
|
<Toolbar>
|
||||||
<ToolbarButton icon='record' title='Record' toggled={mode === 'recording'} onClick={() => {
|
<ToolbarButton icon='record' title='Record' toggled={mode === 'recording'} onClick={() => {
|
||||||
@ -139,10 +145,7 @@ export const Recorder: React.FC<RecorderProps> = ({
|
|||||||
<ToolbarButton icon='microscope' title='Pick locator' toggled={mode === 'inspecting'} onClick={() => {
|
<ToolbarButton icon='microscope' title='Pick locator' toggled={mode === 'inspecting'} onClick={() => {
|
||||||
window.dispatch({ event: 'setMode', params: { mode: mode === 'inspecting' ? 'none' : 'inspecting' } }).catch(() => { });
|
window.dispatch({ event: 'setMode', params: { mode: mode === 'inspecting' ? 'none' : 'inspecting' } }).catch(() => { });
|
||||||
}}>Pick locator</ToolbarButton>
|
}}>Pick locator</ToolbarButton>
|
||||||
<CodeMirrorWrapper text={locator} language={source.language} readOnly={false} focusOnChange={true} wrapLines={true} onChange={text => {
|
<CodeMirrorWrapper text={locator} language={source.language} readOnly={false} focusOnChange={true} wrapLines={true} onChange={onEditorChange} />
|
||||||
setLocator(text);
|
|
||||||
window.dispatch({ event: 'selectorUpdated', params: { selector: text, language: source.language } });
|
|
||||||
}} />
|
|
||||||
<ToolbarButton icon='files' title='Copy' onClick={() => {
|
<ToolbarButton icon='files' title='Copy' onClick={() => {
|
||||||
copy(locator);
|
copy(locator);
|
||||||
}}></ToolbarButton>
|
}}></ToolbarButton>
|
||||||
|
@ -104,15 +104,9 @@ export const CodeMirrorWrapper: React.FC<SourceProps> = ({
|
|||||||
codemirrorRef.current.cm.setSize(measure.width, measure.height);
|
codemirrorRef.current.cm.setSize(measure.width, measure.height);
|
||||||
}, [measure]);
|
}, [measure]);
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useLayoutEffect(() => {
|
||||||
if (!codemirror)
|
if (!codemirror)
|
||||||
return;
|
return;
|
||||||
codemirror.off('change', (codemirror as any).listenerSymbol);
|
|
||||||
(codemirror as any)[listenerSymbol] = undefined;
|
|
||||||
if (onChange) {
|
|
||||||
(codemirror as any)[listenerSymbol] = () => onChange(codemirror.getValue());
|
|
||||||
codemirror.on('change', (codemirror as any)[listenerSymbol]);
|
|
||||||
}
|
|
||||||
|
|
||||||
let valueChanged = false;
|
let valueChanged = false;
|
||||||
if (codemirror.getValue() !== text) {
|
if (codemirror.getValue() !== text) {
|
||||||
@ -155,12 +149,22 @@ export const CodeMirrorWrapper: React.FC<SourceProps> = ({
|
|||||||
codemirrorRef.current!.highlight = highlight;
|
codemirrorRef.current!.highlight = highlight;
|
||||||
codemirrorRef.current!.widgets = widgets;
|
codemirrorRef.current!.widgets = widgets;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Line-less locations have line = 0, but they mean to reveal the file.
|
// Line-less locations have line = 0, but they mean to reveal the file.
|
||||||
if (typeof revealLine === 'number' && codemirrorRef.current!.cm.lineCount() >= revealLine)
|
if (typeof revealLine === 'number' && codemirrorRef.current!.cm.lineCount() >= revealLine)
|
||||||
codemirror.scrollIntoView({ line: Math.max(0, revealLine - 1), ch: 0 }, 50);
|
codemirror.scrollIntoView({ line: Math.max(0, revealLine - 1), ch: 0 }, 50);
|
||||||
|
|
||||||
|
let changeListener: () => void | undefined;
|
||||||
|
if (onChange) {
|
||||||
|
changeListener = () => onChange(codemirror.getValue());
|
||||||
|
codemirror.on('change', changeListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
if (changeListener)
|
||||||
|
codemirror.off('change', changeListener);
|
||||||
|
};
|
||||||
}, [codemirror, text, highlight, revealLine, focusOnChange, onChange]);
|
}, [codemirror, text, highlight, revealLine, focusOnChange, onChange]);
|
||||||
|
|
||||||
return <div className='cm-wrapper' ref={codemirrorElement}></div>;
|
return <div className='cm-wrapper' ref={codemirrorElement}></div>;
|
||||||
};
|
};
|
||||||
|
|
||||||
const listenerSymbol = Symbol('listener');
|
|
||||||
|
Loading…
Reference in New Issue
Block a user