omni-viewer-core 0.3.0 → 0.5.0
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 +28 -0
- package/dist/host/index.d.ts +14 -2
- package/dist/i18n/catalog.en.js +8 -0
- package/dist/i18n/catalog.ja.js +9 -1
- package/dist/i18n/catalog.ko.js +8 -0
- package/dist/i18n/catalog.zh-cn.js +8 -1
- package/dist/parsers/pptx/index.d.ts +1 -0
- package/dist/parsers/pptx/index.js +1 -1
- package/dist/parsers/yaml/index.js +14 -2
- package/dist/parsers/yaml/self-loading.js +26 -14
- package/dist/registry/index.js +1 -1
- package/dist/styles/archive.css +1 -1
- package/dist/styles/pdf.css +26 -0
- package/dist/styles/toml.css +1 -1
- package/dist/styles/yaml.css +1 -1
- package/dist/viewers/archive/index.js +60 -11
- package/dist/viewers/archive/styles.d.ts +1 -1
- package/dist/viewers/archive/styles.js +1 -1
- package/dist/viewers/json/controller.js +13 -24
- package/dist/viewers/json/index.js +5 -1
- package/dist/viewers/markdown/index.d.ts +3 -2
- package/dist/viewers/markdown/index.js +29 -14
- package/dist/viewers/pdf/controller.d.ts +14 -2
- package/dist/viewers/pdf/controller.js +28 -10
- package/dist/viewers/pdf/index.d.ts +79 -8
- package/dist/viewers/pdf/index.js +363 -81
- package/dist/viewers/pdf/self-loading.d.ts +3 -3
- package/dist/viewers/pdf/styles.d.ts +1 -1
- package/dist/viewers/pdf/styles.js +26 -0
- package/dist/viewers/ppt/index.js +3 -3
- package/dist/viewers/structured-styles.d.ts +1 -1
- package/dist/viewers/structured-styles.js +1 -1
- package/dist/viewers/structured.d.ts +1 -0
- package/dist/viewers/structured.js +5 -3
- package/dist/viewers/yaml/controller.js +48 -5
- package/package.json +2 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { ViewerInput
|
|
2
|
-
import { type PdfViewerContext, type PdfViewerDeps, type PdfViewerHandle } from './index.js';
|
|
1
|
+
import type { ViewerInput } from '../types.js';
|
|
2
|
+
import { type PdfMountOptions, type PdfViewerContext, type PdfViewerDeps, type PdfViewerHandle } from './index.js';
|
|
3
3
|
export * from './index.js';
|
|
4
4
|
export declare const selfLoadingPdfDeps: PdfViewerDeps;
|
|
5
5
|
/** mountPdfViewer with the core's own dynamic-import loaders. */
|
|
6
|
-
export declare function mountSelfLoadingPdfViewer(input: ViewerInput, container: HTMLElement, ctx: PdfViewerContext, options?:
|
|
6
|
+
export declare function mountSelfLoadingPdfViewer(input: ViewerInput, container: HTMLElement, ctx: PdfViewerContext, options?: PdfMountOptions): Promise<PdfViewerHandle>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const pdfViewerCss = "\n/* Reverse-contamination guard for 'scoped' mode \u2014 see csv/styles.ts. */\n.omni-viewer--pdf {\n all: initial;\n}\n.omni-viewer--pdf :where(button, input, canvas, img, span, div) {\n all: revert;\n}\n\n:host, .omni-viewer--pdf {\n display: block;\n height: 100%;\n box-sizing: border-box;\n color: var(--omni-fg, #e8e8e8);\n background: var(--omni-bg, #1e1e1e);\n font-family: var(--omni-font, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif);\n font-size: var(--omni-font-size, 13px);\n}\n.omni-pdf, .omni-pdf * { box-sizing: border-box; }\n.omni-pdf {\n position: relative;\n display: flex;\n flex-direction: column;\n height: 100%;\n min-height: 0;\n}\n.omni-pdf__header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n padding: 8px 12px;\n background: var(--omni-bg-secondary, #252526);\n border-bottom: 1px solid var(--omni-border, #3c3c3c);\n flex: none;\n}\n.omni-pdf__title {\n font-weight: 600;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n max-width: 40%;\n}\n.omni-pdf__toolbar {\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n gap: 6px;\n}\n.omni-pdf__page-info {\n color: var(--omni-fg-muted, #9d9d9d);\n margin-right: 8px;\n}\n.omni-pdf__page-input {\n width: 52px;\n padding: 3px 5px;\n margin-right: 5px;\n color: var(--omni-fg, #e8e8e8);\n background: var(--omni-input-bg, #3c3c3c);\n border: 1px solid var(--omni-border, #3c3c3c);\n border-radius: 4px;\n font: inherit;\n text-align: center;\n}\n.omni-pdf__page-input:focus {\n outline: 1px solid var(--omni-accent, #0e639c);\n border-color: var(--omni-accent, #0e639c);\n}\n.omni-pdf button {\n font: inherit;\n color: var(--omni-fg, #e8e8e8);\n background: var(--omni-button-bg, #3a3d41);\n border: 1px solid var(--omni-border, #3c3c3c);\n border-radius: 4px;\n cursor: pointer;\n}\n.omni-pdf button:hover:not(:disabled) {\n background: var(--omni-button-hover-bg, #45494e);\n}\n.omni-pdf button:disabled {\n opacity: 0.45;\n cursor: not-allowed;\n}\n.omni-pdf button[aria-pressed=\"true\"] {\n background: var(--omni-accent, #0e639c);\n border-color: var(--omni-accent, #0e639c);\n color: var(--omni-accent-fg, #ffffff);\n}\n.omni-pdf__tool { padding: 5px 10px; }\n.omni-pdf__markup-wrap {\n position: relative;\n display: inline-flex;\n}\n.omni-pdf__markup-wrap .omni-pdf__tool {\n min-width: 34px;\n padding: 4px 8px;\n font-size: 21px;\n line-height: 1;\n border-radius: 4px 0 0 4px;\n}\n.omni-pdf__markup-menu-btn {\n min-width: 28px;\n padding: 0 6px;\n border-radius: 0 4px 4px 0;\n}\n.omni-pdf__markup-menu {\n position: absolute;\n z-index: 20;\n top: calc(100% + 4px);\n left: 0;\n display: none;\n min-width: 170px;\n padding: 7px;\n background: var(--omni-bg-secondary, #252526);\n border: 1px solid var(--omni-border, #3c3c3c);\n border-radius: 6px;\n box-shadow: 0 6px 18px rgba(0, 0, 0, 0.45);\n}\n.omni-pdf__markup-menu.is-open { display: block; }\n.omni-pdf__markup-choice {\n display: flex;\n align-items: center;\n justify-content: space-between;\n width: 100%;\n box-sizing: border-box;\n min-height: 32px;\n padding: 2px 0;\n}\n.omni-pdf__markup-menu button {\n flex: 1;\n min-height: 32px;\n padding: 5px 8px;\n color: inherit;\n font: inherit;\n}\n.omni-pdf__markup-menu button {\n text-align: left;\n background: transparent;\n border-color: transparent;\n}\n.omni-pdf__markup-menu button:hover,\n.omni-pdf__markup-menu button[aria-checked=\"true\"] { background: var(--omni-button-hover-bg, #45494e); }\n.omni-pdf__markup-menu button[aria-checked=\"true\"]::before { content: \"\u2713 \"; }\n.omni-pdf__highlight-color {\n width: 30px;\n height: 28px;\n padding: 2px;\n border: 1px solid var(--omni-border, #3c3c3c);\n border-radius: 4px;\n background: var(--omni-button-bg, #3a3d41);\n cursor: pointer;\n}\n.omni-pdf__highlight-color:disabled {\n opacity: 0.45;\n cursor: not-allowed;\n}\n.omni-pdf__zoom {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 6px;\n background: var(--omni-bg-secondary, #252526);\n border-bottom: 1px solid var(--omni-border, #3c3c3c);\n flex: none;\n}\n.omni-pdf__zoom-btn {\n width: 28px;\n height: 28px;\n padding: 0;\n font-size: 18px;\n line-height: 1;\n}\n.omni-pdf__zoom-level {\n min-width: 56px;\n text-align: center;\n}\n.omni-pdf__view-menu-wrap { position: relative; }\n.omni-pdf__view-menu-btn {\n width: 30px;\n height: 28px;\n padding: 0;\n font-size: 22px;\n line-height: 1;\n}\n.omni-pdf__view-menu {\n position: absolute;\n z-index: 20;\n top: calc(100% + 4px);\n right: 0;\n display: none;\n min-width: 210px;\n padding: 6px;\n background: var(--omni-bg-secondary, #252526);\n border: 1px solid var(--omni-border, #3c3c3c);\n border-radius: 6px;\n box-shadow: 0 6px 18px rgba(0, 0, 0, 0.45);\n}\n.omni-pdf__view-menu.is-open { display: block; }\n.omni-pdf__view-menu button {\n display: block;\n width: 100%;\n padding: 7px 10px;\n text-align: left;\n background: transparent;\n border-color: transparent;\n}\n.omni-pdf__view-menu button:hover,\n.omni-pdf__view-menu button[aria-checked=\"true\"] {\n background: var(--omni-button-hover-bg, #45494e);\n}\n.omni-pdf__view-menu button[aria-checked=\"true\"]::before {\n content: \"\u2713 \";\n}\n.omni-pdf__view-menu hr {\n height: 1px;\n margin: 5px 2px;\n border: 0;\n background: var(--omni-border, #3c3c3c);\n}\n.omni-pdf__body {\n flex: 1;\n min-height: 0;\n display: grid;\n grid-template-columns: 160px minmax(0, 1fr);\n overflow: hidden;\n}\n.omni-pdf__thumbs {\n overflow: auto;\n min-height: 0;\n background: var(--omni-bg-secondary, #252526);\n border-right: 1px solid var(--omni-border, #3c3c3c);\n padding: 8px;\n}\n.omni-pdf__thumb {\n position: relative;\n display: flex;\n width: 100%;\n min-height: 130px;\n margin: 0 0 8px;\n padding: 6px;\n align-items: center;\n justify-content: center;\n flex-direction: column;\n gap: 4px;\n background: transparent;\n}\n.omni-pdf__thumb:hover,\n.omni-pdf__thumb[aria-current] {\n background: var(--omni-button-hover-bg, #45494e);\n border-color: var(--omni-accent, #0e639c);\n}\n.omni-pdf__thumb.is-dragging { opacity: 0.5; }\n.omni-pdf__thumb.drop-before::before,\n.omni-pdf__thumb.drop-after::after {\n content: \"\";\n position: absolute;\n left: -4px;\n right: -4px;\n height: 3px;\n background: var(--omni-accent, #0e639c);\n border-radius: 2px;\n z-index: 4;\n}\n.omni-pdf__thumb.drop-before::before { top: -6px; }\n.omni-pdf__thumb.drop-after::after { bottom: -6px; }\n.omni-pdf__thumb canvas {\n max-width: 100%;\n background: #ffffff;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.5);\n}\n.omni-pdf__thumb-label {\n font-family: var(--omni-font-mono, Monaco, Menlo, monospace);\n font-size: 10px;\n color: var(--omni-fg-muted, #9d9d9d);\n}\n.omni-pdf__thumb-remove {\n position: absolute;\n top: 2px;\n right: 2px;\n width: 22px;\n height: 22px;\n padding: 0;\n border-radius: 50%;\n}\n.omni-pdf__pages {\n overflow: auto;\n position: relative;\n padding: 20px;\n min-width: 0;\n min-height: 0;\n}\n.omni-pdf__pages--spread {\n display: grid;\n grid-template-columns: repeat(2, max-content);\n align-content: start;\n justify-content: center;\n column-gap: 16px;\n}\n.omni-pdf__spread-blank {\n min-width: 1px;\n}\n.omni-pdf__pages--theme .omni-pdf__page {\n background: var(--omni-bg-secondary, #252526);\n}\n.omni-pdf__pages--theme .omni-pdf__page canvas {\n filter: invert(0.92) hue-rotate(180deg);\n}\n.omni-pdf__page {\n position: relative;\n margin: 0 auto 16px;\n background: #ffffff; /* paper */\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.5);\n}\n.omni-pdf__page canvas {\n display: block;\n max-width: 100%;\n height: auto;\n}\n.omni-pdf__placeholder {\n display: flex;\n width: 100%;\n height: 100%;\n align-items: center;\n justify-content: center;\n color: var(--omni-fg-muted, #9d9d9d);\n}\n.omni-pdf__text-layer {\n position: absolute;\n inset: 0;\n z-index: 1;\n overflow: clip;\n opacity: 1;\n line-height: 1;\n text-align: initial;\n text-size-adjust: none;\n forced-color-adjust: none;\n transform-origin: 0 0;\n caret-color: CanvasText;\n pointer-events: auto;\n user-select: text;\n -webkit-user-select: text;\n}\n.omni-pdf__text-layer span,\n.omni-pdf__text-layer br {\n position: absolute;\n white-space: pre;\n color: transparent;\n cursor: text;\n transform-origin: 0 0;\n user-select: text;\n -webkit-user-select: text;\n}\n.omni-pdf__text-layer ::selection {\n background: rgba(14, 99, 156, 0.35);\n}\n/* While placing text/signature, let clicks fall through to the canvas. */\n.omni-pdf__pages--placing .omni-pdf__text-layer {\n pointer-events: none;\n user-select: none;\n}\n.omni-pdf__annotation {\n position: absolute;\n z-index: 2;\n padding: 0;\n color: #111111; /* ink on paper */\n cursor: move;\n touch-action: none;\n}\n.omni-pdf button.omni-pdf__annotation {\n background: transparent;\n border: 0;\n font: inherit;\n}\n.omni-pdf__annotation img {\n display: block;\n pointer-events: none;\n}\n.omni-pdf__annotation.is-selected,\n.omni-pdf__annotation:hover,\n.omni-pdf__annotation.is-hovered,\n.omni-pdf__annotation:focus-visible,\n.omni-pdf__annotation:focus-within {\n outline: 1px solid var(--omni-accent, #0e639c);\n outline-offset: 2px;\n}\n.omni-pdf__annotation-delete {\n position: absolute;\n top: -10px;\n right: -10px;\n z-index: 1;\n display: none;\n width: 18px;\n height: 18px;\n padding: 0;\n border: 1px solid var(--omni-border, #3c3c3c);\n border-radius: 50%;\n background: var(--omni-bg-secondary, #252526);\n color: var(--omni-fg, #e8e8e8);\n font-size: 15px;\n line-height: 14px;\n cursor: pointer;\n}\n.omni-pdf__annotation.is-selected .omni-pdf__annotation-delete,\n.omni-pdf__annotation:hover .omni-pdf__annotation-delete,\n.omni-pdf__annotation:focus-visible .omni-pdf__annotation-delete,\n.omni-pdf__annotation:focus-within .omni-pdf__annotation-delete {\n display: block;\n}\n.omni-pdf__highlight {\n background: var(--omni-hl-color, #ffeb3b);\n mix-blend-mode: multiply;\n cursor: pointer;\n}\n.omni-pdf__strikeout {\n background: transparent;\n cursor: pointer;\n}\n.omni-pdf__strikeout::after {\n position: absolute;\n top: calc(50% - 1px);\n left: 0;\n width: 100%;\n height: 2px;\n content: '';\n background: var(--omni-hl-color, #ffeb3b);\n}\n.omni-pdf__underline {\n background: transparent;\n cursor: pointer;\n}\n.omni-pdf__underline::after {\n position: absolute;\n bottom: 8%;\n left: 0;\n width: 100%;\n height: 2px;\n content: '';\n background: var(--omni-hl-color, #ffeb3b);\n}\n.omni-pdf__text-editor {\n position: absolute;\n z-index: 3;\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 3px;\n background: var(--omni-bg-secondary, #252526);\n border: 1px solid var(--omni-accent, #0e639c);\n border-radius: 3px;\n}\n.omni-pdf__text-input {\n min-width: 160px;\n font: inherit;\n color: #111111;\n background: #ffffff;\n border: 0;\n border-radius: 2px;\n padding: 2px 4px;\n}\n.omni-pdf__text-size-input {\n width: 52px;\n font: inherit;\n}\n.omni-pdf__color-input {\n width: 28px;\n height: 24px;\n padding: 0;\n border: 0;\n background: transparent;\n cursor: pointer;\n}\n.omni-pdf__status {\n padding: 8px 12px;\n color: var(--omni-fg-muted, #9d9d9d);\n border-top: 1px solid var(--omni-border, #3c3c3c);\n flex: none;\n}\n.omni-pdf__status--error {\n color: var(--omni-error-fg, #f48771);\n font-weight: 600;\n}\n.omni-pdf__modal {\n /* A dialog must be positioned against the visible viewport. Anchoring it\n to the flex viewer made it drift when the host or page list scrolled. */\n position: fixed;\n inset: 0;\n z-index: 1000;\n display: none;\n align-items: center;\n justify-content: center;\n background: rgba(0, 0, 0, 0.55);\n}\n.omni-pdf__modal.is-open { display: flex; }\n.omni-pdf__panel {\n display: flex;\n flex-direction: column;\n gap: 12px;\n padding: 18px;\n background: var(--omni-bg-secondary, #252526);\n border: 1px solid var(--omni-border, #3c3c3c);\n border-radius: 8px;\n}\n.omni-pdf__panel input {\n font: inherit;\n color: var(--omni-fg, #e8e8e8);\n background: var(--omni-input-bg, #3c3c3c);\n border: 1px solid var(--omni-border, #3c3c3c);\n border-radius: 4px;\n padding: 6px 8px;\n}\n.omni-pdf__field {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n}\n.omni-pdf__field input[type=\"color\"] {\n width: 40px;\n height: 26px;\n padding: 0;\n background: transparent;\n cursor: pointer;\n}\n.omni-pdf__panel button { padding: 5px 12px; }\n.omni-pdf__panel-actions {\n display: flex;\n justify-content: flex-end;\n gap: 8px;\n}\n.omni-pdf__error {\n color: var(--omni-error-fg, #f48771);\n}\n.omni-pdf__signature-pad {\n display: block;\n width: min(480px, 80vw);\n height: auto;\n background: #ffffff;\n touch-action: none;\n}\n@media (max-width: 720px) {\n .omni-pdf__body {\n grid-template-columns: minmax(0, 1fr);\n grid-template-rows: minmax(120px, 30vh) minmax(0, 1fr);\n }\n .omni-pdf__thumbs {\n border-right: 0;\n border-bottom: 1px solid var(--omni-border, #3c3c3c);\n }\n .omni-pdf__pages { grid-row: 2; }\n}\n";
|
|
1
|
+
export declare const pdfViewerCss = "\n/* Reverse-contamination guard for 'scoped' mode \u2014 see csv/styles.ts. */\n.omni-viewer--pdf {\n all: initial;\n}\n.omni-viewer--pdf :where(button, input, canvas, img, span, div) {\n all: revert;\n}\n\n:host, .omni-viewer--pdf {\n display: block;\n height: 100%;\n box-sizing: border-box;\n color: var(--omni-fg, #e8e8e8);\n background: var(--omni-bg, #1e1e1e);\n font-family: var(--omni-font, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif);\n font-size: var(--omni-font-size, 13px);\n}\n.omni-pdf, .omni-pdf * { box-sizing: border-box; }\n.omni-pdf {\n position: relative;\n display: flex;\n flex-direction: column;\n height: 100%;\n min-height: 0;\n}\n.omni-pdf__header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n padding: 8px 12px;\n background: var(--omni-bg-secondary, #252526);\n border-bottom: 1px solid var(--omni-border, #3c3c3c);\n flex: none;\n}\n.omni-pdf__title {\n font-weight: 600;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n max-width: 40%;\n}\n.omni-pdf__toolbar {\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n gap: 6px;\n}\n.omni-pdf__page-info {\n color: var(--omni-fg-muted, #9d9d9d);\n margin-right: 8px;\n}\n.omni-pdf__save-mode {\n padding: 2px 6px;\n color: var(--omni-fg-muted, #9d9d9d);\n border: 1px solid var(--omni-border, #3c3c3c);\n border-radius: 999px;\n font-size: 11px;\n white-space: nowrap;\n}\n.omni-pdf__page-input {\n width: 52px;\n padding: 3px 5px;\n margin-right: 5px;\n color: var(--omni-fg, #e8e8e8);\n background: var(--omni-input-bg, #3c3c3c);\n border: 1px solid var(--omni-border, #3c3c3c);\n border-radius: 4px;\n font: inherit;\n text-align: center;\n}\n.omni-pdf__page-input:focus {\n outline: 1px solid var(--omni-accent, #0e639c);\n border-color: var(--omni-accent, #0e639c);\n}\n.omni-pdf button {\n font: inherit;\n color: var(--omni-fg, #e8e8e8);\n background: var(--omni-button-bg, #3a3d41);\n border: 1px solid var(--omni-border, #3c3c3c);\n border-radius: 4px;\n cursor: pointer;\n}\n.omni-pdf button:hover:not(:disabled) {\n background: var(--omni-button-hover-bg, #45494e);\n}\n.omni-pdf button:disabled {\n opacity: 0.45;\n cursor: not-allowed;\n}\n.omni-pdf button[aria-pressed=\"true\"] {\n background: var(--omni-accent, #0e639c);\n border-color: var(--omni-accent, #0e639c);\n color: var(--omni-accent-fg, #ffffff);\n}\n.omni-pdf__tool { padding: 5px 10px; }\n.omni-pdf__markup-wrap {\n position: relative;\n display: inline-flex;\n}\n.omni-pdf__markup-wrap .omni-pdf__tool {\n min-width: 34px;\n padding: 4px 8px;\n font-size: 21px;\n line-height: 1;\n border-radius: 4px 0 0 4px;\n}\n.omni-pdf__markup-menu-btn {\n min-width: 28px;\n padding: 0 6px;\n border-radius: 0 4px 4px 0;\n}\n.omni-pdf__markup-menu {\n position: absolute;\n z-index: 20;\n top: calc(100% + 4px);\n left: 0;\n display: none;\n min-width: 170px;\n padding: 7px;\n background: var(--omni-bg-secondary, #252526);\n border: 1px solid var(--omni-border, #3c3c3c);\n border-radius: 6px;\n box-shadow: 0 6px 18px rgba(0, 0, 0, 0.45);\n}\n.omni-pdf__markup-menu.is-open { display: block; }\n.omni-pdf__markup-choice {\n display: flex;\n align-items: center;\n justify-content: space-between;\n width: 100%;\n box-sizing: border-box;\n min-height: 32px;\n padding: 2px 0;\n}\n.omni-pdf__markup-menu button {\n flex: 1;\n min-height: 32px;\n padding: 5px 8px;\n color: inherit;\n font: inherit;\n}\n.omni-pdf__markup-menu button {\n text-align: left;\n background: transparent;\n border-color: transparent;\n}\n.omni-pdf__markup-menu button:hover,\n.omni-pdf__markup-menu button[aria-checked=\"true\"] { background: var(--omni-button-hover-bg, #45494e); }\n.omni-pdf__markup-menu button[aria-checked=\"true\"]::before { content: \"\u2713 \"; }\n.omni-pdf__highlight-color {\n width: 30px;\n height: 28px;\n padding: 2px;\n border: 1px solid var(--omni-border, #3c3c3c);\n border-radius: 4px;\n background: var(--omni-button-bg, #3a3d41);\n cursor: pointer;\n}\n.omni-pdf__highlight-color:disabled {\n opacity: 0.45;\n cursor: not-allowed;\n}\n.omni-pdf__zoom {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 6px;\n background: var(--omni-bg-secondary, #252526);\n border-bottom: 1px solid var(--omni-border, #3c3c3c);\n flex: none;\n}\n.omni-pdf__zoom-btn {\n width: 28px;\n height: 28px;\n padding: 0;\n font-size: 18px;\n line-height: 1;\n}\n.omni-pdf__zoom-level {\n min-width: 56px;\n text-align: center;\n}\n.omni-pdf__view-menu-wrap { position: relative; }\n.omni-pdf__view-menu-btn {\n width: 30px;\n height: 28px;\n padding: 0;\n font-size: 22px;\n line-height: 1;\n}\n.omni-pdf__view-menu {\n position: absolute;\n z-index: 20;\n top: calc(100% + 4px);\n right: 0;\n display: none;\n min-width: 210px;\n padding: 6px;\n background: var(--omni-bg-secondary, #252526);\n border: 1px solid var(--omni-border, #3c3c3c);\n border-radius: 6px;\n box-shadow: 0 6px 18px rgba(0, 0, 0, 0.45);\n}\n.omni-pdf__view-menu.is-open { display: block; }\n.omni-pdf__view-menu button {\n display: block;\n width: 100%;\n padding: 7px 10px;\n text-align: left;\n background: transparent;\n border-color: transparent;\n}\n.omni-pdf__view-menu button:hover,\n.omni-pdf__view-menu button[aria-checked=\"true\"] {\n background: var(--omni-button-hover-bg, #45494e);\n}\n.omni-pdf__view-menu button[aria-checked=\"true\"]::before {\n content: \"\u2713 \";\n}\n.omni-pdf__view-menu hr {\n height: 1px;\n margin: 5px 2px;\n border: 0;\n background: var(--omni-border, #3c3c3c);\n}\n.omni-pdf__body {\n flex: 1;\n min-height: 0;\n display: grid;\n grid-template-columns: 160px minmax(0, 1fr);\n overflow: hidden;\n}\n.omni-pdf__thumbs {\n overflow: auto;\n min-height: 0;\n background: var(--omni-bg-secondary, #252526);\n border-right: 1px solid var(--omni-border, #3c3c3c);\n padding: 8px;\n}\n.omni-pdf__thumb {\n position: relative;\n display: flex;\n width: 100%;\n min-height: 130px;\n margin: 0 0 8px;\n padding: 6px;\n align-items: center;\n justify-content: center;\n flex-direction: column;\n gap: 4px;\n background: transparent;\n}\n.omni-pdf__thumb:hover,\n.omni-pdf__thumb[aria-current] {\n background: var(--omni-button-hover-bg, #45494e);\n border-color: var(--omni-accent, #0e639c);\n}\n.omni-pdf__thumb.is-dragging { opacity: 0.5; }\n.omni-pdf__thumb.drop-before::before,\n.omni-pdf__thumb.drop-after::after {\n content: \"\";\n position: absolute;\n left: -4px;\n right: -4px;\n height: 3px;\n background: var(--omni-accent, #0e639c);\n border-radius: 2px;\n z-index: 4;\n}\n.omni-pdf__thumb.drop-before::before { top: -6px; }\n.omni-pdf__thumb.drop-after::after { bottom: -6px; }\n.omni-pdf__thumb canvas {\n display: block;\n max-width: 100%;\n background: #ffffff;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.5);\n}\n.omni-pdf__thumb-page {\n position: relative;\n max-width: 100%;\n}\n.omni-pdf__thumb-annotation {\n position: absolute;\n z-index: 1;\n overflow: hidden;\n pointer-events: none;\n color: #111111; /* ink on paper */\n white-space: nowrap;\n}\n.omni-pdf__thumb-annotation img { display: block; }\n.omni-pdf__thumb-annotation.omni-pdf__underline::after,\n.omni-pdf__thumb-annotation.omni-pdf__strikeout::after {\n height: 1px;\n}\n.omni-pdf__thumb-label {\n font-family: var(--omni-font-mono, Monaco, Menlo, monospace);\n font-size: 10px;\n color: var(--omni-fg-muted, #9d9d9d);\n}\n.omni-pdf__thumb-remove {\n position: absolute;\n top: 2px;\n right: 2px;\n width: 22px;\n height: 22px;\n padding: 0;\n border-radius: 50%;\n}\n.omni-pdf__pages {\n overflow: auto;\n position: relative;\n padding: 20px;\n min-width: 0;\n min-height: 0;\n}\n.omni-pdf__pages--spread {\n display: grid;\n grid-template-columns: repeat(2, max-content);\n align-content: start;\n justify-content: center;\n column-gap: 16px;\n}\n.omni-pdf__spread-blank {\n min-width: 1px;\n}\n.omni-pdf__pages--theme .omni-pdf__page {\n background: var(--omni-bg-secondary, #252526);\n}\n.omni-pdf__pages--theme .omni-pdf__page canvas {\n filter: invert(0.92) hue-rotate(180deg);\n}\n.omni-pdf__page {\n position: relative;\n margin: 0 auto 16px;\n background: #ffffff; /* paper */\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.5);\n}\n.omni-pdf__page canvas {\n display: block;\n max-width: 100%;\n height: auto;\n}\n.omni-pdf__placeholder {\n display: flex;\n width: 100%;\n height: 100%;\n align-items: center;\n justify-content: center;\n color: var(--omni-fg-muted, #9d9d9d);\n}\n.omni-pdf__text-layer {\n position: absolute;\n inset: 0;\n z-index: 1;\n overflow: clip;\n opacity: 1;\n line-height: 1;\n text-align: initial;\n text-size-adjust: none;\n forced-color-adjust: none;\n transform-origin: 0 0;\n caret-color: CanvasText;\n pointer-events: auto;\n user-select: text;\n -webkit-user-select: text;\n}\n.omni-pdf__text-layer span,\n.omni-pdf__text-layer br {\n position: absolute;\n white-space: pre;\n color: transparent;\n cursor: text;\n transform-origin: 0 0;\n user-select: text;\n -webkit-user-select: text;\n}\n.omni-pdf__text-layer ::selection {\n background: rgba(14, 99, 156, 0.35);\n}\n/* While placing text/signature, let clicks fall through to the canvas. */\n.omni-pdf__pages--placing .omni-pdf__text-layer {\n pointer-events: none;\n user-select: none;\n}\n.omni-pdf__annotation {\n position: absolute;\n z-index: 2;\n padding: 0;\n color: #111111; /* ink on paper */\n cursor: move;\n touch-action: none;\n}\n.omni-pdf button.omni-pdf__annotation {\n background: transparent;\n border: 0;\n font: inherit;\n}\n.omni-pdf__annotation img {\n display: block;\n pointer-events: none;\n}\n.omni-pdf__annotation.is-selected,\n.omni-pdf__annotation:hover,\n.omni-pdf__annotation.is-hovered,\n.omni-pdf__annotation:focus-visible,\n.omni-pdf__annotation:focus-within {\n outline: 1px solid var(--omni-accent, #0e639c);\n outline-offset: 2px;\n}\n.omni-pdf__annotation-delete {\n position: absolute;\n top: -10px;\n right: -10px;\n z-index: 1;\n display: none;\n width: 18px;\n height: 18px;\n padding: 0;\n border: 1px solid var(--omni-border, #3c3c3c);\n border-radius: 50%;\n background: var(--omni-bg-secondary, #252526);\n color: var(--omni-fg, #e8e8e8);\n font-size: 15px;\n line-height: 14px;\n cursor: pointer;\n}\n.omni-pdf__annotation.is-selected .omni-pdf__annotation-delete,\n.omni-pdf__annotation:hover .omni-pdf__annotation-delete,\n.omni-pdf__annotation:focus-visible .omni-pdf__annotation-delete,\n.omni-pdf__annotation:focus-within .omni-pdf__annotation-delete {\n display: block;\n}\n.omni-pdf__highlight {\n background: var(--omni-hl-color, #ffeb3b);\n mix-blend-mode: multiply;\n cursor: pointer;\n}\n.omni-pdf__strikeout {\n background: transparent;\n cursor: pointer;\n}\n.omni-pdf__strikeout::after {\n position: absolute;\n top: calc(50% - 1px);\n left: 0;\n width: 100%;\n height: 2px;\n content: '';\n background: var(--omni-hl-color, #ffeb3b);\n}\n.omni-pdf__underline {\n background: transparent;\n cursor: pointer;\n}\n.omni-pdf__underline::after {\n position: absolute;\n bottom: 8%;\n left: 0;\n width: 100%;\n height: 2px;\n content: '';\n background: var(--omni-hl-color, #ffeb3b);\n}\n.omni-pdf__text-editor {\n position: absolute;\n z-index: 3;\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 3px;\n background: var(--omni-bg-secondary, #252526);\n border: 1px solid var(--omni-accent, #0e639c);\n border-radius: 3px;\n}\n.omni-pdf__text-input {\n min-width: 160px;\n font: inherit;\n color: #111111;\n background: #ffffff;\n border: 0;\n border-radius: 2px;\n padding: 2px 4px;\n}\n.omni-pdf__text-size-input {\n width: 52px;\n font: inherit;\n}\n.omni-pdf__color-input {\n width: 28px;\n height: 24px;\n padding: 0;\n border: 0;\n background: transparent;\n cursor: pointer;\n}\n.omni-pdf__status {\n padding: 8px 12px;\n color: var(--omni-fg-muted, #9d9d9d);\n border-top: 1px solid var(--omni-border, #3c3c3c);\n flex: none;\n}\n.omni-pdf__status--error {\n color: var(--omni-error-fg, #f48771);\n font-weight: 600;\n}\n.omni-pdf__modal {\n /* A dialog must be positioned against the visible viewport. Anchoring it\n to the flex viewer made it drift when the host or page list scrolled. */\n position: fixed;\n inset: 0;\n z-index: 1000;\n display: none;\n align-items: center;\n justify-content: center;\n background: rgba(0, 0, 0, 0.55);\n}\n.omni-pdf__modal.is-open { display: flex; }\n.omni-pdf__panel {\n display: flex;\n flex-direction: column;\n gap: 12px;\n padding: 18px;\n background: var(--omni-bg-secondary, #252526);\n border: 1px solid var(--omni-border, #3c3c3c);\n border-radius: 8px;\n}\n.omni-pdf__panel input {\n font: inherit;\n color: var(--omni-fg, #e8e8e8);\n background: var(--omni-input-bg, #3c3c3c);\n border: 1px solid var(--omni-border, #3c3c3c);\n border-radius: 4px;\n padding: 6px 8px;\n}\n.omni-pdf__field {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n}\n.omni-pdf__field input[type=\"color\"] {\n width: 40px;\n height: 26px;\n padding: 0;\n background: transparent;\n cursor: pointer;\n}\n.omni-pdf__panel button { padding: 5px 12px; }\n.omni-pdf__panel-actions {\n display: flex;\n justify-content: flex-end;\n gap: 8px;\n}\n.omni-pdf__error {\n color: var(--omni-error-fg, #f48771);\n}\n.omni-pdf__signature-pad {\n display: block;\n width: min(480px, 80vw);\n height: auto;\n background: #ffffff;\n touch-action: none;\n}\n@media (max-width: 720px) {\n .omni-pdf__body {\n grid-template-columns: minmax(0, 1fr);\n grid-template-rows: minmax(120px, 30vh) minmax(0, 1fr);\n }\n .omni-pdf__thumbs {\n border-right: 0;\n border-bottom: 1px solid var(--omni-border, #3c3c3c);\n }\n .omni-pdf__pages { grid-row: 2; }\n}\n";
|
|
@@ -54,6 +54,14 @@ export const pdfViewerCss = `
|
|
|
54
54
|
color: var(--omni-fg-muted, #9d9d9d);
|
|
55
55
|
margin-right: 8px;
|
|
56
56
|
}
|
|
57
|
+
.omni-pdf__save-mode {
|
|
58
|
+
padding: 2px 6px;
|
|
59
|
+
color: var(--omni-fg-muted, #9d9d9d);
|
|
60
|
+
border: 1px solid var(--omni-border, #3c3c3c);
|
|
61
|
+
border-radius: 999px;
|
|
62
|
+
font-size: 11px;
|
|
63
|
+
white-space: nowrap;
|
|
64
|
+
}
|
|
57
65
|
.omni-pdf__page-input {
|
|
58
66
|
width: 52px;
|
|
59
67
|
padding: 3px 5px;
|
|
@@ -268,10 +276,28 @@ export const pdfViewerCss = `
|
|
|
268
276
|
.omni-pdf__thumb.drop-before::before { top: -6px; }
|
|
269
277
|
.omni-pdf__thumb.drop-after::after { bottom: -6px; }
|
|
270
278
|
.omni-pdf__thumb canvas {
|
|
279
|
+
display: block;
|
|
271
280
|
max-width: 100%;
|
|
272
281
|
background: #ffffff;
|
|
273
282
|
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.5);
|
|
274
283
|
}
|
|
284
|
+
.omni-pdf__thumb-page {
|
|
285
|
+
position: relative;
|
|
286
|
+
max-width: 100%;
|
|
287
|
+
}
|
|
288
|
+
.omni-pdf__thumb-annotation {
|
|
289
|
+
position: absolute;
|
|
290
|
+
z-index: 1;
|
|
291
|
+
overflow: hidden;
|
|
292
|
+
pointer-events: none;
|
|
293
|
+
color: #111111; /* ink on paper */
|
|
294
|
+
white-space: nowrap;
|
|
295
|
+
}
|
|
296
|
+
.omni-pdf__thumb-annotation img { display: block; }
|
|
297
|
+
.omni-pdf__thumb-annotation.omni-pdf__underline::after,
|
|
298
|
+
.omni-pdf__thumb-annotation.omni-pdf__strikeout::after {
|
|
299
|
+
height: 1px;
|
|
300
|
+
}
|
|
275
301
|
.omni-pdf__thumb-label {
|
|
276
302
|
font-family: var(--omni-font-mono, Monaco, Menlo, monospace);
|
|
277
303
|
font-size: 10px;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { parsePptBinaryVscode } from '../../parsers/ppt-binary/index.js';
|
|
2
|
-
import { openPptxZip,
|
|
2
|
+
import { openPptxZip, parsePptxLegacy, parsePptxVscode } from '../../parsers/pptx/index.js';
|
|
3
3
|
import { mountPdfViewer } from '../pdf/index.js';
|
|
4
4
|
import { MountAbortedError, VIEWER_ROOT_CLASS } from '../types.js';
|
|
5
5
|
import { createPptController } from './controller.js';
|
|
@@ -41,7 +41,7 @@ export async function mountPptViewer(input, container, ctx, deps = {}, options =
|
|
|
41
41
|
return mountPdfFallback(input, container, ctx, deps, options, 'diag.ppt.empty');
|
|
42
42
|
if (!deck.slides.some(slide => slide.elements.length > 0)) {
|
|
43
43
|
if (isPptx) {
|
|
44
|
-
const legacy = await (deps.parseLegacyPptx?.(input.data, options) ??
|
|
44
|
+
const legacy = await (deps.parseLegacyPptx?.(input.data, options) ?? parsePptxLegacy(input.data, { openZip: deps.openZip ?? openPptxZip }, options));
|
|
45
45
|
if (legacy.result.status !== 'failed' && legacy.result.document.slides.some(slide => slide.elements.length > 0))
|
|
46
46
|
deck = legacy.result.document;
|
|
47
47
|
else
|
|
@@ -64,7 +64,7 @@ export async function mountPptViewer(input, container, ctx, deps = {}, options =
|
|
|
64
64
|
next.setAttribute('aria-label', ctx.i18n.t('ppt.next'));
|
|
65
65
|
jump.setAttribute('aria-label', ctx.i18n.t('ppt.jump'));
|
|
66
66
|
deck.slides.forEach(slide => { const option = el('option'); option.value = String(slide.slideNumber); const title = slide.elements.find(element => element.isTitle)?.paragraphs?.map(paragraph => paragraph.text).join(' '); option.textContent = `Slide ${slide.slideNumber}${title ? `: ${title}` : ''}`; jump.append(option); });
|
|
67
|
-
toolbar.append(prev, next, jump, count, minus,
|
|
67
|
+
toolbar.append(prev, next, jump, count, minus, reset, plus, mode);
|
|
68
68
|
const viewport = el('div', 'omni-ppt__viewport'), slides = el('div', 'omni-ppt__slides');
|
|
69
69
|
viewport.append(slides);
|
|
70
70
|
frame.append(toolbar, viewport);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const structuredViewerCss = ":host,.omni-viewer--toml,.omni-viewer--yaml{display:block;height:100%;color:var(--omni-fg,#ddd);background:var(--omni-bg,#1e1e1e);font:13px var(--omni-font,system-ui)}.omni-structured{height:100%;display:flex;flex-direction:column;box-sizing:border-box}.omni-structured__bar{display:flex;gap:5px;align-items:center;padding:6px;border-bottom:1px solid var(--omni-border,#444)}.omni-structured button,.omni-structured input,.omni-structured select{font:inherit;background:var(--omni-button-bg,#333);color:inherit;border:1px solid var(--omni-border,#555);border-radius:3px;padding:3px 7px}.omni-structured button:disabled{opacity:.5}.omni-structured__search{min-width:180px}.omni-structured__diagnostics{white-space:pre-wrap;color:var(--omni-error,#f48771);padding:6px;border-bottom:1px solid var(--omni-border,#444)}.omni-structured__workspace{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);grid-template-rows:minmax(0,1fr);gap:12px;flex:1;min-height:0;padding:12px}.omni-structured__pane{display:flex;flex-direction:column;min-width:0;min-height:0;border:1px solid var(--omni-border,#444);border-radius:8px;overflow:hidden;background:var(--omni-input-bg,#171717)}.omni-structured__pane-header{display:flex;justify-content:space-between;gap:12px;padding:10px 12px;border-bottom:1px solid var(--omni-border,#444)}.omni-structured__pane-header span{color:var(--omni-fg-muted,#999)}.omni-structured__editor,.omni-structured__tree{box-sizing:border-box;flex:1;min-height:0;padding:10px;background:transparent;color:inherit;font:inherit;font-family:var(--omni-font-mono,ui-monospace,monospace)}.omni-structured__editor{resize:none;border:0;outline:none;line-height:1.5;white-space:pre;overflow:auto}.omni-structured__source-surface{position:relative;flex:1;min-height:0;overflow:hidden}.omni-structured__source-highlight{position:absolute;inset:0;box-sizing:border-box;margin:0;padding:10px;overflow:auto;pointer-events:none;font:inherit;font-family:var(--omni-font-mono,ui-monospace,monospace);line-height:1.5;white-space:pre}.omni-structured__pane--highlighted-source .omni-structured__editor{position:relative;z-index:1;width:100%;height:100%;padding:10px;color:transparent;caret-color:var(--omni-fg,#ddd);-webkit-text-fill-color:transparent}.omni-structured__source-key{color:#9cdcfe}.omni-structured__source-value{color:#ce9178}.omni-structured__source-table{color:#c586c0}.omni-structured__source-comment{color:var(--omni-fg-muted,#999)}.omni-structured__tree{overflow:auto}.omni-structured__node{display:flex;gap:6px;align-items:baseline;min-height:25px}.omni-structured__toggle{width:24px;padding:0!important;border:0!important;background:transparent!important}.omni-structured__key{color:var(--omni-accent,#5aa9e6)}.omni-structured__kind{color:var(--omni-fg-muted,#999)}.omni-structured__value{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.omni-structured__actions{margin-left:auto;display:flex;gap:4px;opacity:0}.omni-structured__node:hover .omni-structured__actions,.omni-structured__actions:focus-within{opacity:1}.omni-structured__raw-preview,.omni-structured__json-preview{flex:1;min-height:0;margin:0;padding:10px;overflow:auto;font-family:var(--omni-font-mono,ui-monospace,monospace);line-height:1.5}.omni-structured__flat-row .omni-structured__key{flex-shrink:0}@media(max-width:720px){.omni-structured__workspace{grid-template-columns:1fr;overflow:auto}.omni-structured__pane{min-height:320px}}";
|
|
1
|
+
export declare const structuredViewerCss = ":host,.omni-viewer--toml,.omni-viewer--yaml{display:block;height:100%;color:var(--omni-fg,#ddd);background:var(--omni-bg,#1e1e1e);font:13px var(--omni-font,system-ui)}.omni-structured{height:100%;display:flex;flex-direction:column;box-sizing:border-box}.omni-structured__bar{display:flex;gap:5px;align-items:center;padding:6px;border-bottom:1px solid var(--omni-border,#444)}.omni-structured button,.omni-structured input,.omni-structured select{font:inherit;background:var(--omni-button-bg,#333);color:inherit;border:1px solid var(--omni-border,#555);border-radius:3px;padding:3px 7px}.omni-structured button:disabled{opacity:.5}.omni-structured__search{min-width:180px}.omni-structured__diagnostics{white-space:pre-wrap;color:var(--omni-error,#f48771);padding:6px;border-bottom:1px solid var(--omni-border,#444)}.omni-structured__workspace{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);grid-template-rows:minmax(0,1fr);gap:12px;flex:1;min-height:0;padding:12px}.omni-structured__pane{display:flex;flex-direction:column;min-width:0;min-height:0;border:1px solid var(--omni-border,#444);border-radius:8px;overflow:hidden;background:var(--omni-input-bg,#171717)}.omni-structured__pane-header{display:flex;justify-content:space-between;gap:12px;padding:10px 12px;border-bottom:1px solid var(--omni-border,#444)}.omni-structured__pane-header span{color:var(--omni-fg-muted,#999)}.omni-structured__editor,.omni-structured__tree{box-sizing:border-box;flex:1;min-height:0;padding:10px;background:transparent;color:inherit;font:inherit;font-family:var(--omni-font-mono,ui-monospace,monospace)}.omni-structured__editor{resize:none;border:0;outline:none;line-height:1.5;white-space:pre;overflow:auto}.omni-structured__source-surface{position:relative;flex:1;min-height:0;overflow:hidden}.omni-structured__source-highlight{position:absolute;inset:0;box-sizing:border-box;margin:0;padding:10px;overflow:auto;pointer-events:none;font:inherit;font-family:var(--omni-font-mono,ui-monospace,monospace);line-height:1.5;white-space:pre}.omni-structured__pane--highlighted-source .omni-structured__editor{position:relative;z-index:1;width:100%;height:100%;padding:10px;color:transparent;caret-color:var(--omni-fg,#ddd);-webkit-text-fill-color:transparent}.omni-structured__source-key{color:#9cdcfe}.omni-structured__source-value{color:#ce9178}.omni-structured__source-table{color:#c586c0}.omni-structured__source-comment{color:var(--omni-fg-muted,#999)}.omni-structured__tree{overflow:auto}.omni-structured__preview-body{position:relative;flex:1;min-height:200px}.omni-structured__preview-body>.omni-structured__tree,.omni-structured__preview-body>.omni-structured__json-preview,.omni-structured__preview-body>.omni-structured__raw-preview{position:absolute;inset:0}.omni-structured__node{display:flex;gap:6px;align-items:baseline;min-height:25px}.omni-structured__toggle{width:24px;padding:0!important;border:0!important;background:transparent!important}.omni-structured__key{color:var(--omni-accent,#5aa9e6)}.omni-structured__kind{color:var(--omni-fg-muted,#999)}.omni-structured__value{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.omni-structured__actions{margin-left:auto;display:flex;gap:4px;opacity:0}.omni-structured__node:hover .omni-structured__actions,.omni-structured__actions:focus-within{opacity:1}.omni-structured__raw-preview,.omni-structured__json-preview{flex:1;min-height:0;margin:0;padding:10px;overflow:auto;font-family:var(--omni-font-mono,ui-monospace,monospace);line-height:1.5}.omni-structured__flat-row .omni-structured__key{flex-shrink:0}@media(max-width:720px){.omni-structured__workspace{grid-template-columns:1fr;overflow:auto}.omni-structured__pane{min-height:320px}}";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export const structuredViewerCss = `:host,.omni-viewer--toml,.omni-viewer--yaml{display:block;height:100%;color:var(--omni-fg,#ddd);background:var(--omni-bg,#1e1e1e);font:13px var(--omni-font,system-ui)}.omni-structured{height:100%;display:flex;flex-direction:column;box-sizing:border-box}.omni-structured__bar{display:flex;gap:5px;align-items:center;padding:6px;border-bottom:1px solid var(--omni-border,#444)}.omni-structured button,.omni-structured input,.omni-structured select{font:inherit;background:var(--omni-button-bg,#333);color:inherit;border:1px solid var(--omni-border,#555);border-radius:3px;padding:3px 7px}.omni-structured button:disabled{opacity:.5}.omni-structured__search{min-width:180px}.omni-structured__diagnostics{white-space:pre-wrap;color:var(--omni-error,#f48771);padding:6px;border-bottom:1px solid var(--omni-border,#444)}.omni-structured__workspace{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);grid-template-rows:minmax(0,1fr);gap:12px;flex:1;min-height:0;padding:12px}.omni-structured__pane{display:flex;flex-direction:column;min-width:0;min-height:0;border:1px solid var(--omni-border,#444);border-radius:8px;overflow:hidden;background:var(--omni-input-bg,#171717)}.omni-structured__pane-header{display:flex;justify-content:space-between;gap:12px;padding:10px 12px;border-bottom:1px solid var(--omni-border,#444)}.omni-structured__pane-header span{color:var(--omni-fg-muted,#999)}.omni-structured__editor,.omni-structured__tree{box-sizing:border-box;flex:1;min-height:0;padding:10px;background:transparent;color:inherit;font:inherit;font-family:var(--omni-font-mono,ui-monospace,monospace)}.omni-structured__editor{resize:none;border:0;outline:none;line-height:1.5;white-space:pre;overflow:auto}.omni-structured__source-surface{position:relative;flex:1;min-height:0;overflow:hidden}.omni-structured__source-highlight{position:absolute;inset:0;box-sizing:border-box;margin:0;padding:10px;overflow:auto;pointer-events:none;font:inherit;font-family:var(--omni-font-mono,ui-monospace,monospace);line-height:1.5;white-space:pre}.omni-structured__pane--highlighted-source .omni-structured__editor{position:relative;z-index:1;width:100%;height:100%;padding:10px;color:transparent;caret-color:var(--omni-fg,#ddd);-webkit-text-fill-color:transparent}.omni-structured__source-key{color:#9cdcfe}.omni-structured__source-value{color:#ce9178}.omni-structured__source-table{color:#c586c0}.omni-structured__source-comment{color:var(--omni-fg-muted,#999)}.omni-structured__tree{overflow:auto}.omni-structured__node{display:flex;gap:6px;align-items:baseline;min-height:25px}.omni-structured__toggle{width:24px;padding:0!important;border:0!important;background:transparent!important}.omni-structured__key{color:var(--omni-accent,#5aa9e6)}.omni-structured__kind{color:var(--omni-fg-muted,#999)}.omni-structured__value{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.omni-structured__actions{margin-left:auto;display:flex;gap:4px;opacity:0}.omni-structured__node:hover .omni-structured__actions,.omni-structured__actions:focus-within{opacity:1}.omni-structured__raw-preview,.omni-structured__json-preview{flex:1;min-height:0;margin:0;padding:10px;overflow:auto;font-family:var(--omni-font-mono,ui-monospace,monospace);line-height:1.5}.omni-structured__flat-row .omni-structured__key{flex-shrink:0}@media(max-width:720px){.omni-structured__workspace{grid-template-columns:1fr;overflow:auto}.omni-structured__pane{min-height:320px}}`;
|
|
1
|
+
export const structuredViewerCss = `:host,.omni-viewer--toml,.omni-viewer--yaml{display:block;height:100%;color:var(--omni-fg,#ddd);background:var(--omni-bg,#1e1e1e);font:13px var(--omni-font,system-ui)}.omni-structured{height:100%;display:flex;flex-direction:column;box-sizing:border-box}.omni-structured__bar{display:flex;gap:5px;align-items:center;padding:6px;border-bottom:1px solid var(--omni-border,#444)}.omni-structured button,.omni-structured input,.omni-structured select{font:inherit;background:var(--omni-button-bg,#333);color:inherit;border:1px solid var(--omni-border,#555);border-radius:3px;padding:3px 7px}.omni-structured button:disabled{opacity:.5}.omni-structured__search{min-width:180px}.omni-structured__diagnostics{white-space:pre-wrap;color:var(--omni-error,#f48771);padding:6px;border-bottom:1px solid var(--omni-border,#444)}.omni-structured__workspace{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);grid-template-rows:minmax(0,1fr);gap:12px;flex:1;min-height:0;padding:12px}.omni-structured__pane{display:flex;flex-direction:column;min-width:0;min-height:0;border:1px solid var(--omni-border,#444);border-radius:8px;overflow:hidden;background:var(--omni-input-bg,#171717)}.omni-structured__pane-header{display:flex;justify-content:space-between;gap:12px;padding:10px 12px;border-bottom:1px solid var(--omni-border,#444)}.omni-structured__pane-header span{color:var(--omni-fg-muted,#999)}.omni-structured__editor,.omni-structured__tree{box-sizing:border-box;flex:1;min-height:0;padding:10px;background:transparent;color:inherit;font:inherit;font-family:var(--omni-font-mono,ui-monospace,monospace)}.omni-structured__editor{resize:none;border:0;outline:none;line-height:1.5;white-space:pre;overflow:auto}.omni-structured__source-surface{position:relative;flex:1;min-height:0;overflow:hidden}.omni-structured__source-highlight{position:absolute;inset:0;box-sizing:border-box;margin:0;padding:10px;overflow:auto;pointer-events:none;font:inherit;font-family:var(--omni-font-mono,ui-monospace,monospace);line-height:1.5;white-space:pre}.omni-structured__pane--highlighted-source .omni-structured__editor{position:relative;z-index:1;width:100%;height:100%;padding:10px;color:transparent;caret-color:var(--omni-fg,#ddd);-webkit-text-fill-color:transparent}.omni-structured__source-key{color:#9cdcfe}.omni-structured__source-value{color:#ce9178}.omni-structured__source-table{color:#c586c0}.omni-structured__source-comment{color:var(--omni-fg-muted,#999)}.omni-structured__tree{overflow:auto}.omni-structured__preview-body{position:relative;flex:1;min-height:200px}.omni-structured__preview-body>.omni-structured__tree,.omni-structured__preview-body>.omni-structured__json-preview,.omni-structured__preview-body>.omni-structured__raw-preview{position:absolute;inset:0}.omni-structured__node{display:flex;gap:6px;align-items:baseline;min-height:25px}.omni-structured__toggle{width:24px;padding:0!important;border:0!important;background:transparent!important}.omni-structured__key{color:var(--omni-accent,#5aa9e6)}.omni-structured__kind{color:var(--omni-fg-muted,#999)}.omni-structured__value{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.omni-structured__actions{margin-left:auto;display:flex;gap:4px;opacity:0}.omni-structured__node:hover .omni-structured__actions,.omni-structured__actions:focus-within{opacity:1}.omni-structured__raw-preview,.omni-structured__json-preview{flex:1;min-height:0;margin:0;padding:10px;overflow:auto;font-family:var(--omni-font-mono,ui-monospace,monospace);line-height:1.5}.omni-structured__flat-row .omni-structured__key{flex-shrink:0}@media(max-width:720px){.omni-structured__workspace{grid-template-columns:1fr;overflow:auto}.omni-structured__pane{min-height:320px}}`;
|
|
@@ -77,7 +77,9 @@ export function mountStructured(input, container, ctx, options, className, css,
|
|
|
77
77
|
const flatBody = el('div', 'omni-structured__tree omni-structured__flat');
|
|
78
78
|
const jsonPreview = el('pre', 'omni-structured__json-preview');
|
|
79
79
|
const rawPreview = el('pre', 'omni-structured__raw-preview');
|
|
80
|
-
|
|
80
|
+
const previewBody = el('div', 'omni-structured__preview-body');
|
|
81
|
+
previewBody.append(treeBody, flatBody, jsonPreview, rawPreview);
|
|
82
|
+
previewPane.append(previewHeader, previewBody);
|
|
81
83
|
workspace.append(sourcePane, previewPane);
|
|
82
84
|
frame.append(toolbar, diagnostics, workspace);
|
|
83
85
|
const copy = (value) => { if (value !== undefined)
|
|
@@ -115,12 +117,12 @@ export function mountStructured(input, container, ctx, options, className, css,
|
|
|
115
117
|
wrap.append(rendered);
|
|
116
118
|
} return wrap; };
|
|
117
119
|
const render = (state) => { if (editor.value !== state.text && document.activeElement !== editor)
|
|
118
|
-
editor.value = state.text; if (sourceHighlight && sourceHighlighter)
|
|
120
|
+
editor.value = state.text; editor.rows = Math.min(state.text.split('\n').length + 1, 200); if (sourceHighlight && sourceHighlighter)
|
|
119
121
|
sourceHighlighter(sourceHighlight, state.text); if (sourceHighlighter)
|
|
120
122
|
sourceHighlighter(rawPreview, state.text);
|
|
121
123
|
else
|
|
122
124
|
rawPreview.textContent = state.text; search.value = state.search; treeMode.setAttribute('aria-pressed', String(state.mode === 'tree')); flatMode.setAttribute('aria-pressed', String(state.mode === 'flat')); jsonMode.setAttribute('aria-pressed', String(state.mode === 'json')); rawMode.setAttribute('aria-pressed', String(state.mode === 'raw')); treeBody.style.display = state.mode === 'tree' ? '' : 'none'; flatBody.style.display = state.mode === 'flat' ? '' : 'none'; jsonPreview.style.display = state.mode === 'json' ? '' : 'none'; rawPreview.style.display = state.mode === 'raw' ? '' : 'none'; jsonPreview.textContent = state.mode === 'json' ? controller.documentJson?.() ?? '' : ''; expand.disabled = collapse.disabled = state.mode !== 'tree'; save.disabled = !ctx.writeback; save.title = ctx.writeback ? '' : ctx.i18n.t('common.noWriteback'); saveAs.disabled = !ctx.save; saveAs.title = ctx.save ? '' : ctx.i18n.t('common.noFileSave'); diagnostics.replaceChildren(); diagnostics.style.display = state.diagnostics.length ? '' : 'none'; for (const diagnostic of state.diagnostics)
|
|
123
|
-
diagnostics.append(el('div', undefined, `${ctx.i18n.t(diagnostic.messageKey)}${diagnostic.location ? ` (${diagnostic.location})` : ''}`)); const shaped = state; const docs = shaped.documents; documentSelect.replaceChildren(); documentSelect.style.display = docs && docs.length > 1 ? '' : 'none'; if (docs && docs.length > 1) {
|
|
125
|
+
diagnostics.append(el('div', undefined, `${ctx.i18n.t(diagnostic.messageKey, diagnostic.args)}${diagnostic.location ? ` (${diagnostic.location})` : ''}`)); const shaped = state; const docs = shaped.documents; documentSelect.replaceChildren(); documentSelect.style.display = docs && docs.length > 1 ? '' : 'none'; if (docs && docs.length > 1) {
|
|
124
126
|
docs.forEach((_, index) => { const option = el('option', undefined, String(index + 1)); option.value = String(index); option.selected = index === shaped.selectedDocument; documentSelect.append(option); });
|
|
125
127
|
documentSelect.onchange = () => controller.dispatch({ type: 'select-document', index: Number(documentSelect.value) });
|
|
126
128
|
} treeBody.replaceChildren(); flatBody.replaceChildren(); const roots = shaped.root ? [shaped.root] : docs ? [docs[shaped.selectedDocument ?? 0]].filter((node) => !!node) : []; roots.forEach(node => { const rendered = renderNode(node, 0, state); if (rendered)
|
|
@@ -1,15 +1,58 @@
|
|
|
1
1
|
import { asciiLower } from '../../parsers/csv/index.js';
|
|
2
2
|
import { parseYaml } from '../../parsers/yaml/index.js';
|
|
3
3
|
export function createYamlController(input, deps) {
|
|
4
|
-
const listeners = new Set(), nodes = new Map();
|
|
4
|
+
const listeners = new Set(), nodes = new Map(), anchors = new Map(), order = new Map();
|
|
5
5
|
const state = { status: 'ok', documents: [], selectedDocument: 0, mode: 'tree', search: '', expanded: new Set(), diagnostics: [], text: typeof input === 'string' ? input : new TextDecoder().decode(input) };
|
|
6
|
-
const index = () => { const result = parseYaml(state.text, deps ? { deps } : {}).result; state.status = result.status; state.diagnostics = result.diagnostics; state.documents = result.status === 'failed' ? [] : result.document.documents; state.selectedDocument = Math.min(state.selectedDocument, Math.max(0, state.documents.length - 1)); nodes.clear(); const walk = (node) => { nodes.set(node.path, node);
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
const index = () => { const result = parseYaml(state.text, deps ? { deps } : {}).result; state.status = result.status; state.diagnostics = result.diagnostics; state.documents = result.status === 'failed' ? [] : result.document.documents; state.selectedDocument = Math.min(state.selectedDocument, Math.max(0, state.documents.length - 1)); nodes.clear(); anchors.clear(); order.clear(); let ordinal = 0; const walk = (node, doc) => { nodes.set(node.path, node); order.set(node, ordinal++); if (node.anchorId) {
|
|
7
|
+
const defs = anchors.get(`${doc}|${node.anchorId}`) ?? [];
|
|
8
|
+
defs.push(node);
|
|
9
|
+
anchors.set(`${doc}|${node.anchorId}`, defs);
|
|
10
|
+
} for (const child of node.children ?? [])
|
|
11
|
+
walk(child, doc); }; state.documents.forEach(document => walk(document, document.path)); };
|
|
12
|
+
const docOf = (path) => path.slice(0, path.indexOf(']') + 1);
|
|
13
|
+
const resolveAlias = (node, doc) => { const defs = node.aliasOf === undefined ? undefined : anchors.get(`${doc}|${node.aliasOf}`); if (!defs?.length)
|
|
14
|
+
return undefined; const at = order.get(node) ?? Number.MAX_SAFE_INTEGER; let target; for (const def of defs) {
|
|
15
|
+
if ((order.get(def) ?? Number.MAX_SAFE_INTEGER) < at)
|
|
16
|
+
target = def;
|
|
17
|
+
else
|
|
18
|
+
break;
|
|
19
|
+
} return target ?? defs[defs.length - 1]; };
|
|
20
|
+
const plain = (node, doc, visiting = new Set()) => {
|
|
21
|
+
if (node.kind === 'alias') {
|
|
22
|
+
if (node.value !== undefined)
|
|
23
|
+
return node.value;
|
|
24
|
+
const target = resolveAlias(node, doc);
|
|
25
|
+
if (!target || visiting.has(target))
|
|
26
|
+
return null;
|
|
27
|
+
visiting.add(target);
|
|
28
|
+
const resolved = plain(target, doc, visiting);
|
|
29
|
+
visiting.delete(target);
|
|
30
|
+
return resolved;
|
|
31
|
+
}
|
|
32
|
+
if (!node.children)
|
|
33
|
+
return node.value;
|
|
34
|
+
if (node.kind === 'seq')
|
|
35
|
+
return node.children.map(child => plain(child, doc, visiting));
|
|
36
|
+
const out = {};
|
|
37
|
+
const merges = [];
|
|
38
|
+
for (const child of node.children)
|
|
39
|
+
child.key === '<<' ? merges.push(child) : out[child.key] = plain(child, doc, visiting);
|
|
40
|
+
for (const merge of merges) {
|
|
41
|
+
const merged = plain(merge, doc, visiting);
|
|
42
|
+
for (const source of Array.isArray(merged) ? merged : [merged]) {
|
|
43
|
+
if (source && typeof source === 'object')
|
|
44
|
+
for (const [key, value] of Object.entries(source)) {
|
|
45
|
+
if (!(key in out))
|
|
46
|
+
out[key] = value;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return out;
|
|
51
|
+
};
|
|
9
52
|
const notify = () => listeners.forEach(listener => listener(state));
|
|
10
53
|
index();
|
|
11
54
|
state.expanded = new Set(state.documents.flatMap(node => [node.path, ...(node.children ?? []).filter(child => !!child.children?.length).map(child => child.path)]));
|
|
12
|
-
return { state, subscribe(listener) { listeners.add(listener); return () => listeners.delete(listener); }, nodePath: id => nodes.get(id)?.path ?? '', nodeValue: id => nodes.get(id)?.raw ?? String(nodes.get(id)?.value ?? ''), nodeJson: id =>
|
|
55
|
+
return { state, subscribe(listener) { listeners.add(listener); return () => listeners.delete(listener); }, nodePath: id => nodes.get(id)?.path ?? '', nodeValue: id => nodes.get(id)?.raw ?? String(nodes.get(id)?.value ?? ''), nodeJson: id => { const node = nodes.get(id) ?? state.documents[state.selectedDocument]; return JSON.stringify(plain(node, docOf(node.path)), null, 2); }, documentJson() { const document = state.documents[state.selectedDocument]; return document ? JSON.stringify(plain(document, document.path), null, 2) : ''; }, dispatch(action) { if (action.type === 'edit-source') {
|
|
13
56
|
state.text = action.text;
|
|
14
57
|
index();
|
|
15
58
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "omni-viewer-core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Shared parsing + rendering core for Omni Viewer (vscode / chrome / obsidian / web)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -283,6 +283,7 @@
|
|
|
283
283
|
"build": "tsc -p tsconfig.build.json && node scripts/build-styles.mjs",
|
|
284
284
|
"test": "vitest run",
|
|
285
285
|
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
286
|
+
"verify:pdf-package": "node scripts/verify-pdf-package.mjs",
|
|
286
287
|
"prepublishOnly": "npm run build && npm test"
|
|
287
288
|
},
|
|
288
289
|
"devDependencies": {
|