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
32 changes: 23 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,30 +97,44 @@ https://github.com/owner/repo/blob/main/src/index.ts#L1-L10

## ダークモード

ダークテーマ対応サイト向けに、GitHub Dark Default テーマ準拠の別バンドルを用意しています。
デフォルトの `git-code-embed.min.js` は `prefers-color-scheme` メディアクエリで OS のテーマ設定に自動追従します。
ライトモード固定・ダークモード固定のバンドルも用意しています。

```html
<script src="https://cdn.jsdelivr.net/gh/hirano00o/git-code-embed@v0/dist/git-code-embed-dark.min.js"></script>
```
| ファイル | 挙動 |
|---|---|
| `git-code-embed.min.js` | OS のダーク/ライト設定に自動追従(推奨) |
| `git-code-embed-light.min.js` | ライトモード固定 |
| `git-code-embed-dark.min.js` | ダークモード固定 |

### はてなブログ(ダークテーマ)での使い方
### はてなブログでの使い方

管理画面の **設定 → 詳細設定** の `<head>` 要素欄に、ダーク版の URL を貼り付けます。
管理画面の **設定 → 詳細設定** の `<head>` 要素欄に以下を貼り付けます。
OS テーマに自動追従させる場合はデフォルトの URL をそのまま使用してください。

```html
<!-- OS のダーク/ライト設定に自動追従(推奨) -->
<script src="https://cdn.jsdelivr.net/gh/hirano00o/git-code-embed@v0/dist/git-code-embed.min.js" defer></script>

<!-- ダークモード固定 -->
<script src="https://cdn.jsdelivr.net/gh/hirano00o/git-code-embed@v0/dist/git-code-embed-dark.min.js" defer></script>

<!-- ライトモード固定 -->
<script src="https://cdn.jsdelivr.net/gh/hirano00o/git-code-embed@v0/dist/git-code-embed-light.min.js" defer></script>
```

### ビルド

```bash
# ライトモード(デフォルト) → dist/git-code-embed.min.js
# オートテーマ(デフォルト、OS のダーク/ライト設定に自動追従) → dist/git-code-embed.min.js
npm run build

# ダークモード → dist/git-code-embed-dark.min.js
# ライトモード固定 → dist/git-code-embed-light.min.js
npm run build:light

# ダークモード固定 → dist/git-code-embed-dark.min.js
npm run build:dark

# 両方同時にビルド
# 全バリアント同時ビルド
npm run build:all
```

Expand Down
68 changes: 58 additions & 10 deletions dist/git-code-embed-dark.min.js

Large diffs are not rendered by default.

245 changes: 245 additions & 0 deletions dist/git-code-embed-light.min.js

Large diffs are not rendered by default.

68 changes: 58 additions & 10 deletions dist/git-code-embed.min.js

Large diffs are not rendered by default.

7 changes: 5 additions & 2 deletions esbuild.config.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import * as esbuild from "esbuild";

const dark = process.argv.includes("--dark");
const theme = dark ? "dark" : "light";
const auto = process.argv.includes("--auto");
const theme = dark ? "dark" : auto ? "auto" : "light";
const outfile = dark
? "dist/git-code-embed-dark.min.js"
: "dist/git-code-embed.min.js";
: auto
? "dist/git-code-embed.min.js"
: "dist/git-code-embed-light.min.js";

esbuild
.build({
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
{
"name": "git-code-embed",
"version": "0.1.0",
"version": "0.2.0",
"description": "Embed GitHub code snippets with syntax highlighting in blog posts",
"main": "dist/git-code-embed.min.js",
"scripts": {
"build": "tsx esbuild.config.ts",
"build": "tsx esbuild.config.ts --auto",
"build:light": "tsx esbuild.config.ts",
"build:dark": "tsx esbuild.config.ts --dark",
"build:all": "tsx esbuild.config.ts && tsx esbuild.config.ts --dark",
"build:all": "tsx esbuild.config.ts --auto && tsx esbuild.config.ts && tsx esbuild.config.ts --dark",
"test": "vitest run",
"test:watch": "vitest"
},
Expand Down
13 changes: 12 additions & 1 deletion src/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export const LIGHT_COLORS = `
--gce-lineno-color: #6e7781;
--gce-lineno-bg: #f6f8fa;
--gce-code-bg: #ffffff;
--gce-code-text: #24292f;
--gce-scrollbar-thumb: #afb8c1;
}

Expand Down Expand Up @@ -62,6 +63,7 @@ export const DARK_COLORS = `
--gce-lineno-color: #8b949e;
--gce-lineno-bg: #161b22;
--gce-code-bg: #0d1117;
--gce-code-text: #e6edf3;
--gce-scrollbar-thumb: #484f58;
}

Expand Down Expand Up @@ -96,7 +98,15 @@ export const DARK_COLORS = `
.gce-container .hljs-doctag { color: #79c0ff; }
`;

const THEME_COLORS = __THEME__ === "dark" ? DARK_COLORS : LIGHT_COLORS;
export function buildThemeCSS(theme: string): string {
if (theme === "dark") return DARK_COLORS;
if (theme === "auto") {
return `${LIGHT_COLORS}\n@media (prefers-color-scheme: dark) {\n${DARK_COLORS}\n}`;
}
return LIGHT_COLORS;
}

const THEME_COLORS = buildThemeCSS(__THEME__);

export const CSS = `
:root {
Expand Down Expand Up @@ -219,6 +229,7 @@ ${THEME_COLORS}
.gce-container .gce-table td.gce-code {
width: 100%;
padding: 0 16px;
color: var(--gce-code-text);
line-height: var(--gce-line-height);
white-space: pre;
vertical-align: top;
Expand Down
57 changes: 56 additions & 1 deletion test/styles.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest";
import { CSS, DARK_COLORS, LIGHT_COLORS } from "../src/styles";
import { buildThemeCSS, CSS, DARK_COLORS, LIGHT_COLORS } from "../src/styles";

describe("LIGHT_COLORS", () => {
it("ライトテーマの背景色を含む", () => {
Expand Down Expand Up @@ -45,6 +45,10 @@ describe("LIGHT_COLORS", () => {
expect(LIGHT_COLORS).toContain("color: #0550ae");
});

it("ライトテーマの基本テキスト色を含む", () => {
expect(LIGHT_COLORS).toContain("--gce-code-text: #24292f");
});

it("ライトテーマのスクロールバー thumb 色を含む", () => {
expect(LIGHT_COLORS).toContain("--gce-scrollbar-thumb: #afb8c1");
});
Expand Down Expand Up @@ -94,11 +98,56 @@ describe("DARK_COLORS", () => {
expect(DARK_COLORS).toContain("color: #79c0ff");
});

it("ダークテーマの基本テキスト色を含む", () => {
expect(DARK_COLORS).toContain("--gce-code-text: #e6edf3");
});

it("ダークテーマのスクロールバー thumb 色を含む", () => {
expect(DARK_COLORS).toContain("--gce-scrollbar-thumb: #484f58");
});
});

describe("buildThemeCSS", () => {
it('"light" → LIGHT_COLORS のみ返す', () => {
expect(buildThemeCSS("light")).toBe(LIGHT_COLORS);
});

it('"dark" → DARK_COLORS のみ返す', () => {
expect(buildThemeCSS("dark")).toBe(DARK_COLORS);
});

it('"auto" → LIGHT_COLORS を含む', () => {
expect(buildThemeCSS("auto")).toContain(LIGHT_COLORS);
});

it('"auto" → DARK_COLORS が @media (prefers-color-scheme: dark) で囲まれている', () => {
const css = buildThemeCSS("auto");
const mediaStart = css.indexOf("@media (prefers-color-scheme: dark)");
expect(mediaStart).toBeGreaterThan(-1);
// DARK_COLORS はメディアクエリブロック内に含まれる
const afterMedia = css.slice(mediaStart);
expect(afterMedia).toContain(DARK_COLORS);
});

it('"auto" → ダーク側の --gce-code-text が @media ブロック内に現れる', () => {
const css = buildThemeCSS("auto");
const mediaStart = css.indexOf("@media (prefers-color-scheme: dark)");
expect(mediaStart).toBeGreaterThan(-1);
const afterMedia = css.slice(mediaStart);
expect(afterMedia).toContain("--gce-code-text: #e6edf3");
});

it('"auto" → LIGHT_COLORS が DARK_COLORS より前に現れる', () => {
const css = buildThemeCSS("auto");
expect(css.indexOf(LIGHT_COLORS)).toBeLessThan(css.indexOf(DARK_COLORS));
});

it('不明な値 → LIGHT_COLORS にフォールバック', () => {
expect(buildThemeCSS("unknown")).toBe(LIGHT_COLORS);
expect(buildThemeCSS("")).toBe(LIGHT_COLORS);
});
});

describe("CSS (テーマ: light)", () => {
it("テーマ非依存の font-family 変数を含む", () => {
expect(CSS).toContain("--gce-font-family:");
Expand All @@ -120,6 +169,12 @@ describe("CSS (テーマ: light)", () => {
expect(CSS).toContain("display: flex");
});

it("td.gce-code に基本テキスト色の CSS 変数を含む", () => {
const match = CSS.match(/\.gce-container \.gce-table td\.gce-code \{([^}]*)\}/);
expect(match).not.toBeNull();
expect(match![1]).toContain("color: var(--gce-code-text)");
});

it("scrollbar-color サポートブラウザ向けの @supports ブロックを含む", () => {
expect(CSS).toContain("@supports (scrollbar-color: auto)");
expect(CSS).toContain("scrollbar-color: var(--gce-scrollbar-thumb) var(--gce-code-bg)");
Expand Down