Skip to content

Commit 6173a70

Browse files
authored
Merge pull request #10657 from quarto-dev/revealjs/remove-sourcemapurl
2 parents 8fd1bee + 0e0d27f commit 6173a70

File tree

6 files changed

+70
-29
lines changed

6 files changed

+70
-29
lines changed

news/changelog-1.6.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ All changes included in 1.6:
1414

1515
## `revealjs` Format
1616

17-
- Update to Reveal JS 5.1.0
17+
- Update to Reveal JS 5.1.0.
18+
- Prevent empty SASS built css file to be included in header.
19+
- Remove wrong `sourceMappingUrl` entry in SASS built css.
1820
- ([#7715](https://github.com/quarto-dev/quarto-cli/issues/7715)): Revealjs don't support anymore special Pandoc syntax making BulletList in Blockquotes become incremental list. This was confusing and unexpected behavior. Supported syntax for incremental list is documented at <https://quarto.org/docs/presentations/revealjs/#incremental-lists>.
1921
- ([#9742](https://github.com/quarto-dev/quarto-cli/issues/9742)): Links to cross-referenced images correctly works.
2022

src/command/render/pandoc-html.ts

Lines changed: 20 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import { ProjectContext } from "../../project/types.ts";
1919

2020
import { TempContext } from "../../core/temp.ts";
2121
import { cssImports, cssResources } from "../../core/css.ts";
22-
import { compileSass } from "../../core/sass.ts";
22+
import { cleanSourceMappingUrl, compileSass } from "../../core/sass.ts";
2323

2424
import { kSourceMappingRegexes } from "../../config/constants.ts";
2525

@@ -38,6 +38,7 @@ import { kMinimal } from "../../format/html/format-html-shared.ts";
3838
import { kSassBundles } from "../../config/types.ts";
3939
import { md5HashBytes } from "../../core/hash.ts";
4040
import { InternalError } from "../../core/lib/error.ts";
41+
import { writeTextFileSyncPreserveMode } from "../../core/write.ts";
4142

4243
// The output target for a sass bundle
4344
// (controls the overall style tag that is emitted)
@@ -126,11 +127,18 @@ export async function resolveSassBundles(
126127
}
127128

128129
for (const target of targets) {
129-
let cssPath = await compileSass(target.bundles, temp);
130-
130+
let cssPath: string | undefined;
131+
cssPath = await compileSass(target.bundles, temp);
132+
// First, Clean CSS
133+
cleanSourceMappingUrl(cssPath);
131134
// look for a sentinel 'dark' value, extract variables
132135
const cssResult = processCssIntoExtras(cssPath, extras, temp);
133136
cssPath = cssResult.path;
137+
138+
// it can happen that processing generate an empty css file (e.g quarto-html deps with Quarto CSS variables)
139+
// in that case, no need to insert the cssPath in the dependency
140+
if (!cssPath) continue;
141+
134142
// Process attributes (forward on to the target)
135143
for (const bundle of target.bundles) {
136144
if (bundle.attribs) {
@@ -425,7 +433,7 @@ function generateThemeCssClasses(
425433
}
426434

427435
interface CSSResult {
428-
path: string;
436+
path: string | undefined;
429437
dark: boolean;
430438
}
431439

@@ -436,13 +444,8 @@ function processCssIntoExtras(
436444
temp: TempContext,
437445
): CSSResult {
438446
extras.html = extras.html || {};
439-
const css = Deno.readTextFileSync(cssPath).replaceAll(
440-
kSourceMappingRegexes[0],
441-
"",
442-
).replaceAll(
443-
kSourceMappingRegexes[1],
444-
"",
445-
);
447+
448+
const css = Deno.readTextFileSync(cssPath);
446449

447450
// Extract dark sentinel value
448451
const hasDarkSentinel = cssHasDarkModeSentinel(css);
@@ -471,23 +474,13 @@ function processCssIntoExtras(
471474

472475
if (dirty) {
473476
const cleanedCss = css.replaceAll(kVariablesRegex, "");
474-
const hash = md5HashBytes(new TextEncoder().encode(cleanedCss));
475-
const newCssPath = temp.createFile({ suffix: `-${hash}.css` });
476-
477-
// Preserve the existing permissions if possible
478-
// See https://github.com/quarto-dev/quarto-cli/issues/660
479-
let mode;
480-
if (Deno.build.os !== "windows") {
481-
const stat = Deno.statSync(cssPath);
482-
if (stat.mode !== null) {
483-
mode = stat.mode;
484-
}
485-
}
486-
487-
if (mode !== undefined) {
488-
Deno.writeTextFileSync(newCssPath, cleanedCss, { mode });
477+
let newCssPath: string | undefined;
478+
if (cleanedCss.trim() === "") {
479+
newCssPath = undefined;
489480
} else {
490-
Deno.writeTextFileSync(newCssPath, cleanedCss);
481+
const hash = md5HashBytes(new TextEncoder().encode(cleanedCss));
482+
newCssPath = temp.createFile({ suffix: `-${hash}.css` });
483+
writeTextFileSyncPreserveMode(newCssPath, cleanedCss);
491484
}
492485

493486
return {

src/core/sass.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ import * as ld from "./lodash.ts";
1717
import { lines } from "./text.ts";
1818
import { sassCache } from "./sass/cache.ts";
1919
import { md5HashBytes } from "./hash.ts";
20+
import { kSourceMappingRegexes } from "../config/constants.ts";
21+
import { writeTextFileSyncPreserveMode } from "./write.ts";
2022

2123
export interface SassVariable {
2224
name: string;
@@ -327,3 +329,15 @@ export async function compileWithCache(
327329
return outputFilePath;
328330
}
329331
}
332+
333+
// Clean sourceMappingUrl from css after saas compilation
334+
export function cleanSourceMappingUrl(cssPath: string): void {
335+
const cleaned = Deno.readTextFileSync(cssPath).replaceAll(
336+
kSourceMappingRegexes[0],
337+
"",
338+
).replaceAll(
339+
kSourceMappingRegexes[1],
340+
"",
341+
);
342+
writeTextFileSyncPreserveMode(cssPath, cleaned);
343+
}

src/core/write.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*
2+
* write.ts
3+
*
4+
* Copyright (C)2024 Posit Software, PBC
5+
*/
6+
7+
export function writeTextFileSyncPreserveMode(
8+
path: string,
9+
data: string,
10+
options?: Deno.WriteFileOptions | undefined,
11+
): void {
12+
// Preserve the existing permissions if possible
13+
// See https://github.com/quarto-dev/quarto-cli/issues/660
14+
let mode;
15+
if (Deno.build.os !== "windows") {
16+
const stat = Deno.statSync(path);
17+
if (stat.mode !== null) {
18+
mode = stat.mode;
19+
}
20+
}
21+
22+
if (mode !== undefined) {
23+
options = { ...options, mode }; // Merge provided options with mode
24+
}
25+
26+
Deno.writeTextFileSync(path, data, options);
27+
}

src/format/reveal/format-reveal-theme.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import { isFileRef } from "../../core/http.ts";
2020
import { pathWithForwardSlashes } from "../../core/path.ts";
2121
import { formatResourcePath } from "../../core/resources.ts";
2222
import {
23+
cleanSourceMappingUrl,
2324
compileSass,
2425
mergeLayers,
2526
outputVariable,
@@ -188,6 +189,8 @@ export async function revealTheme(
188189

189190
// compile sass
190191
const css = await compileSass([bundleLayers, ...brandLayers], temp);
192+
// Remove sourcemap information
193+
cleanSourceMappingUrl(css);
191194
// convert from string to bytes
192195
const hash = md5HashBytes(Deno.readFileSync(css));
193196
const fileName = `quarto-${hash}`;

tests/docs/smoke-all/2024/05/03/9548.qmd

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@ _quarto:
66
tests:
77
revealjs:
88
ensureHtmlElements:
9-
- ['head > link[rel="stylesheet"][href$="quarto-4f64e0fc78c89fc90127583bb01c366c.css"]']
9+
- []
1010
- ['head > link[rel="stylesheet"][href$="beige.css"]']
11+
ensureFileRegexMatches:
12+
- ['<link .* href=.+revealjs/dist/theme/quarto-([a-f0-9]{32})\.css']
1113
---
1214

1315
# Revealjs theme handling

0 commit comments

Comments
 (0)