]> BookStack Code Mirror - bookstack/blob - resources/js/vues/page-editor.js
Merge branch 'master' of git://github.com/Binternet/BookStack into Binternet-master
[bookstack] / resources / js / vues / page-editor.js
1 import * as Dates from "../services/dates";
2
3 let autoSaveFrequency = 30;
4
5 let autoSave = false;
6 let draftErroring = false;
7
8 let currentContent = {
9     title: false,
10     html: false
11 };
12
13 let lastSave = 0;
14
15 function mounted() {
16     let elem = this.$el;
17     this.draftsEnabled = elem.getAttribute('drafts-enabled') === 'true';
18     this.editorType = elem.getAttribute('editor-type');
19     this.pageId= Number(elem.getAttribute('page-id'));
20     this.isNewDraft = Number(elem.getAttribute('page-new-draft')) === 1;
21     this.isUpdateDraft = Number(elem.getAttribute('page-update-draft')) === 1;
22
23     if (this.pageId !== 0 && this.draftsEnabled) {
24         window.setTimeout(() => {
25             this.startAutoSave();
26         }, 1000);
27     }
28
29     if (this.isUpdateDraft || this.isNewDraft) {
30         this.draftText = trans('entities.pages_editing_draft');
31     } else {
32         this.draftText = trans('entities.pages_editing_page');
33     }
34
35     // Listen to save events from editor
36     window.$events.listen('editor-save-draft', this.saveDraft);
37     window.$events.listen('editor-save-page', this.savePage);
38
39     // Listen to content changes from the editor
40     window.$events.listen('editor-html-change', html => {
41         this.editorHTML = html;
42     });
43     window.$events.listen('editor-markdown-change', markdown => {
44         this.editorMarkdown = markdown;
45     });
46 }
47
48 let data = {
49     draftsEnabled: false,
50     editorType: 'wysiwyg',
51     pagedId: 0,
52     isNewDraft: false,
53     isUpdateDraft: false,
54
55     draftText: '',
56     draftUpdated : false,
57     changeSummary: '',
58
59     editorHTML: '',
60     editorMarkdown: '',
61 };
62
63 let methods = {
64
65     startAutoSave() {
66         currentContent.title = document.getElementById('name').value.trim();
67         currentContent.html = this.editorHTML;
68
69         autoSave = window.setInterval(() => {
70             // Return if manually saved recently to prevent bombarding the server
71             if (Date.now() - lastSave < (1000 * autoSaveFrequency)/2) return;
72             const newTitle = document.getElementById('name').value.trim();
73             const newHtml = this.editorHTML;
74
75             if (newTitle !== currentContent.title || newHtml !== currentContent.html) {
76                 currentContent.html = newHtml;
77                 currentContent.title = newTitle;
78                 this.saveDraft();
79             }
80
81         }, 1000 * autoSaveFrequency);
82     },
83
84     saveDraft() {
85         if (!this.draftsEnabled) return;
86
87         const data = {
88             name: document.getElementById('name').value.trim(),
89             html: this.editorHTML
90         };
91
92         if (this.editorType === 'markdown') data.markdown = this.editorMarkdown;
93
94         const url = window.baseUrl(`/ajax/page/${this.pageId}/save-draft`);
95         window.$http.put(url, data).then(response => {
96             draftErroring = false;
97             if (!this.isNewDraft) this.isUpdateDraft = true;
98             this.draftNotifyChange(`${response.data.message} ${Dates.utcTimeStampToLocalTime(response.data.timestamp)}`);
99             lastSave = Date.now();
100         }, errorRes => {
101             if (draftErroring) return;
102             window.$events.emit('error', trans('errors.page_draft_autosave_fail'));
103             draftErroring = true;
104         });
105     },
106
107     savePage() {
108         this.$el.closest('form').submit();
109     },
110
111     draftNotifyChange(text) {
112         this.draftText = text;
113         this.draftUpdated = true;
114         window.setTimeout(() => {
115             this.draftUpdated = false;
116         }, 2000);
117     },
118
119     discardDraft() {
120         let url = window.baseUrl(`/ajax/page/${this.pageId}`);
121         window.$http.get(url).then(response => {
122             if (autoSave) window.clearInterval(autoSave);
123
124             this.draftText = trans('entities.pages_editing_page');
125             this.isUpdateDraft = false;
126             window.$events.emit('editor-html-update', response.data.html);
127             window.$events.emit('editor-markdown-update', response.data.markdown || response.data.html);
128
129             document.getElementById('name').value = response.data.name;
130             window.setTimeout(() => {
131                 this.startAutoSave();
132             }, 1000);
133             window.$events.emit('success', trans('entities.pages_draft_discarded'));
134         });
135     },
136
137 };
138
139 let computed = {
140     changeSummaryShort() {
141         let len = this.changeSummary.length;
142         if (len === 0) return trans('entities.pages_edit_set_changelog');
143         if (len <= 16) return this.changeSummary;
144         return this.changeSummary.slice(0, 16) + '...';
145     }
146 };
147
148 export default {
149     mounted, data, methods, computed,
150 };