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.

128 lines
4.0 KiB

  1. <template lang="pug">
  2. transition(:duration="400")
  3. .modal(v-show='isShown', v-cloak)
  4. transition(name='modal-background')
  5. .modal-background(v-show='isShown')
  6. .modal-container
  7. transition(name='modal-content')
  8. .modal-content.is-expanded(v-show='isShown')
  9. header.is-green
  10. span {{ $t('editor.codeblocktitle') }}
  11. p.modal-notify(v-bind:class='{ "is-active": isLoading }')
  12. span {{ $t('editor.codeblockloading', { name: modeSelected }) }}
  13. i
  14. section.is-gapless
  15. .columns.is-stretched
  16. .column.is-one-quarter.modal-sidebar.is-green(style={'max-width':'350px'})
  17. .model-sidebar-header {{ $t('editor.codeblocklanguage') }}
  18. .model-sidebar-content
  19. p.control.is-fullwidth
  20. select(v-model='modeSelected')
  21. option(v-for='mode in modes', v-bind:value='mode.name') {{ mode.caption }}
  22. .column.ace-container
  23. #codeblock-editor
  24. footer
  25. a.button.is-grey.is-outlined(v-on:click='cancel') {{ $t('editor.discard') }}
  26. a.button.is-green(v-on:click='insertCode') {{ $t('editor.codeblockinsert') }}
  27. </template>
  28. <script>
  29. let codeEditor
  30. let ace
  31. export default {
  32. name: 'editor-codeblock',
  33. data() {
  34. return {
  35. modes: [],
  36. modeSelected: 'text',
  37. modelistLoaded: [],
  38. isLoading: false
  39. }
  40. },
  41. computed: {
  42. content() {
  43. return this.$store.state.editorCodeblock.content
  44. },
  45. isShown() {
  46. return this.$store.state.editorCodeblock.shown
  47. }
  48. },
  49. watch: {
  50. modeSelected(val, oldVal) {
  51. this.loadMode(val)
  52. }
  53. },
  54. methods: {
  55. init() {
  56. let self = this
  57. self._.delay(() => {
  58. codeEditor = ace.edit('codeblock-editor')
  59. codeEditor.setTheme('ace/theme/tomorrow_night')
  60. codeEditor.getSession().setMode('ace/mode/' + self.modeSelected)
  61. codeEditor.setOption('fontSize', '14px')
  62. codeEditor.setOption('hScrollBarAlwaysVisible', false)
  63. codeEditor.setOption('wrap', true)
  64. codeEditor.setOption('useSoftTabs', true)
  65. codeEditor.setOption('tabSize', 2)
  66. codeEditor.setOption('showPrintMargin', false)
  67. codeEditor.setValue(self.content)
  68. codeEditor.focus()
  69. codeEditor.renderer.updateFull()
  70. }, 100)
  71. },
  72. loadMode(m) {
  73. let self = this
  74. if (self._.includes(self.modelistLoaded, m)) {
  75. codeEditor.getSession().setMode('ace/mode/' + m)
  76. } else {
  77. self.isLoading = true
  78. self.$http.get('/js/ace/mode-' + m + '.js').then(resp => {
  79. if (resp.ok) {
  80. eval(resp.bodyText)
  81. self.modelistLoaded.push(m)
  82. ace.acequire('ace/mode/' + m)
  83. codeEditor.getSession().setMode('ace/mode/' + m)
  84. self._.delay(() => { self.isLoading = false }, 500)
  85. } else {
  86. this.$store.dispatch('alert', {
  87. style: 'red',
  88. icon: 'ui-2_square-remove-09',
  89. msg: self.$t('editor.codeblockloadingerror')
  90. })
  91. }
  92. }).catch(err => {
  93. this.$store.dispatch('alert', {
  94. style: 'red',
  95. icon: 'ui-2_square-remove-09',
  96. msg: 'Error: ' + err.body.msg
  97. })
  98. })
  99. }
  100. },
  101. cancel() {
  102. codeEditor.destroy()
  103. this.$store.dispatch('editorCodeblock/close')
  104. },
  105. insertCode() {
  106. let codeBlockText = '\n```' + this.modeSelected + '\n' + codeEditor.getValue() + '\n```\n'
  107. this.$store.dispatch('editor/insert', codeBlockText)
  108. this.$store.dispatch('alert', {
  109. style: 'blue',
  110. icon: 'files_archive-3d-check',
  111. msg: this.$t('editor.codeblocksuccess')
  112. })
  113. this.cancel()
  114. }
  115. },
  116. mounted() {
  117. FuseBox.import('/js/ace/ace.js', (acePkg) => {
  118. ace = acePkg
  119. this.modes = ace.acequire('ace/ext/modelist').modesByName
  120. })
  121. this.$root.$on('editorCodeblock/init', this.init)
  122. }
  123. }
  124. </script>