@file-viewer/doc 2.1.23 → 2.1.25

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.
@@ -150,11 +150,67 @@ function renderTextNode(node) {
150
150
  }
151
151
  return inner;
152
152
  }
153
+ function inlineImageDisplaySizePx(asset) {
154
+ const widthPx = twipsToPx(asset.meta?.displayWidthTwips);
155
+ const heightPx = twipsToPx(asset.meta?.displayHeightTwips);
156
+ return {
157
+ widthPx: widthPx && widthPx > 0 ? widthPx : undefined,
158
+ heightPx: heightPx && heightPx > 0 ? heightPx : undefined,
159
+ };
160
+ }
161
+ function applyInlineImageDisplaySize(style, asset) {
162
+ const { widthPx, heightPx } = inlineImageDisplaySizePx(asset);
163
+ if (!widthPx && !heightPx)
164
+ return;
165
+ if (widthPx)
166
+ style.width = `${widthPx}px`;
167
+ if (heightPx)
168
+ style.height = `${heightPx}px`;
169
+ }
170
+ function sanitizeImageSource(src) {
171
+ const value = String(src || '').trim();
172
+ if (!value)
173
+ return null;
174
+ if (/^data:image\//i.test(value))
175
+ return value;
176
+ if (/^(?:https?:|blob:)/i.test(value))
177
+ return value;
178
+ return null;
179
+ }
180
+ function sanitizeAssetHref(href) {
181
+ const value = String(href || '').trim();
182
+ if (!value)
183
+ return null;
184
+ if (/^(?:data:|blob:|https?:)/i.test(value))
185
+ return value;
186
+ return null;
187
+ }
153
188
  function renderImageNode(node) {
189
+ const src = sanitizeImageSource(node.asset.sourceUrl) || sanitizeImageSource(node.asset.dataUrl);
154
190
  const baseStyle = inlineStyleToCss(node.style);
155
- baseStyle['max-width'] = '100%';
156
- baseStyle.height = 'auto';
157
- const img = `<img class="msdoc-image" src="${escapeHtml(node.asset.dataUrl)}" alt="" style="${styleObjectToCss(baseStyle)}">`;
191
+ const displaySize = inlineImageDisplaySizePx(node.asset);
192
+ if (displaySize.widthPx || displaySize.heightPx) {
193
+ applyInlineImageDisplaySize(baseStyle, node.asset);
194
+ baseStyle['max-width'] = 'none';
195
+ if (!displaySize.heightPx)
196
+ baseStyle.height = 'auto';
197
+ }
198
+ else {
199
+ baseStyle['max-width'] = '100%';
200
+ baseStyle.height = 'auto';
201
+ }
202
+ if (!src || node.asset.displayable === false) {
203
+ const fallbackHref = sanitizeAssetHref(node.asset.dataUrl) || sanitizeAssetHref(node.asset.sourceUrl);
204
+ const label = escapeHtml(String(node.asset.meta?.linkedPath || node.asset.mime || 'image'));
205
+ const inner = fallbackHref
206
+ ? `<a class="msdoc-attachment msdoc-image-fallback" href="${escapeHtml(fallbackHref)}" target="_blank" rel="noreferrer noopener">🖼 ${label}</a>`
207
+ : `<span class="msdoc-image-fallback">🖼 ${label}</span>`;
208
+ if (node.href) {
209
+ return `<a class="msdoc-link" href="${escapeHtml(node.href)}" target="_blank" rel="noreferrer noopener">${inner}</a>`;
210
+ }
211
+ return inner;
212
+ }
213
+ const img = `<img class="msdoc-image" src="${escapeHtml(src)}" alt="" style="${styleObjectToCss(baseStyle)}">`;
158
214
  if (node.href) {
159
215
  return `<a class="msdoc-link" href="${escapeHtml(node.href)}" target="_blank" rel="noreferrer noopener">${img}</a>`;
160
216
  }
@@ -278,6 +334,7 @@ export function defaultMsDocCss() {
278
334
  .msdoc-link{color:#1a73e8;text-decoration:none}
279
335
  .msdoc-link:hover{text-decoration:underline}
280
336
  .msdoc-image{display:inline-block;vertical-align:middle}
337
+ .msdoc-image-fallback{display:inline-flex;align-items:center;gap:6px}
281
338
  .msdoc-attachment{display:inline-flex;align-items:center;gap:6px;padding:4px 8px;border:1px solid #d0d7de;border-radius:6px;background:#f6f8fa;color:#0969da;text-decoration:none}
282
339
  .msdoc-attachments{margin-top:20px;padding-top:12px;border-top:1px solid #e5e7eb}
283
340
  .msdoc-attachments-title{font-weight:600;margin-bottom:8px}
package/dist/types.d.ts CHANGED
@@ -421,13 +421,75 @@ export interface FieldInstructionRaw {
421
421
  raw: string;
422
422
  }
423
423
  export type FieldInstruction = FieldInstructionHyperlink | FieldInstructionIncludePicture | FieldInstructionRaw;
424
+ export interface PicfSummary {
425
+ pictureOffset: number;
426
+ lcb: number;
427
+ cbHeader: number;
428
+ mm?: number;
429
+ xExt?: number;
430
+ yExt?: number;
431
+ dxaGoalTwips?: number;
432
+ dyaGoalTwips?: number;
433
+ scaleXPermille?: number;
434
+ scaleYPermille?: number;
435
+ displayWidthTwips?: number;
436
+ displayHeightTwips?: number;
437
+ }
438
+ export interface OfficeArtBlipMeta {
439
+ recType?: number;
440
+ recInstance?: number;
441
+ fbseBlipType?: number;
442
+ fbseMime?: string | null;
443
+ fbseTag?: number;
444
+ fbseSize?: number;
445
+ fbseRefCount?: number;
446
+ fbseDelayOffset?: number;
447
+ fbseName?: string;
448
+ fbseDelayStream?: string;
449
+ blipIndex?: number;
450
+ sourceShapeId?: number;
451
+ }
452
+ /** PICF / OfficeArt BLIP / linked-picture metadata used by the HTML renderer. */
453
+ export interface ImageAssetMeta extends PicfSummary, OfficeArtBlipMeta {
454
+ linkedPath?: string;
455
+ sourceKind?: 'embedded' | 'linked' | 'fallback';
456
+ localExternal?: boolean;
457
+ browserRenderable?: boolean;
458
+ metafileCompressed?: boolean;
459
+ metafileCompression?: number;
460
+ metafileFilter?: number;
461
+ metafileUncompressedSize?: number;
462
+ metafileCompressedSize?: number;
463
+ metafileOriginalByteLength?: number;
464
+ metafileDecompressed?: boolean;
465
+ vectorConverted?: boolean;
466
+ vectorSourceMime?: string;
467
+ vectorWidth?: number;
468
+ vectorHeight?: number;
469
+ vectorRecordCount?: number;
470
+ fbseIndex?: number;
471
+ dggOffset?: number;
472
+ blipIndex?: number;
473
+ sourceShapeId?: number;
474
+ }
475
+ export interface AttachmentAssetMeta {
476
+ stream?: string;
477
+ label?: string;
478
+ originalPath?: string;
479
+ tempPath?: string;
480
+ dataSize?: number;
481
+ sourceKind?: 'ole10-native' | 'package' | 'content' | 'unknown';
482
+ [key: string]: unknown;
483
+ }
424
484
  export interface ImageAsset {
425
485
  id: string;
426
486
  type: 'image';
427
487
  mime: string;
428
488
  bytes: Uint8Array;
429
489
  dataUrl: string;
430
- meta?: Record<string, unknown>;
490
+ sourceUrl?: string;
491
+ displayable?: boolean;
492
+ meta?: ImageAssetMeta;
431
493
  }
432
494
  export interface AttachmentAsset {
433
495
  id: string;
@@ -436,7 +498,7 @@ export interface AttachmentAsset {
436
498
  mime: string;
437
499
  bytes: Uint8Array;
438
500
  dataUrl: string;
439
- meta?: Record<string, unknown>;
501
+ meta?: AttachmentAssetMeta;
440
502
  }
441
503
  export type MsDocAsset = ImageAsset | AttachmentAsset;
442
504
  export interface ObjectPoolInfo {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@file-viewer/doc",
3
- "version": "2.1.23",
3
+ "version": "2.1.25",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "Browser-native legacy MS-DOC (.doc) parser and HTML renderer extracted from the public msdoc-viewer 0.2.0 line.",
@@ -68,6 +68,7 @@
68
68
  "scripts": {
69
69
  "build": "tsc -b tsconfig.json",
70
70
  "type-check": "tsc -b tsconfig.json",
71
- "verify:github-34": "pnpm build && node scripts/verify-github-34.mjs"
71
+ "verify:github-34": "pnpm build && node scripts/verify-github-34.mjs",
72
+ "verify:github-87": "pnpm build && node scripts/verify-github-87.mjs"
72
73
  }
73
74
  }