@a3s-lab/office 0.44.0 → 0.46.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.
Files changed (25) hide show
  1. package/README.md +24 -0
  2. package/dist/{0~2330.js → 0~2133.js} +325 -19
  3. package/dist/{0~5024.js → 0~4042.js} +110 -2
  4. package/dist/0~document-editor.js +562 -9
  5. package/dist/0~work-docx-export.js +206 -8
  6. package/dist/0~work-docx-import.js +22 -7
  7. package/dist/0~work-office-diagnostics.js +19 -3
  8. package/dist/4174.js +508 -3
  9. package/dist/internal/features/work/editors/document-command-catalog.d.ts +15 -1
  10. package/dist/internal/features/work/editors/document-picture-properties-dialog-model.d.ts +4 -1
  11. package/dist/internal/features/work/editors/document-text-box-ribbon.d.ts +4 -0
  12. package/dist/internal/features/work/editors/document-toolbar.d.ts +2 -1
  13. package/dist/internal/features/work/editors/use-document-insert-commands.d.ts +1 -0
  14. package/dist/internal/features/work/work-document-image-layout.d.ts +14 -0
  15. package/dist/internal/features/work/work-document-text-box.d.ts +64 -0
  16. package/dist/internal/features/work/work-docx-export-image.d.ts +2 -1
  17. package/dist/internal/features/work/work-docx-image-layout-import.d.ts +2 -1
  18. package/dist/internal/features/work/work-docx-image-transform.d.ts +17 -0
  19. package/dist/internal/features/work/work-docx-import.d.ts +3 -1
  20. package/dist/internal/features/work/work-docx-text-box-export.d.ts +25 -0
  21. package/dist/internal/features/work/work-docx-text-box-import.d.ts +26 -0
  22. package/dist/office-kernel.wasm +0 -0
  23. package/dist/styles.css +101 -2
  24. package/docs/latest/en/browser-editor-architecture.md +7 -3
  25. package/package.json +6 -3
@@ -23,6 +23,11 @@ export declare const documentPictureRibbonTab: {
23
23
  readonly label: "图片";
24
24
  readonly contextual: true;
25
25
  };
26
+ export declare const documentTextBoxRibbonTab: {
27
+ readonly id: "textBox";
28
+ readonly label: "文本框";
29
+ readonly contextual: true;
30
+ };
26
31
  export declare const documentTableRibbonTabs: readonly [{
27
32
  readonly id: "tableDesign";
28
33
  readonly label: "表格设计";
@@ -41,7 +46,7 @@ export declare const documentPageChromeRibbonTab: {
41
46
  readonly contextual: true;
42
47
  };
43
48
  export type DocumentStandardRibbonTabId = (typeof documentRibbonTabs)[number]['id'];
44
- export type DocumentRibbonTabId = DocumentStandardRibbonTabId | typeof documentPictureRibbonTab.id | (typeof documentTableRibbonTabs)[number]['id'] | typeof documentPageChromeRibbonTab.id;
49
+ export type DocumentRibbonTabId = DocumentStandardRibbonTabId | typeof documentPictureRibbonTab.id | typeof documentTextBoxRibbonTab.id | (typeof documentTableRibbonTabs)[number]['id'] | typeof documentPageChromeRibbonTab.id;
45
50
  export interface DocumentCommandShortcut {
46
51
  label: string;
47
52
  aria: string;
@@ -533,6 +538,15 @@ export declare const documentCommandCatalog: {
533
538
  readonly editor: readonly ["Mod-Enter"];
534
539
  };
535
540
  };
541
+ readonly insertTextBox: {
542
+ readonly id: "insert.textBox";
543
+ readonly label: "插入文本框";
544
+ readonly location: {
545
+ readonly area: "ribbon";
546
+ readonly tab: "insert";
547
+ readonly group: "text";
548
+ };
549
+ };
536
550
  readonly hyperlink: {
537
551
  readonly id: "insert.hyperlink";
538
552
  readonly label: "添加链接";
@@ -1,4 +1,4 @@
1
- import type { WorkDocumentImageAlignment, WorkDocumentImageHorizontalReference, WorkDocumentImageLayout, WorkDocumentImageProperties, WorkDocumentImageWrapSide, WorkDocumentImageVerticalReference } from '../work-document-image-layout';
1
+ import type { WorkDocumentImageAlignment, WorkDocumentImageHorizontalReference, WorkDocumentImageLayout, WorkDocumentImageProperties, WorkDocumentImageRotation, WorkDocumentImageVerticalReference, WorkDocumentImageWrapSide } from '../work-document-image-layout';
2
2
  export declare const IMAGE_PIXELS_PER_CENTIMETER: number;
3
3
  export interface DocumentPicturePropertiesSource {
4
4
  properties: WorkDocumentImageProperties;
@@ -24,6 +24,9 @@ export interface DocumentPicturePropertiesDraft {
24
24
  cropRight: string;
25
25
  cropBottom: string;
26
26
  cropLeft: string;
27
+ rotation: WorkDocumentImageRotation;
28
+ flipHorizontal: boolean;
29
+ flipVertical: boolean;
27
30
  relativeHeight: string;
28
31
  behindDocument: boolean;
29
32
  allowOverlap: boolean;
@@ -0,0 +1,4 @@
1
+ import type { Editor } from '@tiptap/core';
2
+ export declare function DocumentTextBoxRibbon({ editor }: {
3
+ editor: Editor;
4
+ }): import("react").JSX.Element;
@@ -39,6 +39,7 @@ interface DocumentToolbarProps {
39
39
  pageChromeEditingPart: DocumentPageChromeEditingPart | null;
40
40
  pageChromeShowPageNumber: boolean;
41
41
  onRequestImage: () => void;
42
+ onInsertTextBox?: () => void;
42
43
  onPageChromeEditingPartChange: (part: DocumentPageChromeEditingPart) => void;
43
44
  onClosePageChrome: () => void;
44
45
  onTogglePageChromePageNumber: () => void;
@@ -86,5 +87,5 @@ interface DocumentToolbarProps {
86
87
  onOpenWordCount: () => void;
87
88
  onOpenFindReplace: (mode: DocumentFindReplaceMode) => void;
88
89
  }
89
- export declare function DocumentToolbar({ editor, defaultRibbonCollapsed, reviewOnly, suggestionOnly, history, layoutOpen, layout, layoutFonts, navigationOpen, pageColor, showPageNumbers, showHiddenText, showRulers, spellcheckEnabled, viewMode, zoom, pageChromeEditor, pageChromeEditingPart, pageChromeShowPageNumber, onRequestImage, onPageChromeEditingPartChange, onClosePageChrome, onTogglePageChromePageNumber, onToggleLayout, onLayoutChange, onOpenLayout, onToggleNavigation, onTogglePageNumbers, onToggleHiddenText, onToggleRulers, onPageColorChange, onToggleSpellcheck, onViewModeChange, onZoomChange, onZoomFit, onInsertSection, onInsertNote, onInsertCaption, onInsertCrossReference, onOpenTableOfContents, onOpenIndexEntry, onOpenIndex, citationsOpen, citationSourceCount, onToggleCitations, onInsertField, onRefreshFields, onRefreshIndex, onRefreshTableOfContents, canInsertComment, onInsertComment, commentsOpen, commentCount, onToggleComments, trackChanges, changesOpen, changeCount, findReplaceMode, fileActions, onRibbonTabChange, onToggleTrackChanges, onToggleChanges, onOpenComparison, onDecideChange, onOpenWordCount, onOpenFindReplace, }: DocumentToolbarProps): import("react").JSX.Element;
90
+ export declare function DocumentToolbar({ editor, defaultRibbonCollapsed, reviewOnly, suggestionOnly, history, layoutOpen, layout, layoutFonts, navigationOpen, pageColor, showPageNumbers, showHiddenText, showRulers, spellcheckEnabled, viewMode, zoom, pageChromeEditor, pageChromeEditingPart, pageChromeShowPageNumber, onRequestImage, onInsertTextBox, onPageChromeEditingPartChange, onClosePageChrome, onTogglePageChromePageNumber, onToggleLayout, onLayoutChange, onOpenLayout, onToggleNavigation, onTogglePageNumbers, onToggleHiddenText, onToggleRulers, onPageColorChange, onToggleSpellcheck, onViewModeChange, onZoomChange, onZoomFit, onInsertSection, onInsertNote, onInsertCaption, onInsertCrossReference, onOpenTableOfContents, onOpenIndexEntry, onOpenIndex, citationsOpen, citationSourceCount, onToggleCitations, onInsertField, onRefreshFields, onRefreshIndex, onRefreshTableOfContents, canInsertComment, onInsertComment, commentsOpen, commentCount, onToggleComments, trackChanges, changesOpen, changeCount, findReplaceMode, fileActions, onRibbonTabChange, onToggleTrackChanges, onToggleChanges, onOpenComparison, onDecideChange, onOpenWordCount, onOpenFindReplace, }: DocumentToolbarProps): import("react").JSX.Element;
90
91
  export {};
@@ -11,6 +11,7 @@ export interface DocumentInsertCommands {
11
11
  insertField: (kind: WorkDocumentFieldKind) => void;
12
12
  insertImage: (file: File) => Promise<void>;
13
13
  insertNote: (kind: WorkDocumentNoteKind) => boolean;
14
+ insertTextBox: () => boolean;
14
15
  openIndexEntry: () => void;
15
16
  openIndex: () => void;
16
17
  openTableOfContents: () => void;
@@ -16,6 +16,12 @@ export interface WorkDocumentImageCrop {
16
16
  bottom: number;
17
17
  left: number;
18
18
  }
19
+ export type WorkDocumentImageRotation = 0 | 90 | 180 | 270;
20
+ export interface WorkDocumentImageTransform {
21
+ rotation: WorkDocumentImageRotation;
22
+ flipHorizontal: boolean;
23
+ flipVertical: boolean;
24
+ }
19
25
  export interface WorkDocumentImageLayer {
20
26
  relativeHeight: number;
21
27
  behindDocument: boolean;
@@ -36,6 +42,7 @@ export interface WorkDocumentImageProperties extends WorkDocumentImageLayoutOpti
36
42
  alternativeText: string;
37
43
  position?: WorkDocumentImagePosition | null;
38
44
  crop?: WorkDocumentImageCrop | null;
45
+ transform?: WorkDocumentImageTransform | null;
39
46
  contour?: WorkDocumentImageWrapContour | null;
40
47
  layer?: WorkDocumentImageLayer | null;
41
48
  }
@@ -63,6 +70,7 @@ export declare function documentImageAlternativeText(editor: Editor): string;
63
70
  export declare function documentImageLayoutFromElement(element: Element): WorkDocumentImageLayoutOptions;
64
71
  export declare function documentImagePositionFromElement(element: Element): WorkDocumentImagePosition | null;
65
72
  export declare function documentImageCropFromElement(element: Element): WorkDocumentImageCrop | null;
73
+ export declare function documentImageTransformFromElement(element: Element): WorkDocumentImageTransform | null;
66
74
  export declare function documentImageLayerFromElement(element: Element): WorkDocumentImageLayer;
67
75
  export declare function normalizeDocumentImageLayoutOptions(value: Partial<Record<keyof WorkDocumentImageLayoutOptions, unknown>>): WorkDocumentImageLayoutOptions;
68
76
  export declare function normalizeDocumentImageLayout(value: unknown): WorkDocumentImageLayout;
@@ -76,6 +84,12 @@ export declare function normalizeDocumentImageHorizontalReference(value: unknown
76
84
  export declare function normalizeDocumentImageVerticalReference(value: unknown): WorkDocumentImageVerticalReference;
77
85
  export declare function normalizeDocumentImageCrop(value: Partial<Record<'cropBottom' | 'cropLeft' | 'cropRight' | 'cropTop', unknown>>): WorkDocumentImageCrop | null;
78
86
  export declare function normalizeDocumentImageCropEdge(value: unknown): number;
87
+ export declare function defaultDocumentImageTransform(): WorkDocumentImageTransform;
88
+ export declare function normalizeDocumentImageTransform(value: Partial<Record<keyof WorkDocumentImageTransform, unknown>>): WorkDocumentImageTransform;
89
+ export declare function normalizeDocumentImageRotation(value: unknown): WorkDocumentImageRotation;
90
+ export declare function documentImageTransformIsDefault(transform: WorkDocumentImageTransform): boolean;
91
+ export declare function documentImageTransformCss(transform: WorkDocumentImageTransform): string;
92
+ export declare function applyDocumentImageTransformToElement(element: HTMLElement, transform: WorkDocumentImageTransform | null): void;
79
93
  export declare function normalizeDocumentImageLayer(value: Partial<Record<keyof WorkDocumentImageLayer, unknown>>): WorkDocumentImageLayer;
80
94
  export declare function normalizeDocumentImageRelativeHeight(value: unknown): number;
81
95
  export declare function documentImageLayerCssZIndex(layer: WorkDocumentImageLayer): number;
@@ -0,0 +1,64 @@
1
+ import { type Editor, Node } from '@tiptap/core';
2
+ /** The intentionally small text-box surface supported by Writer. */
3
+ export type WorkDocumentTextBoxLayout = 'inline' | 'floating';
4
+ export type WorkDocumentTextBoxHorizontalReference = 'column' | 'margin' | 'page';
5
+ export type WorkDocumentTextBoxVerticalReference = 'paragraph' | 'margin' | 'page';
6
+ export type WorkDocumentTextBoxVerticalAlign = 'top' | 'center' | 'bottom';
7
+ export interface WorkDocumentTextBoxProperties {
8
+ id: string;
9
+ width: number;
10
+ height: number;
11
+ layout: WorkDocumentTextBoxLayout;
12
+ horizontalOffset: number | null;
13
+ verticalOffset: number | null;
14
+ horizontalReference: WorkDocumentTextBoxHorizontalReference;
15
+ verticalReference: WorkDocumentTextBoxVerticalReference;
16
+ fill: string;
17
+ borderColor: string;
18
+ borderWidth: number;
19
+ padding: number;
20
+ verticalAlign: WorkDocumentTextBoxVerticalAlign;
21
+ docPropertiesId: number | null;
22
+ }
23
+ export interface DocumentTextBoxCommandOptions {
24
+ restoreFocus?: boolean;
25
+ }
26
+ declare module '@tiptap/core' {
27
+ interface Commands<ReturnType> {
28
+ documentTextBox: {
29
+ insertDocumentTextBox: (text?: string, options?: Partial<WorkDocumentTextBoxProperties>) => ReturnType;
30
+ setDocumentTextBoxProperties: (value: Partial<WorkDocumentTextBoxProperties>, options?: DocumentTextBoxCommandOptions) => ReturnType;
31
+ deleteDocumentTextBox: (options?: DocumentTextBoxCommandOptions) => ReturnType;
32
+ };
33
+ }
34
+ }
35
+ export declare const DOCUMENT_TEXT_BOX_DEFAULTS: WorkDocumentTextBoxProperties;
36
+ export declare const DOCUMENT_TEXT_BOX_LIMITS: {
37
+ readonly width: {
38
+ readonly min: 20;
39
+ readonly max: 558.7;
40
+ };
41
+ readonly height: {
42
+ readonly min: 10;
43
+ readonly max: 558.7;
44
+ };
45
+ readonly offset: {
46
+ readonly min: -558.7;
47
+ readonly max: 558.7;
48
+ };
49
+ readonly borderWidth: {
50
+ readonly min: 0;
51
+ readonly max: 10;
52
+ };
53
+ readonly padding: {
54
+ readonly min: 0;
55
+ readonly max: 25;
56
+ };
57
+ };
58
+ export declare const DocumentTextBox: Node<any, any>;
59
+ export declare function documentTextBoxProperties(editor: Editor): WorkDocumentTextBoxProperties;
60
+ export declare function setDocumentTextBoxProperties(editor: Editor, value: Partial<WorkDocumentTextBoxProperties>, options?: DocumentTextBoxCommandOptions): boolean;
61
+ export declare function normalizeDocumentTextBoxProperties(value: Partial<Record<keyof WorkDocumentTextBoxProperties, unknown>>): WorkDocumentTextBoxProperties;
62
+ export declare function textBoxCss(value: Partial<Record<keyof WorkDocumentTextBoxProperties, unknown>>): string;
63
+ export declare function textBoxDomAttributes(value: Partial<Record<keyof WorkDocumentTextBoxProperties, unknown>>): Record<string, string | undefined>;
64
+ export declare function documentTextBoxPropertiesFromElement(element: Element): WorkDocumentTextBoxProperties;
@@ -2,5 +2,6 @@ import type { ParagraphChild } from 'docx';
2
2
  import type { DocxImageCropPatchCollector } from './work-docx-image-crop';
3
3
  import type { DocxImageIdentityPatchCollector } from './work-docx-image-identity';
4
4
  import type { DocxImageLayerPatchCollector } from './work-docx-image-layer';
5
+ import type { DocxImageTransformPatchCollector } from './work-docx-image-transform';
5
6
  import type { DocxImageWrapPatchCollector } from './work-docx-image-wrap';
6
- export declare function imageToDocx(element: HTMLImageElement, docx: typeof import('docx'), cropPatches?: DocxImageCropPatchCollector, wrapPatches?: DocxImageWrapPatchCollector, layerPatches?: DocxImageLayerPatchCollector, identityPatches?: DocxImageIdentityPatchCollector): Promise<ParagraphChild>;
7
+ export declare function imageToDocx(element: HTMLImageElement, docx: typeof import('docx'), cropPatches?: DocxImageCropPatchCollector, wrapPatches?: DocxImageWrapPatchCollector, layerPatches?: DocxImageLayerPatchCollector, identityPatches?: DocxImageIdentityPatchCollector, transformPatches?: DocxImageTransformPatchCollector): Promise<ParagraphChild>;
@@ -1,5 +1,5 @@
1
1
  import { type WorkDocumentImageIdentity, type WorkDocumentImageIdentityRegistry } from './work-document-image-identity';
2
- import { type WorkDocumentImageCrop, type WorkDocumentImageLayer, type WorkDocumentImageLayoutOptions, type WorkDocumentImagePosition } from './work-document-image-layout';
2
+ import { type WorkDocumentImageCrop, type WorkDocumentImageLayer, type WorkDocumentImageLayoutOptions, type WorkDocumentImagePosition, type WorkDocumentImageTransform } from './work-document-image-layout';
3
3
  import { type WorkDocumentImageWrapContour } from './work-document-image-wrap-contour';
4
4
  export interface ImportedDocxImageLayoutMarker {
5
5
  startMarker: string;
@@ -7,6 +7,7 @@ export interface ImportedDocxImageLayoutMarker {
7
7
  options: WorkDocumentImageLayoutOptions;
8
8
  position: WorkDocumentImagePosition | null;
9
9
  crop: WorkDocumentImageCrop | null;
10
+ transform: WorkDocumentImageTransform | null;
10
11
  contour: WorkDocumentImageWrapContour | null;
11
12
  layer: WorkDocumentImageLayer | null;
12
13
  identity: WorkDocumentImageIdentity;
@@ -0,0 +1,17 @@
1
+ import { type WorkDocumentImageTransform } from './work-document-image-layout';
2
+ interface DocxImageTransformPatch {
3
+ marker: string;
4
+ transform: WorkDocumentImageTransform;
5
+ }
6
+ export interface DocxImageTransformReadResult {
7
+ transform: WorkDocumentImageTransform | null;
8
+ supported: boolean;
9
+ }
10
+ export declare function readDocxImageTransform(drawing: Element): DocxImageTransformReadResult;
11
+ export declare class DocxImageTransformPatchCollector {
12
+ readonly patches: DocxImageTransformPatch[];
13
+ private nextMarker;
14
+ marker(transform: WorkDocumentImageTransform | null): string;
15
+ }
16
+ export declare function patchDocxImageTransforms(buffer: ArrayBuffer, patches: readonly DocxImageTransformPatch[]): Promise<ArrayBuffer>;
17
+ export {};
@@ -6,6 +6,7 @@ import { type ImportedDocxCommentMarkers } from './work-docx-comment-import';
6
6
  import { type ImportedDocxEquationMarkers } from './work-docx-equation-import';
7
7
  import { type ImportedDocxFieldMarkers } from './work-docx-field-import';
8
8
  import { type ImportedDocxImageLayoutMarkers } from './work-docx-image-layout-import';
9
+ import { type ImportedDocxTextBoxMarkers } from './work-docx-text-box-import';
9
10
  import { type ImportedDocxIndexMarkers } from './work-docx-index-import';
10
11
  import { type ImportedDocxListMarkers } from './work-docx-list-import';
11
12
  import { type ImportedDocxNumberingChangeMarkers } from './work-docx-numbering-change-import';
@@ -46,6 +47,7 @@ export interface PreparedDocxImport {
46
47
  listMarkers: ImportedDocxListMarkers;
47
48
  numberingChangeMarkers: ImportedDocxNumberingChangeMarkers;
48
49
  imageLayoutMarkers: ImportedDocxImageLayoutMarkers;
50
+ textBoxMarkers: ImportedDocxTextBoxMarkers;
49
51
  paragraphIdentityMarkers: ImportedDocxParagraphIdentityMarkers;
50
52
  paragraphFormattingChangeMarkers: ImportedDocxParagraphFormattingChangeMarkers;
51
53
  paragraphAlignmentMarkers: ImportedDocxParagraphAlignmentMarkers;
@@ -64,6 +66,6 @@ export interface PreparedDocxImport {
64
66
  trackChanges: boolean;
65
67
  }
66
68
  export declare function prepareDocxImport(buffer: ArrayBuffer, sourcePackage?: OoxmlPackage): Promise<PreparedDocxImport>;
67
- export declare function applyDocxSectionsToHtml(html: string, sections: PreparedDocxImport['sections'], captionMarkers?: ImportedDocxCaptionMarkers, bookmarkMarkers?: ImportedDocxBookmarkMarkers, changeMarkers?: ImportedDocxChangeMarkers, commentMarkers?: ImportedDocxCommentMarkers, fieldMarkers?: ImportedDocxFieldMarkers, tableOfContentsMarkers?: ImportedDocxTableOfContentsMarkers, indexMarkers?: ImportedDocxIndexMarkers, equationMarkers?: ImportedDocxEquationMarkers, citationMarkers?: ImportedDocxCitationMarkers, listMarkers?: ImportedDocxListMarkers, numberingChangeMarkers?: ImportedDocxNumberingChangeMarkers, imageLayoutMarkers?: ImportedDocxImageLayoutMarkers, paragraphIdentityMarkers?: ImportedDocxParagraphIdentityMarkers, paragraphFormattingChangeMarkers?: ImportedDocxParagraphFormattingChangeMarkers, paragraphAlignmentMarkers?: ImportedDocxParagraphAlignmentMarkers, runFormattingMarkers?: ImportedDocxRunFormattingMarkers, paragraphDirectionMarkers?: ImportedDocxParagraphDirectionMarkers, paragraphIndentMarkers?: ImportedDocxParagraphIndentMarkers, paragraphSpacingMarkers?: ImportedDocxParagraphSpacingMarkers, paragraphBorderMarkers?: ImportedDocxParagraphBorderMarkers, paragraphShadingMarkers?: ImportedDocxParagraphShadingMarkers, paragraphPaginationMarkers?: ImportedDocxParagraphPaginationMarkers, bibliography?: WorkDocumentContent['bibliography'], tabStopMarkers?: ImportedDocxParagraphTabStopMarkers, tableCellMarkers?: ImportedDocxTableCellMarkers, tableRowMarkers?: ImportedDocxTableRowMarkers, tableSizingMarkers?: ImportedDocxTableSizingMarkers): string;
69
+ export declare function applyDocxSectionsToHtml(html: string, sections: PreparedDocxImport['sections'], captionMarkers?: ImportedDocxCaptionMarkers, bookmarkMarkers?: ImportedDocxBookmarkMarkers, changeMarkers?: ImportedDocxChangeMarkers, commentMarkers?: ImportedDocxCommentMarkers, fieldMarkers?: ImportedDocxFieldMarkers, tableOfContentsMarkers?: ImportedDocxTableOfContentsMarkers, indexMarkers?: ImportedDocxIndexMarkers, equationMarkers?: ImportedDocxEquationMarkers, citationMarkers?: ImportedDocxCitationMarkers, listMarkers?: ImportedDocxListMarkers, numberingChangeMarkers?: ImportedDocxNumberingChangeMarkers, imageLayoutMarkers?: ImportedDocxImageLayoutMarkers, paragraphIdentityMarkers?: ImportedDocxParagraphIdentityMarkers, paragraphFormattingChangeMarkers?: ImportedDocxParagraphFormattingChangeMarkers, paragraphAlignmentMarkers?: ImportedDocxParagraphAlignmentMarkers, runFormattingMarkers?: ImportedDocxRunFormattingMarkers, paragraphDirectionMarkers?: ImportedDocxParagraphDirectionMarkers, paragraphIndentMarkers?: ImportedDocxParagraphIndentMarkers, paragraphSpacingMarkers?: ImportedDocxParagraphSpacingMarkers, paragraphBorderMarkers?: ImportedDocxParagraphBorderMarkers, paragraphShadingMarkers?: ImportedDocxParagraphShadingMarkers, paragraphPaginationMarkers?: ImportedDocxParagraphPaginationMarkers, bibliography?: WorkDocumentContent['bibliography'], tabStopMarkers?: ImportedDocxParagraphTabStopMarkers, tableCellMarkers?: ImportedDocxTableCellMarkers, tableRowMarkers?: ImportedDocxTableRowMarkers, tableSizingMarkers?: ImportedDocxTableSizingMarkers, textBoxMarkers?: ImportedDocxTextBoxMarkers): string;
68
70
  export declare function readDocxLayout(buffer: ArrayBuffer): Promise<ImportedDocumentLayout>;
69
71
  export {};
@@ -0,0 +1,25 @@
1
+ import type { WorkDocumentTextBoxProperties } from './work-document-text-box';
2
+ interface DocxTextBoxIdentityPatch {
3
+ marker: string;
4
+ preferredId: number | null;
5
+ }
6
+ export interface DocxTextBoxIdentityRegistration {
7
+ marker: string;
8
+ docPropertiesId: number | null;
9
+ }
10
+ /**
11
+ * Allocates a marker for each text box and lets the package patcher assign a
12
+ * document-wide `wp:docPr/@id` after all image and shape IDs are known.
13
+ *
14
+ * The `docx` package creates a fresh ID generator per drawing instance, so
15
+ * relying on its default would give every WPS shape the same ID. Delaying the
16
+ * assignment also lets us preserve an imported ID when it is still available,
17
+ * while deterministically repairing collisions with images or other shapes.
18
+ */
19
+ export declare class DocxTextBoxIdentityPatchCollector {
20
+ readonly patches: DocxTextBoxIdentityPatch[];
21
+ private nextMarker;
22
+ register(properties: WorkDocumentTextBoxProperties): DocxTextBoxIdentityRegistration;
23
+ }
24
+ export declare function patchDocxTextBoxIdentities(buffer: ArrayBuffer, patches: readonly DocxTextBoxIdentityPatch[]): Promise<ArrayBuffer>;
25
+ export {};
@@ -0,0 +1,26 @@
1
+ import { type WorkDocumentTextBoxProperties } from './work-document-text-box';
2
+ export interface ImportedDocxTextBoxMarker {
3
+ marker: string;
4
+ properties: WorkDocumentTextBoxProperties;
5
+ }
6
+ export interface ImportedDocxTextBoxMarkers {
7
+ textBoxes: ImportedDocxTextBoxMarker[];
8
+ }
9
+ export interface DocxTextBoxInspection {
10
+ supported: number;
11
+ unsupported: number;
12
+ }
13
+ /**
14
+ * Rewrites supported WPS text boxes into ordinary Word runs for Mammoth.
15
+ * Mammoth intentionally ignores `wps:txbxContent`; the marker is consumed
16
+ * after conversion and replaced with an editable HTML block.
17
+ */
18
+ export declare function markDocxTextBoxes(document: Document): ImportedDocxTextBoxMarkers;
19
+ /**
20
+ * Inspects WPS text-box shapes without mutating the source package. The
21
+ * importer deliberately supports only a shape that is the sole drawing in a
22
+ * paragraph; mixed paragraphs remain on Mammoth's normal compatibility path.
23
+ */
24
+ export declare function inspectDocxTextBoxes(document: Document): DocxTextBoxInspection;
25
+ export declare function applyImportedDocxTextBoxMarkers(document: Document, markers: ImportedDocxTextBoxMarkers): void;
26
+ export declare function hasImportedDocxTextBoxMarkers(markers: ImportedDocxTextBoxMarkers): boolean;
Binary file
package/dist/styles.css CHANGED
@@ -8383,7 +8383,7 @@ button.work-office-collaboration-participant:hover .work-office-collaboration-lo
8383
8383
  display: grid;
8384
8384
  }
8385
8385
 
8386
- .work-document-picture-properties-section.position, .work-document-picture-properties-section.layer, .work-document-picture-properties-section.crop, .work-document-picture-properties-alt-text {
8386
+ .work-document-picture-properties-section.position, .work-document-picture-properties-section.layer, .work-document-picture-properties-section.crop, .work-document-picture-properties-section.transform, .work-document-picture-properties-alt-text {
8387
8387
  grid-column: 1 / -1;
8388
8388
  }
8389
8389
 
@@ -8448,6 +8448,34 @@ button.work-office-collaboration-participant:hover .work-office-collaboration-lo
8448
8448
  display: grid;
8449
8449
  }
8450
8450
 
8451
+ .work-document-picture-properties-transform-row {
8452
+ min-height: 34px;
8453
+ color: var(--a3s-muted);
8454
+ grid-template-columns: 64px minmax(0, 1fr);
8455
+ align-items: center;
8456
+ gap: 8px;
8457
+ font-size: 11px;
8458
+ display: grid;
8459
+ }
8460
+
8461
+ .work-document-picture-properties-transform-options {
8462
+ grid-template-columns: repeat(2, minmax(0, 1fr));
8463
+ gap: 6px 12px;
8464
+ display: grid;
8465
+ }
8466
+
8467
+ .work-document-picture-properties-transform-options .work-office-checkbox {
8468
+ border-radius: 6px;
8469
+ min-height: 34px;
8470
+ padding: 5px 6px;
8471
+ }
8472
+
8473
+ .work-document-picture-properties-transform-help {
8474
+ color: var(--a3s-faint);
8475
+ font-size: 10px;
8476
+ line-height: 1.4;
8477
+ }
8478
+
8451
8479
  .work-document-picture-properties-layer-options {
8452
8480
  grid-template-columns: repeat(2, minmax(0, 1fr));
8453
8481
  gap: 6px 12px;
@@ -11762,6 +11790,10 @@ sub [data-office-character-position-half-points], sup [data-office-character-pos
11762
11790
  .work-document-page .tiptap [data-resize-container][data-node="image"] {
11763
11791
  width: fit-content;
11764
11792
  max-width: 100%;
11793
+ rotate: var(--work-document-image-rotation, 0deg);
11794
+ scale: var(--work-document-image-flip-x, 1)
11795
+ var(--work-document-image-flip-y, 1);
11796
+ transform-origin: center;
11765
11797
  margin-block: 18px;
11766
11798
  display: block !important;
11767
11799
  }
@@ -12601,8 +12633,12 @@ sub [data-office-character-position-half-points], sup [data-office-character-pos
12601
12633
  }
12602
12634
 
12603
12635
  :is(.work-document-preview-page, .work-pdf-export-page.document) img[data-office-image-layout] {
12604
- border-radius: 4px;
12605
12636
  height: auto;
12637
+ rotate: var(--work-document-image-rotation, 0deg);
12638
+ scale: var(--work-document-image-flip-x, 1)
12639
+ var(--work-document-image-flip-y, 1);
12640
+ transform-origin: center;
12641
+ border-radius: 4px;
12606
12642
  margin-block: 18px;
12607
12643
  display: block;
12608
12644
  }
@@ -12771,6 +12807,69 @@ sub [data-office-character-position-half-points], sup [data-office-character-pos
12771
12807
  border-bottom-color: #d69b9b;
12772
12808
  }
12773
12809
 
12810
+ :where(.work-document-page .tiptap, .work-document-preview-page, .work-pdf-export-page.document) [data-document-text-box] {
12811
+ box-sizing: border-box;
12812
+ width: var(--work-document-text-box-width, 120mm);
12813
+ min-width: 20mm;
12814
+ max-width: 100%;
12815
+ height: var(--work-document-text-box-height, 45mm);
12816
+ min-height: 10mm;
12817
+ max-height: 558.7mm;
12818
+ padding: var(--work-document-text-box-padding, 3mm);
12819
+ border: var(--work-document-text-box-border-width, .35mm) solid
12820
+ var(--work-document-text-box-border-color, #4472c4);
12821
+ background: var(--work-document-text-box-fill, #fff2cc);
12822
+ color: inherit;
12823
+ white-space: pre-wrap;
12824
+ overflow-wrap: anywhere;
12825
+ border-radius: 3px;
12826
+ flex-direction: column;
12827
+ justify-content: flex-start;
12828
+ margin: 12px 0;
12829
+ display: flex;
12830
+ overflow: hidden;
12831
+ }
12832
+
12833
+ :where(.work-document-page .tiptap, .work-document-preview-page, .work-pdf-export-page.document) [data-document-text-box][data-text-box-vertical-align="center"] {
12834
+ justify-content: center;
12835
+ }
12836
+
12837
+ :where(.work-document-page .tiptap, .work-document-preview-page, .work-pdf-export-page.document) [data-document-text-box][data-text-box-vertical-align="bottom"] {
12838
+ justify-content: flex-end;
12839
+ }
12840
+
12841
+ :where(.work-document-page .tiptap, .work-document-preview-page, .work-pdf-export-page.document) [data-document-text-box][data-text-box-layout="floating"] {
12842
+ translate: var(--work-document-text-box-horizontal-offset, 0)
12843
+ var(--work-document-text-box-vertical-offset, 0);
12844
+ z-index: 1;
12845
+ position: relative;
12846
+ }
12847
+
12848
+ :where(.work-document-page .tiptap, .work-document-preview-page, .work-pdf-export-page.document) [data-document-text-box] > p {
12849
+ width: 100%;
12850
+ margin: 0;
12851
+ }
12852
+
12853
+ .work-document-page .tiptap [data-document-text-box].ProseMirror-selectednode {
12854
+ outline: 2px solid color-mix(in srgb, var(--a3s-blue) 75%, transparent);
12855
+ outline-offset: 3px;
12856
+ }
12857
+
12858
+ .work-document-text-box-size-field, .work-document-text-box-offset-field {
12859
+ width: 84px;
12860
+ }
12861
+
12862
+ .work-document-text-box-position-field {
12863
+ width: 96px;
12864
+ }
12865
+
12866
+ .work-document-text-box-size-field > span, .work-document-text-box-offset-field > span, .work-document-text-box-position-field > span {
12867
+ text-overflow: ellipsis;
12868
+ white-space: nowrap;
12869
+ max-width: 96px;
12870
+ overflow: hidden;
12871
+ }
12872
+
12774
12873
  .work-document-citation {
12775
12874
  color: #245fc4;
12776
12875
  cursor: default;
@@ -836,12 +836,13 @@ stable ProseMirror position, and distribute list-container height without
836
836
  double-counting nested content.
837
837
 
838
838
  Document image nodes carry typed layout, alignment, wrap-distance, alternative
839
- text, size, and per-image aspect-ratio-lock attributes. The contextual Picture
839
+ text, size, per-image aspect-ratio-lock, and bounded transform attributes. The contextual Picture
840
840
  ribbon keeps fast layout actions and opens one responsive Picture Properties
841
841
  dialog for centimeter width and height, aspect-ratio locking, wrapping,
842
842
  alignment, text distance, signed horizontal and vertical offsets, their column,
843
843
  paragraph, margin, or page reference frames, four-edge percentage cropping,
844
- relative drawing order, behind-text placement, overlap and cell-layout policy,
844
+ quarter-turn rotation, horizontal/vertical reflection, relative drawing order,
845
+ behind-text placement, overlap and cell-layout policy,
845
846
  anchor locking, and alternative text. Applying the complete draft
846
847
  updates only changed attributes in one separated TipTap history entry; cancel
847
848
  and Escape preserve the node and return focus to the exact invoker. Dimensions
@@ -865,7 +866,10 @@ and ordered `wrapPolygon` vertices. Aligned anchors remain aligned,
865
866
  while precise offsets preserve `positionH` and `positionV` reference frames
866
867
  through edit, preview, and regenerated DOCX. Four-edge crop geometry remains
867
868
  typed in the controlled model and round-trips as DrawingML `a:srcRect` for
868
- inline and floating pictures. Supported floating pictures also preserve
869
+ inline and floating pictures. Quarter-turn rotation and reflection round-trip
870
+ as DrawingML `a:xfrm` `rot`, `flipH`, and `flipV` values for inline and floating
871
+ pictures. Arbitrary-angle or malformed transform values are diagnosed and
872
+ normalized to the bounded model. Supported floating pictures also preserve
869
873
  drawing-layer relationships through unsigned `relativeHeight`,
870
874
  `behindDoc`, `allowOverlap`, `layoutInCell`, and `locked` anchor attributes.
871
875
  The browser maps the unsigned drawing order into bounded foreground and
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@a3s-lab/office",
3
- "version": "0.44.0",
3
+ "version": "0.46.0",
4
4
  "description": "Open-source collaborative browser editors for documents, Markdown, spreadsheets, presentations, and PDFs.",
5
5
  "keywords": [
6
6
  "office",
@@ -105,6 +105,7 @@
105
105
  "playground:visual:document-script-fonts": "playwright test visual-tests/document-script-fonts.functional.spec.ts --config playwright.config.ts",
106
106
  "playground:visual:document-opentype": "playwright test visual-tests/document-opentype.functional.spec.ts --config playwright.config.ts",
107
107
  "playground:visual:document-strike": "playwright test visual-tests/document-strike.functional.spec.ts --config playwright.config.ts",
108
+ "playground:visual:document-text-box": "playwright test visual-tests/document-text-box.functional.spec.ts --config playwright.config.ts",
108
109
  "playground:visual:spreadsheet-data-validation": "playwright test visual-tests/spreadsheet-data-validation.functional.spec.ts --config playwright.config.ts",
109
110
  "playground:visual:spreadsheet-conditional-format": "playwright test visual-tests/spreadsheet-conditional-format.functional.spec.ts --config playwright.config.ts",
110
111
  "playground:visual:spreadsheet-date-time": "playwright test visual-tests/spreadsheet-date-time.functional.spec.ts --config playwright.config.ts",
@@ -138,8 +139,10 @@
138
139
  "performance:pdf": "bun .a3s-test/performance/generate-fixtures.ts --pdf-only && bun .a3s-test/performance/benchmark-pdf.ts --url http://127.0.0.1:4175/playground/ --runs 3 --timeout-ms 120000",
139
140
  "performance:presentation": "bun .a3s-test/performance/generate-fixtures.ts --presentations-only && bun .a3s-test/performance/benchmark-presentation.ts --url http://127.0.0.1:4175/playground/ --runs 3 --timeout-ms 120000 --modes default,content-visibility",
140
141
  "test": "rstest",
141
- "test:e2e": "bun run test:e2e:fixtures && a3s-test run tests/e2e/word-page-color.acl --json && a3s-test run tests/e2e/word-page-setup-phone.acl --json && a3s-test run tests/e2e/word-paragraph-layout-phone.acl --json && a3s-test run tests/e2e/word-list-formatting-phone.acl --json && a3s-test run tests/e2e/word-font-picker-phone.acl --json && a3s-test run tests/e2e/word-comments-drawer.acl --json && a3s-test run tests/e2e/word-comment-windowing.acl --json && a3s-test run tests/e2e/word-citations-phone.acl --json && a3s-test run tests/e2e/word-navigation-search.acl --json && a3s-test run tests/e2e/word-navigation-windowing.acl --json && a3s-test run tests/e2e/word-find-replace-phone.acl --json && a3s-test run tests/e2e/word-page-navigation.acl --json && a3s-test run tests/e2e/word-page-windowing.acl --json && a3s-test run tests/e2e/word-ai-question.acl --json && a3s-test run tests/e2e/word-picture-insert.acl --json && a3s-test run tests/e2e/word-picture-alt-text-phone.acl --json && a3s-test run tests/e2e/word-track-changes-phone.acl --json && a3s-test run tests/e2e/word-formatting-revision.acl --json && a3s-test run tests/e2e/word-paragraph-formatting-revision.acl --json && a3s-test run tests/e2e/word-numbering-revision.acl --json && a3s-test run tests/e2e/word-document-comparison.acl --json && a3s-test run tests/e2e/word-review-conflict-phone.acl --json && a3s-test run tests/e2e/word-revision-windowing.acl --json && a3s-test run tests/e2e/word-table-phone.acl --json && a3s-test run tests/e2e/word-table-borders.acl --json && a3s-test run tests/e2e/word-theme-table.acl --json && a3s-test run tests/e2e/word-styled-table.acl --json && a3s-test run tests/e2e/word-multi-page-table.acl --json && a3s-test run tests/e2e/word-cross-reference-phone.acl --json && a3s-test run tests/e2e/word-bookmark-links-phone.acl --json && a3s-test run tests/e2e/word-notes-phone.acl --json && a3s-test run tests/e2e/word-fields-phone.acl --json && a3s-test run tests/e2e/spreadsheet-phone-rename.acl --json && a3s-test run tests/e2e/spreadsheet-phone-find.acl --json && a3s-test run tests/e2e/spreadsheet-phone-context-menu.acl --json && a3s-test run tests/e2e/spreadsheet-phone-task-pane.acl --json && a3s-test run tests/e2e/spreadsheet-maximum-sparse.acl --json && a3s-test run tests/e2e/spreadsheet-cell-style.acl --json && a3s-test run tests/e2e/spreadsheet-paste-special.acl --json && a3s-test run tests/e2e/spreadsheet-hyperlink.acl --json && a3s-test run tests/e2e/presentation-cut-paste-focus.acl --json && a3s-test run tests/e2e/presentation-presenter-view.acl --json && a3s-test run tests/e2e/presentation-phone-chart-pane.acl --json && a3s-test run tests/e2e/presentation-phone-comments.acl --json && a3s-test run tests/e2e/pdf-thumbnail-keyboard.acl --json && a3s-test run tests/e2e/pdf-page-drawer-phone.acl --json && a3s-test run tests/e2e/markdown-phone-modes.acl --json && a3s-test run tests/e2e/office-sidebar-breakpoint.acl --json && a3s-test run tests/e2e/office-docs-navigation.acl --json && a3s-test run tests/e2e/collaboration-playground-entry.acl --json && a3s-test run tests/e2e/collaboration-document-comments.acl --command-timeout-ms 120000 --json && a3s-test run tests/e2e/collaboration-document-suggestions.acl --command-timeout-ms 120000 --json && a3s-test run tests/e2e/collaboration-participants.acl --json && a3s-test run tests/e2e/collaboration-pdf-annotations.acl --json && a3s-test run tests/e2e/collaboration-spreadsheet-cells.acl --json && a3s-test run tests/e2e/collaboration-presentation-elements.acl --json",
142
- "test:e2e:check": "bun run test:e2e:fixtures && a3s-test check tests/e2e/word-page-color.acl --json && a3s-test check tests/e2e/word-page-setup-phone.acl --json && a3s-test check tests/e2e/word-paragraph-layout-phone.acl --json && a3s-test check tests/e2e/word-list-formatting-phone.acl --json && a3s-test check tests/e2e/word-font-picker-phone.acl --json && a3s-test check tests/e2e/word-comments-drawer.acl --json && a3s-test check tests/e2e/word-comment-windowing.acl --json && a3s-test check tests/e2e/word-citations-phone.acl --json && a3s-test check tests/e2e/word-navigation-search.acl --json && a3s-test check tests/e2e/word-navigation-windowing.acl --json && a3s-test check tests/e2e/word-find-replace-phone.acl --json && a3s-test check tests/e2e/word-page-navigation.acl --json && a3s-test check tests/e2e/word-page-windowing.acl --json && a3s-test check tests/e2e/word-ai-question.acl --json && a3s-test check tests/e2e/word-picture-insert.acl --json && a3s-test check tests/e2e/word-picture-alt-text-phone.acl --json && a3s-test check tests/e2e/word-track-changes-phone.acl --json && a3s-test check tests/e2e/word-formatting-revision.acl --json && a3s-test check tests/e2e/word-paragraph-formatting-revision.acl --json && a3s-test check tests/e2e/word-numbering-revision.acl --json && a3s-test check tests/e2e/word-document-comparison.acl --json && a3s-test check tests/e2e/word-review-conflict-phone.acl --json && a3s-test check tests/e2e/word-revision-windowing.acl --json && a3s-test check tests/e2e/word-table-phone.acl --json && a3s-test check tests/e2e/word-table-borders.acl --json && a3s-test check tests/e2e/word-theme-table.acl --json && a3s-test check tests/e2e/word-styled-table.acl --json && a3s-test check tests/e2e/word-multi-page-table.acl --json && a3s-test check tests/e2e/word-cross-reference-phone.acl --json && a3s-test check tests/e2e/word-bookmark-links-phone.acl --json && a3s-test check tests/e2e/word-notes-phone.acl --json && a3s-test check tests/e2e/word-fields-phone.acl --json && a3s-test check tests/e2e/spreadsheet-phone-rename.acl --json && a3s-test check tests/e2e/spreadsheet-phone-find.acl --json && a3s-test check tests/e2e/spreadsheet-phone-context-menu.acl --json && a3s-test check tests/e2e/spreadsheet-phone-task-pane.acl --json && a3s-test check tests/e2e/spreadsheet-maximum-sparse.acl --json && a3s-test check tests/e2e/spreadsheet-cell-style.acl --json && a3s-test check tests/e2e/spreadsheet-paste-special.acl --json && a3s-test check tests/e2e/spreadsheet-hyperlink.acl --json && a3s-test check tests/e2e/presentation-cut-paste-focus.acl --json && a3s-test check tests/e2e/presentation-presenter-view.acl --json && a3s-test check tests/e2e/presentation-phone-chart-pane.acl --json && a3s-test check tests/e2e/presentation-phone-comments.acl --json && a3s-test check tests/e2e/pdf-thumbnail-keyboard.acl --json && a3s-test check tests/e2e/pdf-page-drawer-phone.acl --json && a3s-test check tests/e2e/markdown-phone-modes.acl --json && a3s-test check tests/e2e/office-sidebar-breakpoint.acl --json && a3s-test check tests/e2e/office-docs-navigation.acl --json && a3s-test check tests/e2e/collaboration-playground-entry.acl --json && a3s-test check tests/e2e/collaboration-document-comments.acl --json && a3s-test check tests/e2e/collaboration-document-suggestions.acl --json && a3s-test check tests/e2e/collaboration-participants.acl --json && a3s-test check tests/e2e/collaboration-pdf-annotations.acl --json && a3s-test check tests/e2e/collaboration-spreadsheet-cells.acl --json && a3s-test check tests/e2e/collaboration-presentation-elements.acl --json",
142
+ "test:e2e": "bun run test:e2e:fixtures && a3s-test run tests/e2e/word-page-color.acl --json && a3s-test run tests/e2e/word-page-setup-phone.acl --json && a3s-test run tests/e2e/word-paragraph-layout-phone.acl --json && a3s-test run tests/e2e/word-list-formatting-phone.acl --json && a3s-test run tests/e2e/word-font-picker-phone.acl --json && a3s-test run tests/e2e/word-comments-drawer.acl --json && a3s-test run tests/e2e/word-comment-windowing.acl --json && a3s-test run tests/e2e/word-citations-phone.acl --json && a3s-test run tests/e2e/word-navigation-search.acl --json && a3s-test run tests/e2e/word-navigation-windowing.acl --json && a3s-test run tests/e2e/word-find-replace-phone.acl --json && a3s-test run tests/e2e/word-page-navigation.acl --json && a3s-test run tests/e2e/word-page-windowing.acl --json && a3s-test run tests/e2e/word-ai-question.acl --json && a3s-test run tests/e2e/word-picture-insert.acl --json && a3s-test run tests/e2e/word-picture-alt-text-phone.acl --json && a3s-test run tests/e2e/word-text-box-phone.acl --json && a3s-test run tests/e2e/word-track-changes-phone.acl --json && a3s-test run tests/e2e/word-formatting-revision.acl --json && a3s-test run tests/e2e/word-paragraph-formatting-revision.acl --json && a3s-test run tests/e2e/word-numbering-revision.acl --json && a3s-test run tests/e2e/word-document-comparison.acl --json && a3s-test run tests/e2e/word-review-conflict-phone.acl --json && a3s-test run tests/e2e/word-revision-windowing.acl --json && a3s-test run tests/e2e/word-table-phone.acl --json && a3s-test run tests/e2e/word-table-borders.acl --json && a3s-test run tests/e2e/word-theme-table.acl --json && a3s-test run tests/e2e/word-styled-table.acl --json && a3s-test run tests/e2e/word-multi-page-table.acl --json && a3s-test run tests/e2e/word-cross-reference-phone.acl --json && a3s-test run tests/e2e/word-bookmark-links-phone.acl --json && a3s-test run tests/e2e/word-notes-phone.acl --json && a3s-test run tests/e2e/word-fields-phone.acl --json && a3s-test run tests/e2e/spreadsheet-phone-rename.acl --json && a3s-test run tests/e2e/spreadsheet-phone-find.acl --json && a3s-test run tests/e2e/spreadsheet-phone-context-menu.acl --json && a3s-test run tests/e2e/spreadsheet-phone-task-pane.acl --json && a3s-test run tests/e2e/spreadsheet-maximum-sparse.acl --json && a3s-test run tests/e2e/spreadsheet-cell-style.acl --json && a3s-test run tests/e2e/spreadsheet-paste-special.acl --json && a3s-test run tests/e2e/spreadsheet-hyperlink.acl --json && a3s-test run tests/e2e/presentation-cut-paste-focus.acl --json && a3s-test run tests/e2e/presentation-presenter-view.acl --json && a3s-test run tests/e2e/presentation-phone-chart-pane.acl --json && a3s-test run tests/e2e/presentation-phone-comments.acl --json && a3s-test run tests/e2e/pdf-thumbnail-keyboard.acl --json && a3s-test run tests/e2e/pdf-page-drawer-phone.acl --json && a3s-test run tests/e2e/markdown-phone-modes.acl --json && a3s-test run tests/e2e/office-sidebar-breakpoint.acl --json && a3s-test run tests/e2e/office-docs-navigation.acl --json && a3s-test run tests/e2e/collaboration-playground-entry.acl --json && a3s-test run tests/e2e/collaboration-document-comments.acl --command-timeout-ms 120000 --json && a3s-test run tests/e2e/collaboration-document-suggestions.acl --command-timeout-ms 120000 --json && a3s-test run tests/e2e/collaboration-participants.acl --json && a3s-test run tests/e2e/collaboration-pdf-annotations.acl --json && a3s-test run tests/e2e/collaboration-spreadsheet-cells.acl --json && a3s-test run tests/e2e/collaboration-presentation-elements.acl --json",
143
+ "test:e2e:check": "bun run test:e2e:fixtures && a3s-test check tests/e2e/word-page-color.acl --json && a3s-test check tests/e2e/word-page-setup-phone.acl --json && a3s-test check tests/e2e/word-paragraph-layout-phone.acl --json && a3s-test check tests/e2e/word-list-formatting-phone.acl --json && a3s-test check tests/e2e/word-font-picker-phone.acl --json && a3s-test check tests/e2e/word-comments-drawer.acl --json && a3s-test check tests/e2e/word-comment-windowing.acl --json && a3s-test check tests/e2e/word-citations-phone.acl --json && a3s-test check tests/e2e/word-navigation-search.acl --json && a3s-test check tests/e2e/word-navigation-windowing.acl --json && a3s-test check tests/e2e/word-find-replace-phone.acl --json && a3s-test check tests/e2e/word-page-navigation.acl --json && a3s-test check tests/e2e/word-page-windowing.acl --json && a3s-test check tests/e2e/word-ai-question.acl --json && a3s-test check tests/e2e/word-picture-insert.acl --json && a3s-test check tests/e2e/word-picture-alt-text-phone.acl --json && a3s-test check tests/e2e/word-text-box-phone.acl --json && a3s-test check tests/e2e/word-track-changes-phone.acl --json && a3s-test check tests/e2e/word-formatting-revision.acl --json && a3s-test check tests/e2e/word-paragraph-formatting-revision.acl --json && a3s-test check tests/e2e/word-numbering-revision.acl --json && a3s-test check tests/e2e/word-document-comparison.acl --json && a3s-test check tests/e2e/word-review-conflict-phone.acl --json && a3s-test check tests/e2e/word-revision-windowing.acl --json && a3s-test check tests/e2e/word-table-phone.acl --json && a3s-test check tests/e2e/word-table-borders.acl --json && a3s-test check tests/e2e/word-theme-table.acl --json && a3s-test check tests/e2e/word-styled-table.acl --json && a3s-test check tests/e2e/word-multi-page-table.acl --json && a3s-test check tests/e2e/word-cross-reference-phone.acl --json && a3s-test check tests/e2e/word-bookmark-links-phone.acl --json && a3s-test check tests/e2e/word-notes-phone.acl --json && a3s-test check tests/e2e/word-fields-phone.acl --json && a3s-test check tests/e2e/spreadsheet-phone-rename.acl --json && a3s-test check tests/e2e/spreadsheet-phone-find.acl --json && a3s-test check tests/e2e/spreadsheet-phone-context-menu.acl --json && a3s-test check tests/e2e/spreadsheet-phone-task-pane.acl --json && a3s-test check tests/e2e/spreadsheet-maximum-sparse.acl --json && a3s-test check tests/e2e/spreadsheet-cell-style.acl --json && a3s-test check tests/e2e/spreadsheet-paste-special.acl --json && a3s-test check tests/e2e/spreadsheet-hyperlink.acl --json && a3s-test check tests/e2e/presentation-cut-paste-focus.acl --json && a3s-test check tests/e2e/presentation-presenter-view.acl --json && a3s-test check tests/e2e/presentation-phone-chart-pane.acl --json && a3s-test check tests/e2e/presentation-phone-comments.acl --json && a3s-test check tests/e2e/pdf-thumbnail-keyboard.acl --json && a3s-test check tests/e2e/pdf-page-drawer-phone.acl --json && a3s-test check tests/e2e/markdown-phone-modes.acl --json && a3s-test check tests/e2e/office-sidebar-breakpoint.acl --json && a3s-test check tests/e2e/office-docs-navigation.acl --json && a3s-test check tests/e2e/collaboration-playground-entry.acl --json && a3s-test check tests/e2e/collaboration-document-comments.acl --json && a3s-test check tests/e2e/collaboration-document-suggestions.acl --json && a3s-test check tests/e2e/collaboration-participants.acl --json && a3s-test check tests/e2e/collaboration-pdf-annotations.acl --json && a3s-test check tests/e2e/collaboration-spreadsheet-cells.acl --json && a3s-test check tests/e2e/collaboration-presentation-elements.acl --json",
144
+ "test:e2e:writer-text-box": "bun run test:e2e:fixtures && A3S_TEST_SUITE=tests/e2e/word-text-box-phone.acl bash scripts/run-a3s-test-web-gate.sh",
145
+ "test:e2e:writer-text-box:check": "a3s-test check tests/e2e/word-text-box-phone.acl --json",
143
146
  "test:e2e:fixtures": "bun scripts/create-e2e-fixtures.ts",
144
147
  "test:e2e:numbering-revision": "A3S_TEST_SUITE=tests/e2e/word-numbering-revision.acl bash scripts/run-a3s-test-web-gate.sh",
145
148
  "test:e2e:numbering-revision:check": "a3s-test check tests/e2e/word-numbering-revision.acl --json",