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