Skip to content

Commit bef7b5c

Browse files
authored
feat: allow enabling darkmode via the dark class (#139)
* feat: allow enabling darkmode via the `dark` class * rebuild * fix ci
1 parent 70b1b9c commit bef7b5c

File tree

8 files changed

+127
-107
lines changed

8 files changed

+127
-107
lines changed

.github/workflows/ci.yml

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ jobs:
1919
steps:
2020
- uses: actions/checkout@v4
2121

22-
- uses: denoland/setup-deno@v1
22+
- uses: denoland/setup-deno@v2
2323

2424
- name: Run fmt
2525
run: |
@@ -34,9 +34,7 @@ jobs:
3434
deno task check:types
3535
3636
- name: Install Chromium
37-
run: deno run -A --unstable https://deno.land/x/puppeteer@16.2.0/install.ts
38-
env:
39-
PUPPETEER_PRODUCT: chrome
37+
run: deno run -A npm:puppeteer browsers install chrome
4038

4139
- name: Run tests
4240
run: |

README.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,12 @@ If you want to use the light or dark theme depending on the user's browser
7676
preference, set the following:
7777

7878
```html
79-
<div data-color-mode="auto" data-light-theme="light" data-dark-theme="dark" class="markdown-body">
79+
<div
80+
data-color-mode="auto"
81+
data-light-theme="light"
82+
data-dark-theme="dark"
83+
class="markdown-body"
84+
>
8085
... markdown body here ...
8186
</div>
8287
```

deno.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
"name": "@deno/gfm",
33
"version": "0.10.0",
44
"exports": "./mod.ts",
5+
"nodeModulesDir": "auto",
56
"imports": {
67
"emoji": "jsr:@denosaurs/emoji@^0.3.1",
78
"marked": "npm:marked@^12",
@@ -14,6 +15,7 @@
1415
"sanitize-html": "npm:sanitize-html@^2.13",
1516
"he": "npm:he@^1.2",
1617
"katex": "npm:katex@^0.16",
18+
"css": "npm:css@^3.0.0",
1719
"@std/assert": "jsr:@std/assert@^1.0"
1820
},
1921
"compilerOptions": {
@@ -27,13 +29,11 @@
2729
"ok": "deno fmt --check && deno lint && deno task check:types && deno task test",
2830
"report": "deno coverage cov_profile --html",
2931
"server": "deno run -A --watch=test/,mod.ts ./test/runTestServer.ts",
30-
"test": "deno test --allow-read --allow-env --allow-write --allow-run --allow-net"
32+
"test": "deno test --allow-sys --allow-read --allow-env --allow-write --allow-run --allow-net"
3133
},
3234
"fmt": {
3335
"exclude": [
34-
"./test/fixtures/alerts.md",
35-
"./test/fixtures/lineBreaks.md",
36-
"./test/fixtures/footnote.md",
36+
"./test/fixtures/",
3737
"./example/content.md"
3838
]
3939
}

style.ts

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

style/main.scss

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22
@import "@primer/css/color-modes/themes/dark.scss";
33
@import "@primer/css/markdown/index.scss";
44

5+
.dark {
6+
@include primer-colors-dark;
7+
}
8+
59
.markdown-body {
610
background-color: var(--color-canvas-default);
711
color: var(--color-fg-default);

style/patch.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import $ from "https://deno.land/x/dax@0.36.0/mod.ts";
2-
import css from "npm:css@3.0.0";
2+
import css from "css";
33

44
await $`rm -rf style/node_modules/@primer/primitives`;
55
await $`npm install`.cwd("./style");

test/server_test.ts

Lines changed: 108 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
import { assert, assertEquals } from "@std/assert";
22
import { browserTest } from "./test_utils.ts";
33

4-
Deno.test("basic md table with dollar signs", async () => {
4+
Deno.test({
5+
name: "basic md table with dollar signs",
6+
sanitizeResources: false,
7+
sanitizeOps: false,
8+
}, async () => {
59
await browserTest("basicMarkdownTable", async (page) => {
610
await page.waitForSelector("table", { timeout: 1000 });
711
const tableExists = await page.evaluate(() => {
@@ -78,103 +82,115 @@ Deno.test("basic md table with dollar signs", async () => {
7882
});
7983
});
8084

81-
Deno.test("footnote with style", async () => {
82-
await browserTest("footnotes", async (page) => {
83-
// 1. Test page jump on clicking footnote links
84-
const scrollPositionBefore = await page.evaluate(() => globalThis.scrollY);
85-
await page.click("#footnote-ref-1"); // click the first footnote link. note that we select by id, not href
86-
const scrollPositionAfter = await page.evaluate(() => globalThis.scrollY);
87-
assert(scrollPositionAfter > scrollPositionBefore);
85+
Deno.test(
86+
{ name: "footnote with style", sanitizeResources: false, sanitizeOps: false },
87+
async () => {
88+
await browserTest("footnotes", async (page) => {
89+
// 1. Test page jump on clicking footnote links
90+
const scrollPositionBefore = await page.evaluate(() =>
91+
globalThis.scrollY
92+
);
93+
await page.click("#footnote-ref-1"); // click the first footnote link. note that we select by id, not href
94+
const scrollPositionAfter = await page.evaluate(() => globalThis.scrollY);
95+
assert(scrollPositionAfter > scrollPositionBefore);
8896

89-
await page.click("#footnote-ref-bignote");
90-
const scrollPositionAfter2 = await page.evaluate(() => globalThis.scrollY);
91-
assert(scrollPositionAfter2 === scrollPositionAfter);
97+
await page.click("#footnote-ref-bignote");
98+
const scrollPositionAfter2 = await page.evaluate(() =>
99+
globalThis.scrollY
100+
);
101+
assert(scrollPositionAfter2 === scrollPositionAfter);
92102

93-
await page.click("#footnote-1 > p > a");
94-
const scrollPositionAfter3 = await page.evaluate(() => globalThis.scrollY);
95-
assert(scrollPositionAfter3 < scrollPositionAfter2);
96-
assert(scrollPositionAfter3 > scrollPositionBefore);
103+
await page.click("#footnote-1 > p > a");
104+
const scrollPositionAfter3 = await page.evaluate(() =>
105+
globalThis.scrollY
106+
);
107+
assert(scrollPositionAfter3 < scrollPositionAfter2);
108+
assert(scrollPositionAfter3 > scrollPositionBefore);
97109

98-
// 2. Verify footnote link styling
99-
const beforeContent = await page.evaluate(() => {
100-
const element = document.querySelector("#footnote-ref-1");
101-
if (element) {
102-
return globalThis.getComputedStyle(element, "::before").content;
103-
}
104-
return null;
105-
});
106-
const afterContent = await page.evaluate(() => {
107-
const element = document.querySelector("#footnote-ref-1");
108-
if (element) {
109-
return globalThis.getComputedStyle(element, "::after").content;
110-
}
111-
return null;
112-
});
113-
assertEquals(beforeContent, '"["');
114-
assertEquals(afterContent, '"]"');
110+
// 2. Verify footnote link styling
111+
const beforeContent = await page.evaluate(() => {
112+
const element = document.querySelector("#footnote-ref-1");
113+
if (element) {
114+
return globalThis.getComputedStyle(element, "::before").content;
115+
}
116+
return null;
117+
});
118+
const afterContent = await page.evaluate(() => {
119+
const element = document.querySelector("#footnote-ref-1");
120+
if (element) {
121+
return globalThis.getComputedStyle(element, "::after").content;
122+
}
123+
return null;
124+
});
125+
assertEquals(beforeContent, '"["');
126+
assertEquals(afterContent, '"]"');
115127

116-
// 3. Check Visibility of "Footnotes" H2
117-
const h2Style = await page.evaluate(() => {
118-
const element = document.querySelector("#footnote-label");
119-
if (element) {
120-
const computedStyle = globalThis.getComputedStyle(element);
121-
return {
122-
position: computedStyle.position,
123-
width: computedStyle.width,
124-
height: computedStyle.height,
125-
overflow: computedStyle.overflow,
126-
clip: computedStyle.clip,
127-
wordWrap: computedStyle.wordWrap,
128-
border: computedStyle.border,
129-
};
130-
}
131-
return null;
132-
});
133-
assert(h2Style);
134-
assertEquals(h2Style.position, "absolute");
135-
assertEquals(h2Style.width, "1px");
136-
assertEquals(h2Style.height, "1px");
137-
assertEquals(h2Style.overflow, "hidden");
138-
assertEquals(h2Style.clip, "rect(0px, 0px, 0px, 0px)");
139-
assertEquals(h2Style.wordWrap, "normal");
140-
assertEquals(h2Style.border, "");
128+
// 3. Check Visibility of "Footnotes" H2
129+
const h2Style = await page.evaluate(() => {
130+
const element = document.querySelector("#footnote-label");
131+
if (element) {
132+
const computedStyle = globalThis.getComputedStyle(element);
133+
return {
134+
position: computedStyle.position,
135+
width: computedStyle.width,
136+
height: computedStyle.height,
137+
overflow: computedStyle.overflow,
138+
clip: computedStyle.clip,
139+
wordWrap: computedStyle.wordWrap,
140+
border: computedStyle.border,
141+
};
142+
}
143+
return null;
144+
});
145+
assert(h2Style);
146+
assertEquals(h2Style.position, "absolute");
147+
assertEquals(h2Style.width, "1px");
148+
assertEquals(h2Style.height, "1px");
149+
assertEquals(h2Style.overflow, "hidden");
150+
assertEquals(h2Style.clip, "rect(0px, 0px, 0px, 0px)");
151+
assertEquals(h2Style.wordWrap, "normal");
152+
assertEquals(h2Style.border, "");
141153

142-
// 4. Verify blue box around the footnote after clicking
143-
await page.click("#footnote-ref-1");
144-
const footnoteStyle = await page.evaluate(() => {
145-
const element = document.querySelector("#footnote-1");
146-
if (element) {
147-
return globalThis.getComputedStyle(element)
148-
.outlineColor;
149-
}
150-
return null;
154+
// 4. Verify blue box around the footnote after clicking
155+
await page.click("#footnote-ref-1");
156+
const footnoteStyle = await page.evaluate(() => {
157+
const element = document.querySelector("#footnote-1");
158+
if (element) {
159+
return globalThis.getComputedStyle(element)
160+
.outlineColor;
161+
}
162+
return null;
163+
});
164+
assertEquals(footnoteStyle, "rgb(31, 35, 40)");
151165
});
152-
assertEquals(footnoteStyle, "rgb(31, 35, 40)");
153-
});
154-
});
166+
},
167+
);
155168

156-
Deno.test("yaml style", async () => {
157-
await browserTest("yaml", async (page) => {
158-
const nameStyle = await page.evaluate(() => {
159-
const element = document.querySelector(
160-
"body > main > div > pre > span:nth-child(1)", // doe in the first line
161-
);
162-
if (element) {
163-
return globalThis.getComputedStyle(element).color;
164-
}
165-
return null;
166-
});
167-
assertEquals(nameStyle, "rgb(207, 34, 46)");
169+
Deno.test(
170+
{ name: "yaml style", sanitizeResources: false, sanitizeOps: false },
171+
async () => {
172+
await browserTest("yaml", async (page) => {
173+
const nameStyle = await page.evaluate(() => {
174+
const element = document.querySelector(
175+
"body > main > div > pre > span:nth-child(1)", // doe in the first line
176+
);
177+
if (element) {
178+
return globalThis.getComputedStyle(element).color;
179+
}
180+
return null;
181+
});
182+
assertEquals(nameStyle, "rgb(207, 34, 46)");
168183

169-
const colonStyle = await page.evaluate(() => {
170-
const element = document.querySelector(
171-
"body > main > div > pre > span:nth-child(2)", // : in the first line
172-
);
173-
if (element) {
174-
return globalThis.getComputedStyle(element).color;
175-
}
176-
return null;
184+
const colonStyle = await page.evaluate(() => {
185+
const element = document.querySelector(
186+
"body > main > div > pre > span:nth-child(2)", // : in the first line
187+
);
188+
if (element) {
189+
return globalThis.getComputedStyle(element).color;
190+
}
191+
return null;
192+
});
193+
assertEquals(colonStyle, "rgb(102, 57, 186)");
177194
});
178-
assertEquals(colonStyle, "rgb(102, 57, 186)");
179-
});
180-
});
195+
},
196+
);

test/test_utils.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
1-
import {
2-
default as puppeteer,
3-
type Page,
4-
} from "https://deno.land/x/puppeteer@16.2.0/mod.ts";
1+
import { default as puppeteer, type Page } from "npm:puppeteer";
52
import { CSS, render, type RenderOptions } from "../mod.ts";
63

74
type TestCase = {

0 commit comments

Comments
 (0)