marksites 0.2.6 → 0.2.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/dist/conversion/rendering.d.ts +1 -1
- package/dist/conversion/rendering.js +2 -2
- package/dist/features/annotations/index.d.ts +1 -0
- package/dist/features/annotations/index.js +20 -6
- package/dist/features/document-diff/index.d.ts +0 -1
- package/dist/features/document-diff/index.js +2 -9
- package/dist/features/document-view/index.d.ts +7 -0
- package/dist/features/document-view/index.js +33 -0
- package/dist/features/header/index.js +2 -2
- package/dist/features/table-resizer/index.d.ts +5 -0
- package/dist/features/table-resizer/index.js +14 -0
- package/dist/features/table-sorter/index.d.ts +5 -0
- package/dist/features/table-sorter/index.js +18 -0
- package/dist/markdown-to-html.js +14 -1
- package/dist/server/html-security.js +7 -3
- package/dist/template/document.d.ts +2 -0
- package/dist/template/document.js +6 -0
- package/dist/template/styles.d.ts +1 -1
- package/dist/template/styles.js +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -46,6 +46,8 @@ const html = markdownToHtml(markdown, {
|
|
|
46
46
|
言語名を指定したコードブロックは、`highlight.js` によって自動的にハイライトされます。
|
|
47
47
|
コードブロックには、コードをクリップボードへコピーするボタンと、長い行の折り返しを切り替えるボタンも表示されます。
|
|
48
48
|
|
|
49
|
+
Markdownの表では、列境界をドラッグして列幅を変更できます。見出しをクリックすると、その列を昇順、降順、元の順序へ切り替えられます。列幅変更とソートはマウス、タッチ、キーボードで操作でき、すべて生成HTML内のJavaScriptだけで動作します。
|
|
50
|
+
|
|
49
51
|
````markdown
|
|
50
52
|
```typescript
|
|
51
53
|
const greeting: string = "Hello";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Token } from "marked";
|
|
2
2
|
export declare const GENERATOR_VERSION: string;
|
|
3
|
-
export declare const OUTPUT_COMPATIBILITY_VERSION =
|
|
3
|
+
export declare const OUTPUT_COMPATIBILITY_VERSION = 9;
|
|
4
4
|
export declare function contentHash(value: string | Buffer): string;
|
|
5
5
|
export declare function rewriteMarkdownLinks(token: Token): void;
|
|
6
6
|
export declare function renderFingerprint(): string;
|
|
@@ -4,7 +4,7 @@ import { emptyAnnotationDocument } from "../annotations/model.js";
|
|
|
4
4
|
import { renderMarkdown } from "../markdown-to-html.js";
|
|
5
5
|
const packageMetadata = JSON.parse(readFileSync(new URL("../../package.json", import.meta.url), "utf8"));
|
|
6
6
|
export const GENERATOR_VERSION = packageMetadata.version;
|
|
7
|
-
export const OUTPUT_COMPATIBILITY_VERSION =
|
|
7
|
+
export const OUTPUT_COMPATIBILITY_VERSION = 9;
|
|
8
8
|
export function contentHash(value) {
|
|
9
9
|
return `sha256:${createHash("sha256").update(value).digest("hex")}`;
|
|
10
10
|
}
|
|
@@ -21,7 +21,7 @@ export function rewriteMarkdownLinks(token) {
|
|
|
21
21
|
token.href = rewriteMarkdownHref(token.href);
|
|
22
22
|
}
|
|
23
23
|
export function renderFingerprint() {
|
|
24
|
-
const representativeHtml = renderMarkdown("## Heading\n\n[Document](guide.md)\n\n\n\n```js\nconst value = 1;\n```\n", {
|
|
24
|
+
const representativeHtml = renderMarkdown("## Heading\n\n[Document](guide.md)\n\n\n\n| Name | Value |\n| --- | --- |\n| one | 1 |\n\n```js\nconst value = 1;\n```\n", {
|
|
25
25
|
title: "marksites-render-fingerprint",
|
|
26
26
|
modifiedAt: "2026-01-01T00:00:00.000Z",
|
|
27
27
|
fileTree: {
|
|
@@ -8,7 +8,14 @@ function safeJson(value) {
|
|
|
8
8
|
}
|
|
9
9
|
export function createAnnotationsFeature(data) {
|
|
10
10
|
if (!data)
|
|
11
|
-
return {
|
|
11
|
+
return {
|
|
12
|
+
markup: "",
|
|
13
|
+
documentControl: "",
|
|
14
|
+
panel: "",
|
|
15
|
+
styles: "",
|
|
16
|
+
script: "",
|
|
17
|
+
count: 0,
|
|
18
|
+
};
|
|
12
19
|
const markup = `<script id="marksites-annotations-data" type="application/json">${safeJson(data)}</script>
|
|
13
20
|
<div class="selection-actions" id="selection-actions" hidden role="toolbar" aria-label="選択範囲の操作">
|
|
14
21
|
<button type="button" data-selection-action="copy" data-tooltip="選択範囲をコピー">${renderCopyIcon()}<span data-copy-label>コピー</span></button>
|
|
@@ -23,8 +30,8 @@ export function createAnnotationsFeature(data) {
|
|
|
23
30
|
<label><span>置換後の文字列</span><input type="text" name="replacement" autocomplete="off"></label>
|
|
24
31
|
<p class="text-replace-error" data-replacement-error role="alert" hidden></p>
|
|
25
32
|
<div class="text-replace-alert-actions"><button type="submit">置換</button><button type="button" data-cancel-replace>キャンセル</button></div>
|
|
26
|
-
</form
|
|
27
|
-
|
|
33
|
+
</form>`;
|
|
34
|
+
const documentControl = `<button type="button" class="document-content-action document-replacement-menu" data-replacement-menu aria-expanded="false" title="この文書の文字列置換を管理" aria-label="この文書の文字列置換を管理">${renderEditIcon()}<span>置換</span><span class="text-replacement-count" data-replacement-count hidden>0</span></button>`;
|
|
28
35
|
const panel = `<section class="annotations-panel sidebar-panel" id="sidebar-panel-comments" role="tabpanel" aria-labelledby="sidebar-tab-comments" hidden>
|
|
29
36
|
<div class="annotations-actions"><button type="button" class="annotation-action-add" data-add-document-comment data-tooltip="文書全体にコメントを追加" disabled title="コメントを追加するにはmarksites serveを起動してください">${renderAddIcon()}<span>追加</span></button><button type="button" class="annotation-action-copy" data-copy-all-comments data-tooltip="有効なコメントだけをコピー" aria-label="有効なコメントをコピー">${renderCopyIcon()}<span data-copy-comments-label>コピー</span></button></div>
|
|
30
37
|
<p class="annotations-status" id="annotations-status" role="status"></p>
|
|
@@ -38,7 +45,7 @@ export function createAnnotationsFeature(data) {
|
|
|
38
45
|
.selection-actions button{display:inline-flex;align-items:center;justify-content:center;gap:5px;border:0;border-radius:4px;padding:5px 9px;color:#fff;background:transparent;font:12px/1 system-ui;cursor:pointer}
|
|
39
46
|
.selection-actions button:hover:not(:disabled){background:#57606a}.selection-actions button:disabled{color:#8c959f;cursor:not-allowed}
|
|
40
47
|
.selection-actions [data-tooltip],.annotations-panel [data-tooltip]{position:relative}.selection-actions [data-tooltip]::after,.annotations-panel [data-tooltip]::after{position:absolute;z-index:30;top:calc(100% + 6px);right:0;width:max-content;max-width:220px;padding:5px 7px;color:#fff;font-size:.6875rem;font-weight:400;line-height:1.3;white-space:normal;background:#24292f;border-radius:4px;box-shadow:0 3px 10px rgba(31,35,40,.2);content:attr(data-tooltip);opacity:0;pointer-events:none;transform:translateY(-2px);transition:opacity 120ms ease,transform 120ms ease}.selection-actions [data-tooltip]:hover::after,.selection-actions [data-tooltip]:focus-visible::after,.annotations-panel [data-tooltip]:hover::after,.annotations-panel [data-tooltip]:focus-visible::after{opacity:1;transform:translateY(0)}
|
|
41
|
-
.
|
|
48
|
+
.document-replacement-menu>span:not(.text-replacement-count){line-height:16px}.text-replace-alert{position:fixed;z-index:45;top:50%;left:50%;box-sizing:border-box;display:grid;width:min(440px,calc(100vw - 24px));max-height:calc(100vh - 24px);grid-template-columns:1fr 1fr;gap:10px;padding:12px;overflow-y:auto;color:var(--fgColor-default,#1f2328);background:var(--bgColor-default,#fff);border:1px solid var(--borderColor-default,#d0d7de);border-radius:6px;box-shadow:0 8px 24px rgba(31,35,40,.2);transform:translate(-50%,-50%)}.text-replace-alert-heading,.text-replacement-list{grid-column:1/-1}.text-replace-alert-heading{display:flex;align-items:center;justify-content:space-between}.text-replace-alert label{display:block;min-width:0}.text-replace-alert label span{display:block;margin-bottom:5px;color:var(--fgColor-muted,#59636e);font-size:.75rem;font-weight:600}.text-replace-alert input{box-sizing:border-box;width:100%;height:34px;padding:5px 8px;color:var(--fgColor-default,#1f2328);font:inherit;background:var(--bgColor-default,#fff);border:1px solid var(--borderColor-default,#d0d7de);border-radius:6px}.text-replace-alert input:focus{border-color:var(--borderColor-accent-emphasis,#0969da);outline:2px solid var(--bgColor-accent-muted,#ddf4ff)}.text-replace-error{grid-column:1/-1;margin:0;color:var(--fgColor-danger,#d1242f);font-size:.75rem}.text-replace-error[hidden]{display:none}.text-replace-alert-actions{display:flex;grid-column:1/-1;justify-content:flex-end;gap:6px}.text-replace-alert button{height:34px;padding:0 10px;color:var(--fgColor-default,#1f2328);font:inherit;font-size:.8125rem;font-weight:600;background:var(--button-default-bgColor-rest,#f6f8fa);border:1px solid var(--borderColor-default,#d0d7de);border-radius:6px;cursor:pointer}.text-replace-alert button[type=submit]{color:#fff;background:var(--button-primary-bgColor-rest,#1f883d);border-color:transparent}.text-replace-alert .text-replace-alert-heading button{display:inline-flex;width:28px;height:28px;align-items:center;justify-content:center;padding:0;color:var(--fgColor-muted,#59636e);background:transparent;border:0;border-radius:4px}.text-replace-alert .text-replace-alert-heading button:hover{color:var(--fgColor-default,#1f2328);background:var(--button-default-bgColor-hover,#eaeef2)}.text-replace-alert .text-replace-alert-heading button:focus-visible{color:var(--fgColor-default,#1f2328);background:var(--button-default-bgColor-hover,#eaeef2);outline:2px solid var(--focus-outlineColor,#0969da);outline-offset:1px}.text-replace-alert-heading button svg{width:16px;height:16px;fill:none;stroke:currentColor;stroke-width:1.5;stroke-linecap:round}.text-replacement-list:empty{display:none}.text-replacement-rule{display:grid;grid-template-columns:minmax(0,1fr) auto minmax(0,1fr) auto;align-items:center;gap:8px;padding:8px 0;border-bottom:1px solid var(--borderColor-muted,#d8dee4);font-size:.75rem}.text-replacement-rule code{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.text-replacement-rule button{height:28px;padding:0 8px}.text-replacement{padding:1px 2px;background:var(--bgColor-accent-muted,#ddf4ff);border:1px solid var(--borderColor-accent-emphasis,#0969da);border-radius:3px;box-decoration-break:clone;-webkit-box-decoration-break:clone}.text-replacement-count{display:inline-flex;min-width:16px;height:16px;align-items:center;justify-content:center;margin-left:3px;padding:0 3px;color:#fff;font-size:.6875rem;line-height:16px;background:var(--fgColor-accent,#0969da);border-radius:999px}
|
|
42
49
|
.text-replace-alert:not([hidden]){box-shadow:0 0 0 100vmax rgba(31,35,40,.18),0 8px 24px rgba(31,35,40,.2)}
|
|
43
50
|
.annotations-panel{color:var(--fgColor-default,#1f2328)}
|
|
44
51
|
.annotations-actions{position:sticky;z-index:1;top:-12px;display:flex;gap:8px;margin:-12px -12px 0;padding:10px 12px;background:var(--bgColor-default,#fff);border-bottom:1px solid var(--borderColor-muted,#d8dee4)}.annotations-panel button{padding:6px 10px;color:var(--fgColor-default,#1f2328);font:inherit;font-size:.8125rem;font-weight:600;background:var(--button-default-bgColor-rest,#f6f8fa);border:1px solid var(--borderColor-default,#d0d7de);border-radius:6px;cursor:pointer}.annotations-panel button:hover:not(:disabled){background:var(--button-default-bgColor-hover,#eaeef2)}.annotations-panel button:focus-visible{outline:2px solid var(--focus-outlineColor,#0969da);outline-offset:2px}.annotations-panel button:disabled{color:var(--fgColor-muted,#818b98);cursor:not-allowed}.annotations-actions button{display:inline-flex;min-width:0;flex:1;align-items:center;justify-content:center;gap:5px}.annotations-panel .annotation-action-add:not(:disabled){color:#fff;background:var(--button-primary-bgColor-rest,#1f883d);border-color:var(--button-primary-borderColor-rest,#1f232826)}.annotations-panel .annotation-action-add:hover:not(:disabled){background:var(--button-primary-bgColor-hover,#1a7f37)}.annotations-panel .annotation-action-copy{color:var(--fgColor-muted,#59636e);background:transparent;border-color:var(--borderColor-muted,#d8dee4)}
|
|
@@ -53,7 +60,7 @@ export function createAnnotationsFeature(data) {
|
|
|
53
60
|
const script = `<script>(()=>{
|
|
54
61
|
const dataElement=document.getElementById('marksites-annotations-data');if(!dataElement)return;
|
|
55
62
|
let state=JSON.parse(dataElement.textContent||'{}'),editable=false,pendingSelection=null,editingId=null,replacementSequence=0,replacementRules=[];
|
|
56
|
-
const content=document.querySelector('.markdown-content'),toolbar=document.getElementById('selection-actions'),replaceAlert=document.getElementById('text-replace-alert'),replacementError=document.querySelector('[data-replacement-error]'),replacementMenu=document.querySelector('[data-replacement-menu]'),replacementList=document.querySelector('[data-replacement-list]'),addDocumentComment=document.querySelector('[data-add-document-comment]'),copyAllComments=document.querySelector('[data-copy-all-comments]'),list=document.getElementById('annotations-list'),empty=document.getElementById('annotations-empty'),count=document.getElementById('annotation-count'),panelStatus=document.getElementById('annotations-status'),form=document.getElementById('annotation-form'),formHome=document.createComment('annotation-form-home');form.before(formHome);
|
|
63
|
+
const content=document.querySelector('.markdown-content'),toolbar=document.getElementById('selection-actions'),replaceAlert=document.getElementById('text-replace-alert'),replacementError=document.querySelector('[data-replacement-error]'),replacementMenu=document.querySelector('[data-replacement-menu]'),replacementList=document.querySelector('[data-replacement-list]'),addDocumentComment=document.querySelector('[data-add-document-comment]'),copyAllComments=document.querySelector('[data-copy-all-comments]'),list=document.getElementById('annotations-list'),empty=document.getElementById('annotations-empty'),count=document.getElementById('annotation-count'),panelStatus=document.getElementById('annotations-status'),form=document.getElementById('annotation-form'),formHome=document.createComment('annotation-form-home');form.before(formHome);
|
|
57
64
|
const excluded='button,textarea,input,.selection-actions,.annotations-panel,.file-tree,.table-of-contents,.code-block-actions';
|
|
58
65
|
const groupParameter='comments',groupDefinitions=[['comments',''],['archived','アーカイブ']],validGroups=new Set(['archived']),openGroups=new Set((new URL(location.href).searchParams.get(groupParameter)||'').split(',').filter(key=>validGroups.has(key)));
|
|
59
66
|
function syncGroupState(){const updateUrl=url=>{url.searchParams.delete(groupParameter);if(openGroups.size)url.searchParams.set(groupParameter,groupDefinitions.map(([key])=>key).filter(key=>openGroups.has(key)).join(','));return url};history.replaceState(null,'',updateUrl(new URL(location.href)));for(const link of document.querySelectorAll('a[href]')){const raw=link.getAttribute('href');if(!raw||raw.startsWith('#'))continue;const url=new URL(raw,location.href);if(url.protocol===location.protocol&&url.host===location.host&&url.pathname.endsWith('.html'))link.href=updateUrl(url).href}}
|
|
@@ -95,5 +102,12 @@ async function mutate(method,path,body){body.document=state.document;const formS
|
|
|
95
102
|
async function connect(){if(location.protocol==='file:')return;try{const controller=new AbortController();setTimeout(()=>controller.abort(),1500);const response=await fetch('/_marksites/api/v1/runtime',{cache:'no-store',signal:controller.signal});const runtime=await response.json();if(runtime.data&&runtime.data.service==='marksites'&&runtime.data.apiVersion===1&&runtime.data.projectId&&runtime.data.capabilities.includes('annotations:write')){editable=true;const selectionComment=toolbar.querySelector('[data-selection-action=comment]');selectionComment.disabled=false;selectionComment.title='選択範囲にコメントを追加';addDocumentComment.disabled=false;addDocumentComment.title='文書全体にコメントを追加';const latest=await fetch('/_marksites/api/v1/annotations?document='+encodeURIComponent(state.document),{cache:'no-store'}).then(r=>r.json());if(latest.data)state=latest.data;render()}}catch{}}
|
|
96
103
|
render();syncGroupState();connect();
|
|
97
104
|
})()</script>`;
|
|
98
|
-
return {
|
|
105
|
+
return {
|
|
106
|
+
markup,
|
|
107
|
+
documentControl,
|
|
108
|
+
panel,
|
|
109
|
+
styles,
|
|
110
|
+
script,
|
|
111
|
+
count: countActiveAnnotations(data),
|
|
112
|
+
};
|
|
99
113
|
}
|
|
@@ -3,7 +3,6 @@ export interface DocumentDiffFeature {
|
|
|
3
3
|
content: string;
|
|
4
4
|
control: string;
|
|
5
5
|
styles: string;
|
|
6
|
-
script: string;
|
|
7
6
|
hasChanges: boolean;
|
|
8
7
|
}
|
|
9
8
|
export declare function createDocumentDiffFeature(current: string, previous: string | undefined, markedOptions?: Omit<MarkedOptions, "async" | "renderer">): DocumentDiffFeature;
|
|
@@ -403,14 +403,7 @@ export function createDocumentDiffFeature(current, previous, markedOptions = {})
|
|
|
403
403
|
const styles = `
|
|
404
404
|
body.markdown-body[data-theme="dark"]{--diff-insert-bg:#58a6ff1a;--diff-delete-bg:#ff7b7226;--diff-delete-fg:#ff938a}body.markdown-body[data-theme="light"]{--diff-insert-bg:#0969da12;--diff-delete-bg:#cf222e18;--diff-delete-fg:#b4232c}
|
|
405
405
|
.document-diff-structural-insert{background:var(--diff-insert-bg,#0969da12);box-shadow:inset 3px 0 var(--fgColor-accent,#0969da)}.document-diff-structural-delete{color:var(--diff-delete-fg,#b4232c);background:var(--diff-delete-bg,#cf222e18);text-decoration:line-through;text-decoration-thickness:2px}.document-diff-code code>span{display:block;min-height:1.5em;white-space:pre-wrap}.document-diff-link-target{margin-inline-start:2px;color:var(--fgColor-muted,#59636e);font-size:.875em;overflow-wrap:anywhere}.document-diff-link-delete{pointer-events:none}
|
|
406
|
-
.document-diff-content{
|
|
406
|
+
.document-diff-content{box-sizing:border-box;min-width:0;margin-bottom:72px;padding:clamp(28px,3vw,52px);color:var(--fgColor-default,#1f2328);background:var(--bgColor-default,#fff);border:1px solid var(--borderColor-muted,#d8dee4);border-radius:8px;box-shadow:0 1px 2px rgba(31,35,40,.04)}.document-diff-content[hidden]{display:none}.document-diff-block{position:relative;margin:0 -12px;padding:1px 12px 1px 22px;border-left:2px solid var(--fgColor-muted,#59636e)}.document-diff-block::before{position:absolute;top:3px;left:7px;font-weight:700;line-height:1;content:""}.document-diff-block.document-diff-insert{background:var(--diff-insert-bg,#0969da12);border-left-style:solid;border-left-color:var(--fgColor-accent,#0969da)}.document-diff-block.document-diff-insert::before{color:var(--fgColor-accent,#0969da);content:"+"}.document-diff-block.document-diff-delete{color:var(--diff-delete-fg,#b4232c);background:var(--diff-delete-bg,#cf222e18);border-left-color:var(--diff-delete-fg,#b4232c);border-left-style:dashed;opacity:.9}.document-diff-block.document-diff-delete::before{color:var(--diff-delete-fg,#b4232c);content:"−"}.document-diff-block.document-diff-delete :is(a,button,input,select,textarea){pointer-events:none}.document-diff-inline-insert,.document-diff-inline-delete{padding:1px 2px;border-radius:2px;box-decoration-break:clone;-webkit-box-decoration-break:clone}.document-diff-inline-insert{color:var(--fgColor-default,#1f2328);background:var(--diff-insert-bg,#0969da12);text-decoration-line:underline;text-decoration-style:double;text-decoration-color:var(--fgColor-accent,#0969da);text-underline-offset:3px}.document-diff-inline-delete{color:var(--diff-delete-fg,#b4232c);background:var(--diff-delete-bg,#cf222e18);text-decoration:line-through;text-decoration-thickness:2px}.document-diff-toggle[aria-pressed="true"]{color:var(--fgColor-accent,#0969da);background:var(--bgColor-accent-muted,#ddf4ff)}.document-diff-toggle:disabled{color:var(--fgColor-muted,#59636e);opacity:.45;cursor:not-allowed}.document-diff-toggle svg[hidden]{display:none}@media(max-width:900px){.document-diff-content{margin-bottom:32px}}@media(max-width:600px){.document-diff-content{padding:24px 20px;border-radius:6px}}
|
|
407
407
|
`;
|
|
408
|
-
|
|
409
|
-
const parameter='document-view',button=document.querySelector('[data-document-diff-toggle]'),current=document.querySelector('.markdown-content'),diff=document.querySelector('.document-diff-content'),available=${hasChanges};
|
|
410
|
-
const update=url=>{if(document.body.dataset.documentView==='diff'||(!available&&new URL(location.href).searchParams.get(parameter)==='diff'))url.searchParams.set(parameter,'diff');else url.searchParams.delete(parameter);return url};
|
|
411
|
-
function syncLinks(){for(const link of document.querySelectorAll('a[href]')){const raw=link.getAttribute('href');if(!raw||raw.startsWith('#'))continue;const url=new URL(raw,location.href);if(url.protocol===location.protocol&&url.host===location.host&&url.pathname.endsWith('.html'))link.href=update(url).href}}
|
|
412
|
-
function apply(view,write=true){const showDiff=available&&view==='diff';document.body.dataset.documentView=showDiff?'diff':'current';current.hidden=showDiff;diff.hidden=!showDiff;button.setAttribute('aria-pressed',String(showDiff));button.querySelector('[data-document-diff-icon]').hidden=showDiff;button.querySelector('[data-document-current-icon]').hidden=!showDiff;const label=available?(showDiff?'最新版を表示':'差分を表示'):'前回からの変更はありません';button.setAttribute('aria-label',label);button.title=label;if(write)history.replaceState(null,'',update(new URL(location.href)));syncLinks();window.marksitesApplyLanguage?.()}
|
|
413
|
-
apply(new URL(location.href).searchParams.get(parameter)==='diff',available);if(available)button.addEventListener('click',()=>apply(document.body.dataset.documentView==='diff'?'current':'diff'));
|
|
414
|
-
})()</script>`;
|
|
415
|
-
return { content, control, styles, script, hasChanges };
|
|
408
|
+
return { content, control, styles, hasChanges };
|
|
416
409
|
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { escapeHtml } from "../../utils/html.js";
|
|
2
|
+
function renderSourceLines(markdown) {
|
|
3
|
+
const lines = markdown.split("\n");
|
|
4
|
+
if (lines.length > 1 && lines.at(-1) === "")
|
|
5
|
+
lines.pop();
|
|
6
|
+
return lines
|
|
7
|
+
.map((line) => `<span class="markdown-source-line">${escapeHtml(line.replace(/\r$/, ""))}</span>`)
|
|
8
|
+
.join("");
|
|
9
|
+
}
|
|
10
|
+
export function createDocumentViewFeature(markdown, hasDiff) {
|
|
11
|
+
const control = `<button type="button" class="document-content-action document-preview-toggle" data-document-preview-toggle aria-label="Previewを表示" title="Previewを表示" aria-pressed="true"><span>Preview</span></button>
|
|
12
|
+
<button type="button" class="document-content-action document-source-toggle" data-document-source-toggle aria-label="コードを表示" title="コードを表示" aria-pressed="false"><span>コード</span></button>`;
|
|
13
|
+
const content = `<main class="markdown-source-content" aria-label="Markdown原文" hidden><pre><code>${renderSourceLines(markdown)}</code></pre></main>`;
|
|
14
|
+
const styles = `
|
|
15
|
+
.document-content{position:relative;grid-area:content;min-width:0}.document-content-actions{display:flex;min-height:44px;align-items:center;justify-content:flex-start;gap:4px;margin-bottom:12px;padding:0 4px;border-bottom:1px solid var(--borderColor-muted,#d8dee4)}.document-content-action{position:relative;display:inline-flex;height:36px;align-items:center;justify-content:center;gap:6px;padding:0 10px;color:var(--fgColor-muted,#59636e);font:inherit;font-size:.75rem;font-weight:600;background:transparent;border:0;border-radius:6px 6px 0 0;cursor:pointer}.document-content-action:hover:not(:disabled){color:var(--fgColor-default,#1f2328);background:var(--button-default-bgColor-hover,#eaeef2)}.document-content-action:focus-visible{outline:2px solid var(--focus-outlineColor,#0969da);outline-offset:-2px}.document-content-action>span{line-height:16px}.document-content-action[aria-pressed="true"]{color:var(--fgColor-default,#1f2328)}.document-content-action[aria-pressed="true"]::after{position:absolute;right:8px;bottom:-5px;left:8px;height:2px;background:var(--borderColor-accent-emphasis,#0969da);content:""}.document-content-action:disabled{color:var(--fgColor-muted,#59636e);opacity:.45;cursor:not-allowed}
|
|
16
|
+
.markdown-source-content{box-sizing:border-box;min-width:0;margin-bottom:72px;padding:8px 0 24px;color:var(--fgColor-default,#1f2328);background:transparent;border:0;border-radius:0;box-shadow:none}.markdown-source-content[hidden]{display:none}.markdown-source-content pre{margin:0;padding:8px 0;overflow:auto;color:var(--codeBlock-fgColor,#24292f);background:transparent;border:0;border-radius:0;counter-reset:markdown-source-line}.markdown-source-content code{display:block;min-width:max-content;padding:0;color:inherit;background:transparent;white-space:pre;font:12px/1.5 ui-monospace,SFMono-Regular,SF Mono,Menlo,Consolas,monospace}.markdown-source-line{position:relative;display:block;min-height:1.5em;padding:0 20px 0 64px}.markdown-source-line::before{position:absolute;top:0;bottom:0;left:0;box-sizing:border-box;width:48px;padding-right:12px;color:var(--fgColor-muted,#59636e);border-right:1px solid var(--borderColor-muted,#d8dee4);content:counter(markdown-source-line);counter-increment:markdown-source-line;text-align:right;user-select:none}
|
|
17
|
+
@media(max-width:900px){.markdown-source-content{margin-bottom:32px}}@media(max-width:600px){.document-content-actions{overflow-x:auto}.markdown-source-line{padding-right:12px;padding-left:52px}.markdown-source-line::before{width:40px;padding-right:9px}}
|
|
18
|
+
.document-content{box-sizing:border-box;margin-bottom:72px;background:var(--bgColor-default,#fff);border:1px solid var(--borderColor-muted,#d8dee4);border-radius:8px;box-shadow:0 1px 2px rgba(31,35,40,.04);overflow:hidden}.document-content-actions{margin-bottom:0}.document-content>.markdown-content,.document-content>.document-diff-content{margin:0;border:0;border-radius:0;box-shadow:none}.document-content>.markdown-source-content{margin:0;padding-top:20px}@media(max-width:900px){.document-content{margin-bottom:32px}.document-content>.markdown-source-content{margin-bottom:0}}@media(max-width:600px){.document-content{border-radius:6px}.document-content>.markdown-content,.document-content>.document-diff-content{border-radius:0}}
|
|
19
|
+
.document-content-action{border-radius:6px}.document-replacement-menu{margin-left:auto}.document-content>.markdown-source-content{padding-top:0}.markdown-source-content pre{padding-top:0}.markdown-source-line::before{position:sticky;top:auto;bottom:auto;left:0;display:inline-block;height:1.5em;margin-left:-64px;margin-right:16px;background:var(--bgColor-default,#fff);vertical-align:top}@media(max-width:600px){.markdown-source-line::before{margin-left:-52px;margin-right:12px}}
|
|
20
|
+
.markdown-source-content pre::before{position:sticky;left:47px;display:block;width:1px;height:12px;background:var(--borderColor-muted,#d8dee4);content:""}@media(max-width:600px){.markdown-source-content pre::before{left:39px}}
|
|
21
|
+
`;
|
|
22
|
+
const script = `<script>(()=>{
|
|
23
|
+
const parameter='document-view',previewButton=document.querySelector('[data-document-preview-toggle]'),sourceButton=document.querySelector('[data-document-source-toggle]'),replacementButton=document.querySelector('[data-replacement-menu]'),diffButton=document.querySelector('[data-document-diff-toggle]'),current=document.querySelector('.markdown-content'),source=document.querySelector('.markdown-source-content'),diff=document.querySelector('.document-diff-content'),available=${hasDiff},pageUrl=new URL(location.href);
|
|
24
|
+
let intent=['markdown','diff'].includes(pageUrl.searchParams.get(parameter))?pageUrl.searchParams.get(parameter):'current';
|
|
25
|
+
const update=url=>{url.searchParams.delete(parameter);if(intent==='markdown'||intent==='diff')url.searchParams.set(parameter,intent);return url};
|
|
26
|
+
function syncLinks(){for(const link of document.querySelectorAll('a[href]')){const raw=link.getAttribute('href');if(!raw||raw.startsWith('#'))continue;const url=new URL(raw,location.href);if(url.protocol===location.protocol&&url.host===location.host&&url.pathname.endsWith('.html'))link.href=update(url).href}}
|
|
27
|
+
function syncLabels(){const english=document.body.dataset.language==='en',showDiff=document.body.dataset.documentView==='diff',previewLabel=english?'Show preview':'Previewを表示',sourceLabel=english?'Show code':'コードを表示';previewButton.setAttribute('aria-label',previewLabel);previewButton.title=previewLabel;sourceButton.setAttribute('aria-label',sourceLabel);sourceButton.title=sourceLabel;const diffLabel=available?(showDiff?(english?'Show latest':'最新版を表示'):(english?'Show changes':'差分を表示')):(english?'No changes since the previous build':'前回からの変更はありません');diffButton.setAttribute('aria-label',diffLabel);diffButton.title=diffLabel}
|
|
28
|
+
function apply(view,write=true){intent=view;const actual=view==='markdown'?'markdown':view==='diff'&&available?'diff':'current',showCurrent=actual==='current',showSource=actual==='markdown',showDiff=actual==='diff';document.body.dataset.documentView=actual;current.hidden=!showCurrent;source.hidden=!showSource;diff.hidden=!showDiff;previewButton.setAttribute('aria-pressed',String(showCurrent));sourceButton.setAttribute('aria-pressed',String(showSource));if(replacementButton)replacementButton.disabled=!showCurrent;diffButton.setAttribute('aria-pressed',String(showDiff));diffButton.querySelector('[data-document-diff-icon]').hidden=showDiff;diffButton.querySelector('[data-document-current-icon]').hidden=!showDiff;syncLabels();if(write)history.replaceState(null,'',update(new URL(location.href)));syncLinks()}
|
|
29
|
+
window.marksitesSyncDocumentViewLabels=syncLabels;
|
|
30
|
+
previewButton.addEventListener('click',()=>apply('current'));sourceButton.addEventListener('click',()=>apply('markdown'));if(available)diffButton.addEventListener('click',()=>apply(document.body.dataset.documentView==='diff'?'current':'diff'));for(const link of document.querySelectorAll('.table-of-contents a[href^="#"]'))link.addEventListener('click',()=>{if(document.body.dataset.documentView==='markdown')apply('current')});apply(intent,available||intent!=='diff');
|
|
31
|
+
})()</script>`;
|
|
32
|
+
return { control, content, styles, script };
|
|
33
|
+
}
|
|
@@ -39,14 +39,14 @@ const english=new Map(${JSON.stringify([
|
|
|
39
39
|
["アーカイブを開く", "Open archive"], ["アーカイブを閉じる", "Close archive"], ["コメントを保存", "Save comment"], ["編集をキャンセル", "Cancel editing"],
|
|
40
40
|
["有効なコメントをすべてコピー", "Copy all active comments"], ["有効なコメントだけをコピー", "Copy active comments only"], ["有効なコメントをコピー", "Copy active comments"], ["コメントをコピーしました", "Comment copied"], ["コピー失敗", "Copy failed"], ["コピーに失敗しました", "Copy failed"], ["保存中…", "Saving…"], ["保存に失敗しました", "Save failed"], ["このコメントを削除しますか?", "Delete this comment?"],
|
|
41
41
|
["コメントを追加するにはmarksites serveを起動してください", "Start marksites serve to add comments"], ["別の画面でコメントが更新されました。最新の内容を確認して、もう一度操作してください。", "Comments changed in another window. Review the latest version and try again."],
|
|
42
|
-
["差分を表示", "Show changes"], ["最新版を表示", "Show latest"], ["前回からの変更はありません", "No changes since the previous build"],
|
|
42
|
+
["差分を表示", "Show changes"], ["最新版を表示", "Show latest"], ["前回からの変更はありません", "No changes since the previous build"], ["Preview", "Preview"], ["コード", "Code"], ["Previewを表示", "Show preview"], ["コードを表示", "Show code"], ["文書表示と操作", "Document view and actions"],
|
|
43
43
|
["コードをコピー", "Copy code"], ["長い行を折り返す", "Wrap long lines"], ["折り返しを解除", "Disable line wrapping"], ["コードをコピーしました", "Code copied"], ["コードをコピーできませんでした", "Could not copy code"],
|
|
44
44
|
["文書ナビゲーション", "Document navigation"], ["文書サイドバー", "Document sidebar"], ["パンくずリスト", "Breadcrumbs"]
|
|
45
45
|
])});
|
|
46
46
|
const skipText=node=>{const parent=node.parentElement;if(!parent)return true;if(parent.closest('.file-tree-name,.file-tree summary span,.file-breadcrumbs ol,.table-of-contents a,.annotation-card>p,.annotation-quote,.annotation-source,.code-language'))return true;return Boolean(parent.closest('.markdown-content')&&!parent.closest('.code-toolbar'))};
|
|
47
47
|
const translate=value=>{if(english.has(value))return english.get(value);if(value.startsWith('更新 '))return'Updated '+value.slice(3);if(/^(\d{4})年(\d{1,2})月(\d{1,2})日$/.test(value))return value.replace(/^(\d{4})年(\d{1,2})月(\d{1,2})日$/,'$1-$2-$3');if(/^コメント\d+件$/.test(value))return value.replace(/^コメント(\d+)件$/,'$1 comments');if(/^ファイル\d+件$/.test(value))return value.replace(/^ファイル(\d+)件$/,'$1 files');return value};
|
|
48
48
|
function applyNode(node,language){if(node.nodeType===Node.TEXT_NODE){if(skipText(node))return;if(!textOriginal.has(node))textOriginal.set(node,node.data);const original=textOriginal.get(node),trimmed=original.trim(),next=language==='en'?original.replace(trimmed,translate(trimmed)):original;if(node.data!==next)node.data=next;return}if(node.nodeType!==Node.ELEMENT_NODE)return;const element=node,attributes=['aria-label','title','placeholder'];let originals=attributeOriginal.get(element);if(!originals){originals=new Map();attributeOriginal.set(element,originals)}for(const name of attributes){if(!element.hasAttribute(name)&&!originals.has(name))continue;if(!originals.has(name))originals.set(name,element.getAttribute(name));const original=originals.get(name),next=language==='en'?translate(original):original;if(element.getAttribute(name)!==next)element.setAttribute(name,next)}for(const child of element.childNodes)applyNode(child,language)}
|
|
49
|
-
function applyLanguage(language){document.documentElement.lang=language;document.body.dataset.language=language;for(const root of document.querySelectorAll('.site-header,.file-sidebar,.file-navigation,.document-sidebar,.selection-actions,.code-toolbar'))applyNode(root,language);const button=document.querySelector('[data-language-toggle]'),label=document.querySelector('[data-language-label]'),next=language==='ja'?'en':'ja';label.textContent=language==='ja'?'JA':'EN';button.setAttribute('aria-label',next==='en'?'英語に切り替え':'Switch to Japanese');button.title=button.getAttribute('aria-label')}
|
|
49
|
+
function applyLanguage(language){document.documentElement.lang=language;document.body.dataset.language=language;for(const root of document.querySelectorAll('.site-header,.file-sidebar,.file-navigation,.document-sidebar,.document-content-actions,.selection-actions,.code-toolbar'))applyNode(root,language);const button=document.querySelector('[data-language-toggle]'),label=document.querySelector('[data-language-label]'),next=language==='ja'?'en':'ja';label.textContent=language==='ja'?'JA':'EN';button.setAttribute('aria-label',next==='en'?'英語に切り替え':'Switch to Japanese');button.title=button.getAttribute('aria-label');window.marksitesSyncDocumentViewLabels?.()}
|
|
50
50
|
function syncLinks(){const language=document.body.dataset.language,theme=document.body.dataset.theme;const update=url=>{url.searchParams.delete(languageParameter);if(language==='en')url.searchParams.set(languageParameter,'en');url.searchParams.set(themeParameter,theme);return url};history.replaceState(null,'',update(new URL(location.href)));for(const link of document.querySelectorAll('a[href]')){const raw=link.getAttribute('href');if(!raw||raw.startsWith('#'))continue;const url=new URL(raw,location.href);if(url.protocol===location.protocol&&url.host===location.host&&url.pathname.endsWith('.html'))link.href=update(url).href}}
|
|
51
51
|
function applyTheme(theme){document.documentElement.dataset.theme=theme;document.body.dataset.theme=theme;const dark=theme==='dark',button=document.querySelector('[data-theme-toggle]');button.querySelector('[data-theme-dark-icon]').hidden=dark;button.querySelector('[data-theme-light-icon]').hidden=!dark;const label=dark?(document.body.dataset.language==='en'?'Switch to light mode':'ライトモードに切り替え'):(document.body.dataset.language==='en'?'Switch to dark mode':'ダークモードに切り替え');button.setAttribute('aria-label',label);button.title=label}
|
|
52
52
|
const initialLanguage=pageUrl.searchParams.get(languageParameter)==='en'?'en':'ja',initialTheme=['dark','light'].includes(pageUrl.searchParams.get(themeParameter))?pageUrl.searchParams.get(themeParameter):(matchMedia('(prefers-color-scheme: dark)').matches?'dark':'light');applyLanguage(initialLanguage);applyTheme(initialTheme);syncLinks();
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export function createTableResizerFeature(enabled) {
|
|
2
|
+
if (!enabled)
|
|
3
|
+
return { styles: "", script: "" };
|
|
4
|
+
const styles = `
|
|
5
|
+
.table-resizable-container { position: relative; max-width: 100%; margin-bottom: var(--base-size-16); overflow-x: auto; }
|
|
6
|
+
.markdown-content .table-resizable-container table.is-column-resizable { display: table; table-layout: fixed; max-width: none; margin-bottom: 0; overflow: visible; }
|
|
7
|
+
.table-column-resizer { position: absolute; z-index: 2; top: 0; width: 10px; padding: 0; background: transparent; border: 0; transform: translateX(-5px); cursor: col-resize; touch-action: none; user-select: none; }
|
|
8
|
+
.table-column-resizer::after { position: absolute; top: 0; bottom: 0; left: 4px; width: 2px; background: var(--borderColor-accent-emphasis, #0969da); content: ""; opacity: 0; }
|
|
9
|
+
.table-column-resizer:hover::after, .table-column-resizer:focus-visible::after, .table-column-resizer.is-resizing::after { opacity: 1; }
|
|
10
|
+
.table-column-resizer:focus-visible { outline: 2px solid var(--focus-outlineColor, #0969da); outline-offset: -2px; }
|
|
11
|
+
body.is-resizing-table-column { cursor: col-resize; user-select: none; }`;
|
|
12
|
+
const script = `<script>(()=>{const minimum=48;for(const table of document.querySelectorAll('.markdown-content table')){const headers=table.tHead?.rows[0]?.cells;if(!headers?.length||Array.from(headers).some(cell=>cell.colSpan!==1)||table.querySelector(':scope > colgroup'))continue;const widths=Array.from(headers,cell=>cell.getBoundingClientRect().width);const container=document.createElement('div');container.className='table-resizable-container';table.before(container);container.append(table);const group=document.createElement('colgroup');for(const width of widths){const column=document.createElement('col');column.style.width=width+'px';group.append(column)}table.prepend(group);table.classList.add('is-column-resizable');const handles=[];const layout=()=>{table.style.width=widths.reduce((sum,width)=>sum+width,0)+'px';let offset=0;handles.forEach((handle,index)=>{offset+=widths[index];handle.style.left=offset+'px';handle.style.height=table.offsetHeight+'px'})};Array.from(headers).forEach((cell,index)=>{const handle=document.createElement('button');handle.type='button';handle.className='table-column-resizer';handle.setAttribute('aria-label',(cell.textContent?.trim()||String(index+1))+'列の幅を変更');handle.setAttribute('aria-orientation','vertical');handles.push(handle);container.append(handle);let drag=null;const resize=width=>{widths[index]=Math.max(minimum,width);group.children[index].style.width=widths[index]+'px';layout()};handle.addEventListener('pointerdown',event=>{if(event.button!==0)return;event.preventDefault();event.stopPropagation();drag={id:event.pointerId,x:event.clientX,width:widths[index]};handle.setPointerCapture(event.pointerId);handle.classList.add('is-resizing');document.body.classList.add('is-resizing-table-column')});handle.addEventListener('click',event=>event.stopPropagation());handle.addEventListener('pointermove',event=>{if(!drag||drag.id!==event.pointerId)return;resize(drag.width+event.clientX-drag.x)});const finish=event=>{if(!drag||drag.id!==event.pointerId)return;drag=null;handle.classList.remove('is-resizing');document.body.classList.remove('is-resizing-table-column')};handle.addEventListener('pointerup',finish);handle.addEventListener('pointercancel',finish);handle.addEventListener('keydown',event=>{if(event.key!=='ArrowLeft'&&event.key!=='ArrowRight')return;event.preventDefault();resize(widths[index]+(event.key==='ArrowLeft'?-10:10))})});layout()}})();</script>`;
|
|
13
|
+
return { styles, script };
|
|
14
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export function createTableSorterFeature(enabled) {
|
|
2
|
+
if (!enabled)
|
|
3
|
+
return { styles: "", script: "" };
|
|
4
|
+
const styles = `
|
|
5
|
+
.markdown-content table.is-column-sortable th { position: relative; padding-right: 40px; cursor: pointer; user-select: none; transition: background-color 120ms ease; }
|
|
6
|
+
.markdown-content table.is-column-sortable th:hover { background: var(--bgColor-muted, #f6f8fa); }
|
|
7
|
+
.markdown-content table.is-column-sortable th:focus-visible { outline: 2px solid var(--focus-outlineColor, #0969da); outline-offset: -2px; }
|
|
8
|
+
.table-sort-indicator { position: absolute; top: 50%; right: 11px; display: inline-flex; width: 18px; height: 18px; align-items: center; justify-content: center; color: var(--fgColor-muted, #59636e); border-radius: 5px; transform: translateY(-50%); transition: color 120ms ease, background-color 120ms ease; }
|
|
9
|
+
.table-sort-indicator svg { display: block; width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
|
|
10
|
+
.table-sort-indicator path { opacity: .38; transition: opacity 120ms ease; }
|
|
11
|
+
th:hover .table-sort-indicator { color: var(--fgColor-default, #1f2328); background: var(--bgColor-neutral-muted, #818b981f); }
|
|
12
|
+
th[aria-sort="ascending"] .table-sort-indicator, th[aria-sort="descending"] .table-sort-indicator { color: var(--fgColor-accent, #0969da); background: var(--bgColor-accent-muted, #ddf4ff); }
|
|
13
|
+
th[aria-sort="ascending"] .table-sort-chevron-up, th[aria-sort="descending"] .table-sort-chevron-down { opacity: 1; }
|
|
14
|
+
th[aria-sort="ascending"] .table-sort-chevron-down, th[aria-sort="descending"] .table-sort-chevron-up { opacity: .15; }
|
|
15
|
+
@media (prefers-reduced-motion: reduce) { .markdown-content table.is-column-sortable th, .table-sort-indicator, .table-sort-indicator path { transition: none; } }`;
|
|
16
|
+
const script = `<script>(()=>{const collator=new Intl.Collator(undefined,{numeric:true,sensitivity:'base'});for(const table of document.querySelectorAll('.markdown-content table')){const headers=table.tHead?.rows[0]?.cells,bodies=Array.from(table.tBodies);if(!headers?.length||!bodies.length||Array.from(headers).some(cell=>cell.colSpan!==1))continue;const originals=bodies.map(body=>Array.from(body.rows));let active=-1,direction=0;const apply=(index,next)=>{active=index;direction=next;Array.from(headers).forEach((header,column)=>header.setAttribute('aria-sort',column===active&&direction!==0?(direction===1?'ascending':'descending'):'none'));bodies.forEach((body,bodyIndex)=>{const original=originals[bodyIndex];const order=new Map(original.map((row,rowIndex)=>[row,rowIndex]));const rows=direction===0?[...original]:[...original].sort((left,right)=>{const leftValue=left.cells[index]?.textContent?.trim()??'',rightValue=right.cells[index]?.textContent?.trim()??'';const compared=collator.compare(leftValue,rightValue);return direction*compared||(order.get(left)-order.get(right))});body.append(...rows)})};Array.from(headers).forEach((header,index)=>{header.tabIndex=0;header.setAttribute('aria-sort','none');const indicator=document.createElement('span');indicator.className='table-sort-indicator';indicator.setAttribute('aria-hidden','true');indicator.innerHTML='<svg viewBox="0 0 16 16"><path class="table-sort-chevron-up" d="M5 6.5 8 3.5l3 3"/><path class="table-sort-chevron-down" d="m5 9.5 3 3 3-3"/></svg>';header.append(indicator);const sort=()=>apply(index,active===index?(direction===1?-1:direction===-1?0:1):1);header.addEventListener('click',event=>{if(event.target.closest('button,a,input,select,textarea'))return;sort()});header.addEventListener('keydown',event=>{if(event.key!=='Enter'&&event.key!==' ')return;if(event.target!==header)return;event.preventDefault();sort()})});table.classList.add('is-column-sortable')}})();</script>`;
|
|
17
|
+
return { styles, script };
|
|
18
|
+
}
|
package/dist/markdown-to-html.js
CHANGED
|
@@ -7,6 +7,9 @@ import { createTableOfContentsFeature } from "./features/table-of-contents/index
|
|
|
7
7
|
import { createSidebarFeature } from "./features/sidebar/index.js";
|
|
8
8
|
import { createImageViewerFeature } from "./features/image-viewer/index.js";
|
|
9
9
|
import { createDocumentDiffFeature } from "./features/document-diff/index.js";
|
|
10
|
+
import { createDocumentViewFeature } from "./features/document-view/index.js";
|
|
11
|
+
import { createTableResizerFeature } from "./features/table-resizer/index.js";
|
|
12
|
+
import { createTableSorterFeature } from "./features/table-sorter/index.js";
|
|
10
13
|
import { renderDocument } from "./template/document.js";
|
|
11
14
|
import { escapeHtml } from "./utils/html.js";
|
|
12
15
|
/** Convert Markdown into a standalone HTML document styled like GitHub. */
|
|
@@ -39,6 +42,7 @@ export function renderMarkdown(markdown, options = {}, annotations, previousMark
|
|
|
39
42
|
const fileTreeScript = renderFileTreeScript(fileTree !== "");
|
|
40
43
|
const modifiedAt = renderModifiedAt(options.modifiedAt);
|
|
41
44
|
const documentDiff = createDocumentDiffFeature(markdown, previousMarkdown, options.markedOptions);
|
|
45
|
+
const documentView = createDocumentViewFeature(markdown, documentDiff.hasChanges);
|
|
42
46
|
const breadcrumbs = fileTree
|
|
43
47
|
? renderBreadcrumbs(options.fileTree?.breadcrumbs)
|
|
44
48
|
: `<nav class="file-breadcrumbs" aria-label="ファイルパス"><span aria-current="page">${escapeHtml(rawTitle)}</span></nav>\n`;
|
|
@@ -50,6 +54,8 @@ export function renderMarkdown(markdown, options = {}, annotations, previousMark
|
|
|
50
54
|
});
|
|
51
55
|
const annotationFeature = createAnnotationsFeature(annotations);
|
|
52
56
|
const imageViewer = createImageViewerFeature(/<img\b/i.test(content));
|
|
57
|
+
const tableResizer = createTableResizerFeature(/<table\b/i.test(content));
|
|
58
|
+
const tableSorter = createTableSorterFeature(/<table\b/i.test(content));
|
|
53
59
|
const sidebar = createSidebarFeature({
|
|
54
60
|
tableOfContents: toc.markup,
|
|
55
61
|
tableOfContentsTitle: toc.title,
|
|
@@ -64,6 +70,8 @@ export function renderMarkdown(markdown, options = {}, annotations, previousMark
|
|
|
64
70
|
regions: {
|
|
65
71
|
header: header.markup,
|
|
66
72
|
fileSidebar,
|
|
73
|
+
documentControls: `${documentView.control}${annotationFeature.documentControl}`,
|
|
74
|
+
sourceContent: documentView.content,
|
|
67
75
|
diffContent: `<main class="document-diff-content" aria-label="文書の差分" hidden>\n${documentDiff.content}</main>`,
|
|
68
76
|
sidebar: sidebar.markup,
|
|
69
77
|
overlays: `${annotationFeature.markup}${imageViewer.markup}`,
|
|
@@ -74,11 +82,14 @@ export function renderMarkdown(markdown, options = {}, annotations, previousMark
|
|
|
74
82
|
annotationFeature.styles,
|
|
75
83
|
imageViewer.styles,
|
|
76
84
|
header.styles,
|
|
85
|
+
documentView.styles,
|
|
77
86
|
documentDiff.styles,
|
|
87
|
+
tableResizer.styles,
|
|
88
|
+
tableSorter.styles,
|
|
78
89
|
],
|
|
79
90
|
scripts: [
|
|
80
91
|
header.script,
|
|
81
|
-
|
|
92
|
+
documentView.script,
|
|
82
93
|
fileTreeScript,
|
|
83
94
|
renderModifiedAtScript(modifiedAt !== ""),
|
|
84
95
|
sidebar.script,
|
|
@@ -86,6 +97,8 @@ export function renderMarkdown(markdown, options = {}, annotations, previousMark
|
|
|
86
97
|
`\n${codeBlocks.renderScript()}\n`,
|
|
87
98
|
`${annotationFeature.script}\n`,
|
|
88
99
|
...(imageViewer.script ? [`${imageViewer.script}\n`] : []),
|
|
100
|
+
...(tableSorter.script ? [`${tableSorter.script}\n`] : []),
|
|
101
|
+
...(tableResizer.script ? [`${tableResizer.script}\n`] : []),
|
|
89
102
|
],
|
|
90
103
|
},
|
|
91
104
|
});
|
|
@@ -5,10 +5,12 @@ import { createAnnotationsFeature } from "../features/annotations/index.js";
|
|
|
5
5
|
import { createCodeBlocksFeature } from "../features/code-blocks/index.js";
|
|
6
6
|
import { createHeaderFeature } from "../features/header/index.js";
|
|
7
7
|
import { createImageViewerFeature } from "../features/image-viewer/index.js";
|
|
8
|
-
import {
|
|
8
|
+
import { createDocumentViewFeature } from "../features/document-view/index.js";
|
|
9
9
|
import { renderFileTreeScript, renderModifiedAtScript, } from "../features/file-tree/index.js";
|
|
10
10
|
import { createSidebarFeature } from "../features/sidebar/index.js";
|
|
11
11
|
import { createTableOfContentsFeature } from "../features/table-of-contents/index.js";
|
|
12
|
+
import { createTableResizerFeature } from "../features/table-resizer/index.js";
|
|
13
|
+
import { createTableSorterFeature } from "../features/table-sorter/index.js";
|
|
12
14
|
function scriptBody(script) {
|
|
13
15
|
return /^<script[^>]*>([\s\S]*)<\/script>$/.exec(script)?.[1] ?? "";
|
|
14
16
|
}
|
|
@@ -37,8 +39,10 @@ function generatedScriptBodies() {
|
|
|
37
39
|
scriptBody(renderedToc.script),
|
|
38
40
|
scriptBody(annotations.script),
|
|
39
41
|
scriptBody(createImageViewerFeature(true).script),
|
|
40
|
-
scriptBody(
|
|
41
|
-
scriptBody(
|
|
42
|
+
scriptBody(createTableResizerFeature(true).script),
|
|
43
|
+
scriptBody(createTableSorterFeature(true).script),
|
|
44
|
+
scriptBody(createDocumentViewFeature("same", false).script),
|
|
45
|
+
scriptBody(createDocumentViewFeature("after", true).script),
|
|
42
46
|
scriptBody(createSidebarFeature({
|
|
43
47
|
tableOfContents: renderedToc.markup,
|
|
44
48
|
tableOfContentsTitle: renderedToc.title,
|
|
@@ -19,10 +19,16 @@ ${documentStyles}${parts.regions.fileSidebar ? `\n${fileTreeStyles}` : ""}${part
|
|
|
19
19
|
<body class="${bodyClass}">
|
|
20
20
|
${parts.regions.header}
|
|
21
21
|
${parts.regions.fileSidebar}
|
|
22
|
+
<div class="document-content">
|
|
23
|
+
<div class="document-content-actions" role="toolbar" aria-label="文書表示と操作">
|
|
24
|
+
${parts.regions.documentControls}
|
|
25
|
+
</div>
|
|
22
26
|
<main class="markdown-content">
|
|
23
27
|
${parts.content}
|
|
24
28
|
</main>
|
|
29
|
+
${parts.regions.sourceContent}
|
|
25
30
|
${parts.regions.diffContent}
|
|
31
|
+
</div>
|
|
26
32
|
${parts.regions.sidebar}
|
|
27
33
|
${parts.regions.overlays}
|
|
28
34
|
${parts.assets.scripts.map(trustedScript).join("")}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export declare const githubMarkdownCss: string;
|
|
2
2
|
export declare const highlightCss: string;
|
|
3
3
|
export declare const highlightThemeStyles = "body[data-theme=\"dark\"] .hljs{color:var(--codeBlock-fgColor);background:var(--codeBlock-bgColor)}\nbody[data-theme=\"dark\"] :is(.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-template-tag,.hljs-template-variable,.hljs-type,.hljs-variable.language_){color:var(--color-prettylights-syntax-keyword)}\nbody[data-theme=\"dark\"] :is(.hljs-title,.hljs-title.class_,.hljs-title.function_){color:var(--color-prettylights-syntax-entity)}\nbody[data-theme=\"dark\"] :is(.hljs-attr,.hljs-attribute,.hljs-literal,.hljs-meta,.hljs-number,.hljs-operator,.hljs-variable,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id){color:var(--color-prettylights-syntax-constant)}\nbody[data-theme=\"dark\"] :is(.hljs-regexp,.hljs-string,.hljs-meta .hljs-string){color:var(--color-prettylights-syntax-string)}\nbody[data-theme=\"dark\"] :is(.hljs-built_in,.hljs-symbol){color:var(--color-prettylights-syntax-variable)}\nbody[data-theme=\"dark\"] :is(.hljs-comment,.hljs-code,.hljs-formula){color:var(--color-prettylights-syntax-comment)}\nbody[data-theme=\"dark\"] :is(.hljs-name,.hljs-quote,.hljs-selector-tag,.hljs-selector-pseudo){color:var(--color-prettylights-syntax-entity-tag)}";
|
|
4
|
-
export declare const documentStyles = " body.markdown-body { box-sizing: border-box; min-width: 200px; width: calc(100% - 64px); max-width: none; margin: 0 32px; padding: 32px 0 0; display: grid; grid-template-columns: minmax(0, 1fr) 300px; grid-template-areas: \"content toc\"; column-gap: 32px; align-items: start; }\n .markdown-content, .document-sidebar { box-sizing: border-box; }\n .markdown-content {
|
|
4
|
+
export declare const documentStyles = " body.markdown-body { box-sizing: border-box; min-width: 200px; width: calc(100% - 64px); max-width: none; margin: 0 32px; padding: 32px 0 0; display: grid; grid-template-columns: minmax(0, 1fr) 300px; grid-template-areas: \"content toc\"; column-gap: 32px; align-items: start; }\n .document-content, .markdown-content, .document-sidebar { box-sizing: border-box; }\n .markdown-content { min-width: 0; margin-bottom: 72px; padding: clamp(28px, 3vw, 52px); border: 1px solid var(--borderColor-muted, #d8dee4); border-radius: 8px; box-shadow: 0 1px 2px rgba(31, 35, 40, 0.04); }\n .markdown-content :is(h1, h2, h3, h4, h5, h6) { scroll-margin-top: 32px; }\n .code-block { margin-bottom: 16px; overflow: hidden; border: 1px solid var(--borderColor-muted, #d8dee4); border-radius: 8px; }\n .code-toolbar { display: flex; min-height: 38px; align-items: center; justify-content: space-between; padding: 0 8px 0 14px; color: var(--fgColor-muted, #59636e); background: var(--bgColor-muted, #f6f8fa); border-bottom: 1px solid var(--borderColor-muted, #d8dee4); }\n .code-language { font-size: 0.75rem; font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; }\n .code-tools { display: flex; gap: 2px; }\n .code-tool { display: inline-flex; min-height: 30px; align-items: center; justify-content: center; gap: 5px; padding: 4px 8px; color: inherit; font: inherit; font-size: 0.75rem; line-height: 1; background: transparent; border: 0; border-radius: 5px; cursor: pointer; }\n .code-tool-label, [data-copy-label] { display: inline-flex; align-items: center; line-height: 1; }\n .code-tool:hover { color: var(--fgColor-default, #1f2328); background: var(--button-default-bgColor-hover, #eaeef2); }\n .code-tool:focus-visible { outline: 2px solid var(--focus-outlineColor, #0969da); outline-offset: -2px; }\n .code-tool[aria-pressed=\"true\"] { color: var(--fgColor-accent, #0969da); background: var(--bgColor-accent-muted, #ddf4ff); }\n .code-block pre { margin: 0; border-radius: 0; }\n .code-block pre, .code-block pre code { color: var(--codeBlock-fgColor, #24292f); background: var(--codeBlock-bgColor, #fff); }\n .code-block pre code { display: block; }\n .code-block.is-wrapped pre code { white-space: pre-wrap; overflow-wrap: anywhere; }\n .panel-toggle-icon { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; transition: transform 120ms ease; }\n .action-icon { display: block; width: 14px; height: 14px; flex: none; fill: none; stroke: currentColor; stroke-width: 1.25; stroke-linecap: round; stroke-linejoin: round; }\n .table-of-contents ul { margin: 0; padding: 0; list-style: none; }\n .table-of-contents li { margin: 2px 0 2px calc(var(--toc-level) * 12px); }\n .table-of-contents a { position: relative; display: block; padding: 6px 10px; color: var(--fgColor-muted, #59636e); font-size: 0.875rem; line-height: 1.4; overflow-wrap: anywhere; text-decoration: none; border-radius: 0 6px 6px 0; transition: color 120ms ease, background-color 120ms ease; }\n .table-of-contents a::before { position: absolute; top: 0; bottom: 0; left: 0; width: 2px; background: transparent; content: \"\"; }\n .table-of-contents a:hover { color: var(--fgColor-default, #1f2328); background: var(--bgColor-muted, #f6f8fa); text-decoration: none; }\n .table-of-contents a:focus-visible { outline: 2px solid var(--focus-outlineColor, #0969da); outline-offset: -2px; }\n .table-of-contents a[aria-current=\"location\"] { color: var(--fgColor-accent, #0969da); font-weight: 600; background: linear-gradient(90deg, var(--bgColor-accent-muted, #ddf4ff), transparent); }\n .table-of-contents a[aria-current=\"location\"]::before { background: var(--borderColor-accent-emphasis, #0969da); }\n @media (max-width: 900px) {\n body.markdown-body { width: calc(100% - 24px); max-width: none; margin: 0 12px; padding: 12px 0 0; grid-template-columns: minmax(0, 1fr); grid-template-areas: \"toc\" \"content\"; gap: 16px; }\n .markdown-content { margin-bottom: 32px; }\n }\n @media (max-width: 600px) { .markdown-content { padding: 24px 20px; border-radius: 6px; } }\n @media (prefers-reduced-motion: reduce) { .table-of-contents a, .panel-toggle-icon { transition: none; } }";
|
|
5
5
|
export declare const fileTreeStyles = " body.markdown-body.has-file-tree { width: 100%; margin: 0; padding: 32px 32px 0 0; grid-template-columns: 280px minmax(0, 1fr) 300px; grid-template-areas: \"files content toc\"; column-gap: 32px; }\n body.markdown-body.has-file-tree.file-sidebar-collapsed { width: calc(100% - 64px); margin: 0 32px; padding: 32px 0 0; grid-template-columns: minmax(0, 1fr) 300px; grid-template-areas: \"content toc\"; }\n .file-sidebar { grid-area: files; position: fixed; z-index: 45; top: 0; bottom: 0; left: 0; box-sizing: border-box; display: flex; width: 280px; min-height: 0; flex-direction: column; color: var(--fgColor-default, #1f2328); background: var(--bgColor-default, #fff); border: 0; border-right: 1px solid var(--borderColor-muted, #d8dee4); border-radius: 0; overflow: hidden; }\n .file-sidebar-header { display: flex; min-height: 52px; flex: none; align-items: center; gap: 9px; padding: 0 12px; font-size: 0.875rem; font-weight: 700; border-bottom: 1px solid var(--borderColor-muted, #d8dee4); }\n .file-sidebar-header > span { min-width: 0; flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n .file-sidebar[hidden], .file-sidebar-open[hidden], .file-sidebar-close[hidden] { display: none; }\n .file-sidebar-close { position: fixed; z-index: 50; top: 13px; left: 12px; display: inline-flex; width: 30px; height: 30px; flex: none; align-items: center; justify-content: center; padding: 0; color: var(--fgColor-muted, #59636e); background: transparent; border: 0; border-radius: 6px; cursor: pointer; }\n .file-sidebar-close:hover { color: var(--fgColor-default, #1f2328); background: var(--button-default-bgColor-hover, #eaeef2); }\n .file-sidebar-close:focus-visible { outline: 2px solid var(--focus-outlineColor, #0969da); outline-offset: -2px; }\n .file-breadcrumbs { display: flex; align-items: center; gap: 8px; margin: 0; padding-bottom: 14px; border-bottom: 1px solid var(--borderColor-muted, #d8dee4); }\n .file-breadcrumbs ol { display: flex; min-width: 0; min-height: 28px; flex: 0 1 auto; flex-wrap: wrap; align-items: baseline; gap: 6px; margin: 0; padding: 0; list-style: none; }\n .file-breadcrumbs li { display: inline-block; min-width: 0; height: 28px; color: var(--fgColor-muted, #59636e); font-size: 0.875rem; line-height: 28px; }\n .file-breadcrumbs li + li::before { margin-right: 6px; color: var(--fgColor-muted, #818b98); content: \"/\"; }\n .file-breadcrumb-separator { height: 28px; margin-right: -2px; color: var(--fgColor-muted, #818b98); font-size: 0.875rem; line-height: 28px; }\n .file-breadcrumbs a { display: inline-block; height: 28px; color: var(--fgColor-accent, #0969da); font-weight: 500; line-height: 28px; text-decoration: none; vertical-align: baseline; }\n .file-breadcrumbs a:hover { text-decoration: underline; }\n .file-breadcrumbs [aria-current=\"page\"] { color: var(--fgColor-default, #1f2328); font-weight: 600; white-space: nowrap; }\n .file-sidebar-open { position: fixed; z-index: 50; top: 13px; left: 12px; display: inline-flex; width: 30px; height: 30px; flex: none; align-items: center; justify-content: center; padding: 0; color: var(--fgColor-muted, #59636e); background: transparent; border: 0; border-radius: 6px; cursor: pointer; }\n .file-tree-popover-toggle { position: relative; top: 1px; display: inline-flex; height: 28px; min-width: 0; flex: none; align-items: center; justify-content: center; gap: 3px; padding: 0; color: var(--fgColor-accent, #0969da); font: inherit; font-size: 0.875rem; font-weight: 600; line-height: 28px; background: transparent; border: 0; border-radius: 4px; cursor: pointer; }\n .file-tree-popover-toggle span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n .file-sidebar-toggle-icon { display: block; width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.2; stroke-linecap: round; stroke-linejoin: round; }\n .file-sidebar-open:hover { color: var(--fgColor-default, #1f2328); background: var(--button-default-bgColor-hover, #eaeef2); }\n .file-sidebar-open:focus-visible, .file-tree-popover-toggle:focus-visible { outline: 2px solid var(--focus-outlineColor, #0969da); outline-offset: 2px; }\n .file-tree-popover-toggle:hover { color: var(--fgColor-accent, #0969da); text-decoration: underline; background: transparent; }\n .file-tree-popover-toggle:disabled { color: var(--fgColor-default, #1f2328); text-decoration: none; cursor: default; }\n .file-tree-popover-toggle:disabled .panel-toggle-icon { display: none; }\n .file-tree-popover-toggle .panel-toggle-icon { width: 13px; height: 13px; flex: none; transform: translateY(1px); }\n .copy-file-path .copy-icon { transform: none; }\n .file-tree-popover-toggle[aria-expanded=\"true\"] .panel-toggle-icon { transform: translateY(1px) rotate(180deg); }\n .copy-file-path { display: inline-flex; width: 28px; height: 28px; flex: none; align-items: center; justify-content: center; padding: 0; color: var(--fgColor-muted, #59636e); background: transparent; border: 0; border-radius: 5px; cursor: pointer; }\n .copy-file-path:hover { color: var(--fgColor-default, #1f2328); background: var(--button-default-bgColor-hover, #eaeef2); }\n .copy-file-path:focus-visible { outline: 2px solid var(--focus-outlineColor, #0969da); outline-offset: 2px; }\n .file-tree { box-sizing: border-box; overflow: auto; padding: 12px; color: var(--fgColor-default, #1f2328); background: var(--bgColor-default, #fff); scrollbar-width: thin; scrollbar-color: var(--borderColor-default, #d0d7de) transparent; }\n .file-tree-sidebar { min-height: 0; flex: 1; padding: 10px 12px 16px; }\n .file-tree-popover { position: absolute; z-index: 15; top: calc(100% + 6px); left: 0; width: min(360px, calc(100vw - 48px)); max-height: min(520px, calc(100vh - 96px)); border: 1px solid var(--borderColor-default, #d0d7de); border-radius: 8px; box-shadow: 0 8px 24px rgba(31,35,40,.16); }\n .file-tree-view-tabs { display: grid; grid-template-columns: 1fr 1fr; margin: 0 0 8px; padding: 2px; background: var(--bgColor-muted, #f6f8fa); border-radius: 6px; }\n .file-tree-view-tabs button { min-height: 28px; padding: 3px 8px; color: var(--fgColor-muted, #59636e); font: inherit; font-size: 0.75rem; font-weight: 600; background: transparent; border: 0; border-radius: 4px; cursor: pointer; }\n .file-tree-view-tabs button[aria-selected=\"true\"] { color: var(--fgColor-default, #1f2328); background: var(--bgColor-default, #fff); box-shadow: 0 1px 2px rgba(31,35,40,.12); }\n .file-tree-view-tabs button:focus-visible { outline: 2px solid var(--focus-outlineColor, #0969da); outline-offset: 1px; }\n .file-tree-filter { margin: 0 0 8px; }\n .file-tree-filter-input { box-sizing: border-box; width: 100%; min-height: 32px; padding: 5px 9px; color: var(--fgColor-default, #1f2328); font: inherit; font-size: 0.8125rem; line-height: 1.4; background: var(--bgColor-default, #fff); border: 1px solid var(--borderColor-default, #d0d7de); border-radius: 6px; outline: none; }\n .file-tree-filter-input::placeholder { color: var(--fgColor-muted, #59636e); }\n .file-tree-filter-input:focus { border-color: var(--borderColor-accent-emphasis, #0969da); box-shadow: 0 0 0 2px var(--bgColor-accent-muted, #ddf4ff); }\n .file-tree-filter-empty { margin: 10px 4px 2px; color: var(--fgColor-muted, #59636e); font-size: 0.8125rem; text-align: center; }\n .file-tree ul { margin: 0; padding: 0; list-style: none; }\n .file-tree [hidden] { display: none; }\n .file-tree details { margin: 0; }\n .file-tree details > ul { margin-left: 10px; padding-left: 10px; border-left: 1px solid var(--borderColor-muted, #d8dee4); }\n .file-tree summary { padding: 5px 7px; color: var(--fgColor-default, #1f2328); font-size: 0.875rem; font-weight: 600; line-height: 1.35; border-radius: 5px; cursor: pointer; user-select: none; }\n .folder-icon { display: inline-block; width: 14px; height: 14px; margin-right: 5px; vertical-align: -2px; fill: none; stroke: currentColor; stroke-width: 1.25; stroke-linecap: round; stroke-linejoin: round; }\n .file-tree summary:hover { background: var(--bgColor-muted, #f6f8fa); }\n .file-tree summary::marker { color: var(--fgColor-muted, #59636e); }\n .file-tree a { display: flex; margin: 1px 0; padding: 5px 8px; align-items: center; gap: 6px; overflow: hidden; color: var(--fgColor-muted, #59636e); font-size: 0.875rem; line-height: 1.35; text-decoration: none; white-space: nowrap; border-radius: 5px; }\n .file-tree-name { min-width: 0; flex: 1; overflow: hidden; text-overflow: ellipsis; }\n .file-tree-comment-count { display: inline-flex; min-width: 18px; height: 18px; flex: none; align-items: center; justify-content: center; padding: 0 5px; color: var(--fgColor-muted, #59636e); font-size: 0.6875rem; font-weight: 600; line-height: 18px; background: var(--bgColor-neutral-muted, #818b981f); border-radius: 9px; }\n .file-tree-directory-comment-count { float: right; margin-left: 6px; }\n .file-tree details[open] > summary > .file-tree-directory-comment-count { display: none; }\n .file-tree a[aria-current=\"page\"] .file-tree-comment-count { color: var(--fgColor-accent, #0969da); background: var(--bgColor-default, #fff); }\n .file-tree a:hover { color: var(--fgColor-default, #1f2328); background: var(--bgColor-muted, #f6f8fa); text-decoration: none; }\n .file-tree a:focus-visible { outline: 2px solid var(--focus-outlineColor, #0969da); outline-offset: -2px; }\n .file-tree a[aria-current=\"page\"] { color: var(--fgColor-accent, #0969da); font-weight: 600; background: var(--bgColor-accent-muted, #ddf4ff); }\n .file-tree-recent { position: relative; isolation: isolate; }\n .file-tree-recent::before { position: absolute; z-index: -1; top: 0; bottom: 0; left: 12px; width: 1px; content: \"\"; background: var(--borderColor-muted, #d8dee4); }\n .file-tree-date { position: relative; z-index: 1; margin: 10px 0 3px; background: var(--bgColor-default, #fff); }\n .file-tree-date:first-child { margin-top: 4px; }\n .file-tree-date button { display: flex; width: 100%; min-height: 28px; align-items: center; gap: 4px; padding: 4px 7px; color: var(--fgColor-default, #1f2328); font: inherit; font-size: 0.75rem; font-weight: 600; text-align: left; background: transparent; border: 0; border-radius: 5px; cursor: pointer; }\n .file-tree-date button:hover { background: var(--bgColor-muted, #f6f8fa); }\n .file-tree-date button:focus-visible { outline: 2px solid var(--focus-outlineColor, #0969da); outline-offset: -2px; }\n .file-tree-date button svg { width: 12px; height: 12px; flex: none; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; transition: transform 120ms ease; }\n .file-tree-date button[aria-expanded=\"false\"] svg { transform: rotate(-90deg); }\n .file-tree-date button span { min-width: 18px; margin-left: auto; padding: 1px 5px; color: var(--fgColor-muted, #59636e); font-size: 0.6875rem; font-weight: 600; line-height: 16px; text-align: center; background: var(--bgColor-neutral-muted, #818b981f); border-radius: 9px; }\n .file-tree-recent .is-date-collapsed { display: none; }\n .file-tree-directory-group { display: none; }\n .file-tree-directory-group .folder-icon { width: 13px; height: 13px; flex: none; }\n .file-tree-directory-group span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n .file-tree-recent-file { position: relative; margin-left: 22px; }\n .file-tree-recent-file a { position: relative; margin-top: 0; margin-bottom: 0; overflow: visible; align-items: center; gap: 7px; }\n .file-tree-recent-time { width: 32px; flex: none; color: var(--fgColor-muted, #59636e); font-size: 0.6875rem; font-variant-numeric: tabular-nums; text-align: right; }\n .file-tree-recent-label { display: flex; min-width: 0; flex: 1; }\n .file-tree-recent-label .file-tree-name { position: relative; top: -1px; width: 100%; color: var(--fgColor-default, #1f2328); font-size: 0.8125rem; font-weight: 400; }\n .file-tree-recent-file a:hover .file-tree-name { text-decoration: underline; text-underline-offset: 2px; }\n .file-tree-directory-tooltip { position: fixed; z-index: 100; top: 0; left: 0; display: none; max-width: min(240px, calc(100vw - 16px)); flex-direction: column; align-items: flex-start; gap: 3px; padding: 6px 8px; color: var(--fgColor-default, #1f2328); font-size: 0.6875rem; font-weight: 400; line-height: 1.35; white-space: nowrap; background: var(--bgColor-default, #fff); border: 1px solid var(--borderColor-default, #d0d7de); border-radius: 5px; box-shadow: 0 2px 8px rgba(31,35,40,.16); transform: translateY(-50%); pointer-events: none; }\n .file-tree-directory-tooltip::before { position: absolute; top: 50%; right: calc(100% - 4px); width: 7px; height: 7px; content: \"\"; background: var(--bgColor-default, #fff); border: 0 solid var(--borderColor-default, #d0d7de); border-width: 0 0 1px 1px; transform: translateY(-50%) rotate(45deg); }\n .file-tree-directory-tooltip-path { display: flex; max-width: 220px; align-items: center; gap: 5px; overflow: hidden; }\n .file-tree-directory-tooltip-path .folder-icon { width: 12px; height: 12px; flex: none; margin: 0; }\n .file-tree-directory-tooltip-path > span { overflow: hidden; text-overflow: ellipsis; }\n .file-tree-recent-file a:hover .file-tree-directory-tooltip, .file-tree-recent-file a:focus-visible .file-tree-directory-tooltip { display: flex; }\n .file-tree-recent-file .file-tree-comment-count { margin-top: 0; }\n .file-tree-recent-empty { margin: 10px 4px 2px; color: var(--fgColor-muted, #59636e); font-size: 0.8125rem; text-align: center; }\n @media (max-width: 900px) {\n body.markdown-body.has-file-tree, body.markdown-body.has-file-tree.file-sidebar-collapsed { width: calc(100% - 24px); margin: 0 12px; padding: 12px 0 0; grid-template-columns: minmax(0, 1fr); grid-template-areas: \"toc\" \"content\"; gap: 16px; }\n .file-sidebar { width: min(280px, calc(100vw - 24px)); box-shadow: 8px 0 24px rgba(31,35,40,.18); }\n }\n @media (max-width: 600px) { .file-tree-popover { width: calc(100vw - 40px); max-height: calc(100vh - 80px); } }\n ";
|
package/dist/template/styles.js
CHANGED
|
@@ -12,8 +12,8 @@ body[data-theme="dark"] :is(.hljs-built_in,.hljs-symbol){color:var(--color-prett
|
|
|
12
12
|
body[data-theme="dark"] :is(.hljs-comment,.hljs-code,.hljs-formula){color:var(--color-prettylights-syntax-comment)}
|
|
13
13
|
body[data-theme="dark"] :is(.hljs-name,.hljs-quote,.hljs-selector-tag,.hljs-selector-pseudo){color:var(--color-prettylights-syntax-entity-tag)}`;
|
|
14
14
|
export const documentStyles = ` body.markdown-body { box-sizing: border-box; min-width: 200px; width: calc(100% - 64px); max-width: none; margin: 0 32px; padding: 32px 0 0; display: grid; grid-template-columns: minmax(0, 1fr) 300px; grid-template-areas: "content toc"; column-gap: 32px; align-items: start; }
|
|
15
|
-
.markdown-content, .document-sidebar { box-sizing: border-box; }
|
|
16
|
-
.markdown-content {
|
|
15
|
+
.document-content, .markdown-content, .document-sidebar { box-sizing: border-box; }
|
|
16
|
+
.markdown-content { min-width: 0; margin-bottom: 72px; padding: clamp(28px, 3vw, 52px); border: 1px solid var(--borderColor-muted, #d8dee4); border-radius: 8px; box-shadow: 0 1px 2px rgba(31, 35, 40, 0.04); }
|
|
17
17
|
.markdown-content :is(h1, h2, h3, h4, h5, h6) { scroll-margin-top: 32px; }
|
|
18
18
|
.code-block { margin-bottom: 16px; overflow: hidden; border: 1px solid var(--borderColor-muted, #d8dee4); border-radius: 8px; }
|
|
19
19
|
.code-toolbar { display: flex; min-height: 38px; align-items: center; justify-content: space-between; padding: 0 8px 0 14px; color: var(--fgColor-muted, #59636e); background: var(--bgColor-muted, #f6f8fa); border-bottom: 1px solid var(--borderColor-muted, #d8dee4); }
|