diff --git a/package-lock.json b/package-lock.json index e9da0fd31c..f7d68928b2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -60,7 +60,7 @@ "cross-env": "7.0.3", "dts-bundle": "0.7.3", "esbuild": "0.20.2", - "esbuild-plugin-minify-html": "0.1.1", + "esbuild-plugin-minify-html": "0.1.2", "esbuild-plugin-replace": "1.4.0", "eslint": "9.20.1", "eslint-config-prettier": "10.0.1", @@ -7742,9 +7742,9 @@ } }, "node_modules/esbuild-plugin-minify-html": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/esbuild-plugin-minify-html/-/esbuild-plugin-minify-html-0.1.1.tgz", - "integrity": "sha512-ODIH0dAfDvinqIgiEU+exULe8YlyDvUn0s16bkKrxjt7KaBxJm5/mHisqhzVJJuS/lTBos3yLU64N4xCr5MMTw==", + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/esbuild-plugin-minify-html/-/esbuild-plugin-minify-html-0.1.2.tgz", + "integrity": "sha512-tGkkwAI/rQ7beYVuU6nyuseSWFbfXi08Yl96tEkqh3Te5BZAud0umEpyAoKGwkjutptheVJlm010wMDpKIhJaw==", "dev": true }, "node_modules/esbuild-plugin-replace": { @@ -25551,9 +25551,9 @@ } }, "esbuild-plugin-minify-html": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/esbuild-plugin-minify-html/-/esbuild-plugin-minify-html-0.1.1.tgz", - "integrity": "sha512-ODIH0dAfDvinqIgiEU+exULe8YlyDvUn0s16bkKrxjt7KaBxJm5/mHisqhzVJJuS/lTBos3yLU64N4xCr5MMTw==", + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/esbuild-plugin-minify-html/-/esbuild-plugin-minify-html-0.1.2.tgz", + "integrity": "sha512-tGkkwAI/rQ7beYVuU6nyuseSWFbfXi08Yl96tEkqh3Te5BZAud0umEpyAoKGwkjutptheVJlm010wMDpKIhJaw==", "dev": true }, "esbuild-plugin-replace": { diff --git a/package.json b/package.json index 619f9317c8..e3a196bad9 100644 --- a/package.json +++ b/package.json @@ -121,7 +121,7 @@ "cross-env": "7.0.3", "dts-bundle": "0.7.3", "esbuild": "0.20.2", - "esbuild-plugin-minify-html": "0.1.1", + "esbuild-plugin-minify-html": "0.1.2", "esbuild-plugin-replace": "1.4.0", "eslint": "9.20.1", "eslint-config-prettier": "10.0.1", diff --git a/scripts/build.js b/scripts/build.js index 9ab24d2028..9cadda1e10 100644 --- a/scripts/build.js +++ b/scripts/build.js @@ -1,5 +1,5 @@ const esbuild = require('esbuild'); -const minifyHTML = require('esbuild-plugin-minify-html').default; +const { minify: minifyHTML, default: minifyHTMLPlugin } = require('esbuild-plugin-minify-html'); const fs = require('fs'); const path = require('path'); @@ -11,7 +11,27 @@ const { arrToObj, mkdir, uint8arrayToString, iife, getFileNames, getEnvVars } = const args = process.argv.slice(2); const devMode = args.includes('--dev'); -const outDir = path.resolve(__dirname + '/../build'); +const root = path.resolve(__dirname + '/..'); +const outDir = path.resolve(root, 'build'); + +const minifyHTMLOptions = { + collapseWhitespace: true, + collapseBooleanAttributes: true, + minifyJS: true, + minifyCSS: true, + processScripts: ['importmap'], +}; + +const copyFile = async (filePath, outputName) => { + const src = path.resolve(root, filePath); + const dist = path.resolve(outDir, outputName); + if (devMode || !filePath.endsWith('.html')) { + return fs.promises.copyFile(src, dist); + } + const content = await fs.promises.readFile(src, 'utf8'); + const minified = await minifyHTML(content, minifyHTMLOptions); + fs.writeFileSync(dist, minified, 'utf8'); +}; const prepareDir = async () => { mkdir(outDir); @@ -22,30 +42,14 @@ const prepareDir = async () => { } const fileNames = await getFileNames(outDir + '/livecodes/'); await Promise.all(fileNames.map(async (f) => fs.promises.unlink(outDir + '/livecodes/' + f))); - - if (process.env.CF_PAGES) { + await Promise.all([ // add headers in Cloudflare - await fs.promises.copyFile( - path.resolve(__dirname + '/../src/_headers'), - path.resolve(outDir + '/_headers'), - ); - } - await fs.promises.copyFile( - path.resolve(__dirname + '/../src/favicon.ico'), - path.resolve(outDir + '/favicon.ico'), - ); - await fs.promises.copyFile( - path.resolve(__dirname + '/../src/404.html'), - path.resolve(outDir + '/404.html'), - ); - await fs.promises.copyFile( - path.resolve(__dirname + '/../src/index.html'), - path.resolve(outDir + '/index.html'), - ); - await fs.promises.copyFile( - path.resolve(__dirname + '/../src/livecodes/html/app-base.html'), - path.resolve(outDir + '/app.html'), - ); + process.env.CF_PAGES ? copyFile('src/_headers', '_headers') : Promise.resolve(), + copyFile('src/favicon.ico', 'favicon.ico'), + copyFile('src/404.html', '404.html'), + copyFile('src/index.html', 'index.html'), + copyFile('src/livecodes/html/app-base.html', 'app.html'), + ]); }; /** @type {Partial} */ @@ -63,32 +67,19 @@ const baseOptions = { loader: { '.html': 'text', '.ttf': 'file' }, logLevel: 'error', external: ['codemirror', '@codemirror/*', '@lezer/*', '@replit/codemirror-*'], - plugins: [ - ...(devMode - ? [] - : [ - minifyHTML({ - collapseWhitespace: true, - collapseBooleanAttributes: true, - minifyJS: true, - minifyCSS: true, - processScripts: ['importmap'], - }), - ]), - ], + plugins: [...(devMode ? [] : [minifyHTMLPlugin(minifyHTMLOptions)])], }; -const sdkBuild = () => { +const sdkBuild = async () => { const sdkSrcDir = 'src/sdk/'; const sdkSrcMod = sdkSrcDir + 'index.ts'; - const sdkOutDir = 'build/sdk/'; + const sdkOutDir = 'sdk/'; - fs.copyFileSync(path.resolve('LICENSE'), path.resolve(sdkOutDir + 'LICENSE')); - fs.copyFileSync(path.resolve('README.md'), path.resolve(sdkOutDir + 'README.md')); - fs.copyFileSync( - path.resolve(sdkSrcDir + 'package.sdk.json'), - path.resolve(sdkOutDir + 'package.json'), - ); + await Promise.all([ + copyFile('LICENSE', sdkOutDir + 'LICENSE'), + copyFile('README.md', sdkOutDir + 'README.md'), + copyFile(sdkSrcDir + 'package.sdk.json', sdkOutDir + 'package.json'), + ]); const sdkOptions = { ...baseOptions, @@ -101,20 +92,20 @@ const sdkBuild = () => { ...sdkOptions, entryPoints: [sdkSrcMod], outdir: undefined, - outfile: sdkOutDir + 'livecodes.js', + outfile: path.resolve(outDir, sdkOutDir, 'livecodes.js'), }), esbuild.build({ ...sdkOptions, entryPoints: [sdkSrcMod], outdir: undefined, - outfile: sdkOutDir + 'livecodes.cjs', + outfile: path.resolve(outDir, sdkOutDir, 'livecodes.cjs'), format: 'cjs', }), esbuild.build({ ...sdkOptions, entryPoints: [sdkSrcMod], outdir: undefined, - outfile: sdkOutDir + 'livecodes.umd.js', + outfile: path.resolve(outDir, sdkOutDir, 'livecodes.umd.js'), format: 'iife', globalName: 'livecodes', }), @@ -122,7 +113,7 @@ const sdkBuild = () => { ...sdkOptions, entryPoints: [sdkSrcDir + 'react.tsx'], outdir: undefined, - outfile: sdkOutDir + 'react.js', + outfile: path.resolve(outDir, sdkOutDir, 'react.js'), external: ['react'], jsx: 'automatic', }), @@ -130,7 +121,7 @@ const sdkBuild = () => { ...sdkOptions, entryPoints: [sdkSrcDir + 'vue.ts'], outdir: undefined, - outfile: sdkOutDir + 'vue.js', + outfile: path.resolve(outDir, sdkOutDir, 'vue.js'), external: ['vue'], alias: { '@vue/runtime-core': 'vue', diff --git a/scripts/inject-css.js b/scripts/inject-css.js index 880bebac4e..339c85c556 100644 --- a/scripts/inject-css.js +++ b/scripts/inject-css.js @@ -13,7 +13,7 @@ const injectCss = async () => { var html = fs.readFileSync(path.resolve(htmlFile), 'utf8'); var css = fs.readFileSync(path.resolve(outDir + cssFile), 'utf8'); - var result = html.replace('', ``); + var result = html.replace('', ``); fs.writeFileSync(path.resolve(htmlFile), result, 'utf8'); fs.unlinkSync(path.resolve(outDir + cssFile)); }; diff --git a/src/index.html b/src/index.html index f1038a7c66..12afbf1d47 100644 --- a/src/index.html +++ b/src/index.html @@ -79,80 +79,6 @@ fill-rule="evenodd" style="display: block; margin: 0 auto" > - - @@ -179,7 +105,6 @@ - - @@ -214,7 +138,6 @@ d="M290.1287 87.017L147.3196 0 4.5106 87.017 0 89.8789v180.0482L147.5 360l4.5106-2.7648L295 269.9271V89.8303zm-4.511 177.2837l-133.7875 81.7786V182.6194l133.9679-81.6331zm-142.809 81.7786L8.8407 264.2521V100.9863l133.968 81.6331zM13.6223 92.6919l133.6973-81.536 133.6974 81.536-133.6974 81.4873L13.487 92.6919z" fill="#444" /> - @@ -225,17 +148,16 @@ - + - + - + - * { transform: scale(0.8); } @@ -91,15 +85,87 @@ body, } @keyframes pulsate { - 0% { + 0%, + 100% { opacity: 0.2; } 50% { opacity: 1; } +} + +/* Logo SVG */ +.B { + stroke: none; +} + +.C { + fill: url('#C'); +} +.E { + fill-rule: nonzero; +} + +@keyframes pulse2 { + 0%, 100% { - opacity: 0.2; + opacity: 0; + } + + 50% { + opacity: 1; + } +} + +@keyframes pulse { + 0%, + 100% { + opacity: 0.9; + } + + 50% { + opacity: 1; + } +} + +@keyframes colorPulse { + 0%, + 100% { + stop-color: #d7d7d7; + } + + 50% { + stop-color: #b0b0b0; + } +} + +@keyframes colorPulse2 { + 0%, + 100% { + stop-color: #626262; } + + 50% { + stop-color: #444; + } +} + +#loading:not(.click-to-load) #cube-container { + animation: pulse2 3s ease-in-out infinite; + scale: 0.9; + transform-origin: center; +} + +#loading:not(.click-to-load) #inner-cube { + animation: pulse 2s ease-in-out infinite; +} + +#loading:not(.click-to-load) #gradient-stop-1 { + animation: colorPulse 4s ease-in-out infinite; +} + +#loading:not(.click-to-load) #gradient-stop-2 { + animation: colorPulse2 4s ease-in-out infinite; }