Skip to content

Commit

Permalink
Merge pull request #11862 from quarto-dev/bugfix/11860
Browse files Browse the repository at this point in the history
Bugfix/11860
  • Loading branch information
cscheid authored Jan 14, 2025
2 parents d25eb87 + 0636a19 commit 182adf7
Show file tree
Hide file tree
Showing 10 changed files with 84 additions and 7 deletions.
10 changes: 7 additions & 3 deletions news/changelog-1.7.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,17 @@ All changes included in 1.7:

- ([#11608](https://github.com/quarto-dev/quarto-cli/pull/11608)): Do not issue error message when calling `quarto check info`.

## `typst` Format
## `html` format

- ([#11860])(https://github.com/quarto-dev/quarto-cli/issues/11860)): ES6 modules that import other local JS modules in documents with `embed-resources: true` are now correctly embedded.

## `pdf` format

- ([#11578](https://github.com/quarto-dev/quarto-cli/issues/11578)): Typst column layout widths use fractional `fr` units instead of percent `%` units for unitless and default widths in order to fill the enclosing block and not spill outside it.
- ([#11835](https://github.com/quarto-dev/quarto-cli/issues/11835)): Take markdown structure into account when detecting minimum heading level.

## `pdf` Format
## `typst` format

- ([#11578](https://github.com/quarto-dev/quarto-cli/issues/11578)): Typst column layout widths use fractional `fr` units instead of percent `%` units for unitless and default widths in order to fill the enclosing block and not spill outside it.
- ([#11835](https://github.com/quarto-dev/quarto-cli/issues/11835)): Take markdown structure into account when detecting minimum heading level.

## Lua Filters and extensions
Expand Down
2 changes: 1 addition & 1 deletion src/core/data-url.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { encode as base64Encode } from "encoding/base64";
import { encodeBase64 as base64Encode } from "encoding/base64";

export function asDataUrl(
content: string | ArrayBuffer,
Expand Down
2 changes: 2 additions & 0 deletions src/core/esbuild.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ export async function esbuildCommand(
if (result.success) {
return result.stdout;
} else {
console.error(result.stderr);

throw new Error("esbuild command failed");
}
}
32 changes: 30 additions & 2 deletions src/core/pandoc/self-contained.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,34 @@
* Copyright (C) 2020-2023 Posit Software, PBC
*/

import { basename, dirname } from "../../deno_ral/path.ts";
import { basename, dirname, join } from "../../deno_ral/path.ts";
import { formatResourcePath, pandocBinaryPath } from "../../core/resources.ts";
import { execProcess } from "../../core/process.ts";
import { parseHtml } from "../deno-dom.ts";
import { Element, HTMLDocument } from "deno_dom/deno-dom-wasm-noinit.ts";
import { esbuildCompile } from "../esbuild.ts";
import { asDataUrl } from "../data-url.ts";

const bundleModules = async (dom: HTMLDocument, workingDir: string) => {
const modules = dom.querySelectorAll("script[type='module']");
for (const module of modules) {
const src = (module as Element).getAttribute("src");
if (src) {
const srcName = join(workingDir, src);
const srcDir = dirname(srcName);
const jsSource = await esbuildCompile(
Deno.readTextFileSync(srcName),
srcDir,
[],
"esm",
);
(module as Element).setAttribute(
"src",
asDataUrl(jsSource!, "application/javascript"),
);
}
}
};

export const pandocIngestSelfContainedContent = async (
file: string,
Expand All @@ -23,9 +48,12 @@ export const pandocIngestSelfContainedContent = async (

// The raw html contents
const contents = Deno.readTextFileSync(file);
const dom = await parseHtml(contents);
await bundleModules(dom, workingDir);

const input: string[] = [];
input.push("````````{=html}");
input.push(contents);
input.push(dom.documentElement!.outerHTML);
input.push("````````");

// Run pandoc to suck in dependencies
Expand Down
2 changes: 2 additions & 0 deletions tests/docs/playwright/embed-resources/issue-11860/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
inner
/.quarto/
2 changes: 2 additions & 0 deletions tests/docs/playwright/embed-resources/issue-11860/hello.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const hello = 'world';
alert("We're here!");
1 change: 1 addition & 0 deletions tests/docs/playwright/embed-resources/issue-11860/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import { hello } from './hello.js';
11 changes: 11 additions & 0 deletions tests/docs/playwright/embed-resources/issue-11860/main.qmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
format:
html:
embed-resources: true
---

```{=html}
<script type="module" src="./main.js"></script>
```

## oh oh
14 changes: 13 additions & 1 deletion tests/integration/playwright-tests.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,27 @@ await initState();

// const promises = [];
const fileNames: string[] = [];
const extraOpts = [
{
pathSuffix: "docs/playwright/embed-resources/issue-11860/main.qmd",
options: ["--output-dir=inner"],
}
]

for (const { path: fileName } of globOutput) {
const input = fileName;
const options: string[] = [];
for (const extraOpt of extraOpts) {
if (fileName.endsWith(extraOpt.pathSuffix)) {
options.push(...extraOpt.options);
}
}

// sigh, we have a race condition somewhere in
// mediabag inspection if we don't wait all renders
// individually. This is very slow..
await execProcess({
cmd: [quartoDevCmd(), "render", input],
cmd: [quartoDevCmd(), "render", input, ...options],
});
fileNames.push(fileName);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { expect, Page, test } from "@playwright/test";

test("es6 modules to be bundled correctly in documents with embed-resources=true", async ({ page }) => {
const messages: string[] = [];
page.on('response', (response) => {
if (!response.ok()) {
messages.push(`[${response.status()}] ${response.url()}`);
}
});
page.on('pageerror', (error) => {
messages.push(`[${error.name}] ${error.message}`);
});
await page.goto('./embed-resources/issue-11860/inner/main.html');
expect(messages).toStrictEqual([]);
});

0 comments on commit 182adf7

Please sign in to comment.