]> BookStack Code Mirror - bookstack/blob - resources/assets/js/vues/page-editor.js
Merge pull request #529 from cipi1965/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 draft events from editor
38     window.$events.listen('editor-save-draft', this.saveDraft);
39
40     // Listen to content changes from the editor
41     window.$events.listen('editor-html-change', html => {
42         this.editorHTML = html;
43     });
44     window.$events.listen('editor-markdown-change', markdown => {
45         this.editorMarkdown = markdown;
46     });
47 }
48
49 let data = {
50     draftsEnabled: false,
51     editorType: 'wysiwyg',
52     pagedId: 0,
53     isNewDraft: false,
54     isUpdateDraft: false,
55
56     draftText: '',
57     draftUpdated : false,
58     changeSummary: '',
59
60     editorHTML: '',
61     editorMarkdown: '',
62 };
63
64 let methods = {
65
66     startAutoSave() {
67         currentContent.title = document.getElementById('name').value.trim();
68         currentContent.html = this.editorHTML;
69
70         autoSave = window.setInterval(() => {
71             // Return if manually saved recently to prevent bombarding the server
72             if (Date.now() - lastSave < (1000 * autoSaveFrequency)/2) return;
73             let newTitle = document.getElementById('name').value.trim();
74             let newHtml = this.editorHTML;
75
76             if (newTitle !== currentContent.title || newHtml !== currentContent.html) {
77                 currentContent.html = newHtml;
78                 currentContent.title = newTitle;
79                 this.saveDraft();
80             }
81
82         }, 1000 * autoSaveFrequency);
83     },
84
85     saveDraft() {
86         if (!this.draftsEnabled) return;
87
88         let data = {
89             name: document.getElementById('name').value.trim(),
90             html: this.editorHTML
91         };
92
93         if (this.editorType === 'markdown') data.markdown = this.editorMarkdown;
94
95         let url = window.baseUrl(`/ajax/page/${this.pageId}/save-draft`);
96         window.$http.put(url, data).then(response => {
97             draftErroring = false;
98             let updateTime = moment.utc(moment.unix(response.data.timestamp)).toDate();
99             if (!this.isNewPageDraft) this.isUpdateDraft = true;
100             this.draftNotifyChange(response.data.message + moment(updateTime).format('HH:mm'));
101             lastSave = Date.now();
102         }, errorRes => {
103             if (draftErroring) return;
104             window.$events('error', trans('errors.page_draft_autosave_fail'));
105             draftErroring = true;
106         });
107     },
108
109
110     draftNotifyChange(text) {
111         this.draftText = text;
112         this.draftUpdated = true;
113         window.setTimeout(() => {
114             this.draftUpdated = false;
115         }, 2000);
116     },
117
118     discardDraft() {
119         let url = window.baseUrl(`/ajax/page/${this.pageId}`);
120         window.$http.get(url).then(response => {
121             if (autoSave) window.clearInterval(autoSave);
122
123             this.draftText = trans('entities.pages_editing_page');
124             this.isUpdateDraft = false;
125             window.$events.emit('editor-html-update', response.data.html);
126             window.$events.emit('editor-markdown-update', response.data.markdown || response.data.html);
127
128             document.getElementById('name').value = response.data.name;
129             window.setTimeout(() => {
130                 this.startAutoSave();
131             }, 1000);
132             window.$events.emit('success', trans('entities.pages_draft_discarded'));
133         });
134     },
135
136 };
137
138 let computed = {
139     changeSummaryShort() {
140         let len = this.changeSummary.length;
141         if (len === 0) return trans('entities.pages_edit_set_changelog');
142         if (len <= 16) return this.changeSummary;
143         return this.changeSummary.slice(0, 16) + '...';
144     }
145 };
146
147 module.exports = {
148     mounted, data, methods, computed,
149 };