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.

126 lines
4.1 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('showPrintMargin', false)
  65. codeEditor.setValue(self.content)
  66. codeEditor.focus()
  67. codeEditor.renderer.updateFull()
  68. }, 100)
  69. },
  70. loadMode (m) {
  71. let self = this
  72. if (self._.includes(self.modelistLoaded, m)) {
  73. codeEditor.getSession().setMode('ace/mode/' + m)
  74. } else {
  75. self.isLoading = true
  76. self.$http.get('/js/ace/mode-' + m + '.js').then(resp => {
  77. if(resp.ok) {
  78. eval(resp.bodyText)
  79. self.modelistLoaded.push(m)
  80. ace.acequire('ace/mode/' + m)
  81. codeEditor.getSession().setMode('ace/mode/' + m)
  82. self._.delay(() => { self.isLoading = false }, 500)
  83. } else {
  84. this.$store.dispatch('alert', {
  85. style: 'red',
  86. icon: 'square-cross',
  87. msg: self.$t('editor.codeblockloadingerror')
  88. })
  89. }
  90. }).catch(err => {
  91. his.$store.dispatch('alert', {
  92. style: 'red',
  93. icon: 'square-cross',
  94. msg: 'Error: ' + err.body.msg
  95. })
  96. })
  97. }
  98. },
  99. cancel () {
  100. codeEditor.destroy()
  101. this.$store.dispatch('editorCodeblock/close')
  102. },
  103. insertCode () {
  104. let codeBlockText = '\n```' + this.modeSelected + '\n' + codeEditor.getValue() + '\n```\n'
  105. this.$store.dispatch('editor/insert', codeBlockText)
  106. this.$store.dispatch('alert', {
  107. style: 'blue',
  108. icon: 'inbox',
  109. msg: this.$t('editor.codeblocksuccess')
  110. })
  111. this.cancel()
  112. }
  113. },
  114. mounted() {
  115. FuseBox.import('/js/ace/ace.js', (acePkg) => {
  116. ace = acePkg
  117. this.modes = ace.acequire('ace/ext/modelist').modesByName
  118. })
  119. this.$root.$on('editorCodeblock/init', this.init)
  120. }
  121. }
  122. </script>