You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

223 lines
6.3 KiB

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