editor.component.js 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. /* global $, siteRoot */
  2. let mde
  3. export default {
  4. name: 'editor',
  5. props: ['currentPath'],
  6. data() {
  7. return {}
  8. },
  9. computed: {
  10. insertContent() {
  11. return this.$store.state.editor.insertContent
  12. }
  13. },
  14. methods: {
  15. insert(content) {
  16. if (mde.codemirror.doc.somethingSelected()) {
  17. mde.codemirror.execCommand('singleSelection')
  18. }
  19. mde.codemirror.doc.replaceSelection(this.insertContent)
  20. },
  21. save() {
  22. let self = this
  23. this.$http.put(window.location.href, {
  24. markdown: mde.value()
  25. }).then(resp => {
  26. return resp.json()
  27. }).then(resp => {
  28. if (resp.ok) {
  29. window.location.assign(siteRoot + '/' + self.currentPath)
  30. } else {
  31. self.$store.dispatch('alert', {
  32. style: 'red',
  33. icon: 'ui-2_square-remove-09',
  34. msg: resp.msg
  35. })
  36. }
  37. }).catch(err => {
  38. self.$store.dispatch('alert', {
  39. style: 'red',
  40. icon: 'ui-2_square-remove-09',
  41. msg: 'Error: ' + err.body.msg
  42. })
  43. })
  44. }
  45. },
  46. mounted() {
  47. let self = this
  48. FuseBox.import('/js/simplemde/simplemde.min.js', (SimpleMDE) => {
  49. mde = new SimpleMDE({
  50. autofocus: true,
  51. autoDownloadFontAwesome: false,
  52. element: this.$refs.editorTextArea,
  53. placeholder: 'Enter Markdown formatted content here...',
  54. spellChecker: false,
  55. status: false,
  56. toolbar: [
  57. {
  58. name: 'bold',
  59. action: SimpleMDE.toggleBold,
  60. className: 'icon-bold',
  61. title: 'Bold'
  62. },
  63. {
  64. name: 'italic',
  65. action: SimpleMDE.toggleItalic,
  66. className: 'icon-italic',
  67. title: 'Italic'
  68. },
  69. {
  70. name: 'strikethrough',
  71. action: SimpleMDE.toggleStrikethrough,
  72. className: 'icon-strikethrough',
  73. title: 'Strikethrough'
  74. },
  75. '|',
  76. {
  77. name: 'heading-1',
  78. action: SimpleMDE.toggleHeading1,
  79. className: 'icon-header fa-header-x fa-header-1',
  80. title: 'Header (Level 1)'
  81. },
  82. {
  83. name: 'heading-2',
  84. action: SimpleMDE.toggleHeading2,
  85. className: 'icon-header fa-header-x fa-header-2',
  86. title: 'Header (Level 2)'
  87. },
  88. {
  89. name: 'heading-3',
  90. action: SimpleMDE.toggleHeading3,
  91. className: 'icon-header fa-header-x fa-header-3',
  92. title: 'Header (Level 3)'
  93. },
  94. {
  95. name: 'quote',
  96. action: SimpleMDE.toggleBlockquote,
  97. className: 'nc-icon-outline text_quote',
  98. title: 'Quote'
  99. },
  100. '|',
  101. {
  102. name: 'unordered-list',
  103. action: SimpleMDE.toggleUnorderedList,
  104. className: 'nc-icon-outline text_list-bullet',
  105. title: 'Bullet List'
  106. },
  107. {
  108. name: 'ordered-list',
  109. action: SimpleMDE.toggleOrderedList,
  110. className: 'nc-icon-outline text_list-numbers',
  111. title: 'Numbered List'
  112. },
  113. '|',
  114. {
  115. name: 'link',
  116. action: (editor) => {
  117. window.alert('Coming soon!')
  118. // todo
  119. },
  120. className: 'nc-icon-outline ui-2_link-68',
  121. title: 'Insert Link'
  122. },
  123. {
  124. name: 'image',
  125. action: (editor) => {
  126. self.$store.dispatch('editorFile/open', { mode: 'image' })
  127. },
  128. className: 'nc-icon-outline design_image',
  129. title: 'Insert Image'
  130. },
  131. {
  132. name: 'file',
  133. action: (editor) => {
  134. self.$store.dispatch('editorFile/open', { mode: 'file' })
  135. },
  136. className: 'nc-icon-outline files_zip-54',
  137. title: 'Insert File'
  138. },
  139. {
  140. name: 'video',
  141. action: (editor) => {
  142. self.$store.dispatch('editorVideo/open')
  143. },
  144. className: 'nc-icon-outline media-1_video-64',
  145. title: 'Insert Video Player'
  146. },
  147. '|',
  148. {
  149. name: 'inline-code',
  150. action: (editor) => {
  151. if (!editor.codemirror.doc.somethingSelected()) {
  152. return self.$store.dispatch('alert', {
  153. style: 'orange',
  154. icon: 'design_drag',
  155. msg: 'Invalid selection. Select at least 1 character.'
  156. })
  157. }
  158. let curSel = editor.codemirror.doc.getSelections()
  159. curSel = self._.map(curSel, (s) => {
  160. return '`' + s + '`'
  161. })
  162. editor.codemirror.doc.replaceSelections(curSel)
  163. },
  164. className: 'nc-icon-outline arrows-4_enlarge-46',
  165. title: 'Inline Code'
  166. },
  167. {
  168. name: 'code-block',
  169. action: (editor) => {
  170. self.$store.dispatch('editorCodeblock/open', {
  171. initialContent: (mde.codemirror.doc.somethingSelected()) ? mde.codemirror.doc.getSelection() : ''
  172. })
  173. },
  174. className: 'nc-icon-outline design_code',
  175. title: 'Code Block'
  176. },
  177. '|',
  178. {
  179. name: 'table',
  180. action: (editor) => {
  181. window.alert('Coming soon!')
  182. // todo
  183. },
  184. className: 'nc-icon-outline ui-2_grid-square',
  185. title: 'Insert Table'
  186. },
  187. {
  188. name: 'horizontal-rule',
  189. action: SimpleMDE.drawHorizontalRule,
  190. className: 'nc-icon-outline design_distribute-vertical',
  191. title: 'Horizontal Rule'
  192. }
  193. ],
  194. shortcuts: {
  195. 'toggleBlockquote': null,
  196. 'toggleFullScreen': null
  197. }
  198. })
  199. // Save
  200. $(window).bind('keydown', (ev) => {
  201. if (ev.ctrlKey || ev.metaKey) {
  202. switch (String.fromCharCode(ev.which).toLowerCase()) {
  203. case 's':
  204. ev.preventDefault()
  205. self.save()
  206. break
  207. }
  208. }
  209. })
  210. // Listeners
  211. this.$root.$on('editor/save', this.save)
  212. this.$root.$on('editor/insert', this.insert)
  213. this.$store.dispatch('pageLoader/complete')
  214. })
  215. }
  216. }