@a3s-lab/office 0.30.0 → 0.31.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 (29) hide show
  1. package/README.md +22 -5
  2. package/dist/{0~7231.js → 0~4808.js} +189 -2
  3. package/dist/0~5050.js +10 -1
  4. package/dist/{0~7360.js → 0~7240.js} +244 -15
  5. package/dist/0~document-editor.js +622 -125
  6. package/dist/0~work-docx-export.js +214 -26
  7. package/dist/0~work-docx-import.js +17 -6
  8. package/dist/0~work-office-diagnostics.js +25 -4
  9. package/dist/4104.js +1 -1
  10. package/dist/4121.js +412 -11
  11. package/dist/6282.js +431 -2
  12. package/dist/internal/features/work/editors/document-command-catalog.d.ts +27 -0
  13. package/dist/internal/features/work/editors/document-dom-selection.d.ts +7 -0
  14. package/dist/internal/features/work/editors/document-editor-support.d.ts +1 -0
  15. package/dist/internal/features/work/editors/document-index-dialog.d.ts +10 -0
  16. package/dist/internal/features/work/editors/document-index-entry-dialog.d.ts +10 -0
  17. package/dist/internal/features/work/editors/document-references-ribbon.d.ts +19 -0
  18. package/dist/internal/features/work/editors/document-toolbar.d.ts +4 -1
  19. package/dist/internal/features/work/editors/use-document-insert-commands.d.ts +3 -0
  20. package/dist/internal/features/work/work-document-index-fields.d.ts +19 -0
  21. package/dist/internal/features/work/work-document-index-nodes.d.ts +32 -0
  22. package/dist/internal/features/work/work-document-index.d.ts +63 -0
  23. package/dist/internal/features/work/work-docx-import.d.ts +3 -1
  24. package/dist/internal/features/work/work-docx-index-export.d.ts +14 -0
  25. package/dist/internal/features/work/work-docx-index-import.d.ts +23 -0
  26. package/dist/office-kernel.wasm +0 -0
  27. package/dist/styles.css +296 -0
  28. package/docs/latest/en/browser-editor-architecture.md +14 -0
  29. package/package.json +4 -1
@@ -0,0 +1,32 @@
1
+ import { Node, type CommandProps } from '@tiptap/core';
2
+ import { type WorkDocumentIndexBuildOptions, type WorkDocumentIndexEntry, type WorkDocumentIndexEntryDraft, type WorkDocumentIndexOptions } from './work-document-index';
3
+ declare module '@tiptap/core' {
4
+ interface Commands<ReturnType> {
5
+ documentIndexEntry: {
6
+ markDocumentIndexEntry: (value: WorkDocumentIndexEntryDraft) => ReturnType;
7
+ updateDocumentIndexEntry: (value: WorkDocumentIndexEntryDraft) => ReturnType;
8
+ };
9
+ documentIndex: {
10
+ insertDocumentIndex: (options?: WorkDocumentIndexOptions, buildOptions?: WorkDocumentIndexBuildOptions) => ReturnType;
11
+ updateDocumentIndex: (options: WorkDocumentIndexOptions, buildOptions?: WorkDocumentIndexBuildOptions) => ReturnType;
12
+ refreshDocumentIndexes: (buildOptions?: WorkDocumentIndexBuildOptions) => ReturnType;
13
+ };
14
+ }
15
+ }
16
+ export declare const DocumentIndexEntry: Node<any, any>;
17
+ export declare const DocumentIndex: Node<any, any>;
18
+ export declare function selectedDocumentIndexEntry(editor: {
19
+ state: CommandProps['state'];
20
+ }): WorkDocumentIndexEntry | null;
21
+ export declare function selectedDocumentIndexOptions(editor: {
22
+ state: CommandProps['state'];
23
+ }): WorkDocumentIndexOptions | null;
24
+ export declare function selectedDocumentIndexDraft(editor: {
25
+ state: CommandProps['state'];
26
+ }): WorkDocumentIndexEntryDraft | null;
27
+ export declare function documentHasIndexEntries(editor: {
28
+ state: CommandProps['state'];
29
+ }): boolean;
30
+ export declare function documentHasIndex(editor: {
31
+ state: CommandProps['state'];
32
+ }): boolean;
@@ -0,0 +1,63 @@
1
+ import type { Node as ProseMirrorNode } from '@tiptap/pm/model';
2
+ import type { WorkDocumentFieldContextResolver } from './work-document-fields';
3
+ export type WorkDocumentIndexLeader = 'dot' | 'dash' | 'underline' | 'none';
4
+ export type WorkDocumentIndexFormat = 'indented' | 'run-in';
5
+ export interface WorkDocumentIndexEntryDraft {
6
+ mainEntry: string;
7
+ subEntry: string;
8
+ crossReference: string;
9
+ pageBold: boolean;
10
+ pageItalic: boolean;
11
+ }
12
+ export interface WorkDocumentIndexEntry extends WorkDocumentIndexEntryDraft {
13
+ id: string;
14
+ }
15
+ export interface WorkDocumentIndexPage {
16
+ pageNumber: number;
17
+ pageBold: boolean;
18
+ pageItalic: boolean;
19
+ targetIds: string[];
20
+ }
21
+ export interface WorkDocumentIndexGeneratedEntry {
22
+ mainEntry: string;
23
+ subEntry: string;
24
+ crossReference: string;
25
+ pages: WorkDocumentIndexPage[];
26
+ }
27
+ export interface WorkDocumentIndexOptions {
28
+ columns: number;
29
+ format: WorkDocumentIndexFormat;
30
+ rightAlignPageNumbers: boolean;
31
+ leader: WorkDocumentIndexLeader;
32
+ }
33
+ export interface WorkDocumentIndexValue {
34
+ id: string;
35
+ options: WorkDocumentIndexOptions;
36
+ entries: WorkDocumentIndexGeneratedEntry[];
37
+ truncated: boolean;
38
+ }
39
+ export interface WorkDocumentIndexBuildOptions {
40
+ resolveContext?: WorkDocumentFieldContextResolver;
41
+ }
42
+ export declare const DEFAULT_DOCUMENT_INDEX_OPTIONS: WorkDocumentIndexOptions;
43
+ export declare const MAX_DOCUMENT_INDEX_ENTRIES = 512;
44
+ export declare const MAX_DOCUMENT_INDEX_MARKERS = 2048;
45
+ export declare const MAX_DOCUMENT_INDEX_TERM_LENGTH = 240;
46
+ export declare function normalizeDocumentIndexEntryDraft(source: Partial<WorkDocumentIndexEntryDraft> | null | undefined): WorkDocumentIndexEntryDraft | null;
47
+ export declare function normalizeDocumentIndexEntry(source: Partial<WorkDocumentIndexEntry> | null | undefined, fallbackId?: string): WorkDocumentIndexEntry | null;
48
+ export declare function normalizeDocumentIndexOptions(source: Partial<WorkDocumentIndexOptions> | null | undefined): WorkDocumentIndexOptions;
49
+ export declare function normalizeDocumentIndexValue(source: Omit<WorkDocumentIndexValue, 'truncated'> & {
50
+ truncated?: boolean;
51
+ }): WorkDocumentIndexValue;
52
+ export declare function buildDocumentIndexEntries(document: ProseMirrorNode, options?: WorkDocumentIndexBuildOptions): {
53
+ entries: WorkDocumentIndexGeneratedEntry[];
54
+ truncated: boolean;
55
+ };
56
+ export declare function documentIndexEntryHtml(source: Partial<WorkDocumentIndexEntry>): string;
57
+ export declare function documentIndexHtml(source: Omit<WorkDocumentIndexValue, 'truncated'> & {
58
+ truncated?: boolean;
59
+ }): string;
60
+ export declare function documentIndexEntryFromElement(element: HTMLElement, index?: number): WorkDocumentIndexEntry | null;
61
+ export declare function documentIndexValueFromElement(element: HTMLElement, index?: number): WorkDocumentIndexValue;
62
+ export declare function normalizeDocumentIndexesHtml(source: string): string;
63
+ export declare function indexLeader(value: unknown): WorkDocumentIndexLeader | null;
@@ -5,6 +5,7 @@ import { type ImportedDocxCitationMarkers } from './work-docx-citation-import';
5
5
  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
+ import { type ImportedDocxIndexMarkers } from './work-docx-index-import';
8
9
  import { type ImportedDocxTableOfContentsMarkers } from './work-docx-table-of-contents-import';
9
10
  import { type ImportedDocxImageLayoutMarkers } from './work-docx-image-layout-import';
10
11
  import { type ImportedDocxListMarkers } from './work-docx-list-import';
@@ -38,6 +39,7 @@ export interface PreparedDocxImport {
38
39
  commentMarkers: ImportedDocxCommentMarkers;
39
40
  fieldMarkers: ImportedDocxFieldMarkers;
40
41
  tableOfContentsMarkers: ImportedDocxTableOfContentsMarkers;
42
+ indexMarkers: ImportedDocxIndexMarkers;
41
43
  equationMarkers: ImportedDocxEquationMarkers;
42
44
  citationMarkers: ImportedDocxCitationMarkers;
43
45
  listMarkers: ImportedDocxListMarkers;
@@ -60,6 +62,6 @@ export interface PreparedDocxImport {
60
62
  trackChanges: boolean;
61
63
  }
62
64
  export declare function prepareDocxImport(buffer: ArrayBuffer, sourcePackage?: OoxmlPackage): Promise<PreparedDocxImport>;
63
- export declare function applyDocxSectionsToHtml(html: string, sections: PreparedDocxImport['sections'], captionMarkers?: ImportedDocxCaptionMarkers, bookmarkMarkers?: ImportedDocxBookmarkMarkers, changeMarkers?: ImportedDocxChangeMarkers, commentMarkers?: ImportedDocxCommentMarkers, fieldMarkers?: ImportedDocxFieldMarkers, tableOfContentsMarkers?: ImportedDocxTableOfContentsMarkers, equationMarkers?: ImportedDocxEquationMarkers, citationMarkers?: ImportedDocxCitationMarkers, listMarkers?: ImportedDocxListMarkers, 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;
65
+ 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, 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;
64
66
  export declare function readDocxLayout(buffer: ArrayBuffer): Promise<ImportedDocumentLayout>;
65
67
  export {};
@@ -0,0 +1,14 @@
1
+ import type { FileChild, ParagraphChild } from 'docx';
2
+ import { type WorkDocumentIndexGeneratedEntry, type WorkDocumentIndexOptions } from './work-document-index';
3
+ export interface DocxIndexPatch {
4
+ marker: string;
5
+ options: WorkDocumentIndexOptions;
6
+ entries: WorkDocumentIndexGeneratedEntry[];
7
+ }
8
+ export declare class DocxIndexPatchCollector {
9
+ readonly patches: DocxIndexPatch[];
10
+ add(element: HTMLElement): DocxIndexPatch;
11
+ }
12
+ export declare function docxDocumentIndex(element: HTMLElement, docx: typeof import('docx'), collector: DocxIndexPatchCollector): FileChild[];
13
+ export declare function docxIndexEntryRun(element: HTMLElement, docx: typeof import('docx')): ParagraphChild | null;
14
+ export declare function patchDocxIndexes(buffer: ArrayBuffer, patches: readonly DocxIndexPatch[]): Promise<ArrayBuffer>;
@@ -0,0 +1,23 @@
1
+ import { type WorkDocumentIndexEntryDraft, type WorkDocumentIndexGeneratedEntry, type WorkDocumentIndexOptions } from './work-document-index';
2
+ import { type DocxFieldOccurrence } from './work-docx-field-instructions';
3
+ export interface ImportedDocxIndexMarkers {
4
+ entries: ImportedDocxIndexEntryMarker[];
5
+ indexes: ImportedDocxIndexMarker[];
6
+ }
7
+ export interface ImportedDocxIndexEntryMarker {
8
+ start: string;
9
+ end: string;
10
+ id: string;
11
+ value: WorkDocumentIndexEntryDraft;
12
+ }
13
+ export interface ImportedDocxIndexMarker {
14
+ marker: string;
15
+ id: string;
16
+ options: WorkDocumentIndexOptions;
17
+ entries: WorkDocumentIndexGeneratedEntry[];
18
+ }
19
+ export declare function markDocxIndexes(document: Document): ImportedDocxIndexMarkers;
20
+ export declare function applyImportedDocxIndexMarkers(document: Document, markers: ImportedDocxIndexMarkers): void;
21
+ export declare function hasImportedDocxIndexMarkers(markers: ImportedDocxIndexMarkers): boolean;
22
+ export declare function supportedDocxIndexEntryField(field: DocxFieldOccurrence): boolean;
23
+ export declare function supportedDocxIndexField(field: DocxFieldOccurrence): boolean;
Binary file
package/dist/styles.css CHANGED
@@ -12749,6 +12749,302 @@ sub [data-office-character-position-half-points], sup [data-office-character-pos
12749
12749
  }
12750
12750
  }
12751
12751
 
12752
+ .work-document-index-entry {
12753
+ border: 1px solid color-mix(in srgb, var(--a3s-blue) 34%, var(--a3s-line));
12754
+ background: color-mix(in srgb, var(--a3s-blue) 7%, var(--a3s-panel));
12755
+ max-width: min(260px, 80%);
12756
+ color: var(--a3s-ink);
12757
+ cursor: default;
12758
+ vertical-align: baseline;
12759
+ border-radius: 4px;
12760
+ align-items: baseline;
12761
+ gap: 5px;
12762
+ margin-inline: 3px;
12763
+ padding: 1px 5px;
12764
+ font-size: 9px;
12765
+ line-height: 1.45;
12766
+ display: inline-flex;
12767
+ }
12768
+
12769
+ .work-document-index-entry > span {
12770
+ color: color-mix(in srgb, var(--a3s-blue) 78%, var(--a3s-ink));
12771
+ white-space: nowrap;
12772
+ font-size: 8px;
12773
+ font-weight: 650;
12774
+ }
12775
+
12776
+ .work-document-index-entry > strong {
12777
+ text-overflow: ellipsis;
12778
+ white-space: nowrap;
12779
+ font-weight: 560;
12780
+ overflow: hidden;
12781
+ }
12782
+
12783
+ .work-document-index-entry.ProseMirror-selectednode {
12784
+ border-color: var(--a3s-blue);
12785
+ outline: 2px solid color-mix(in srgb, var(--a3s-blue) 22%, transparent);
12786
+ outline-offset: 1px;
12787
+ }
12788
+
12789
+ .work-document-index {
12790
+ box-sizing: border-box;
12791
+ border: 1px solid color-mix(in srgb, var(--a3s-line) 82%, #8aa7d8);
12792
+ background: color-mix(in srgb, var(--a3s-panel) 96%, #edf4ff);
12793
+ width: 100%;
12794
+ color: var(--a3s-ink);
12795
+ cursor: default;
12796
+ border-radius: 6px;
12797
+ margin: 14px 0 20px;
12798
+ padding: 14px 16px 16px;
12799
+ }
12800
+
12801
+ .work-document-index.ProseMirror-selectednode {
12802
+ border-color: var(--a3s-blue);
12803
+ outline: 2px solid color-mix(in srgb, var(--a3s-blue) 22%, transparent);
12804
+ outline-offset: 2px;
12805
+ }
12806
+
12807
+ .work-document-index-header {
12808
+ border-bottom: 1px solid var(--a3s-line);
12809
+ justify-content: space-between;
12810
+ align-items: baseline;
12811
+ gap: 12px;
12812
+ margin-bottom: 10px;
12813
+ padding-bottom: 7px;
12814
+ display: flex;
12815
+ }
12816
+
12817
+ .work-document-index-header strong {
12818
+ font-family: var(--a3s-font-display, inherit);
12819
+ letter-spacing: -.02em;
12820
+ font-size: 18px;
12821
+ font-weight: 680;
12822
+ }
12823
+
12824
+ .work-document-index-header span {
12825
+ color: var(--a3s-muted);
12826
+ font-variant-numeric: tabular-nums;
12827
+ font-size: 9px;
12828
+ }
12829
+
12830
+ .work-document-index-list {
12831
+ column-gap: 22px;
12832
+ margin: 0;
12833
+ padding: 0;
12834
+ list-style: none;
12835
+ }
12836
+
12837
+ .work-document-index[data-index-columns="2"] .work-document-index-list {
12838
+ column-count: 2;
12839
+ }
12840
+
12841
+ .work-document-index[data-index-columns="3"] .work-document-index-list {
12842
+ column-count: 3;
12843
+ }
12844
+
12845
+ .work-document-index[data-index-columns="4"] .work-document-index-list {
12846
+ column-count: 4;
12847
+ }
12848
+
12849
+ .work-document-index-list > li {
12850
+ break-inside: avoid;
12851
+ align-items: baseline;
12852
+ gap: 5px;
12853
+ min-width: 0;
12854
+ padding-block: 1px;
12855
+ font-size: 10px;
12856
+ line-height: 1.55;
12857
+ display: flex;
12858
+ }
12859
+
12860
+ .work-document-index-main, .work-document-index-sub {
12861
+ text-overflow: ellipsis;
12862
+ white-space: nowrap;
12863
+ overflow: hidden;
12864
+ }
12865
+
12866
+ .work-document-index-sub {
12867
+ color: color-mix(in srgb, var(--a3s-ink) 82%, var(--a3s-muted));
12868
+ padding-left: 12px;
12869
+ }
12870
+
12871
+ .work-document-index[data-index-format="run-in"] .work-document-index-sub {
12872
+ padding-left: 0;
12873
+ }
12874
+
12875
+ .work-document-index[data-index-format="run-in"] .work-document-index-sub:before {
12876
+ content: ", ";
12877
+ }
12878
+
12879
+ .work-document-index-list > li > i {
12880
+ border-bottom: 1px dotted
12881
+ color-mix(in srgb, var(--a3s-muted) 68%, transparent);
12882
+ flex: 20px;
12883
+ min-width: 10px;
12884
+ transform: translateY(-2px);
12885
+ }
12886
+
12887
+ .work-document-index[data-index-leader="dash"] .work-document-index-list > li > i {
12888
+ border-bottom-style: dashed;
12889
+ }
12890
+
12891
+ .work-document-index[data-index-leader="underline"] .work-document-index-list > li > i {
12892
+ border-bottom-style: solid;
12893
+ }
12894
+
12895
+ .work-document-index[data-index-leader="none"] .work-document-index-list > li > i, .work-document-index[data-index-right-align-page-numbers="false"] .work-document-index-list > li > i {
12896
+ border: 0;
12897
+ flex: 0 0 3px;
12898
+ min-width: 3px;
12899
+ }
12900
+
12901
+ .work-document-index-pages {
12902
+ font-variant-numeric: tabular-nums;
12903
+ flex: none;
12904
+ }
12905
+
12906
+ .work-document-index-pages a {
12907
+ color: inherit;
12908
+ text-decoration: none;
12909
+ }
12910
+
12911
+ .work-document-index-pages a:hover {
12912
+ color: var(--a3s-blue);
12913
+ text-decoration: underline;
12914
+ }
12915
+
12916
+ .work-document-index-pages a.bold {
12917
+ font-weight: 700;
12918
+ }
12919
+
12920
+ .work-document-index-pages a.italic {
12921
+ font-style: italic;
12922
+ }
12923
+
12924
+ .work-document-index-cross-reference, .work-document-index-empty {
12925
+ color: var(--a3s-muted);
12926
+ font-style: italic;
12927
+ }
12928
+
12929
+ .work-document-index-entry-dialog, .work-document-index-dialog {
12930
+ width: min(540px, 100%);
12931
+ }
12932
+
12933
+ .work-document-index-entry-dialog-fields, .work-document-index-dialog-grid {
12934
+ grid-template-columns: repeat(2, minmax(0, 1fr));
12935
+ gap: 10px;
12936
+ display: grid;
12937
+ }
12938
+
12939
+ .work-document-index-entry-dialog label, .work-document-index-dialog-field, .work-document-index-entry-dialog-mode {
12940
+ min-width: 0;
12941
+ color: var(--a3s-muted);
12942
+ gap: 6px;
12943
+ font-size: 10px;
12944
+ display: grid;
12945
+ }
12946
+
12947
+ .work-document-index-entry-dialog-mode, .work-document-index-dialog-options, .work-document-index-entry-dialog-page-style {
12948
+ border: 1px solid var(--a3s-line);
12949
+ background: var(--a3s-panel-soft);
12950
+ border-radius: 7px;
12951
+ margin-top: 14px;
12952
+ padding: 10px;
12953
+ }
12954
+
12955
+ .work-document-index-entry-dialog-page-style, .work-document-index-dialog-options {
12956
+ align-items: center;
12957
+ gap: 14px;
12958
+ display: flex;
12959
+ }
12960
+
12961
+ .work-document-index-entry-dialog-page-style > legend {
12962
+ color: var(--a3s-muted);
12963
+ padding-inline: 4px;
12964
+ font-size: 10px;
12965
+ }
12966
+
12967
+ .work-document-index-dialog-options > .work-document-index-dialog-field {
12968
+ min-width: 180px;
12969
+ margin-left: auto;
12970
+ }
12971
+
12972
+ .work-document-index-dialog .work-office-select {
12973
+ width: 100%;
12974
+ }
12975
+
12976
+ .work-document-index-dialog-preview {
12977
+ border: 1px solid var(--a3s-line);
12978
+ background: var(--a3s-bg);
12979
+ color: var(--a3s-ink);
12980
+ border-radius: 7px;
12981
+ gap: 5px;
12982
+ margin-top: 14px;
12983
+ padding: 14px;
12984
+ font-size: 10px;
12985
+ display: grid;
12986
+ }
12987
+
12988
+ .work-document-index-dialog-preview > legend {
12989
+ font-size: 14px;
12990
+ }
12991
+
12992
+ .work-document-index-dialog-preview > span {
12993
+ align-items: baseline;
12994
+ gap: 5px;
12995
+ display: flex;
12996
+ }
12997
+
12998
+ .work-document-index-dialog-preview > span.nested {
12999
+ padding-left: 16px;
13000
+ }
13001
+
13002
+ .work-document-index-dialog-preview[data-index-format="run-in"] > span.nested {
13003
+ padding-left: 0;
13004
+ }
13005
+
13006
+ .work-document-index-dialog-preview i {
13007
+ border-bottom: 1px dotted var(--a3s-muted);
13008
+ flex: 1;
13009
+ }
13010
+
13011
+ .work-document-index-dialog-preview[data-index-leader="dash"] i {
13012
+ border-bottom-style: dashed;
13013
+ }
13014
+
13015
+ .work-document-index-dialog-preview[data-index-leader="underline"] i {
13016
+ border-bottom-style: solid;
13017
+ }
13018
+
13019
+ .work-document-index-dialog-preview[data-index-leader="none"] i, .work-document-index-dialog-preview[data-index-right-align-page-numbers="false"] i {
13020
+ border: 0;
13021
+ flex: 0 0 5px;
13022
+ }
13023
+
13024
+ @media (width <= 560px) {
13025
+ .work-document-index {
13026
+ padding-inline: 12px;
13027
+ }
13028
+
13029
+ .work-document-index-list {
13030
+ column-count: 1 !important;
13031
+ }
13032
+
13033
+ .work-document-index-entry-dialog-fields, .work-document-index-dialog-grid {
13034
+ grid-template-columns: 1fr;
13035
+ }
13036
+
13037
+ .work-document-index-entry-dialog-page-style, .work-document-index-dialog-options {
13038
+ flex-direction: column;
13039
+ align-items: stretch;
13040
+ }
13041
+
13042
+ .work-document-index-dialog-options > .work-document-index-dialog-field {
13043
+ min-width: 0;
13044
+ margin-left: 0;
13045
+ }
13046
+ }
13047
+
12752
13048
  .work-document-equation {
12753
13049
  vertical-align: -.12em;
12754
13050
  border-radius: .2em;
@@ -109,6 +109,20 @@ model:
109
109
  then restores one typed block after paragraph identities are applied. Each
110
110
  imported TOC matches its cached rows independently, so repeated TOCs can
111
111
  target the same heading.
112
+ Native indexes use a separate inline `documentIndexEntry` atom and block
113
+ `documentIndex` atom. The inline node owns stable identity plus primary,
114
+ secondary, cross-reference, and page-emphasis intent; the block owns only
115
+ bounded options, generated rows, and truncation state. One collector walks
116
+ the canonical TipTap document, obtains pages from the existing field-context
117
+ resolver, groups normalized terms, and merges same-page markers while
118
+ retaining every target ID. Mark/edit and block insert/customize/refresh each
119
+ dispatch one transaction. DOCX export maps inline atoms to native
120
+ `w:fldSimple` `XE` fields, writes an `INDEX` content control through an
121
+ isolated marker collector/patcher, and emits cached `Index1`/`Index2` rows.
122
+ Import marks supported XE boundaries and removes supported INDEX controls
123
+ before Mammoth conversion, then reconstructs typed atoms and reconnects
124
+ cached page rows to matching marker identities. Unsupported switches and
125
+ malformed structures remain on the field diagnostic path.
112
126
  Page Layout keeps direct margin, orientation, paper,
113
127
  and equal-column presets in the ribbon; custom margins and advanced columns
114
128
  open the corresponding controlled Page Setup tab instead of duplicating a
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@a3s-lab/office",
3
- "version": "0.30.0",
3
+ "version": "0.31.0",
4
4
  "description": "Open-source collaborative browser editors for documents, Markdown, spreadsheets, presentations, and PDFs.",
5
5
  "keywords": [
6
6
  "office",
@@ -88,6 +88,7 @@
88
88
  "playground:typecheck": "tsc --noEmit -p playground/tsconfig.json",
89
89
  "playground:visual": "playwright test --config playwright.config.ts",
90
90
  "playground:visual:document-emphasis": "playwright test visual-tests/document-emphasis.functional.spec.ts --config playwright.config.ts",
91
+ "playground:visual:document-index": "playwright test visual-tests/document-index.functional.spec.ts --config playwright.config.ts",
91
92
  "playground:visual:document-hidden-text": "playwright test visual-tests/document-hidden-text.functional.spec.ts --config playwright.config.ts",
92
93
  "playground:visual:document-legacy-text-effects": "playwright test visual-tests/document-legacy-text-effects.functional.spec.ts --config playwright.config.ts",
93
94
  "playground:visual:document-proofing-languages": "playwright test visual-tests/document-proofing-languages.functional.spec.ts --config playwright.config.ts",
@@ -210,6 +211,8 @@
210
211
  "test:e2e:writer-proofing-languages:check": "a3s-test check tests/e2e/word-proofing-languages.acl --json",
211
212
  "test:e2e:writer-table-of-contents": "A3S_TEST_SUITE=tests/e2e/word-table-of-contents.acl bash scripts/run-a3s-test-web-gate.sh",
212
213
  "test:e2e:writer-table-of-contents:check": "a3s-test check tests/e2e/word-table-of-contents.acl --json",
214
+ "test:e2e:writer-document-index": "A3S_TEST_SUITE=tests/e2e/word-document-index.acl bash scripts/run-a3s-test-web-gate.sh",
215
+ "test:e2e:writer-document-index:check": "a3s-test check tests/e2e/word-document-index.acl --json",
213
216
  "test:e2e:writer-run-border": "A3S_TEST_SUITE=tests/e2e/word-run-border.acl bash scripts/run-a3s-test-web-gate.sh",
214
217
  "test:e2e:writer-run-border:check": "a3s-test check tests/e2e/word-run-border.acl --json",
215
218
  "test:e2e:writer-run-shading": "A3S_TEST_SUITE=tests/e2e/word-run-shading.acl bash scripts/run-a3s-test-web-gate.sh",