diff --git a/src/js/highlightWorker.js b/src/js/highlightWorker.js new file mode 100644 index 0000000..1ac6e27 --- /dev/null +++ b/src/js/highlightWorker.js @@ -0,0 +1,15 @@ +import hljs from 'highlight.js/lib/core'; +import json from 'highlight.js/lib/languages/json'; +import plaintext from 'highlight.js/lib/languages/plaintext'; + +hljs.registerLanguage('json', json); +hljs.registerLanguage('plaintext', plaintext); + +self.onmessage = (event) => { + const { code, language } = event.data; + + const result = hljs.highlight(code, { language }); + + // Post the result back to the main thread + self.postMessage(result.value); +}; diff --git a/src/main.js b/src/main.js index e3ed8b4..bb98df0 100644 --- a/src/main.js +++ b/src/main.js @@ -1,11 +1,10 @@ -import hljs from 'highlight.js/lib/core'; -import json from 'highlight.js/lib/languages/json'; -import plaintext from 'highlight.js/lib/languages/plaintext'; import { registerSW } from 'virtual:pwa-register'; import { toggleColorMode } from './js/theme.js'; import { copyTextFromInput, downloadFile, handleDrop, handleTextFiles } from './js/utils.js'; import createUUID from './js/uuid.js'; +const highlightWorker = new Worker(new URL('./js/highlightWorker.js', import.meta.url), { type: 'module' }); + document.addEventListener('DOMContentLoaded', function () { const button = document.querySelector('.form__button'); const input = document.querySelector('.form__input'); @@ -21,9 +20,6 @@ document.addEventListener('DOMContentLoaded', function () { return document.querySelector('input[name="export"]:checked').value; } - hljs.registerLanguage('json', json); - hljs.registerLanguage('plaintext', plaintext); - async function generatePairs(format) { const usernames = input.value.split('\n').filter((i) => i); let generatedPairs = []; @@ -44,14 +40,18 @@ document.addEventListener('DOMContentLoaded', function () { format = generatedPairs.length && format === 'json' ? 'json' : 'text'; - result.innerHTML = format === 'json' ? JSON.stringify(generatedPairs, null, 2) : generatedPairs.join('\n'); + const codeToHighlight = format === 'json' ? JSON.stringify(generatedPairs, null, 2) : generatedPairs.join('\n'); - result.dataset.highlighted = ''; + // Use the Web Worker to highlight the code + highlightWorker.postMessage({ code: codeToHighlight, language: format === 'json' ? 'json' : 'plaintext' }); - result.classList.toggle('language-json', format === 'json'); - result.classList.toggle('language-plaintext', format !== 'json'); + highlightWorker.onmessage = (event) => { + result.innerHTML = event.data; - hljs.highlightElement(result); + result.classList.add('hljs'); + result.classList.toggle('language-json', format === 'json'); + result.classList.toggle('language-plaintext', format !== 'json'); + }; } button.addEventListener('click', async () => { diff --git a/vite.config.js b/vite.config.js index c20aee8..865ac66 100644 --- a/vite.config.js +++ b/vite.config.js @@ -11,156 +11,156 @@ import viteSvgSpriteWrapper from 'vite-svg-sprite-wrapper'; const root = resolve(__dirname, 'src'); const outDir = resolve(__dirname, 'dist'); export default defineConfig({ - root, - css: { - postcss: { - plugins: [ - cssnano({ - preset: ['default', { discardComments: { removeAll: true } }], - }), - ], - }, - }, - plugins: [ - viteSvgSpriteWrapper({ - icons: './src/img/svg/*.svg', - outputDir: './src/img', - sprite: { - svg: { - dimensionAttributes: false, - }, - }, - }), - VitePWA({ - // includeAssets: [ - // '/css/style.css', - // '/fonts/MinecraftBold.woff2', - // '/fonts/MinecraftRegular.woff2', - // '/serviceworker.js', - // '/main.js', - // '/img/sprite.svg', - // ], - workbox: { - globPatterns: ['**/*'], - }, - // add this to cache all the - // static assets in the public folder - includeAssets: ['**/*'], - registerType: 'autoUpdate', - selfDestroying: true, - devOptions: { - enabled: true, - }, - manifest: { - name: 'Minecraft Offline UUID Generator', - short_name: 'UUID Generator', - theme_color: '#171615', - background_color: '#3EAE30', - display: 'standalone', - scope: '.', - start_url: '.', - description: 'A tool to generate Minecraft offline UUIDs', - orientation: 'any', - icons: [ - { - src: './favicon-16x16.png', - sizes: '16x16', - }, - { - src: './favicon-32x32.png', - sizes: '32x32', - }, - { - src: './favicon-48x48.png', - sizes: '48x48', - }, - { - src: './favicon-192x192.png', - sizes: '192x192', - }, - { - src: './favicon-167x167.png', - sizes: '167x167', - purpose: 'maskable', - }, - { - src: './favicon-180x180.png', - sizes: '180x180', - }, - { - src: './favicon-512x512.png', - sizes: '512x512', - }, - ], - }, - }), - handlebars({ - partialDirectory: resolve(__dirname, 'src/parts'), - }), - viteImagemin({ - gifsicle: { - optimizationLevel: 7, - interlaced: false, - }, - optipng: { - optimizationLevel: 7, - }, - mozjpeg: { - quality: 20, - }, - pngquant: { - quality: [0.8, 0.9], - speed: 4, - }, - svgo: { - plugins: [ - { - name: 'removeViewBox', - }, - { - name: 'removeEmptyAttrs', - active: false, - }, - ], - }, - }), - ], - build: { - outDir, - emptyOutDir: true, - rollupOptions: { - // input: { - // main: resolve(root, 'index.html'), - // example: resolve(root, 'example', 'index.html') - // }, - input: Object.fromEntries( - glob.sync(['./src/*.html', './src/**/*.html', '!./src/parts/**']).map((file) => [ - // This remove `src/` as well as the file extension from each - // file, so e.g. src/nested/foo.html becomes nested/foo - relative(__dirname, file.slice(0, file.length - extname(file).length)), - // This expands the relative paths to absolute paths, so e.g. - // src/nested/foo becomes /project/src/nested/fo.js - fileURLToPath(new URL(file, import.meta.url)), - ]), - ), - output: { - chunkFileNames: 'js/[name]-[hash].js', - entryFileNames: 'js/[name]-[hash].js', + root, + css: { + postcss: { + plugins: [ + cssnano({ + preset: ['default', { discardComments: { removeAll: true } }], + }), + ], + }, + }, + plugins: [ + viteSvgSpriteWrapper({ + icons: './src/img/svg/*.svg', + outputDir: './src/img', + sprite: { + svg: { + dimensionAttributes: false, + }, + }, + }), + VitePWA({ + // includeAssets: [ + // '/css/style.css', + // '/fonts/MinecraftBold.woff2', + // '/fonts/MinecraftRegular.woff2', + // '/serviceworker.js', + // '/main.js', + // '/img/sprite.svg', + // ], + workbox: { + globPatterns: ['**/*'], + }, + // add this to cache all the + // static assets in the public folder + includeAssets: ['**/*'], + registerType: 'autoUpdate', + selfDestroying: true, + devOptions: { + enabled: true, + }, + manifest: { + name: 'Minecraft Offline UUID Generator', + short_name: 'UUID Generator', + theme_color: '#171615', + background_color: '#3EAE30', + display: 'standalone', + scope: '.', + start_url: '.', + description: 'A tool to generate Minecraft offline UUIDs', + orientation: 'any', + icons: [ + { + src: './favicon-16x16.png', + sizes: '16x16', + }, + { + src: './favicon-32x32.png', + sizes: '32x32', + }, + { + src: './favicon-48x48.png', + sizes: '48x48', + }, + { + src: './favicon-192x192.png', + sizes: '192x192', + }, + { + src: './favicon-167x167.png', + sizes: '167x167', + purpose: 'maskable', + }, + { + src: './favicon-180x180.png', + sizes: '180x180', + }, + { + src: './favicon-512x512.png', + sizes: '512x512', + }, + ], + }, + }), + handlebars({ + partialDirectory: resolve(__dirname, 'src/parts'), + }), + viteImagemin({ + gifsicle: { + optimizationLevel: 7, + interlaced: false, + }, + optipng: { + optimizationLevel: 7, + }, + mozjpeg: { + quality: 20, + }, + pngquant: { + quality: [0.8, 0.9], + speed: 4, + }, + svgo: { + plugins: [ + { + name: 'removeViewBox', + }, + { + name: 'removeEmptyAttrs', + active: false, + }, + ], + }, + }), + ], + build: { + outDir, + emptyOutDir: true, + rollupOptions: { + // input: { + // main: resolve(root, 'index.html'), + // example: resolve(root, 'example', 'index.html') + // }, + input: Object.fromEntries( + glob.sync(['./src/*.html', './src/**/*.html', '!./src/parts/**']).map((file) => [ + // This remove `src/` as well as the file extension from each + // file, so e.g. src/nested/foo.html becomes nested/foo + relative(__dirname, file.slice(0, file.length - extname(file).length)), + // This expands the relative paths to absolute paths, so e.g. + // src/nested/foo becomes /project/src/nested/fo.js + fileURLToPath(new URL(file, import.meta.url)), + ]), + ), + output: { + chunkFileNames: 'js/[name]-[hash].js', + entryFileNames: 'js/[name]-[hash].js', - assetFileNames: ({ name }) => { - if (/\.(gif|jpe?g|png|svg)$/.test(name ?? '')) { - return 'img/[name]-[hash][extname]'; - } + assetFileNames: ({ name }) => { + if (/\.(gif|jpe?g|png|svg)$/.test(name ?? '')) { + return 'img/[name]-[hash][extname]'; + } - if (/\.css$/.test(name ?? '')) { - return 'css/[name]-[hash][extname]'; - } + if (/\.css$/.test(name ?? '')) { + return 'css/[name]-[hash][extname]'; + } - // default value - // ref: https://rollupjs.org/guide/en/#outputassetfilenames - return 'assets/[name]-[hash][extname]'; - }, - }, - }, - }, + // default value + // ref: https://rollupjs.org/guide/en/#outputassetfilenames + return 'assets/[name]-[hash][extname]'; + }, + }, + }, + }, });