1 import * as Dates from "../services/dates";
2 import {onSelect} from "../services/dom";
11 this.draftsEnabled = this.$opts.draftsEnabled === 'true';
12 this.editorType = this.$opts.editorType;
13 this.pageId = Number(this.$opts.pageId);
14 this.isNewDraft = this.$opts.pageNewDraft === 'true';
15 this.hasDefaultTitle = this.$opts.isDefaultTitle || false;
18 this.container = this.$el;
19 this.titleElem = this.$refs.titleContainer.querySelector('input');
20 this.saveDraftButton = this.$refs.saveDraft;
21 this.discardDraftButton = this.$refs.discardDraft;
22 this.discardDraftWrap = this.$refs.discardDraftWrap;
23 this.draftDisplay = this.$refs.draftDisplay;
24 this.draftDisplayIcon = this.$refs.draftDisplayIcon;
25 this.changelogInput = this.$refs.changelogInput;
26 this.changelogDisplay = this.$refs.changelogDisplay;
29 this.draftText = this.$opts.draftText;
30 this.autosaveFailText = this.$opts.autosaveFailText;
31 this.editingPageText = this.$opts.editingPageText;
32 this.draftDiscardedText = this.$opts.draftDiscardedText;
33 this.setChangelogText = this.$opts.setChangelogText;
37 this.editorMarkdown = '';
43 this.draftHasError = false;
45 if (this.pageId !== 0 && this.draftsEnabled) {
46 window.setTimeout(() => {
50 this.draftDisplay.innerHTML = this.draftText;
52 this.setupListeners();
53 this.setInitialFocus();
57 // Listen to save events from editor
58 window.$events.listen('editor-save-draft', this.saveDraft.bind(this));
59 window.$events.listen('editor-save-page', this.savePage.bind(this));
61 // Listen to content changes from the editor
62 window.$events.listen('editor-html-change', html => {
63 this.editorHTML = html;
65 window.$events.listen('editor-markdown-change', markdown => {
66 this.editorMarkdown = markdown;
70 this.changelogInput.addEventListener('change', this.updateChangelogDisplay.bind(this));
73 onSelect(this.saveDraftButton, this.saveDraft.bind(this));
74 onSelect(this.discardDraftButton, this.discardDraft.bind(this));
78 if (this.hasDefaultTitle) {
79 return this.titleElem.select();
82 window.setTimeout(() => {
83 window.$events.emit('editor::focus', '');
88 let lastContent = this.titleElem.value.trim() + '::' + this.editorHTML;
89 this.autoSaveInterval = window.setInterval(() => {
90 // Stop if manually saved recently to prevent bombarding the server
91 let savedRecently = (Date.now() - this.autoSave.last < (this.autoSave.frequency)/2);
92 if (savedRecently) return;
93 const newContent = this.titleElem.value.trim() + '::' + this.editorHTML;
94 if (newContent !== lastContent) {
95 lastContent = newContent;
99 }, this.autoSave.frequency);
103 this.container.closest('form').submit();
108 name: this.titleElem.value.trim(),
109 html: this.editorHTML,
112 if (this.editorType === 'markdown') {
113 data.markdown = this.editorMarkdown;
117 const resp = await window.$http.put(`/ajax/page/${this.pageId}/save-draft`, data);
118 this.draftHasError = false;
119 if (!this.isNewDraft) {
120 this.toggleDiscardDraftVisibility(true);
122 this.draftNotifyChange(`${resp.data.message} ${Dates.utcTimeStampToLocalTime(resp.data.timestamp)}`);
123 this.autoSave.last = Date.now();
125 if (!this.draftHasError) {
126 this.draftHasError = true;
127 window.$events.emit('error', this.autosaveFailText);
133 draftNotifyChange(text) {
134 this.draftDisplay.innerText = text;
135 this.draftDisplayIcon.classList.add('visible');
136 window.setTimeout(() => {
137 this.draftDisplayIcon.classList.remove('visible');
141 async discardDraft() {
144 response = await window.$http.get(`/ajax/page/${this.pageId}`);
146 return console.error(e);
149 if (this.autoSave.interval) {
150 window.clearInterval(this.autoSave.interval);
153 this.draftDisplay.innerText = this.editingPageText;
154 this.toggleDiscardDraftVisibility(false);
155 window.$events.emit('editor-html-update', response.data.html || '');
156 window.$events.emit('editor-markdown-update', response.data.markdown || response.data.html);
158 this.titleElem.value = response.data.name;
159 window.setTimeout(() => {
160 this.startAutoSave();
162 window.$events.emit('success', this.draftDiscardedText);
166 updateChangelogDisplay() {
167 let summary = this.changelogInput.value.trim();
168 if (summary.length === 0) {
169 summary = this.setChangelogText;
170 } else if (summary.length > 16) {
171 summary = summary.slice(0, 16) + '...';
173 this.changelogDisplay.innerText = summary;
176 toggleDiscardDraftVisibility(show) {
177 this.discardDraftWrap.classList.toggle('hidden', !show);
182 export default PageEditor;