oasis-editor 0.0.95 → 0.0.96

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.
@@ -6,7 +6,7 @@
6
6
  * statements that pointed there continue to work via the barrel
7
7
  * re-export in `src/core/model.ts`.
8
8
  */
9
- export type { EditorUnderlineStyle, EditorLigatures, EditorNumberSpacing, EditorNumberForm, EditorTextLanguage, EditorBorderStyle, EditorEmphasisMark, EditorTabStop, EditorParagraphListStyle, EditorImageCrop, EditorImageFillMode, EditorImageFloatingPosition, EditorImageFloatingLayout, EditorImageRunData, EditorWrapPolygonPoint, EditorFieldData, EditorFieldChar, EditorFootnoteReferenceData, EditorEndnoteReferenceData, EditorRevision, EditorRevisionMetadata, EditorStructuralRevision, EditorPropertyRevision, EditorAsset, EditorFootnoteNumberFormat, EditorFootnoteRestart, EditorDocxWidthValue, EditorTableLayout, EditorTableRowHeightRule, } from './types/primitives.js';
9
+ export type { EditorUnderlineStyle, EditorLigatures, EditorNumberSpacing, EditorNumberForm, EditorTextLanguage, EditorBorderStyle, EditorEmphasisMark, EditorTabStop, EditorParagraphListStyle, EditorImageCrop, EditorImageFillMode, EditorImageFloatingPosition, EditorImageFloatingLayout, EditorImageRunData, EditorWrapPolygonPoint, EditorFieldData, EditorFieldChar, EditorFootnoteReferenceData, EditorEndnoteReferenceData, EditorRevision, EditorRevisionMetadata, EditorStructuralRevision, EditorPropertyRevision, EditorAsset, EditorFootnoteNumberFormat, EditorFootnoteRestart, EditorDocxWidthValue, EditorTableLayout, EditorTableRowHeightRule, EditorGradientStop, EditorTextFill, EditorTextOutline, } from './types/primitives.js';
10
10
  export type { EditorTextStyle, EditorParagraphStyle, EditorTableStyle, EditorTableFloatingLayout, EditorTableConditionalFormat, EditorConditionalRowStyle, EditorTableConditionalType, EditorTableConditionalFlags, EditorTableCellStyle, EditorNamedStyle, } from './types/styles.js';
11
11
  export type { EditorRunBase, EditorTextRun, EditorTextBoxShape, EditorTextBoxBody, EditorTextBoxData, EditorDropCap, EditorParagraphNode, EditorTableCellNode, EditorTableRowStyle, EditorTableRowNode, EditorTableNode, EditorBlockNode, } from './types/nodes.js';
12
12
  export type { RunKind, RunOfKind, RunVisitor } from './runKind.js';
@@ -20,6 +20,30 @@ export interface EditorBorderStyle {
20
20
  }
21
21
  /** `w:em/@w:val`: the emphasis mark drawn over each glyph of a run. */
22
22
  export type EditorEmphasisMark = "dot" | "comma" | "circle" | "underDot" | "none";
23
+ /** One color stop in a `w14:gradFill` gradient. `position` is 0–1 (0 = start, 1 = end). */
24
+ export interface EditorGradientStop {
25
+ position: number;
26
+ color: string;
27
+ alpha?: number;
28
+ }
29
+ /**
30
+ * `w14:textFill` — rich glyph fill that supersedes the plain `w:color`.
31
+ * Phase 2b: gradient canvas/PDF rendering is deferred; only solid is fully rendered now.
32
+ */
33
+ export type EditorTextFill = {
34
+ type: "solid";
35
+ color: string;
36
+ } | {
37
+ type: "gradient";
38
+ stops: EditorGradientStop[];
39
+ angle?: number;
40
+ };
41
+ /** `w14:textOutline` — real stroke on glyphs, supersedes the legacy boolean `w:outline`. */
42
+ export interface EditorTextOutline {
43
+ widthPt: number;
44
+ color?: string;
45
+ fill?: EditorTextFill;
46
+ }
23
47
  export interface EditorTabStop {
24
48
  position: number;
25
49
  type: "left" | "center" | "right" | "decimal" | "bar" | "clear";
@@ -1,4 +1,4 @@
1
- import { EditorBorderStyle, EditorDocxWidthValue, EditorEmphasisMark, EditorLigatures, EditorNumberForm, EditorNumberSpacing, EditorPropertyRevision, EditorStructuralRevision, EditorTabStop, EditorTextLanguage, EditorUnderlineStyle } from './primitives.js';
1
+ import { EditorBorderStyle, EditorDocxWidthValue, EditorEmphasisMark, EditorLigatures, EditorNumberForm, EditorNumberSpacing, EditorPropertyRevision, EditorStructuralRevision, EditorTabStop, EditorTextFill, EditorTextLanguage, EditorTextOutline, EditorUnderlineStyle } from './primitives.js';
2
2
 
3
3
  export interface EditorTextStyle {
4
4
  styleId?: string;
@@ -50,6 +50,10 @@ export interface EditorTextStyle {
50
50
  fontFamily?: string | null;
51
51
  fontSize?: number | null;
52
52
  color?: string | null;
53
+ /** `w14:textFill` — supersedes `color` when present (solid or gradient glyph fill). */
54
+ textFill?: EditorTextFill | null;
55
+ /** `w14:textOutline` — real stroke on glyphs, supersedes the boolean `outline` when present. */
56
+ textOutline?: EditorTextOutline | null;
53
57
  highlight?: string | null;
54
58
  shading?: string | null;
55
59
  language?: EditorTextLanguage | null;
@@ -69,6 +69,10 @@ export interface OasisPdfTextOptions {
69
69
  horizontalScale?: number;
70
70
  /** PDF text render mode (`Tr`): 0 fill (default), 1 stroke, 2 fill+stroke. */
71
71
  renderMode?: number;
72
+ /** Stroke color for render modes 1 (stroke) and 2 (fill+stroke). Defaults to `color`. */
73
+ strokeColor?: string;
74
+ /** Stroke line width in pt for render modes 1 and 2. Defaults to 3% of fontSize. */
75
+ strokeWidth?: number;
72
76
  }
73
77
  export interface OasisPdfImageResource {
74
78
  resourceName: string;
@@ -9,6 +9,14 @@ export type DocxTextDirection = "lrTb" | "tbRl" | "btLr" | "lrTbV" | "tbRlV";
9
9
  /** Validate a raw `w:textDirection/@w:val` token, or return undefined. */
10
10
  export declare function parseTextDirection(value: string | null | undefined): DocxTextDirection | undefined;
11
11
  export declare function getFirstChildByTagNameNS(element: XmlElement | null | undefined, namespace: string, localName: string): XmlElement | null;
12
+ /**
13
+ * Finds a direct `w14:localName` child of `element`, also searching inside
14
+ * `mc:AlternateContent/mc:Choice` branches (which carry w14 markup in files
15
+ * produced by modern Word). The `mc:Fallback` branch used by
16
+ * `getChildrenByTagNameNS` would not contain w14 elements, so a separate
17
+ * helper is needed for these extension elements.
18
+ */
19
+ export declare function getFirstW14Child(element: XmlElement | null | undefined, localName: string): XmlElement | null;
12
20
  export declare function getAttributeValue(element: XmlElement | null, localName: string): string | null;
13
21
  export declare function findElementDeep(element: XmlElement, localName: string): XmlElement | null;
14
22
  /**
@@ -2519,7 +2519,7 @@ function OasisEditorAppLazy(props = {}) {
2519
2519
  onCleanup(() => {
2520
2520
  cancelled = true;
2521
2521
  });
2522
- import("./OasisEditorApp-C_Ao4zIF.js").then((m) => {
2522
+ import("./OasisEditorApp-CMTq6BTy.js").then((m) => {
2523
2523
  cancelled = true;
2524
2524
  setProgress(1);
2525
2525
  setTimeout(() => setApp(() => m.OasisEditorApp), 180);
@@ -21209,7 +21209,14 @@ function drawParagraph(ctx, paragraph, lines, state, originX, originY, onUpdate,
21209
21209
  italic: Boolean(styles.italic),
21210
21210
  sample: fragment.text.slice(0, 80)
21211
21211
  });
21212
- ctx.fillStyle = styles.color ?? "#000000";
21212
+ ctx.fillStyle = resolveCanvasTextFill(
21213
+ ctx,
21214
+ styles,
21215
+ line,
21216
+ fragment,
21217
+ originX,
21218
+ originY
21219
+ );
21213
21220
  if (styles.shading) {
21214
21221
  drawFragmentShading(
21215
21222
  ctx,
@@ -21441,8 +21448,36 @@ function drawScaledText(ctx, text, x, y, scale) {
21441
21448
  ctx.fillText(text, 0, 0);
21442
21449
  ctx.restore();
21443
21450
  }
21451
+ function resolveCanvasTextFill(ctx, styles, line, fragment, originX, originY) {
21452
+ const fill = styles.textFill;
21453
+ if (!fill) return styles.color ?? "#000000";
21454
+ if (fill.type === "solid") return fill.color;
21455
+ if (fill.stops.length < 2) return styles.color ?? "#000000";
21456
+ const bounds = resolveFragmentPaintBounds(line, fragment);
21457
+ if (!bounds) return fill.stops[0].color;
21458
+ const x0 = originX + bounds.left;
21459
+ const x1 = originX + bounds.right;
21460
+ const y0 = originY + line.top;
21461
+ const y1 = originY + line.top + line.height;
21462
+ const cx = (x0 + x1) / 2;
21463
+ const cy = (y0 + y1) / 2;
21464
+ const angleDeg = fill.angle ?? 0;
21465
+ const rad = angleDeg * Math.PI / 180;
21466
+ const dx = Math.cos(rad) * (x1 - x0) / 2;
21467
+ const dy = Math.sin(rad) * (y1 - y0) / 2;
21468
+ const gradient = ctx.createLinearGradient(cx - dx, cy - dy, cx + dx, cy + dy);
21469
+ for (const stop of fill.stops) {
21470
+ const alpha = stop.alpha ?? 1;
21471
+ const r = Number.parseInt(stop.color.slice(1, 3), 16);
21472
+ const g2 = Number.parseInt(stop.color.slice(3, 5), 16);
21473
+ const b = Number.parseInt(stop.color.slice(5, 7), 16);
21474
+ gradient.addColorStop(stop.position, `rgba(${r},${g2},${b},${alpha})`);
21475
+ }
21476
+ return gradient;
21477
+ }
21444
21478
  function drawStyledText(ctx, text, x, y, scale, styles) {
21445
- if (!styles.outline && !styles.shadow && !styles.emboss && !styles.imprint) {
21479
+ const hasEffects = styles.outline || styles.shadow || styles.emboss || styles.imprint || styles.textOutline;
21480
+ if (!hasEffects) {
21446
21481
  drawScaledText(ctx, text, x, y, scale);
21447
21482
  return;
21448
21483
  }
@@ -21461,7 +21496,20 @@ function drawStyledText(ctx, text, x, y, scale, styles) {
21461
21496
  ctx.shadowOffsetY = 1;
21462
21497
  ctx.shadowBlur = 1;
21463
21498
  }
21464
- if (styles.outline) {
21499
+ if (styles.textOutline) {
21500
+ ctx.strokeStyle = styles.textOutline.color ?? ctx.fillStyle;
21501
+ ctx.lineWidth = styles.textOutline.widthPt * PX_PER_POINT;
21502
+ drawScaledText(ctx, text, x, y, scale);
21503
+ if (scale === 1) {
21504
+ ctx.strokeText(text, x, y);
21505
+ } else {
21506
+ ctx.save();
21507
+ ctx.translate(x, y);
21508
+ ctx.scale(scale, 1);
21509
+ ctx.strokeText(text, 0, 0);
21510
+ ctx.restore();
21511
+ }
21512
+ } else if (styles.outline) {
21465
21513
  ctx.strokeStyle = ctx.fillStyle;
21466
21514
  ctx.lineWidth = 0.75;
21467
21515
  if (scale === 1) {
@@ -32507,6 +32555,35 @@ function parseTextDirection(value) {
32507
32555
  function getFirstChildByTagNameNS(element, namespace, localName) {
32508
32556
  return getChildrenByTagNameNS(element, namespace, localName)[0] ?? null;
32509
32557
  }
32558
+ function getFirstW14Child(element, localName) {
32559
+ if (!element) return null;
32560
+ for (let i = 0; i < element.childNodes.length; i++) {
32561
+ const node = element.childNodes[i];
32562
+ if ((node == null ? void 0 : node.nodeType) !== node.ELEMENT_NODE) continue;
32563
+ const el = node;
32564
+ if (el.namespaceURI === WORD14_NS && el.localName === localName) {
32565
+ return el;
32566
+ }
32567
+ if (el.namespaceURI === MARKUP_COMPAT_NS && el.localName === "AlternateContent") {
32568
+ for (let j = 0; j < el.childNodes.length; j++) {
32569
+ const child = el.childNodes[j];
32570
+ if ((child == null ? void 0 : child.nodeType) !== child.ELEMENT_NODE) continue;
32571
+ const choiceEl = child;
32572
+ if (choiceEl.namespaceURI === MARKUP_COMPAT_NS && choiceEl.localName === "Choice") {
32573
+ for (let k = 0; k < choiceEl.childNodes.length; k++) {
32574
+ const gc = choiceEl.childNodes[k];
32575
+ if ((gc == null ? void 0 : gc.nodeType) !== gc.ELEMENT_NODE) continue;
32576
+ const gcEl = gc;
32577
+ if (gcEl.namespaceURI === WORD14_NS && gcEl.localName === localName) {
32578
+ return gcEl;
32579
+ }
32580
+ }
32581
+ }
32582
+ }
32583
+ }
32584
+ }
32585
+ return null;
32586
+ }
32510
32587
  function getAttributeValue(element, localName) {
32511
32588
  if (!element) {
32512
32589
  return null;
@@ -33213,6 +33290,56 @@ function mergeStyles(base, local) {
33213
33290
  function parseShdFill(element) {
33214
33291
  return normalizeImportedHexColor(getAttributeValue(element, "fill"));
33215
33292
  }
33293
+ function parseW14SolidFillColor(solidFillEl) {
33294
+ const srgbClr = getFirstChildByTagNameNS(solidFillEl, WORD14_NS, "srgbClr");
33295
+ if (!srgbClr) return null;
33296
+ const val = getAttributeValue(srgbClr, "val");
33297
+ return val ? normalizeImportedHexColor(val) ?? null : null;
33298
+ }
33299
+ function parseW14TextFill(fillEl) {
33300
+ const solidFill = getFirstChildByTagNameNS(fillEl, WORD14_NS, "solidFill");
33301
+ if (solidFill) {
33302
+ const color = parseW14SolidFillColor(solidFill);
33303
+ if (color) return { type: "solid", color };
33304
+ }
33305
+ const gradFill = getFirstChildByTagNameNS(fillEl, WORD14_NS, "gradFill");
33306
+ if (gradFill) {
33307
+ const gsLst = getFirstChildByTagNameNS(gradFill, WORD14_NS, "gsLst");
33308
+ if (gsLst) {
33309
+ const stops = [];
33310
+ for (let i = 0; i < gsLst.childNodes.length; i++) {
33311
+ const node = gsLst.childNodes[i];
33312
+ if ((node == null ? void 0 : node.nodeType) !== node.ELEMENT_NODE) continue;
33313
+ const gs = node;
33314
+ if (gs.namespaceURI !== WORD14_NS || gs.localName !== "gs") continue;
33315
+ const posVal = getAttributeValue(gs, "pos");
33316
+ const pos = posVal !== null ? Number(posVal) / 1e5 : NaN;
33317
+ if (!Number.isFinite(pos)) continue;
33318
+ const srgbClr = getFirstChildByTagNameNS(gs, WORD14_NS, "srgbClr");
33319
+ if (!srgbClr) continue;
33320
+ const colorVal = getAttributeValue(srgbClr, "val");
33321
+ if (!colorVal) continue;
33322
+ const color = normalizeImportedHexColor(colorVal);
33323
+ if (!color) continue;
33324
+ const alphaEl = getFirstChildByTagNameNS(srgbClr, WORD14_NS, "alpha");
33325
+ const alphaRaw = alphaEl ? getAttributeValue(alphaEl, "val") : null;
33326
+ const alpha = alphaRaw !== null ? Number(alphaRaw) / 1e5 : void 0;
33327
+ const stop = { position: pos, color };
33328
+ if (alpha !== void 0 && Number.isFinite(alpha)) stop.alpha = alpha;
33329
+ stops.push(stop);
33330
+ }
33331
+ if (stops.length > 0) {
33332
+ const linEl = getFirstChildByTagNameNS(gradFill, WORD14_NS, "lin");
33333
+ const angRaw = linEl ? getAttributeValue(linEl, "ang") : null;
33334
+ const angle = angRaw !== null ? Number(angRaw) / 6e4 : void 0;
33335
+ const result = { type: "gradient", stops };
33336
+ if (angle !== void 0 && Number.isFinite(angle)) result.angle = angle;
33337
+ return result;
33338
+ }
33339
+ }
33340
+ }
33341
+ return null;
33342
+ }
33216
33343
  function normalizeImportedRunStyle(style2, paragraphStyleId) {
33217
33344
  if (!style2) {
33218
33345
  return void 0;
@@ -33315,6 +33442,8 @@ function normalizeImportedRunStyle(style2, paragraphStyleId) {
33315
33442
  ),
33316
33443
  fontSize: hd(style2.fontSize, effective.fontSize, defaultEffective.fontSize),
33317
33444
  color: dd(effective.color, defaultEffective.color),
33445
+ textFill: dd(effective.textFill, defaultEffective.textFill),
33446
+ textOutline: dd(effective.textOutline, defaultEffective.textOutline),
33318
33447
  highlight: dd(effective.highlight, defaultEffective.highlight),
33319
33448
  shading: dd(effective.shading, defaultEffective.shading),
33320
33449
  language: dd(effective.language, defaultEffective.language),
@@ -33564,6 +33693,28 @@ function parseRunStyle(runProperties, theme) {
33564
33693
  styles.color = themeColor;
33565
33694
  }
33566
33695
  }
33696
+ const textFillEl = getFirstW14Child(runProperties, "textFill");
33697
+ if (textFillEl) {
33698
+ const textFill = parseW14TextFill(textFillEl);
33699
+ if (textFill) styles.textFill = textFill;
33700
+ }
33701
+ const textOutlineEl = getFirstW14Child(runProperties, "textOutline");
33702
+ if (textOutlineEl) {
33703
+ const wAttr = textOutlineEl.getAttributeNS(WORD14_NS, "w");
33704
+ const widthEmu = wAttr !== null ? Number(wAttr) : NaN;
33705
+ const widthPt = Number.isFinite(widthEmu) && widthEmu > 0 ? widthEmu / 12700 : 0.5;
33706
+ const textOutline = { widthPt };
33707
+ const outlineFill = parseW14TextFill(textOutlineEl);
33708
+ if (outlineFill) {
33709
+ textOutline.fill = outlineFill;
33710
+ if (outlineFill.type === "solid") {
33711
+ textOutline.color = outlineFill.color;
33712
+ } else if (outlineFill.type === "gradient" && outlineFill.stops[0]) {
33713
+ textOutline.color = outlineFill.stops[0].color;
33714
+ }
33715
+ }
33716
+ styles.textOutline = textOutline;
33717
+ }
33567
33718
  const highlight = getFirstChildByTagNameNS(
33568
33719
  runProperties,
33569
33720
  WORD_NS,
@@ -37137,7 +37288,7 @@ function importDocxInWorker(buffer, options = {}) {
37137
37288
  const worker = new Worker(
37138
37289
  new URL(
37139
37290
  /* @vite-ignore */
37140
- "" + new URL("assets/importDocxWorker-DAbfLHtp.js", import.meta.url).href,
37291
+ "" + new URL("assets/importDocxWorker-M34STPYy.js", import.meta.url).href,
37141
37292
  import.meta.url
37142
37293
  ),
37143
37294
  {
@@ -1,4 +1,4 @@
1
- import { O, c6, c7, c8, c9, ca, a8, cb, Q, bR, cc, cd, ce, N, cf, bP, cg, ch, ci, cj, ck, c1, cl, cm, cn, co, cp, cq, cr, cs, ct, cu, cv, cw, ad, cx, c0, cy, c8 as c82, cd as cd2, cf as cf2, co as co2, cq as cq2, cv as cv2, cz, bT, bO, cA, cB, cC, bQ, cD, cE, bS } from "./index-BQEtsRa0.js";
1
+ import { O, c6, c7, c8, c9, ca, a8, cb, Q, bR, cc, cd, ce, N, cf, bP, cg, ch, ci, cj, ck, c1, cl, cm, cn, co, cp, cq, cr, cs, ct, cu, cv, cw, ad, cx, c0, cy, c8 as c82, cd as cd2, cf as cf2, co as co2, cq as cq2, cv as cv2, cz, bT, bO, cA, cB, cC, bQ, cD, cE, bS } from "./index-D0bOD23M.js";
2
2
  export {
3
3
  O as BalloonShell,
4
4
  c6 as Button,