2
0

editor.js 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. // ====================================
  2. // Markdown Editor
  3. // ====================================
  4. if($('#mk-editor').length === 1) {
  5. let mdeModalOpenState = false;
  6. let mdeCurrentEditor = null;
  7. Vue.filter('filesize', (v) => {
  8. return _.toUpper(filesize(v));
  9. });
  10. //=include editor-image.js
  11. //=include editor-file.js
  12. //=include editor-video.js
  13. //=include editor-codeblock.js
  14. var mde = new SimpleMDE({
  15. autofocus: true,
  16. autoDownloadFontAwesome: false,
  17. element: $("#mk-editor").get(0),
  18. placeholder: 'Enter Markdown formatted content here...',
  19. spellChecker: false,
  20. status: false,
  21. toolbar: [{
  22. name: "bold",
  23. action: SimpleMDE.toggleBold,
  24. className: "icon-bold",
  25. title: "Bold",
  26. },
  27. {
  28. name: "italic",
  29. action: SimpleMDE.toggleItalic,
  30. className: "icon-italic",
  31. title: "Italic",
  32. },
  33. {
  34. name: "strikethrough",
  35. action: SimpleMDE.toggleStrikethrough,
  36. className: "icon-strikethrough",
  37. title: "Strikethrough",
  38. },
  39. '|',
  40. {
  41. name: "heading-1",
  42. action: SimpleMDE.toggleHeading1,
  43. className: "icon-header fa-header-x fa-header-1",
  44. title: "Big Heading",
  45. },
  46. {
  47. name: "heading-2",
  48. action: SimpleMDE.toggleHeading2,
  49. className: "icon-header fa-header-x fa-header-2",
  50. title: "Medium Heading",
  51. },
  52. {
  53. name: "heading-3",
  54. action: SimpleMDE.toggleHeading3,
  55. className: "icon-header fa-header-x fa-header-3",
  56. title: "Small Heading",
  57. },
  58. {
  59. name: "quote",
  60. action: SimpleMDE.toggleBlockquote,
  61. className: "icon-quote-left",
  62. title: "Quote",
  63. },
  64. '|',
  65. {
  66. name: "unordered-list",
  67. action: SimpleMDE.toggleUnorderedList,
  68. className: "icon-th-list",
  69. title: "Bullet List",
  70. },
  71. {
  72. name: "ordered-list",
  73. action: SimpleMDE.toggleOrderedList,
  74. className: "icon-list-ol",
  75. title: "Numbered List",
  76. },
  77. '|',
  78. {
  79. name: "link",
  80. action: (editor) => {
  81. /*if(!mdeModalOpenState) {
  82. mdeModalOpenState = true;
  83. $('#modal-editor-link').slideToggle();
  84. }*/
  85. },
  86. className: "icon-link2",
  87. title: "Insert Link",
  88. },
  89. {
  90. name: "image",
  91. action: (editor) => {
  92. if(!mdeModalOpenState) {
  93. vueImage.open();
  94. }
  95. },
  96. className: "icon-image",
  97. title: "Insert Image",
  98. },
  99. {
  100. name: "file",
  101. action: (editor) => {
  102. if(!mdeModalOpenState) {
  103. vueFile.open();
  104. }
  105. },
  106. className: "icon-paper",
  107. title: "Insert File",
  108. },
  109. {
  110. name: "video",
  111. action: (editor) => {
  112. if(!mdeModalOpenState) {
  113. vueVideo.open();
  114. }
  115. },
  116. className: "icon-video-camera2",
  117. title: "Insert Video Player",
  118. },
  119. '|',
  120. {
  121. name: "inline-code",
  122. action: (editor) => {
  123. if(!editor.codemirror.doc.somethingSelected()) {
  124. return alerts.pushError('Invalid selection','You must select at least 1 character first.');
  125. }
  126. let curSel = editor.codemirror.doc.getSelections();
  127. curSel = _.map(curSel, (s) => {
  128. return '`' + s + '`';
  129. });
  130. editor.codemirror.doc.replaceSelections(curSel);
  131. },
  132. className: "icon-terminal",
  133. title: "Inline Code",
  134. },
  135. {
  136. name: "code-block",
  137. action: (editor) => {
  138. if(!mdeModalOpenState) {
  139. mdeModalOpenState = true;
  140. if(mde.codemirror.doc.somethingSelected()) {
  141. vueCodeBlock.initContent = mde.codemirror.doc.getSelection();
  142. }
  143. vueCodeBlock.open();
  144. }
  145. },
  146. className: "icon-code",
  147. title: "Code Block",
  148. },
  149. '|',
  150. {
  151. name: "table",
  152. action: (editor) => {
  153. //todo
  154. },
  155. className: "icon-table",
  156. title: "Insert Table",
  157. },
  158. {
  159. name: "horizontal-rule",
  160. action: SimpleMDE.drawHorizontalRule,
  161. className: "icon-minus2",
  162. title: "Horizontal Rule",
  163. }
  164. ],
  165. shortcuts: {
  166. "toggleBlockquote": null,
  167. "toggleFullScreen": null
  168. }
  169. });
  170. //-> Save
  171. let saveCurrentDocument = (ev) => {
  172. $.ajax(window.location.href, {
  173. data: {
  174. markdown: mde.value()
  175. },
  176. dataType: 'json',
  177. method: 'PUT'
  178. }).then((rData, rStatus, rXHR) => {
  179. if(rData.ok) {
  180. window.location.assign('/' + pageEntryPath);
  181. } else {
  182. alerts.pushError('Something went wrong', rData.error);
  183. }
  184. }, (rXHR, rStatus, err) => {
  185. alerts.pushError('Something went wrong', 'Save operation failed.');
  186. });
  187. };
  188. $('.btn-edit-save, .btn-create-save').on('click', (ev) => {
  189. saveCurrentDocument(ev);
  190. });
  191. $(window).bind('keydown', (ev) => {
  192. if (ev.ctrlKey || ev.metaKey) {
  193. switch (String.fromCharCode(ev.which).toLowerCase()) {
  194. case 's':
  195. ev.preventDefault();
  196. saveCurrentDocument(ev);
  197. break;
  198. }
  199. }
  200. });
  201. }