Skip to content

Commit 6545afa

Browse files
committed
Changed autosave handling for better editor performance
This changes how the editors interact with the parent page-editor compontent, which handles auto-saving. Instead of blasting the full editor content upon any change to that parent compontent, the editors just alert of a change, without the content. The parent compontent then requests the editor content from the editor component when it needs that data for an autosave. For #3981
1 parent 3149575 commit 6545afa

File tree

5 files changed

+64
-31
lines changed

5 files changed

+64
-31
lines changed

resources/js/components/markdown-editor.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,4 +137,13 @@ export class MarkdownEditor extends Component {
137137
return drawioAttrEl.getAttribute('drawio-url') || '';
138138
}
139139

140+
/**
141+
* Get the content of this editor.
142+
* Used by the parent page editor component.
143+
* @return {{html: String, markdown: String}}
144+
*/
145+
getContent() {
146+
return this.editor.actions.getContent();
147+
}
148+
140149
}

resources/js/components/page-editor.js

Lines changed: 28 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,11 @@ export class PageEditor extends Component {
3333
this.setChangelogText = this.$opts.setChangelogText;
3434

3535
// State data
36-
this.editorHTML = '';
37-
this.editorMarkdown = '';
3836
this.autoSave = {
3937
interval: null,
4038
frequency: 30000,
4139
last: 0,
40+
pendingChange: false,
4241
};
4342
this.shownWarningsCache = new Set();
4443

@@ -59,12 +58,12 @@ export class PageEditor extends Component {
5958
window.$events.listen('editor-save-page', this.savePage.bind(this));
6059

6160
// Listen to content changes from the editor
62-
window.$events.listen('editor-html-change', html => {
63-
this.editorHTML = html;
64-
});
65-
window.$events.listen('editor-markdown-change', markdown => {
66-
this.editorMarkdown = markdown;
67-
});
61+
const onContentChange = () => this.autoSave.pendingChange = true;
62+
window.$events.listen('editor-html-change', onContentChange);
63+
window.$events.listen('editor-markdown-change', onContentChange);
64+
65+
// Listen to changes on the title input
66+
this.titleElem.addEventListener('input', onContentChange);
6867

6968
// Changelog controls
7069
const updateChangelogDebounced = debounce(this.updateChangelogDisplay.bind(this), 300, false);
@@ -89,33 +88,28 @@ export class PageEditor extends Component {
8988
}
9089

9190
startAutoSave() {
92-
let lastContent = this.titleElem.value.trim() + '::' + this.editorHTML;
93-
this.autoSaveInterval = window.setInterval(() => {
94-
// Stop if manually saved recently to prevent bombarding the server
95-
let savedRecently = (Date.now() - this.autoSave.last < (this.autoSave.frequency)/2);
96-
if (savedRecently) return;
97-
const newContent = this.titleElem.value.trim() + '::' + this.editorHTML;
98-
if (newContent !== lastContent) {
99-
lastContent = newContent;
100-
this.saveDraft();
101-
}
91+
this.autoSave.interval = window.setInterval(this.runAutoSave.bind(this), this.autoSave.frequency);
92+
}
10293

103-
}, this.autoSave.frequency);
94+
runAutoSave() {
95+
// Stop if manually saved recently to prevent bombarding the server
96+
const savedRecently = (Date.now() - this.autoSave.last < (this.autoSave.frequency)/2);
97+
if (savedRecently || !this.autoSave.pendingChange) {
98+
return;
99+
}
100+
101+
this.saveDraft()
104102
}
105103

106104
savePage() {
107105
this.container.closest('form').submit();
108106
}
109107

110108
async saveDraft() {
111-
const data = {
112-
name: this.titleElem.value.trim(),
113-
html: this.editorHTML,
114-
};
109+
const data = {name: this.titleElem.value.trim()};
115110

116-
if (this.editorType === 'markdown') {
117-
data.markdown = this.editorMarkdown;
118-
}
111+
const editorContent = this.getEditorComponent().getContent();
112+
Object.assign(data, editorContent);
119113

120114
let didSave = false;
121115
try {
@@ -132,6 +126,7 @@ export class PageEditor extends Component {
132126
}
133127

134128
didSave = true;
129+
this.autoSave.pendingChange = false;
135130
} catch (err) {
136131
// Save the editor content in LocalStorage as a last resort, just in case.
137132
try {
@@ -207,4 +202,11 @@ export class PageEditor extends Component {
207202
}
208203
}
209204

205+
/**
206+
* @return MarkdownEditor|WysiwygEditor
207+
*/
208+
getEditorComponent() {
209+
return window.$components.first('markdown-editor') || window.$components.first('wysiwyg-editor');
210+
}
211+
210212
}

resources/js/components/wysiwyg-editor.js

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@ export class WysiwygEditor extends Component {
2525
});
2626

2727
window.$events.emitPublic(this.elem, 'editor-tinymce::pre-init', {config: this.tinyMceConfig});
28-
window.tinymce.init(this.tinyMceConfig);
28+
window.tinymce.init(this.tinyMceConfig).then(editors => {
29+
this.editor = editors[0];
30+
});
2931
}
3032

3133
getDrawIoUrl() {
@@ -36,4 +38,15 @@ export class WysiwygEditor extends Component {
3638
return '';
3739
}
3840

41+
/**
42+
* Get the content of this editor.
43+
* Used by the parent page editor component.
44+
* @return {{html: String}}
45+
*/
46+
getContent() {
47+
return {
48+
html: this.editor.getContent()
49+
};
50+
}
51+
3952
}

resources/js/markdown/actions.js

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,28 @@ export class Actions {
66
*/
77
constructor(editor) {
88
this.editor = editor;
9+
this.lastContent = {
10+
html: '',
11+
markdown: '',
12+
};
913
}
1014

1115
updateAndRender() {
1216
const content = this.editor.cm.getValue();
1317
this.editor.config.inputEl.value = content;
1418

1519
const html = this.editor.markdown.render(content);
16-
window.$events.emit('editor-html-change', html);
17-
window.$events.emit('editor-markdown-change', content);
20+
window.$events.emit('editor-html-change', '');
21+
window.$events.emit('editor-markdown-change', '');
22+
this.lastContent.html = html;
23+
this.lastContent.markdown = content;
1824
this.editor.display.patchWithHtml(html);
1925
}
2026

27+
getContent() {
28+
return this.lastContent;
29+
}
30+
2131
insertImage() {
2232
const cursorPos = this.editor.cm.getCursor('from');
2333
/** @type {ImageManager} **/

resources/js/wysiwyg/config.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -185,11 +185,10 @@ function getSetupCallback(options) {
185185
});
186186

187187
function editorChange() {
188-
const content = editor.getContent();
189188
if (options.darkMode) {
190189
editor.contentDocument.documentElement.classList.add('dark-mode');
191190
}
192-
window.$events.emit('editor-html-change', content);
191+
window.$events.emit('editor-html-change', '');
193192
}
194193

195194
// Custom handler hook

0 commit comments

Comments
 (0)