1
0
mirror of https://github.com/laurent22/joplin.git synced 2025-06-27 23:28:38 +02:00

Fixed WebView race condition

This commit is contained in:
Laurent Cozic
2020-10-16 12:26:20 +01:00
parent 1e0d2b7b86
commit 66059939a3
3 changed files with 19 additions and 3 deletions

View File

@ -100,7 +100,7 @@ export default function NoteBodyViewer(props:Props) {
injectedJavaScript={injectedJs.join('\n')} injectedJavaScript={injectedJs.join('\n')}
originWhitelist={['file://*', './*', 'http://*', 'https://*']} originWhitelist={['file://*', './*', 'http://*', 'https://*']}
mixedContentMode="always" mixedContentMode="always"
allowFileAccess={true} // TODO: Implement logic to avoid race condition between source and allowFileAccess allowFileAccess={true}
onLoadEnd={onLoadEnd} onLoadEnd={onLoadEnd}
onError={onError} onError={onError}
onMessage={onMessage} onMessage={onMessage}

View File

@ -27,6 +27,7 @@ export default function useSource(noteBody:string, noteMarkupLanguage:number, th
const [source, setSource] = useState<Source>(undefined); const [source, setSource] = useState<Source>(undefined);
const [injectedJs, setInjectedJs] = useState<string[]>([]); const [injectedJs, setInjectedJs] = useState<string[]>([]);
const [resourceLoadedTime, setResourceLoadedTime] = useState(0); const [resourceLoadedTime, setResourceLoadedTime] = useState(0);
const [isFirstRender, setIsFirstRender] = useState(true);
const rendererTheme = useMemo(() => { const rendererTheme = useMemo(() => {
return { return {
@ -141,12 +142,24 @@ export default function useSource(noteBody:string, noteMarkupLanguage:number, th
setInjectedJs(js); setInjectedJs(js);
} }
// When mounted, we need to render the webview in two stages;
// - First without any source, so that all webview props are setup properly
// - Secondly with the source to actually render the note
// This is necessary to prevent a race condition that could cause an ERR_ACCESS_DENIED error
// https://github.com/react-native-webview/react-native-webview/issues/656#issuecomment-551312436
if (isFirstRender) {
setIsFirstRender(false);
setSource(undefined);
setInjectedJs([]);
} else {
renderNote(); renderNote();
}
return () => { return () => {
cancelled = true; cancelled = true;
} }
}, [resourceLoadedTime, noteBody, noteMarkupLanguage, themeId, rendererTheme, highlightedKeywords, noteResources, noteHash]); }, [resourceLoadedTime, noteBody, noteMarkupLanguage, themeId, rendererTheme, highlightedKeywords, noteResources, noteHash, isFirstRender]);
return { source, injectedJs }; return { source, injectedJs };
} }

View File

@ -1035,6 +1035,9 @@ class NoteScreenComponent extends BaseScreenComponent {
bodyComponent = this.useBetaEditor() bodyComponent = this.useBetaEditor()
// Note: blurOnSubmit is necessary to get multiline to work. // Note: blurOnSubmit is necessary to get multiline to work.
// See https://github.com/facebook/react-native/issues/12717#issuecomment-327001997 // See https://github.com/facebook/react-native/issues/12717#issuecomment-327001997
//
// 2020-10-16: As of React Native 0.63, the Markdown Editor no longer crashes in Android, however the
// cursor is still too unreliable to be usable, so we disable it in Android.
? <MarkdownEditor ? <MarkdownEditor
ref={this.markdownEditorRef} // For focusing the Markdown editor ref={this.markdownEditorRef} // For focusing the Markdown editor
editorFont={editorFont(this.props.editorFont)} editorFont={editorFont(this.props.editorFont)}