Skip to content

Commit 6c3aa07

Browse files
Changing the way themes load by using a cdn to fetch the css
1 parent 4956c54 commit 6c3aa07

File tree

1 file changed

+64
-55
lines changed

1 file changed

+64
-55
lines changed

src/plugin/CodeBlock.vue

Lines changed: 64 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -92,34 +92,18 @@ import Prism from 'prismjs';
9292
import UAParser from 'ua-parser-js';
9393
import { Props } from '@/types';
9494
95+
import { version } from 'prismjs/package.json';
96+
9597
import StatusIcons from '@/plugin/StatusIcons.vue';
96-
const neonBunnyCarrotTheme = import.meta.glob('./themes/neon-bunny-carrot.css', { eager: true, as: 'raw' });
97-
const neonBunnyTheme = import.meta.glob('./themes/neon-bunny.css', { eager: true, as: 'raw' });
98-
const prismTheme = import.meta.glob('prismjs/themes/prism.css', { eager: true, as: 'raw' });
99-
const prismThemeCoy = import.meta.glob('prismjs/themes/prism-coy.css', { eager: true, as: 'raw' });
100-
const prismThemeDark = import.meta.glob('prismjs/themes/prism-dark.css', { eager: true, as: 'raw' });
101-
const prismThemeFunky = import.meta.glob('prismjs/themes/prism-funky.css', { eager: true, as: 'raw' });
102-
const prismThemeOkaidia = import.meta.glob('prismjs/themes/prism-okaidia.css', { eager: true, as: 'raw' });
103-
const prismThemeSolarizedlight = import.meta.glob('prismjs/themes/prism-solarizedlight.css', { eager: true, as: 'raw' });
104-
const prismThemeTomorrow = import.meta.glob('prismjs/themes/prism-tomorrow.css', { eager: true, as: 'raw' });
105-
const prismThemeTwilight = import.meta.glob('prismjs/themes/prism-twilight.css', { eager: true, as: 'raw' });
106-
107-
// import neonBunnyCarrotTheme from '@/plugin/themes/neon-bunny-carrot.css?inline';
108-
// import neonBunnyTheme from '@/plugin/themes/neon-bunny.css?inline';
109-
// import prismTheme from 'prismjs/themes/prism.css?inline';
110-
// import prismThemeCoy from 'prismjs/themes/prism-coy.css?inline';
111-
// import prismThemeDark from 'prismjs/themes/prism-dark.css?inline';
112-
// import prismThemeFunky from 'prismjs/themes/prism-funky.css?inline';
113-
// import prismThemeOkaidia from 'prismjs/themes/prism-okaidia.css?inline';
114-
// import prismThemeSolarizedlight from 'prismjs/themes/prism-solarizedlight.css?inline';
115-
// import prismThemeTomorrow from 'prismjs/themes/prism-tomorrow.css?inline';
116-
// import prismThemeTwilight from 'prismjs/themes/prism-twilight.css?inline';
98+
import { neonBunnyCarrotTheme, neonBunnyTheme } from '@/plugin/themes';
99+
117100
118101
// -------------------------------------------------- Emits & Slots & Injects //
119102
const emit = defineEmits(['run', 'update:copy-status']);
120103
const slots = useSlots();
121104
const codeBlockGlobalOptions = inject<Props>('codeBlockGlobalOptions');
122105
106+
123107
// -------------------------------------------------- Props //
124108
const props = defineProps({
125109
browserWindow: {
@@ -228,23 +212,26 @@ const props = defineProps({
228212
},
229213
});
230214
215+
231216
// -------------------------------------------------- Data //
232-
const copyTextValue = ref<string>('');
233217
const convertedCode = ref(null);
234-
const copying = ref<boolean>(false);
235218
const copyStatus = ref<string>('copy');
219+
const copyTextValue = ref<string>('');
220+
const copying = ref<boolean>(false);
221+
const isLoading = ref<boolean>(false);
236222
const isMobile = ref<boolean>(false);
223+
const prismCdn = ref(`https://cdn.jsdelivr.net/gh/PrismJS/prism@${version}/themes`);
237224
const runTextValue = ref<string>('');
238-
const stylesheetId = 'v-code-block--theme';
239225
const useTheme = ref<boolean | string>('');
240226
227+
241228
// -------------------------------------------------- Computed //
242229
const codeBlockClasses = computed<string>(() => {
243230
return isMobile.value ? 'v-code-block--mobile' : '';
244231
});
245232
246233
const codeTagStyles = computed<StyleValue>(() => {
247-
const width = useTheme.value === 'coy' ? '100%' : '';
234+
const width = useTheme.value === 'coy' && isLoading.value === false ? '100%' : '';
248235
return { width };
249236
});
250237
@@ -324,6 +311,7 @@ const tabGroupStyle = computed<StyleValue>(() => {
324311
};
325312
});
326313
314+
327315
// -------------------------------------------------- Watch //
328316
watch(props, () => {
329317
if (props.theme) {
@@ -340,6 +328,7 @@ watch(props, () => {
340328
}
341329
});
342330
331+
343332
// -------------------------------------------------- Mounts //
344333
onBeforeMount(() => {
345334
copyTextValue.value = props.copyText;
@@ -352,6 +341,7 @@ onMounted(() => {
352341
mobileCheck();
353342
});
354343
344+
355345
// -------------------------------------------------- Methods //
356346
function convertCode(): void {
357347
if (props.lang === 'json') {
@@ -404,56 +394,65 @@ function copyCode(): void {
404394
405395
function loadTheme(): void {
406396
let selectedTheme = null;
407-
const loadedThemeStyles = document.getElementById(stylesheetId);
408397
const head = document.getElementsByTagName('head')[0];
409398
const themeStyles = document.createElement('style');
399+
const themeId = `v-code-block--theme-${useTheme.value}`;
400+
const loadedTheme = document.body.getAttribute('data-v-code-block-theme');
410401
411-
if (loadedThemeStyles) {
412-
loadedThemeStyles.remove();
402+
let isPrismTheme = true;
403+
let cssFilename = '';
404+
405+
// If theme is loaded, do not keep trying to add it again //
406+
if (loadedTheme === useTheme.value) {
407+
return;
413408
}
414409
410+
document.body.setAttribute('data-v-code-block-theme', useTheme.value);
411+
412+
themeStyles.setAttribute('type', 'text/css');
413+
themeStyles.setAttribute('data-theme-id', themeId);
414+
themeStyles.setAttribute('data-theme', 'v-code-block--theme-sheet');
415+
415416
switch (useTheme.value) {
416417
case 'neon-bunny':
417418
selectedTheme = neonBunnyTheme;
419+
isPrismTheme = false;
418420
break;
419421
case 'neon-bunny-carrot':
420422
selectedTheme = neonBunnyCarrotTheme;
421-
break;
422-
case 'coy':
423-
selectedTheme = prismThemeCoy;
424-
break;
425-
case 'dark':
426-
selectedTheme = prismThemeDark;
427-
break;
428-
case 'funky':
429-
selectedTheme = prismThemeFunky;
430-
break;
431-
case 'okaidia':
432-
selectedTheme = prismThemeOkaidia;
433-
break;
434-
case 'solarizedlight':
435-
selectedTheme = prismThemeSolarizedlight;
436-
break;
437-
case 'tomorrow':
438-
selectedTheme = prismThemeTomorrow;
439-
break;
440-
case 'twilight':
441-
selectedTheme = prismThemeTwilight;
423+
isPrismTheme = false;
442424
break;
443425
case 'default':
444426
case 'prism':
445-
selectedTheme = prismTheme;
427+
isPrismTheme = true;
428+
cssFilename = 'prism.css';
446429
break;
447430
default:
448-
selectedTheme = prismTheme;
431+
isPrismTheme = true;
432+
cssFilename = `prism-${useTheme.value}.css`;
449433
break;
450434
}
451435
452-
themeStyles.setAttribute('type', 'text/css');
453-
themeStyles.id = stylesheetId;
454-
themeStyles.appendChild(document.createTextNode(selectedTheme));
436+
if (!isPrismTheme) {
437+
removeStylesheets();
455438
456-
head.appendChild(themeStyles);
439+
themeStyles.appendChild(document.createTextNode(selectedTheme));
440+
head.appendChild(themeStyles);
441+
442+
return;
443+
}
444+
445+
isLoading.value = true;
446+
447+
fetch(`${prismCdn.value}/${cssFilename}`).then((response) => {
448+
return response.text();
449+
}).then((data) => {
450+
removeStylesheets();
451+
452+
themeStyles.appendChild(document.createTextNode(data));
453+
head.appendChild(themeStyles);
454+
isLoading.value = false;
455+
});
457456
}
458457
459458
function mobileCheck(): void {
@@ -466,6 +465,16 @@ window.addEventListener('orientationchange', () => {
466465
mobileCheck();
467466
});
468467
468+
function removeStylesheets() {
469+
const themeSheets = document.querySelectorAll('[data-theme="v-code-block--theme-sheet"]');
470+
471+
if (themeSheets.length > 0) {
472+
themeSheets.forEach((themeSheet) => {
473+
themeSheet.remove();
474+
});
475+
}
476+
}
477+
469478
function runCode(): void {
470479
emit('run');
471480
}

0 commit comments

Comments
 (0)