mirror of
https://github.com/microsoft/playwright.git
synced 2024-12-12 00:52:05 +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);
|
||||
}, [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'>
|
||||
<Toolbar>
|
||||
<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={() => {
|
||||
window.dispatch({ event: 'setMode', params: { mode: mode === 'inspecting' ? 'none' : 'inspecting' } }).catch(() => { });
|
||||
}}>Pick locator</ToolbarButton>
|
||||
<CodeMirrorWrapper text={locator} language={source.language} readOnly={false} focusOnChange={true} wrapLines={true} onChange={text => {
|
||||
setLocator(text);
|
||||
window.dispatch({ event: 'selectorUpdated', params: { selector: text, language: source.language } });
|
||||
}} />
|
||||
<CodeMirrorWrapper text={locator} language={source.language} readOnly={false} focusOnChange={true} wrapLines={true} onChange={onEditorChange} />
|
||||
<ToolbarButton icon='files' title='Copy' onClick={() => {
|
||||
copy(locator);
|
||||
}}></ToolbarButton>
|
||||
|
@ -104,15 +104,9 @@ export const CodeMirrorWrapper: React.FC<SourceProps> = ({
|
||||
codemirrorRef.current.cm.setSize(measure.width, measure.height);
|
||||
}, [measure]);
|
||||
|
||||
React.useEffect(() => {
|
||||
React.useLayoutEffect(() => {
|
||||
if (!codemirror)
|
||||
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;
|
||||
if (codemirror.getValue() !== text) {
|
||||
@ -155,12 +149,22 @@ export const CodeMirrorWrapper: React.FC<SourceProps> = ({
|
||||
codemirrorRef.current!.highlight = highlight;
|
||||
codemirrorRef.current!.widgets = widgets;
|
||||
}
|
||||
|
||||
// Line-less locations have line = 0, but they mean to reveal the file.
|
||||
if (typeof revealLine === 'number' && codemirrorRef.current!.cm.lineCount() >= revealLine)
|
||||
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]);
|
||||
|
||||
return <div className='cm-wrapper' ref={codemirrorElement}></div>;
|
||||
};
|
||||
|
||||
const listenerSymbol = Symbol('listener');
|
||||
|
Loading…
Reference in New Issue
Block a user