diff options
Diffstat (limited to 'app/assets/javascripts/vue_shared/components/source_viewer/source_viewer.vue')
-rw-r--r-- | app/assets/javascripts/vue_shared/components/source_viewer/source_viewer.vue | 52 |
1 files changed, 49 insertions, 3 deletions
diff --git a/app/assets/javascripts/vue_shared/components/source_viewer/source_viewer.vue b/app/assets/javascripts/vue_shared/components/source_viewer/source_viewer.vue index 9dc6dc1b93a..a4d50466f8f 100644 --- a/app/assets/javascripts/vue_shared/components/source_viewer/source_viewer.vue +++ b/app/assets/javascripts/vue_shared/components/source_viewer/source_viewer.vue @@ -5,6 +5,7 @@ import eventHub from '~/notes/event_hub'; import languageLoader from '~/content_editor/services/highlight_js_language_loader'; import addBlobLinksTracking from '~/blob/blob_links_tracking'; import Tracking from '~/tracking'; +import axios from '~/lib/utils/axios_utils'; import { EVENT_ACTION, EVENT_LABEL_VIEWER, @@ -14,6 +15,7 @@ import { LEGACY_FALLBACKS, CODEOWNERS_FILE_NAME, CODEOWNERS_LANGUAGE, + SVELTE_LANGUAGE, } from './constants'; import Chunk from './components/chunk.vue'; import { registerPlugins } from './plugins/index'; @@ -52,13 +54,24 @@ export default { }; }, computed: { + isLfsBlob() { + const { storedExternally, externalStorage, simpleViewer } = this.blob; + + return storedExternally && externalStorage === 'lfs' && simpleViewer?.fileType === 'text'; + }, splitContent() { return this.content.split(/\r?\n/); }, language() { - return this.blob.name === this.$options.codeownersFileName - ? this.$options.codeownersLanguage - : ROUGE_TO_HLJS_LANGUAGE_MAP[this.blob.language?.toLowerCase()]; + if (this.blob.name && this.blob.name.endsWith(`.${SVELTE_LANGUAGE}`)) { + // override for svelte files until https://github.com/rouge-ruby/rouge/issues/1717 is resolved + return SVELTE_LANGUAGE; + } else if (this.blob.name === this.$options.codeownersFileName) { + // override for codeowners files + return this.$options.codeownersLanguage; + } + + return ROUGE_TO_HLJS_LANGUAGE_MAP[this.blob.language?.toLowerCase()]; }, lineNumbers() { return this.splitContent.length; @@ -76,6 +89,15 @@ export default { }, }, async created() { + if (this.isLfsBlob) { + await axios + .get(this.blob.externalStorageUrl || this.blob.rawPath) + .then((result) => { + this.content = result.data; + }) + .catch(() => this.$emit('error')); + } + addBlobLinksTracking(); this.trackEvent(EVENT_LABEL_VIEWER); @@ -168,12 +190,36 @@ export default { // If no language can be mapped to highlight.js we load all common languages else we load only the core (smallest footprint) return !this.language ? import('highlight.js/lib/common') : import('highlight.js/lib/core'); }, + async loadSubLanguages(languageDefinition) { + if (!languageDefinition?.contains) return; + + // generate list of languages to load + const languages = new Set( + languageDefinition.contains + .filter((component) => Boolean(component.subLanguage)) + .map((component) => component.subLanguage), + ); + + if (languageDefinition.subLanguage) { + languages.add(languageDefinition.subLanguage); + } + + // load all sub-languages at once + await Promise.all( + [...languages].map(async (subLanguage) => { + const subLanguageDefinition = await languageLoader[subLanguage](); + this.hljs.registerLanguage(subLanguage, subLanguageDefinition.default); + }), + ); + }, async loadLanguage() { let languageDefinition; try { languageDefinition = await languageLoader[this.language](); this.hljs.registerLanguage(this.language, languageDefinition.default); + + await this.loadSubLanguages(this.hljs.getLanguage(this.language)); } catch (message) { this.$emit('error', message); } |