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
return drawioAttrEl.getAttribute('drawio-url') || '';
}
return drawioAttrEl.getAttribute('drawio-url') || '';
}
+ /**
+ * Get the content of this editor.
+ * Used by the parent page editor component.
+ * @return {{html: String, markdown: String}}
+ */
+ getContent() {
+ return this.editor.actions.getContent();
+ }
+
this.setChangelogText = this.$opts.setChangelogText;
// State data
this.setChangelogText = this.$opts.setChangelogText;
// State data
- this.editorHTML = '';
- this.editorMarkdown = '';
this.autoSave = {
interval: null,
frequency: 30000,
last: 0,
this.autoSave = {
interval: null,
frequency: 30000,
last: 0,
};
this.shownWarningsCache = new Set();
};
this.shownWarningsCache = new Set();
window.$events.listen('editor-save-page', this.savePage.bind(this));
// Listen to content changes from the editor
window.$events.listen('editor-save-page', this.savePage.bind(this));
// Listen to content changes from the editor
- window.$events.listen('editor-html-change', html => {
- this.editorHTML = html;
- });
- window.$events.listen('editor-markdown-change', markdown => {
- this.editorMarkdown = markdown;
- });
+ const onContentChange = () => this.autoSave.pendingChange = true;
+ window.$events.listen('editor-html-change', onContentChange);
+ window.$events.listen('editor-markdown-change', onContentChange);
+
+ // Listen to changes on the title input
+ this.titleElem.addEventListener('input', onContentChange);
// Changelog controls
const updateChangelogDebounced = debounce(this.updateChangelogDisplay.bind(this), 300, false);
// Changelog controls
const updateChangelogDebounced = debounce(this.updateChangelogDisplay.bind(this), 300, false);
- let lastContent = this.titleElem.value.trim() + '::' + this.editorHTML;
- this.autoSaveInterval = window.setInterval(() => {
- // Stop if manually saved recently to prevent bombarding the server
- let savedRecently = (Date.now() - this.autoSave.last < (this.autoSave.frequency)/2);
- if (savedRecently) return;
- const newContent = this.titleElem.value.trim() + '::' + this.editorHTML;
- if (newContent !== lastContent) {
- lastContent = newContent;
- this.saveDraft();
- }
+ this.autoSave.interval = window.setInterval(this.runAutoSave.bind(this), this.autoSave.frequency);
+ }
- }, this.autoSave.frequency);
+ runAutoSave() {
+ // Stop if manually saved recently to prevent bombarding the server
+ const savedRecently = (Date.now() - this.autoSave.last < (this.autoSave.frequency)/2);
+ if (savedRecently || !this.autoSave.pendingChange) {
+ return;
+ }
+
+ this.saveDraft()
- const data = {
- name: this.titleElem.value.trim(),
- html: this.editorHTML,
- };
+ const data = {name: this.titleElem.value.trim()};
- if (this.editorType === 'markdown') {
- data.markdown = this.editorMarkdown;
- }
+ const editorContent = this.getEditorComponent().getContent();
+ Object.assign(data, editorContent);
let didSave = false;
try {
let didSave = false;
try {
+ this.autoSave.pendingChange = false;
} catch (err) {
// Save the editor content in LocalStorage as a last resort, just in case.
try {
} catch (err) {
// Save the editor content in LocalStorage as a last resort, just in case.
try {
+ /**
+ * @return MarkdownEditor|WysiwygEditor
+ */
+ getEditorComponent() {
+ return window.$components.first('markdown-editor') || window.$components.first('wysiwyg-editor');
+ }
+
});
window.$events.emitPublic(this.elem, 'editor-tinymce::pre-init', {config: this.tinyMceConfig});
});
window.$events.emitPublic(this.elem, 'editor-tinymce::pre-init', {config: this.tinyMceConfig});
- window.tinymce.init(this.tinyMceConfig);
+ window.tinymce.init(this.tinyMceConfig).then(editors => {
+ this.editor = editors[0];
+ });
+ /**
+ * Get the content of this editor.
+ * Used by the parent page editor component.
+ * @return {{html: String}}
+ */
+ getContent() {
+ return {
+ html: this.editor.getContent()
+ };
+ }
+
}
\ No newline at end of file
}
\ No newline at end of file
*/
constructor(editor) {
this.editor = editor;
*/
constructor(editor) {
this.editor = editor;
+ this.lastContent = {
+ html: '',
+ markdown: '',
+ };
this.editor.config.inputEl.value = content;
const html = this.editor.markdown.render(content);
this.editor.config.inputEl.value = content;
const html = this.editor.markdown.render(content);
- window.$events.emit('editor-html-change', html);
- window.$events.emit('editor-markdown-change', content);
+ window.$events.emit('editor-html-change', '');
+ window.$events.emit('editor-markdown-change', '');
+ this.lastContent.html = html;
+ this.lastContent.markdown = content;
this.editor.display.patchWithHtml(html);
}
this.editor.display.patchWithHtml(html);
}
+ getContent() {
+ return this.lastContent;
+ }
+
insertImage() {
const cursorPos = this.editor.cm.getCursor('from');
/** @type {ImageManager} **/
insertImage() {
const cursorPos = this.editor.cm.getCursor('from');
/** @type {ImageManager} **/
});
function editorChange() {
});
function editorChange() {
- const content = editor.getContent();
if (options.darkMode) {
editor.contentDocument.documentElement.classList.add('dark-mode');
}
if (options.darkMode) {
editor.contentDocument.documentElement.classList.add('dark-mode');
}
- window.$events.emit('editor-html-change', content);
+ window.$events.emit('editor-html-change', '');