@file-viewer/renderer-text 2.1.30 → 2.2.1

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.en.md CHANGED
@@ -11,6 +11,9 @@ import { textRenderer } from '@file-viewer/renderer-text'
11
11
  const options = {
12
12
  builtinRenderers: 'none',
13
13
  renderers: textRenderer,
14
+ text: {
15
+ lineNumbers: true,
16
+ },
14
17
  }
15
18
  ```
16
19
 
@@ -29,10 +32,13 @@ const options = {
29
32
  ## Capabilities
30
33
 
31
34
  - Code and text preview uses `highlight.js` core with per-language dynamic imports instead of registering every language up front.
35
+ - Code, text, and virtualized Markdown source views show their file type, indexing status, and line-count metadata bar by default. Set `options.text.toolbar: false` to hide this renderer-local bar without hiding the viewer-level download, search, or zoom toolbar.
36
+ - Regular code and text previews can show a line-number gutter with `options.text.lineNumbers: true`. The gutter is excluded from copied source, search matches, and assistive reading. Virtual large-text views keep their existing gutter unless it is explicitly set to `false`.
32
37
  - `patch` uses `diff2html` on demand for side-by-side review.
33
38
  - `bundle` / `bdl` parses Git bundle headers, refs, commit history, file trees, and readable blobs; regular OFS_DELTA / REF_DELTA objects are resolved in the browser, while very large packs or bundles that depend on external prerequisites surface a clear boundary notice.
34
39
  - HTML, XML, Vue, and similar files are escaped and shown as source, never executed.
35
40
  - Markdown uses `marked` for a read-only reading surface with dark/light theme support, table scrolling, and a unified zoom provider.
41
+ - Markdown no longer falls back to source because of the general large-text threshold. Set `options.text.markdownVirtualizeAboveBytes` only when an application must bound exceptionally large Markdown files.
36
42
  - Does not depend on any online service or public CDN, making it suitable for intranet logs, configs, snippets, README files, and knowledge-base attachments.
37
43
 
38
44
  ## Migration Note
package/README.md CHANGED
@@ -11,6 +11,9 @@ import { textRenderer } from '@file-viewer/renderer-text'
11
11
  const options = {
12
12
  builtinRenderers: 'none',
13
13
  renderers: textRenderer,
14
+ text: {
15
+ lineNumbers: true,
16
+ },
14
17
  }
15
18
  ```
16
19
 
@@ -29,10 +32,13 @@ const options = {
29
32
  ## 能力边界
30
33
 
31
34
  - 代码和文本使用 `highlight.js` core + 按语言动态加载,避免一次性注册全部语言。
35
+ - 代码、文本和超大 Markdown 源码视图默认显示文件类型、索引状态和行数元信息栏;传入 `options.text.toolbar: false` 可隐藏该 renderer 内部栏,不影响 Viewer 的下载、搜索、缩放等全局工具栏。
36
+ - 普通代码和文本可通过 `options.text.lineNumbers: true` 显示行号;行号不会进入复制内容、搜索结果或无障碍朗读。超大文本保留原有的虚拟行号栏,可显式传 `false` 隐藏。
32
37
  - `patch` 使用 `diff2html` 按需渲染左右比对视图。
33
38
  - `bundle` / `bdl` 会解析 Git bundle header、refs、commit 历史、文件树和可读 blob;常规 OFS_DELTA / REF_DELTA 会在浏览器端还原,超大包或依赖外部 prerequisite 的包会给出清晰边界提示。
34
39
  - HTML / XML / Vue 等文件按源码方式转义展示,不执行脚本。
35
40
  - Markdown 使用 `marked` 输出只读阅读面,并保留明暗主题、表格滚动和统一缩放 provider。
41
+ - Markdown 不再因为通用大文本阈值自动退化成源码;如业务必须限制超大 Markdown,可单独设置 `options.text.markdownVirtualizeAboveBytes`。
36
42
  - 不绑定任何在线服务或公共 CDN,适合内网日志、配置、代码片段、README 和知识库附件预览。
37
43
 
38
44
  ## 迁移说明
package/dist/code.js CHANGED
@@ -136,6 +136,9 @@ const clampZoom = (value) => {
136
136
  const lineCountOf = (value) => {
137
137
  return value.split(/\r\n|\r|\n/).length;
138
138
  };
139
+ const createLineNumberText = (lineCount) => {
140
+ return Array.from({ length: lineCount }, (_, index) => String(index + 1)).join('\n');
141
+ };
139
142
  /**
140
143
  * Framework-neutral text/code renderer.
141
144
  *
@@ -146,6 +149,7 @@ const lineCountOf = (value) => {
146
149
  * @param type 文件扩展名,用于选择 highlight.js 语言
147
150
  */
148
151
  export default async function renderText(buffer, target, type, context) {
152
+ var _a, _b, _c, _d;
149
153
  const t = createFileViewerTranslator(context === null || context === void 0 ? void 0 : context.options);
150
154
  const extension = type || 'txt';
151
155
  const normalizedExtension = extension.trim().toLowerCase();
@@ -164,20 +168,33 @@ export default async function renderText(buffer, target, type, context) {
164
168
  }
165
169
  const text = await readText(buffer);
166
170
  const language = resolveLanguage(extension);
171
+ const lineCount = lineCountOf(text);
172
+ const showToolbar = ((_b = (_a = context === null || context === void 0 ? void 0 : context.options) === null || _a === void 0 ? void 0 : _a.text) === null || _b === void 0 ? void 0 : _b.toolbar) !== false;
173
+ const showLineNumbers = ((_d = (_c = context === null || context === void 0 ? void 0 : context.options) === null || _c === void 0 ? void 0 : _c.text) === null || _d === void 0 ? void 0 : _d.lineNumbers) === true;
167
174
  let disposed = false;
168
175
  let zoom = 1;
169
176
  const zoomEmitter = createZoomChangeEmitter();
170
177
  const root = createElement('div', 'code-viewer');
171
178
  root.dataset.viewerZoomProvider = 'code';
179
+ root.dataset.textToolbar = String(showToolbar);
180
+ root.dataset.lineNumbers = String(showLineNumbers);
172
181
  const toolbar = createElement('div', 'code-toolbar');
173
- toolbar.append(createElement('span', '', extension.toUpperCase()), createElement('strong', '', `${lineCountOf(text)} lines`));
174
- const pre = createElement('pre', 'code-area');
182
+ toolbar.append(createElement('span', '', extension.toUpperCase()), createElement('strong', '', `${lineCount} lines`));
183
+ const pre = createElement('pre', showLineNumbers ? 'code-area code-area--line-numbers' : 'code-area');
175
184
  const code = createElement('code', `hljs language-${language}`);
176
185
  code.innerHTML = language === 'plaintext'
177
186
  ? escapeHtml(text)
178
187
  : t('text.code.loadingHighlight');
188
+ if (showLineNumbers) {
189
+ const gutter = createElement('span', 'code-line-numbers', createLineNumberText(lineCount));
190
+ gutter.setAttribute('aria-hidden', 'true');
191
+ pre.append(gutter);
192
+ }
179
193
  pre.append(code);
180
- root.append(toolbar, pre);
194
+ if (showToolbar) {
195
+ root.append(toolbar);
196
+ }
197
+ root.append(pre);
181
198
  root.style.setProperty('--code-font-size', `${13 * zoom}px`);
182
199
  target.replaceChildren(createStyle(), root);
183
200
  const updateHighlighted = async () => {
@@ -1 +1 @@
1
- export declare const codeStyle = "\n.code-viewer{min-height:100%;--code-bg:#f6f8fa;--code-toolbar-bg:rgba(255,255,255,.92);--code-border:rgba(31,35,40,.12);--code-text:#24292f;--code-muted:#57606a;--code-keyword:#cf222e;--code-title:#8250df;--code-string:#0a3069;--code-number:#0550ae;--code-comment:#6e7781;--code-attr:#953800;--code-built-in:#116329;background:var(--code-bg);color:var(--code-text);box-sizing:border-box}\n.code-toolbar{position:sticky;top:0;z-index:1;display:flex;height:42px;align-items:center;justify-content:space-between;gap:16px;padding:0 16px;border-bottom:1px solid var(--code-border);background:var(--code-toolbar-bg);backdrop-filter:blur(12px);box-sizing:border-box}\n.code-toolbar span,.code-toolbar strong{color:var(--code-muted);font-size:12px;font-weight:700;letter-spacing:0}\n.code-area{display:block;min-width:min-content;margin:0;padding:18px 20px 28px;overflow:auto;background:transparent;box-sizing:border-box}\n.code-area code{display:block;padding:0;overflow:visible;background:transparent;color:inherit;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,'Liberation Mono',monospace;font-size:var(--code-font-size,13px);line-height:1.7;tab-size:2;white-space:pre}\n.code-area .hljs-comment,.code-area .hljs-quote{color:var(--code-comment)}\n.code-area .hljs-keyword,.code-area .hljs-selector-tag,.code-area .hljs-subst{color:var(--code-keyword)}\n.code-area .hljs-string,.code-area .hljs-doctag,.code-area .hljs-regexp{color:var(--code-string)}\n.code-area .hljs-title,.code-area .hljs-section,.code-area .hljs-selector-id{color:var(--code-title);font-weight:700}\n.code-area .hljs-number,.code-area .hljs-literal,.code-area .hljs-variable,.code-area .hljs-template-variable{color:var(--code-number)}\n.code-area .hljs-attr,.code-area .hljs-attribute,.code-area .hljs-name,.code-area .hljs-selector-class{color:var(--code-attr)}\n.code-area .hljs-built_in,.code-area .hljs-type,.code-area .hljs-class .hljs-title{color:var(--code-built-in)}\n[data-viewer-theme='dark'] .code-viewer{--code-bg:#0d1117;--code-toolbar-bg:rgba(13,17,23,.92);--code-border:rgba(139,148,158,.24);--code-text:#e6edf3;--code-muted:#8b949e;--code-keyword:#ff7b72;--code-title:#d2a8ff;--code-string:#a5d6ff;--code-number:#79c0ff;--code-comment:#8b949e;--code-attr:#ffa657;--code-built-in:#7ee787}\n@media (prefers-color-scheme:dark){[data-viewer-theme='system'] .code-viewer{--code-bg:#0d1117;--code-toolbar-bg:rgba(13,17,23,.92);--code-border:rgba(139,148,158,.24);--code-text:#e6edf3;--code-muted:#8b949e;--code-keyword:#ff7b72;--code-title:#d2a8ff;--code-string:#a5d6ff;--code-number:#79c0ff;--code-comment:#8b949e;--code-attr:#ffa657;--code-built-in:#7ee787}}\n";
1
+ export declare const codeStyle = "\n.code-viewer{min-height:100%;--code-bg:#f6f8fa;--code-toolbar-bg:rgba(255,255,255,.92);--code-border:rgba(31,35,40,.12);--code-text:#24292f;--code-muted:#57606a;--code-keyword:#cf222e;--code-title:#8250df;--code-string:#0a3069;--code-number:#0550ae;--code-comment:#6e7781;--code-attr:#953800;--code-built-in:#116329;background:var(--code-bg);color:var(--code-text);box-sizing:border-box}\n.code-toolbar{position:sticky;top:0;z-index:1;display:flex;height:42px;align-items:center;justify-content:space-between;gap:16px;padding:0 16px;border-bottom:1px solid var(--code-border);background:var(--code-toolbar-bg);backdrop-filter:blur(12px);box-sizing:border-box}\n.code-toolbar span,.code-toolbar strong{color:var(--code-muted);font-size:12px;font-weight:700;letter-spacing:0}\n.code-area{display:block;min-width:min-content;margin:0;padding:18px 20px 28px;overflow:auto;background:transparent;box-sizing:border-box}\n.code-area--line-numbers{display:grid;grid-template-columns:max-content max-content;padding:18px 0 28px}\n.code-line-numbers{position:sticky;left:0;z-index:1;display:block;min-width:4ch;padding:0 12px 0 16px;border-right:1px solid var(--code-border);background:var(--code-bg);color:var(--code-muted);font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,'Liberation Mono',monospace;font-size:var(--code-font-size,13px);line-height:1.7;text-align:right;white-space:pre;user-select:none;box-sizing:border-box}\n.code-area.code-area--line-numbers code{padding:0 20px}\n.code-area code{display:block;padding:0;overflow:visible;background:transparent;color:inherit;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,'Liberation Mono',monospace;font-size:var(--code-font-size,13px);line-height:1.7;tab-size:2;white-space:pre}\n.code-area .hljs-comment,.code-area .hljs-quote{color:var(--code-comment)}\n.code-area .hljs-keyword,.code-area .hljs-selector-tag,.code-area .hljs-subst{color:var(--code-keyword)}\n.code-area .hljs-string,.code-area .hljs-doctag,.code-area .hljs-regexp{color:var(--code-string)}\n.code-area .hljs-title,.code-area .hljs-section,.code-area .hljs-selector-id{color:var(--code-title);font-weight:700}\n.code-area .hljs-number,.code-area .hljs-literal,.code-area .hljs-variable,.code-area .hljs-template-variable{color:var(--code-number)}\n.code-area .hljs-attr,.code-area .hljs-attribute,.code-area .hljs-name,.code-area .hljs-selector-class{color:var(--code-attr)}\n.code-area .hljs-built_in,.code-area .hljs-type,.code-area .hljs-class .hljs-title{color:var(--code-built-in)}\n[data-viewer-theme='dark'] .code-viewer{--code-bg:#0d1117;--code-toolbar-bg:rgba(13,17,23,.92);--code-border:rgba(139,148,158,.24);--code-text:#e6edf3;--code-muted:#8b949e;--code-keyword:#ff7b72;--code-title:#d2a8ff;--code-string:#a5d6ff;--code-number:#79c0ff;--code-comment:#8b949e;--code-attr:#ffa657;--code-built-in:#7ee787}\n@media (prefers-color-scheme:dark){[data-viewer-theme='system'] .code-viewer{--code-bg:#0d1117;--code-toolbar-bg:rgba(13,17,23,.92);--code-border:rgba(139,148,158,.24);--code-text:#e6edf3;--code-muted:#8b949e;--code-keyword:#ff7b72;--code-title:#d2a8ff;--code-string:#a5d6ff;--code-number:#79c0ff;--code-comment:#8b949e;--code-attr:#ffa657;--code-built-in:#7ee787}}\n";
package/dist/codeStyle.js CHANGED
@@ -3,6 +3,9 @@ export const codeStyle = `
3
3
  .code-toolbar{position:sticky;top:0;z-index:1;display:flex;height:42px;align-items:center;justify-content:space-between;gap:16px;padding:0 16px;border-bottom:1px solid var(--code-border);background:var(--code-toolbar-bg);backdrop-filter:blur(12px);box-sizing:border-box}
4
4
  .code-toolbar span,.code-toolbar strong{color:var(--code-muted);font-size:12px;font-weight:700;letter-spacing:0}
5
5
  .code-area{display:block;min-width:min-content;margin:0;padding:18px 20px 28px;overflow:auto;background:transparent;box-sizing:border-box}
6
+ .code-area--line-numbers{display:grid;grid-template-columns:max-content max-content;padding:18px 0 28px}
7
+ .code-line-numbers{position:sticky;left:0;z-index:1;display:block;min-width:4ch;padding:0 12px 0 16px;border-right:1px solid var(--code-border);background:var(--code-bg);color:var(--code-muted);font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,'Liberation Mono',monospace;font-size:var(--code-font-size,13px);line-height:1.7;text-align:right;white-space:pre;user-select:none;box-sizing:border-box}
8
+ .code-area.code-area--line-numbers code{padding:0 20px}
6
9
  .code-area code{display:block;padding:0;overflow:visible;background:transparent;color:inherit;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,'Liberation Mono',monospace;font-size:var(--code-font-size,13px);line-height:1.7;tab-size:2;white-space:pre}
7
10
  .code-area .hljs-comment,.code-area .hljs-quote{color:var(--code-comment)}
8
11
  .code-area .hljs-keyword,.code-area .hljs-selector-tag,.code-area .hljs-subst{color:var(--code-keyword)}
package/dist/index.js CHANGED
@@ -6,8 +6,8 @@ if (textDefinitions.length !== textRendererIds.length) {
6
6
  }
7
7
  export const textRendererDefinitions = textDefinitions;
8
8
  export const renderFileViewerCode = (buffer, target, type, context) => import('./code.js').then(({ default: renderCode }) => renderCode(buffer, target, type, context));
9
- export const renderFileViewerMarkdown = (buffer, target, type, context) => import('./largeText.js').then(async ({ default: renderLargeText, shouldVirtualizeTextBuffer }) => {
10
- if (shouldVirtualizeTextBuffer(buffer, context)) {
9
+ export const renderFileViewerMarkdown = (buffer, target, type, context) => import('./largeText.js').then(async ({ default: renderLargeText, shouldVirtualizeMarkdownBuffer }) => {
10
+ if (shouldVirtualizeMarkdownBuffer(buffer, context)) {
11
11
  return renderLargeText(buffer, target, type || 'md', context);
12
12
  }
13
13
  const { default: renderMarkdown } = await import('./markdown.js');
@@ -3,4 +3,5 @@ export declare const DEFAULT_LARGE_TEXT_THRESHOLD_BYTES: number;
3
3
  export declare const DEFAULT_LARGE_TEXT_LINE_SEGMENT_BYTES: number;
4
4
  export declare const DEFAULT_LARGE_TEXT_OVERSCAN_LINES = 12;
5
5
  export declare const shouldVirtualizeTextBuffer: (buffer: ArrayBuffer, context?: FileRenderContext) => boolean;
6
+ export declare const shouldVirtualizeMarkdownBuffer: (buffer: ArrayBuffer, context?: FileRenderContext) => boolean;
6
7
  export default function renderLargeText(buffer: ArrayBuffer, target: HTMLDivElement, type?: string, context?: FileRenderContext): Promise<FileViewerRenderedInstance>;
package/dist/largeText.js CHANGED
@@ -174,6 +174,14 @@ export const shouldVirtualizeTextBuffer = (buffer, context) => {
174
174
  : DEFAULT_LARGE_TEXT_THRESHOLD_BYTES;
175
175
  return buffer.byteLength > threshold;
176
176
  };
177
+ export const shouldVirtualizeMarkdownBuffer = (buffer, context) => {
178
+ var _a, _b;
179
+ const configured = (_b = (_a = context === null || context === void 0 ? void 0 : context.options) === null || _a === void 0 ? void 0 : _a.text) === null || _b === void 0 ? void 0 : _b.markdownVirtualizeAboveBytes;
180
+ if (!Number.isFinite(configured)) {
181
+ return false;
182
+ }
183
+ return buffer.byteLength > Math.max(0, Number(configured));
184
+ };
177
185
  const largeTextStyle = `
178
186
  .code-viewer--virtual{height:100%;min-height:240px;display:flex;flex-direction:column;overflow:hidden}
179
187
  .code-viewer--virtual .code-toolbar{flex:0 0 42px}
@@ -187,13 +195,13 @@ const largeTextStyle = `
187
195
  .code-virtual-number{position:sticky;left:0;z-index:1;display:inline-block;width:var(--code-line-number-width,7ch);flex:0 0 var(--code-line-number-width,7ch);padding:0 1.25ch 0 .75ch;border-right:1px solid var(--code-border);background:var(--code-bg);color:var(--code-muted);text-align:right;user-select:none;box-sizing:border-box}
188
196
  .code-virtual-content{display:inline-block;padding:0 18px;white-space:pre}
189
197
  .code-virtual-content mark{border-radius:2px;background:#ffd54f;color:#1f2328}
190
- .code-line-segments{position:sticky;left:var(--code-line-number-width,7ch);z-index:1;display:inline-flex;height:100%;align-items:center;gap:2px;padding:0 4px;border-right:1px solid var(--code-border);background:var(--code-toolbar-bg)}
198
+ .code-line-segments{position:sticky;left:var(--code-line-number-offset,var(--code-line-number-width,7ch));z-index:1;display:inline-flex;height:100%;align-items:center;gap:2px;padding:0 4px;border-right:1px solid var(--code-border);background:var(--code-toolbar-bg)}
191
199
  .code-line-segments button{width:22px;height:18px;padding:0;border:1px solid var(--code-border);border-radius:4px;background:var(--code-bg);color:var(--code-muted);font:700 11px/1 ui-monospace,SFMono-Regular,Menlo,monospace;cursor:pointer}
192
200
  .code-line-segments button:disabled{cursor:not-allowed;opacity:.4}
193
201
  .code-line-segments span{min-width:64px;color:var(--code-muted);font-size:11px;line-height:1;text-align:center}
194
202
  `;
195
203
  export default async function renderLargeText(buffer, target, type = 'txt', context) {
196
- var _a, _b, _c, _d, _e, _f, _g;
204
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
197
205
  const t = createFileViewerTranslator(context === null || context === void 0 ? void 0 : context.options);
198
206
  const documentRef = target.ownerDocument;
199
207
  const bytes = new Uint8Array(buffer);
@@ -205,6 +213,10 @@ export default async function renderLargeText(buffer, target, type = 'txt', cont
205
213
  const overscan = Number.isFinite(configuredOverscan)
206
214
  ? clamp(Math.trunc(Number(configuredOverscan)), 2, 100)
207
215
  : DEFAULT_LARGE_TEXT_OVERSCAN_LINES;
216
+ const showToolbar = ((_f = (_e = context === null || context === void 0 ? void 0 : context.options) === null || _e === void 0 ? void 0 : _e.text) === null || _f === void 0 ? void 0 : _f.toolbar) !== false;
217
+ // Undefined preserves the large-text renderer's pre-option behavior. An
218
+ // explicit boolean has the same meaning in both regular and virtual views.
219
+ const showLineNumbers = ((_h = (_g = context === null || context === void 0 ? void 0 : context.options) === null || _g === void 0 ? void 0 : _g.text) === null || _h === void 0 ? void 0 : _h.lineNumbers) !== false;
208
220
  let disposed = false;
209
221
  let zoom = 1;
210
222
  let scheduledFrame = 0;
@@ -216,9 +228,13 @@ export default async function renderLargeText(buffer, target, type = 'txt', cont
216
228
  const style = documentRef.createElement('style');
217
229
  style.textContent = `${codeStyle}\n${largeTextStyle}`;
218
230
  const root = documentRef.createElement('div');
219
- root.className = 'code-viewer code-viewer--virtual';
231
+ root.className = showLineNumbers
232
+ ? 'code-viewer code-viewer--virtual code-viewer--line-numbers'
233
+ : 'code-viewer code-viewer--virtual';
220
234
  root.dataset.viewerZoomProvider = 'code';
221
235
  root.dataset.viewerSearchProvider = 'code-virtual';
236
+ root.dataset.textToolbar = String(showToolbar);
237
+ root.dataset.lineNumbers = String(showLineNumbers);
222
238
  const toolbar = documentRef.createElement('div');
223
239
  toolbar.className = 'code-toolbar';
224
240
  const extensionLabel = documentRef.createElement('span');
@@ -230,9 +246,11 @@ export default async function renderLargeText(buffer, target, type = 'txt', cont
230
246
  status.textContent = t('text.code.indexingLargeFile', { progress: 0 });
231
247
  toolbarMeta.append(status, lineSummary);
232
248
  toolbar.append(extensionLabel, toolbarMeta);
233
- root.append(toolbar);
249
+ if (showToolbar) {
250
+ root.append(toolbar);
251
+ }
234
252
  target.replaceChildren(style, root);
235
- (_e = context === null || context === void 0 ? void 0 : context.onProgressiveRender) === null || _e === void 0 ? void 0 : _e.call(context);
253
+ (_j = context === null || context === void 0 ? void 0 : context.onProgressiveRender) === null || _j === void 0 ? void 0 : _j.call(context);
236
254
  const index = await buildLargeTextIndex(bytes, target, progress => {
237
255
  if (!disposed) {
238
256
  status.textContent = t('text.code.indexingLargeFile', { progress });
@@ -245,6 +263,7 @@ export default async function renderLargeText(buffer, target, type = 'txt', cont
245
263
  root.dataset.totalLines = String(index.lineCount);
246
264
  lineSummary.textContent = `${formatLargeNumber(index.lineCount)} lines`;
247
265
  root.style.setProperty('--code-line-number-width', `${Math.max(6, String(index.lineCount).length + 2)}ch`);
266
+ root.style.setProperty('--code-line-number-offset', showLineNumbers ? 'var(--code-line-number-width)' : '0px');
248
267
  const viewport = documentRef.createElement('div');
249
268
  viewport.className = 'code-virtual-scroll';
250
269
  viewport.dataset.viewerScrollContainer = 'true';
@@ -315,10 +334,13 @@ export default async function renderLargeText(buffer, target, type = 'txt', cont
315
334
  if (line.lineIndex === activeLine) {
316
335
  row.classList.add('code-virtual-line--match');
317
336
  }
318
- const number = documentRef.createElement('span');
319
- number.className = 'code-virtual-number';
320
- number.textContent = String(line.lineIndex + 1);
321
- row.append(number);
337
+ if (showLineNumbers) {
338
+ const number = documentRef.createElement('span');
339
+ number.className = 'code-virtual-number';
340
+ number.setAttribute('aria-hidden', 'true');
341
+ number.textContent = String(line.lineIndex + 1);
342
+ row.append(number);
343
+ }
322
344
  const currentSegment = (_a = lineSegments.get(line.lineIndex)) !== null && _a !== void 0 ? _a : 0;
323
345
  const decoded = decodeLargeTextSegment(index, line, currentSegment, segmentBytes);
324
346
  if (decoded.segmentCount > 1) {
@@ -520,7 +542,7 @@ export default async function renderLargeText(buffer, target, type = 'txt', cont
520
542
  getState: getZoomState,
521
543
  subscribe: zoomEmitter.subscribe
522
544
  });
523
- (_f = context === null || context === void 0 ? void 0 : context.registerExportAdapter) === null || _f === void 0 ? void 0 : _f.call(context, { print: false, exportHtml: false });
545
+ (_k = context === null || context === void 0 ? void 0 : context.registerExportAdapter) === null || _k === void 0 ? void 0 : _k.call(context, { print: false, exportHtml: false });
524
546
  viewport.addEventListener('scroll', scheduleRender, { passive: true });
525
547
  viewport.addEventListener('click', event => {
526
548
  var _a, _b;
@@ -546,7 +568,7 @@ export default async function renderLargeText(buffer, target, type = 'txt', cont
546
568
  lineSegments.set(lineIndex, clamp(next, 0, segmentCount - 1));
547
569
  renderWindow(true);
548
570
  });
549
- const ResizeObserverCtor = (_g = getWindow(target)) === null || _g === void 0 ? void 0 : _g.ResizeObserver;
571
+ const ResizeObserverCtor = (_l = getWindow(target)) === null || _l === void 0 ? void 0 : _l.ResizeObserver;
550
572
  const resizeObserver = ResizeObserverCtor
551
573
  ? new ResizeObserverCtor(() => {
552
574
  updateSpacerHeight();
package/dist/markdown.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { marked } from 'marked';
2
2
  import { createFileViewerZoomChangeEmitter as createZoomChangeEmitter, readFileViewerText as readText, registerFileViewerZoomProvider, unregisterFileViewerZoomProvider, } from '@file-viewer/core';
3
3
  const markdownStyle = `
4
- .markdown-viewer{min-height:100%;padding:28px 16px 48px;background:#eef1f4;overflow:auto;box-sizing:border-box}
4
+ .markdown-viewer{min-height:100%;padding:28px 16px 48px;background:var(--file-viewer-render-surface-background,#eef1f4);overflow:auto;box-sizing:border-box}
5
5
  .markdown-body{color-scheme:light;--bgColor-default:#fff;--bgColor-muted:#f6f8fa;--bgColor-neutral-muted:#818b981f;--borderColor-default:#d1d9e0;--borderColor-muted:#d1d9e0b3;--borderColor-neutral-muted:#d1d9e0b3;--fgColor-default:#1f2328;--fgColor-muted:#59636e;--fgColor-accent:#0969da;background:var(--bgColor-default);border:1px solid rgba(20,35,53,.1);border-radius:12px;margin:0 auto;box-sizing:border-box;min-width:200px;max-width:var(--markdown-max-width,980px);padding:var(--markdown-padding,45px);color:var(--fgColor-default);font-size:var(--markdown-font-size,16px);box-shadow:0 18px 42px rgba(15,23,42,.1)}
6
6
  .markdown-body h1,.markdown-body h2,.markdown-body h3{margin-top:24px;margin-bottom:16px;font-weight:700;line-height:1.25}
7
7
  .markdown-body h1{padding-bottom:.3em;border-bottom:1px solid var(--borderColor-muted);font-size:2em}
@@ -21,10 +21,10 @@ const markdownStyle = `
21
21
  .markdown-mermaid svg{display:block;max-width:100%;height:auto;margin:auto}
22
22
  .markdown-mermaid-error{margin:-8px 0 16px;color:#cf222e;font-size:.875em}
23
23
  [data-viewer-theme='dark'] .markdown-mermaid-error{color:#ff7b72}
24
- [data-viewer-theme='dark'] .markdown-viewer{background:#101820}
24
+ [data-viewer-theme='dark'] .markdown-viewer{background:var(--file-viewer-render-surface-background,#101820)}
25
25
  [data-viewer-theme='dark'] .markdown-body{color-scheme:dark;--bgColor-default:#0d1117;--bgColor-muted:#151b23;--bgColor-neutral-muted:#656c7633;--borderColor-default:#3d444d;--borderColor-muted:#3d444db3;--borderColor-neutral-muted:#3d444db3;--fgColor-default:#f0f6fc;--fgColor-muted:#9198a1;--fgColor-accent:#4493f8;background:var(--bgColor-default);border-color:rgba(139,148,158,.26);color:var(--fgColor-default);box-shadow:0 24px 56px rgba(0,0,0,.38)}
26
26
  @media (max-width:767px){.markdown-viewer{padding:14px 10px 28px}.markdown-body{padding:22px 18px;border-radius:10px}}
27
- @media (prefers-color-scheme:dark){[data-viewer-theme='system'] .markdown-viewer{background:#101820}[data-viewer-theme='system'] .markdown-body{color-scheme:dark;--bgColor-default:#0d1117;--bgColor-muted:#151b23;--bgColor-neutral-muted:#656c7633;--borderColor-default:#3d444d;--borderColor-muted:#3d444db3;--borderColor-neutral-muted:#3d444db3;--fgColor-default:#f0f6fc;--fgColor-muted:#9198a1;--fgColor-accent:#4493f8;background:var(--bgColor-default);border-color:rgba(139,148,158,.26);color:var(--fgColor-default);box-shadow:0 24px 56px rgba(0,0,0,.38)}}
27
+ @media (prefers-color-scheme:dark){[data-viewer-theme='system'] .markdown-viewer{background:var(--file-viewer-render-surface-background,#101820)}[data-viewer-theme='system'] .markdown-body{color-scheme:dark;--bgColor-default:#0d1117;--bgColor-muted:#151b23;--bgColor-neutral-muted:#656c7633;--borderColor-default:#3d444d;--borderColor-muted:#3d444db3;--borderColor-neutral-muted:#3d444db3;--fgColor-default:#f0f6fc;--fgColor-muted:#9198a1;--fgColor-accent:#4493f8;background:var(--bgColor-default);border-color:rgba(139,148,158,.26);color:var(--fgColor-default);box-shadow:0 24px 56px rgba(0,0,0,.38)}}
28
28
  `;
29
29
  const createStyle = () => {
30
30
  const style = document.createElement('style');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@file-viewer/renderer-text",
3
- "version": "2.1.30",
3
+ "version": "2.2.1",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "Standalone code, text, Markdown, patch diff, and Git bundle renderer plugin for Flyfish File Viewer.",
@@ -57,7 +57,7 @@
57
57
  "LICENSE"
58
58
  ],
59
59
  "dependencies": {
60
- "@file-viewer/core": "2.1.30",
60
+ "@file-viewer/core": "2.2.1",
61
61
  "diff2html": "^3.4.56",
62
62
  "highlight.js": "^11.11.1",
63
63
  "marked": "^18.0.5",