1
0
mirror of https://github.com/laurent22/joplin.git synced 2024-12-24 10:27:10 +02:00

Desktop: Fixes #3534: Undoing changes multiple time on an existing note could result in a blank note

This commit is contained in:
Laurent Cozic 2020-07-23 19:56:53 +00:00
parent 8f8d11c9b3
commit 71e5304298
4 changed files with 28 additions and 23 deletions

View File

@ -162,6 +162,7 @@ const TinyMCE = (props:NoteBodyEditorProps, ref:any) => {
const lastOnChangeEventInfo = useRef<any>({ const lastOnChangeEventInfo = useRef<any>({
content: null, content: null,
resourceInfos: null, resourceInfos: null,
contentKey: null,
}); });
const rootIdRef = useRef<string>(`tinymce-${Date.now()}${Math.round(Math.random() * 10000)}`); const rootIdRef = useRef<string>(`tinymce-${Date.now()}${Math.round(Math.random() * 10000)}`);
@ -722,7 +723,7 @@ const TinyMCE = (props:NoteBodyEditorProps, ref:any) => {
for (const cssFile of cssFiles) loadedCssFiles_.push(cssFile); for (const cssFile of cssFiles) loadedCssFiles_.push(cssFile);
for (const jsFile of jsFiles) loadedJsFiles_.push(jsFile); for (const jsFile of jsFiles) loadedJsFiles_.push(jsFile);
console.info('loadDocumentAssets: files to load', cssFiles, jsFiles); // console.info('loadDocumentAssets: files to load', cssFiles, jsFiles);
if (cssFiles.length) { if (cssFiles.length) {
for (const cssFile of cssFiles) { for (const cssFile of cssFiles) {
@ -767,12 +768,31 @@ const TinyMCE = (props:NoteBodyEditorProps, ref:any) => {
const result = await props.markupToHtml(props.contentMarkupLanguage, props.content, markupRenderOptions({ resourceInfos: props.resourceInfos })); const result = await props.markupToHtml(props.contentMarkupLanguage, props.content, markupRenderOptions({ resourceInfos: props.resourceInfos }));
if (cancelled) return; if (cancelled) return;
editor.setContent(result.html);
if (lastOnChangeEventInfo.current.contentKey !== props.contentKey) {
// Need to clear UndoManager to avoid this problem:
// - Load note 1
// - Make a change
// - Load note 2
// - Undo => content is that of note 1
//
// The doc is not very clear what's the different between
// clear() and reset() but it seems reset() works best, in
// particular for the onPaste bug.
//
// It seems the undo manager must be reset after having
// set the initial content (not before). Otherwise undoing multiple
// times would result in an empty note.
// https://github.com/laurent22/joplin/issues/3534
editor.undoManager.reset();
}
lastOnChangeEventInfo.current = { lastOnChangeEventInfo.current = {
content: props.content, content: props.content,
resourceInfos: props.resourceInfos, resourceInfos: props.resourceInfos,
contentKey: props.contentKey,
}; };
editor.setContent(result.html);
} }
await loadDocumentAssets(editor, await props.allAssets(props.contentMarkupLanguage)); await loadDocumentAssets(editor, await props.allAssets(props.contentMarkupLanguage));
@ -785,22 +805,7 @@ const TinyMCE = (props:NoteBodyEditorProps, ref:any) => {
return () => { return () => {
cancelled = true; cancelled = true;
}; };
}, [editor, props.markupToHtml, props.allAssets, props.content, props.resourceInfos]); }, [editor, props.markupToHtml, props.allAssets, props.content, props.resourceInfos, props.contentKey]);
useEffect(() => {
if (!editor) return;
// Need to clear UndoManager to avoid this problem:
// - Load note 1
// - Make a change
// - Load note 2
// - Undo => content is that of note 1
// The doc is not very clear what's the different between
// clear() and reset() but it seems reset() works best, in
// particular for the onPaste bug.
editor.undoManager.reset();
}, [editor, props.contentKey]);
useEffect(() => { useEffect(() => {
if (!editor) return () => {}; if (!editor) return () => {};

View File

@ -18,7 +18,7 @@ export default function useMessageHandler(scrollWhenReady:any, setScrollWhenRead
const args = event.args; const args = event.args;
const arg0 = args && args.length >= 1 ? args[0] : null; const arg0 = args && args.length >= 1 ? args[0] : null;
if (msg !== 'percentScroll') console.info(`Got ipc-message: ${msg}`, arg0); // if (msg !== 'percentScroll') console.info(`Got ipc-message: ${msg}`, arg0);
if (msg.indexOf('error:') === 0) { if (msg.indexOf('error:') === 0) {
const s = msg.split(':'); const s = msg.split(':');

View File

@ -139,9 +139,9 @@ class NoteRevisionViewerComponent extends React.PureComponent {
// We try to get most links work though, except for internal (joplin://) links. // We try to get most links work though, except for internal (joplin://) links.
const msg = event.channel ? event.channel : ''; const msg = event.channel ? event.channel : '';
const args = event.args; // const args = event.args;
if (msg !== 'percentScroll') console.info(`Got ipc-message: ${msg}`, args); // if (msg !== 'percentScroll') console.info(`Got ipc-message: ${msg}`, args);
try { try {
if (msg.indexOf('joplin://') === 0) { if (msg.indexOf('joplin://') === 0) {

View File

@ -662,7 +662,7 @@ class BaseApplication {
this.dbLogger_.setLevel(initArgs.logLevel); this.dbLogger_.setLevel(initArgs.logLevel);
if (Setting.value('env') === 'dev' && Setting.value('appType') === 'desktop') { if (Setting.value('env') === 'dev' && Setting.value('appType') === 'desktop') {
this.logger_.addTarget('console', { level: Logger.LEVEL_DEBUG }); // this.logger_.addTarget('console', { level: Logger.LEVEL_DEBUG });
this.dbLogger_.addTarget('console', { level: Logger.LEVEL_WARN }); this.dbLogger_.addTarget('console', { level: Logger.LEVEL_WARN });
} }