/app/assets/javascripts/content_editor/extensions/code_block_highlight.js

https://gitlab.com/523/gitlab-ce · JavaScript · 65 lines · 60 code · 4 blank · 1 comment · 2 complexity · 365cc33faf78297bb4895eadc9d42c30 MD5 · raw file

  1. import { CodeBlockLowlight } from '@tiptap/extension-code-block-lowlight';
  2. import { textblockTypeInputRule } from '@tiptap/core';
  3. import { VueNodeViewRenderer } from '@tiptap/vue-2';
  4. import languageLoader from '../services/code_block_language_loader';
  5. import CodeBlockWrapper from '../components/wrappers/code_block.vue';
  6. const extractLanguage = (element) => element.getAttribute('lang');
  7. export const backtickInputRegex = /^```([a-z]+)?[\s\n]$/;
  8. export const tildeInputRegex = /^~~~([a-z]+)?[\s\n]$/;
  9. export default CodeBlockLowlight.extend({
  10. isolating: true,
  11. exitOnArrowDown: false,
  12. addAttributes() {
  13. return {
  14. language: {
  15. default: null,
  16. parseHTML: (element) => extractLanguage(element),
  17. },
  18. class: {
  19. // eslint-disable-next-line @gitlab/require-i18n-strings
  20. default: 'code highlight',
  21. },
  22. };
  23. },
  24. addInputRules() {
  25. const getAttributes = (match) => languageLoader?.loadLanguageFromInputRule(match) || {};
  26. return [
  27. textblockTypeInputRule({
  28. find: backtickInputRegex,
  29. type: this.type,
  30. getAttributes,
  31. }),
  32. textblockTypeInputRule({
  33. find: tildeInputRegex,
  34. type: this.type,
  35. getAttributes,
  36. }),
  37. ];
  38. },
  39. parseHTML() {
  40. return [
  41. ...(this.parent?.() || []),
  42. {
  43. tag: 'div.markdown-code-block',
  44. skip: true,
  45. },
  46. ];
  47. },
  48. renderHTML({ HTMLAttributes }) {
  49. return [
  50. 'pre',
  51. {
  52. ...HTMLAttributes,
  53. class: `content-editor-code-block ${gon.user_color_scheme} ${HTMLAttributes.class}`,
  54. },
  55. ['code', {}, 0],
  56. ];
  57. },
  58. addNodeView() {
  59. return new VueNodeViewRenderer(CodeBlockWrapper);
  60. },
  61. });