-import * as Dates from "../services/dates";
-import {onSelect} from "../services/dom";
-import {debounce} from "../services/util";
-
-/**
- * Page Editor
- * @extends {Component}
- */
-class PageEditor {
+import * as Dates from '../services/dates';
+import {onSelect} from '../services/dom';
+import {debounce} from '../services/util';
+import {Component} from './component';
+
+export class PageEditor extends Component {
+
setup() {
// Options
this.draftsEnabled = this.$opts.draftsEnabled === 'true';
this.draftDisplayIcon = this.$refs.draftDisplayIcon;
this.changelogInput = this.$refs.changelogInput;
this.changelogDisplay = this.$refs.changelogDisplay;
- this.changeEditorButtons = this.$manyRefs.changeEditor;
+ this.changeEditorButtons = this.$manyRefs.changeEditor || [];
this.switchDialogContainer = this.$refs.switchDialog;
// Translations
this.setChangelogText = this.$opts.setChangelogText;
// State data
- this.editorHTML = '';
- this.editorMarkdown = '';
this.autoSave = {
interval: null,
frequency: 30000,
last: 0,
+ pendingChange: false,
};
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-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);
setInitialFocus() {
if (this.hasDefaultTitle) {
- return this.titleElem.select();
+ this.titleElem.select();
+ return;
}
window.setTimeout(() => {
}
startAutoSave() {
- 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();
}
savePage() {
}
async 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 {
}
didSave = true;
+ this.autoSave.pendingChange = false;
} catch (err) {
// Save the editor content in LocalStorage as a last resort, just in case.
try {
const saveKey = `draft-save-fail-${(new Date()).toISOString()}`;
window.localStorage.setItem(saveKey, JSON.stringify(data));
- } catch (err) {}
+ } catch (lsErr) {
+ console.error(lsErr);
+ }
window.$events.emit('error', this.autosaveFailText);
}
try {
response = await window.$http.get(`/ajax/page/${this.pageId}`);
} catch (e) {
- return console.error(e);
+ console.error(e);
+ return;
}
if (this.autoSave.interval) {
this.startAutoSave();
}, 1000);
window.$events.emit('success', this.draftDiscardedText);
-
}
updateChangelogDisplay() {
if (summary.length === 0) {
summary = this.setChangelogText;
} else if (summary.length > 16) {
- summary = summary.slice(0, 16) + '...';
+ summary = `${summary.slice(0, 16)}...`;
}
this.changelogDisplay.innerText = summary;
}
event.preventDefault();
const link = event.target.closest('a').href;
- const dialog = this.switchDialogContainer.components['confirm-dialog'];
+ /** @var {ConfirmDialog} * */
+ const dialog = window.$components.firstOnElement(this.switchDialogContainer, 'confirm-dialog');
const [saved, confirmed] = await Promise.all([this.saveDraft(), dialog.show()]);
if (saved && confirmed) {
}
}
-}
+ /**
+ * @return MarkdownEditor|WysiwygEditor
+ */
+ getEditorComponent() {
+ return window.$components.first('markdown-editor') || window.$components.first('wysiwyg-editor');
+ }
-export default PageEditor;
\ No newline at end of file
+}