Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions demo/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
<script src="languages.js"></script>

<!-- Highlight.js -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/atom-one-dark.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/atom-one-dark.min.css" integrity="sha256-Qjf/ynzmqttDjEV+CmdbElxTS73aW4f0HzoUlWA7zJs=" crossorigin="anonymous" referrerpolicy="no-referrer">
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js" integrity="sha256-g3pvpbDHNrUrveKythkPMF2j/J7UFoHbUyFQcFe1yEY=" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script>hljs.highlightAll();</script>

<style>
Expand Down
2 changes: 1 addition & 1 deletion dist/spotlight.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/spotlight.js
Original file line number Diff line number Diff line change
Expand Up @@ -1931,7 +1931,7 @@
const scaleH = vh / intrinsicHeight;
const viewportLandscape = vw >= vh;

let baseScale = 1;
let baseScale;

if (viewportLandscape) {
// Desktop / Landscape
Expand Down
55 changes: 30 additions & 25 deletions vite.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ function spotlightOptimizer() {
const ids = new Set(out.match(idRegex) || []);
const map = new Map();
let idx = 0;

// Generator for short names: a, b, ... z, A ... Z, aa, ab ...
const chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
function generateId(n) {
Expand All @@ -57,17 +57,22 @@ function spotlightOptimizer() {

// Assign short names
// Sort by length desc just in case, though greedy regex handles it
Array.from(ids).sort((a, b) => b.length - a.length).forEach(id => {
map.set(id, generateId(idx++));
});
Array.from(ids)
.sort((a, b) => b.length - a.length)
.forEach((id) => {
map.set(id, generateId(idx++));
});

// Replace all occurrences
out = out.replace(idRegex, (m) => map.get(m));

// 1. Minify the large injected CSS template literal assigned to `const css = `...`;
// 1. Minify the large injected CSS template literal assigned to `const css = `...`;`
out = out.replace(/const\s+css\s*=\s*`([\s\S]*?)`;/, (m, p1) => {
try {
const min = csso.minify(p1).css.replace(/`/g, '\\`');
const min = csso
.minify(p1)
.css.replace(/\\/g, '\\\\')
.replace(/`/g, '\\`');
return `const css = \`${min}\`;`;
} catch (err) {
return m;
Expand All @@ -91,8 +96,8 @@ function spotlightOptimizer() {
],
});
if (res && res.error) return svg;
// Escape backticks to keep template literals safe
return res.data.replace(/`/g, '\\`');
// Escape backslashes first, then backticks to keep template literals safe
return res.data.replace(/\\/g, '\\\\').replace(/`/g, '\\`');
} catch (err) {
return svg;
}
Expand All @@ -102,35 +107,35 @@ function spotlightOptimizer() {
const htmlRegex = /\.innerHTML\s*=\s*`([\s\S]*?)`;/g;
let match;
const replacements = [];

while ((match = htmlRegex.exec(out)) !== null) {
const fullMatch = match[0];
const content = match[1];

// Skip if it looks like it was already handled by SVG optimizer (starts with <svg)
if (content.trim().startsWith('<svg')) continue;

try {
const min = await htmlMinify(content, {
collapseWhitespace: true,
removeComments: true,
quoteCharacter: "'",
minifyCSS: true,
});
// Escape backticks
const safeMin = min.replace(/`/g, '\\`');
replacements.push({
start: match.index,
end: match.index + fullMatch.length,
replacement: fullMatch.replace(content, safeMin)
});
const min = await htmlMinify(content, {
collapseWhitespace: true,
removeComments: true,
quoteCharacter: "'",
minifyCSS: true,
});
// Escape backslashes first, then backticks
const safeMin = min.replace(/\\/g, '\\\\').replace(/`/g, '\\`');
replacements.push({
start: match.index,
end: match.index + fullMatch.length,
replacement: fullMatch.replace(content, safeMin),
});
} catch (e) {}
}

// Apply replacements from end to start
for (let i = replacements.length - 1; i >= 0; i--) {
const r = replacements[i];
out = out.slice(0, r.start) + r.replacement + out.slice(r.end);
const r = replacements[i];
out = out.slice(0, r.start) + r.replacement + out.slice(r.end);
}

return { code: out, map: null };
Expand Down
11 changes: 7 additions & 4 deletions vite.config.safe.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,13 @@ function minifyInlineCssSvg() {

let out = code;

// Minify the large injected CSS template literal assigned to `const css = `...`;
// Minify the large injected CSS template literal assigned to `const css = `...`;`
out = out.replace(/const\s+css\s*=\s*`([\s\S]*?)`;/, (m, p1) => {
try {
const min = csso.minify(p1).css.replace(/`/g, '\\`');
const min = csso
.minify(p1)
.css.replace(/\\/g, '\\\\')
.replace(/`/g, '\\`');
return `const css = \`${min}\`;`;
} catch (err) {
return m;
Expand All @@ -63,8 +66,8 @@ function minifyInlineCssSvg() {
],
});
if (res && res.error) return svg;
// Escape backticks to keep template literals safe
return res.data.replace(/`/g, '\\`');
// Escape backslashes first, then backticks to keep template literals safe
return res.data.replace(/\\/g, '\\\\').replace(/`/g, '\\`');
} catch (err) {
return svg;
}
Expand Down