From 1838774fad1a2910cf212f2e37f3d0c2be8250bf Mon Sep 17 00:00:00 2001 From: skanehira Date: Mon, 6 Feb 2023 18:42:25 +0900 Subject: [PATCH] fix: circular reference when using module that built with esbuild (#605) --- docx-wasm/js/builder.ts | 142 ++++++++++++++++++++++++++++++ docx-wasm/js/comment.ts | 23 ----- docx-wasm/js/hyperlink.ts | 28 ------ docx-wasm/js/index.ts | 16 ++-- docx-wasm/js/paragraph.ts | 69 --------------- docx-wasm/js/table-cell.ts | 4 +- docx-wasm/js/table-of-contents.ts | 6 +- 7 files changed, 155 insertions(+), 133 deletions(-) create mode 100644 docx-wasm/js/builder.ts diff --git a/docx-wasm/js/builder.ts b/docx-wasm/js/builder.ts new file mode 100644 index 0000000..bf264c5 --- /dev/null +++ b/docx-wasm/js/builder.ts @@ -0,0 +1,142 @@ +import { Comment } from "./comment"; +import { CommentEnd } from "./comment-end"; +import { Paragraph } from "./paragraph"; +import { Table } from "./table"; +import { Run } from "./run"; +import { Insert } from "./insert"; +import { Delete } from "./delete"; +import { BookmarkStart } from "./bookmark-start"; +import { BookmarkEnd } from "./bookmark-end"; +import { Hyperlink, convertHyperlinkType } from "./hyperlink"; +import { setParagraphProperty } from "./paragraph-property"; + +import * as wasm from "./pkg"; + +type Child = | Paragraph + | Table + | Comment + | Hyperlink; + +function buildHyperlink(child: Hyperlink) { + let hyperlink = wasm.createHyperlink(child.v, convertHyperlinkType(child)); + + child.children.forEach((child) => { + if (child instanceof Run) { + const run = child.build(); + hyperlink = hyperlink.add_run(run); + } else if (child instanceof Insert) { + const insert = child.build(); + hyperlink = hyperlink.add_insert(insert); + } else if (child instanceof Delete) { + const del = child.build(); + hyperlink = hyperlink.add_delete(del); + } else if (child instanceof BookmarkStart) { + hyperlink = hyperlink.add_bookmark_start(child.id, child.name); + } else if (child instanceof BookmarkEnd) { + hyperlink = hyperlink.add_bookmark_end(child.id); + } else if (child instanceof Comment) { + hyperlink = hyperlink.add_comment_start(build(child)); + } else if (child instanceof CommentEnd) { + hyperlink = hyperlink.add_comment_end(child.id); + } + }); + + return hyperlink; +} + +function buildParagraph(child: Paragraph) { + let paragraph = wasm.createParagraph(); + child.children.forEach((child) => { + if (child instanceof Run) { + const run = child.build(); + paragraph = paragraph.add_run(run); + } else if (child instanceof Insert) { + const insert = child.build(); + paragraph = paragraph.add_insert(insert); + } else if (child instanceof Delete) { + const del = child.build(); + paragraph = paragraph.add_delete(del); + } else if (child instanceof Hyperlink) { + paragraph = paragraph.add_hyperlink(build(child)); + } else if (child instanceof BookmarkStart) { + paragraph = paragraph.add_bookmark_start(child.id, child.name); + } else if (child instanceof BookmarkEnd) { + paragraph = paragraph.add_bookmark_end(child.id); + } else if (child instanceof Comment) { + const comment = build(child); + paragraph = paragraph.add_comment_start(comment as wasm.Comment); + } else if (child instanceof CommentEnd) { + paragraph = paragraph.add_comment_end(child.id); + } + }); + + paragraph = setParagraphProperty(paragraph, child.property); + + if (typeof child.property.styleId !== "undefined") { + paragraph = paragraph.style(child.property.styleId); + } + + if (child.property.runProperty.del) { + paragraph = paragraph.delete( + child.property.runProperty.del.author, + child.property.runProperty.del.date + ); + } + + if (child.property.runProperty.ins) { + paragraph = paragraph.insert( + child.property.runProperty.ins.author, + child.property.runProperty.ins.date + ); + } + + if (child.property.paragraphPropertyChange) { + let change = wasm.createParagraphPropertyChange(); + change = change + .author(child.property.paragraphPropertyChange._author) + .date(child.property.paragraphPropertyChange._date); + + if (child.property.paragraphPropertyChange._property.numbering) { + change = change.numbering( + child.property.paragraphPropertyChange._property.numbering.id, + child.property.paragraphPropertyChange._property.numbering.level + ); + } + // TODO: add style, indent, alignment + paragraph = paragraph.paragraph_property_change(change); + } + + return paragraph; +} + +function buildComment(child: Comment) { + let comment = wasm.createComment(child.id); + child.children.forEach((c) => { + if (c instanceof Paragraph) { + comment = comment.add_paragraph(buildParagraph(c)); + } else if (child instanceof Table) { + // TODO: Support later + } + }); + if (child._author) { + comment = comment.author(child._author); + } + if (child._date) { + comment = comment.date(child._date); + } + if (child._parentCommentId) { + comment = comment.parent_comment_id(child._parentCommentId); + } + return comment; +} + +export function build(child: Child) { + if (child instanceof Comment) { + return buildComment(child) as T; + } else if (child instanceof Paragraph) { + return buildParagraph(child) as T; + } else if (child instanceof Hyperlink) { + return buildHyperlink(child) as T; + } + throw new Error(`not found builder for child: ${child}`); +} diff --git a/docx-wasm/js/comment.ts b/docx-wasm/js/comment.ts index 66c0da7..ffc2886 100644 --- a/docx-wasm/js/comment.ts +++ b/docx-wasm/js/comment.ts @@ -1,8 +1,6 @@ import { Paragraph } from "./paragraph"; import { Table } from "./table"; -import * as wasm from "./pkg"; - export class Comment { id: number; _author: string; @@ -33,25 +31,4 @@ export class Comment { this._parentCommentId = id; return this; } - - build() { - let comment = wasm.createComment(this.id); - this.children.forEach((child) => { - if (child instanceof Paragraph) { - comment = comment.add_paragraph(child.build()); - } else if (child instanceof Table) { - // TODO: Support later - } - }); - if (this._author) { - comment = comment.author(this._author); - } - if (this._date) { - comment = comment.date(this._date); - } - if (this._parentCommentId) { - comment = comment.parent_comment_id(this._parentCommentId); - } - return comment; - } } diff --git a/docx-wasm/js/hyperlink.ts b/docx-wasm/js/hyperlink.ts index a920a74..94a8604 100644 --- a/docx-wasm/js/hyperlink.ts +++ b/docx-wasm/js/hyperlink.ts @@ -55,34 +55,6 @@ export class Hyperlink { this.children.push(end); return this; } - - build() { - let hyperlink = wasm.createHyperlink(this.v, convertHyperlinkType(this)); - - this.children.forEach((child) => { - if (child instanceof Run) { - const run = child.build(); - hyperlink = hyperlink.add_run(run); - } else if (child instanceof Insert) { - const insert = child.build(); - hyperlink = hyperlink.add_insert(insert); - } else if (child instanceof Delete) { - const del = child.build(); - hyperlink = hyperlink.add_delete(del); - } else if (child instanceof BookmarkStart) { - hyperlink = hyperlink.add_bookmark_start(child.id, child.name); - } else if (child instanceof BookmarkEnd) { - hyperlink = hyperlink.add_bookmark_end(child.id); - } else if (child instanceof Comment) { - const comment = child.build(); - hyperlink = hyperlink.add_comment_start(comment); - } else if (child instanceof CommentEnd) { - hyperlink = hyperlink.add_comment_end(child.id); - } - }); - - return hyperlink; - } } export const convertHyperlinkType = (link: Hyperlink): wasm.HyperlinkType => { diff --git a/docx-wasm/js/index.ts b/docx-wasm/js/index.ts index 43bfe14..f8ed28d 100644 --- a/docx-wasm/js/index.ts +++ b/docx-wasm/js/index.ts @@ -14,6 +14,7 @@ import { Styles } from "./styles"; import { WebExtension } from "./webextension"; import { Footer } from "./footer"; import { Header } from "./header"; +import { build } from "./builder"; import { SectionProperty, @@ -329,8 +330,7 @@ export class Docx { this.children.forEach((child) => { if (child instanceof Paragraph) { - let p = child.build(); - docx = docx.add_paragraph(p); + docx = docx.add_paragraph(build(child)); } else if (child instanceof Table) { let t = child.build(); docx = docx.add_table(t); @@ -392,7 +392,7 @@ export class Docx { let header = wasm.createHeader(); this.sectionProperty._header.children.forEach((c) => { if (c instanceof Paragraph) { - header = header.add_paragraph(c.build()); + header = header.add_paragraph(build(c)); } else { header = header.add_table(c.build()); } @@ -404,7 +404,7 @@ export class Docx { let header = wasm.createHeader(); this.sectionProperty._firstHeader.children.forEach((c) => { if (c instanceof Paragraph) { - header = header.add_paragraph(c.build()); + header = header.add_paragraph(build(c)); } else { header = header.add_table(c.build()); } @@ -416,7 +416,7 @@ export class Docx { let header = wasm.createHeader(); this.sectionProperty._evenHeader.children.forEach((c) => { if (c instanceof Paragraph) { - header = header.add_paragraph(c.build()); + header = header.add_paragraph(build(c)); } else { header = header.add_table(c.build()); } @@ -428,7 +428,7 @@ export class Docx { let footer = wasm.createFooter(); this.sectionProperty._footer.children.forEach((c) => { if (c instanceof Paragraph) { - footer = footer.add_paragraph(c.build()); + footer = footer.add_paragraph(build(c)); } else { footer = footer.add_table(c.build()); } @@ -440,7 +440,7 @@ export class Docx { let footer = wasm.createFooter(); this.sectionProperty._firstFooter.children.forEach((c) => { if (c instanceof Paragraph) { - footer = footer.add_paragraph(c.build()); + footer = footer.add_paragraph(build(c)); } else { footer = footer.add_table(c.build()); } @@ -452,7 +452,7 @@ export class Docx { let footer = wasm.createFooter(); this.sectionProperty._evenFooter.children.forEach((c) => { if (c instanceof Paragraph) { - footer = footer.add_paragraph(c.build()); + footer = footer.add_paragraph(build(c)); } else { footer = footer.add_table(c.build()); } diff --git a/docx-wasm/js/paragraph.ts b/docx-wasm/js/paragraph.ts index 73c1644..8594675 100644 --- a/docx-wasm/js/paragraph.ts +++ b/docx-wasm/js/paragraph.ts @@ -6,7 +6,6 @@ import { AlignmentType, SpecialIndentKind, ParagraphPropertyChange, - setParagraphProperty, } from "./paragraph-property"; import { Insert } from "./insert"; import { Delete } from "./delete"; @@ -16,8 +15,6 @@ import { Comment } from "./comment"; import { CommentEnd } from "./comment-end"; import { Hyperlink } from "./hyperlink"; -import * as wasm from "./pkg"; - export type ParagraphChild = | Run | Insert @@ -163,70 +160,4 @@ export class Paragraph { this.property.paragraphPropertyChange = propertyChange; return this; } - - build() { - let paragraph = wasm.createParagraph(); - this.children.forEach((child) => { - if (child instanceof Run) { - const run = child.build(); - paragraph = paragraph.add_run(run); - } else if (child instanceof Insert) { - const insert = child.build(); - paragraph = paragraph.add_insert(insert); - } else if (child instanceof Delete) { - const del = child.build(); - paragraph = paragraph.add_delete(del); - } else if (child instanceof Hyperlink) { - const hyperlink = child.build(); - paragraph = paragraph.add_hyperlink(hyperlink); - } else if (child instanceof BookmarkStart) { - paragraph = paragraph.add_bookmark_start(child.id, child.name); - } else if (child instanceof BookmarkEnd) { - paragraph = paragraph.add_bookmark_end(child.id); - } else if (child instanceof Comment) { - const comment = child.build(); - paragraph = paragraph.add_comment_start(comment); - } else if (child instanceof CommentEnd) { - paragraph = paragraph.add_comment_end(child.id); - } - }); - - paragraph = setParagraphProperty(paragraph, this.property); - - if (typeof this.property.styleId !== "undefined") { - paragraph = paragraph.style(this.property.styleId); - } - - if (this.property.runProperty.del) { - paragraph = paragraph.delete( - this.property.runProperty.del.author, - this.property.runProperty.del.date - ); - } - - if (this.property.runProperty.ins) { - paragraph = paragraph.insert( - this.property.runProperty.ins.author, - this.property.runProperty.ins.date - ); - } - - if (this.property.paragraphPropertyChange) { - let change = wasm.createParagraphPropertyChange(); - change = change - .author(this.property.paragraphPropertyChange._author) - .date(this.property.paragraphPropertyChange._date); - - if (this.property.paragraphPropertyChange._property.numbering) { - change = change.numbering( - this.property.paragraphPropertyChange._property.numbering.id, - this.property.paragraphPropertyChange._property.numbering.level - ); - } - // TODO: add style, indent, alignment - paragraph = paragraph.paragraph_property_change(change); - } - - return paragraph; - } } diff --git a/docx-wasm/js/table-cell.ts b/docx-wasm/js/table-cell.ts index 0712a62..5bc4a11 100644 --- a/docx-wasm/js/table-cell.ts +++ b/docx-wasm/js/table-cell.ts @@ -5,6 +5,7 @@ import { TableCellBorders, PositionKeys } from "./table-cell-borders"; import { TableCellBorderPosition, TableCellBorder } from "./table-cell-border"; import * as wasm from "./pkg"; import { convertBorderType } from "./run"; +import { build } from "./builder"; export type VMergeType = "restart" | "continue"; @@ -224,8 +225,7 @@ export class TableCell { let cell = wasm.createTableCell(); this.children.forEach((c) => { if (c instanceof Paragraph) { - const paragraph = c.build(); - cell = cell.add_paragraph(paragraph); + cell = cell.add_paragraph(build(c)); } else if (c instanceof Table) { const table = c.build(); cell = cell.add_table(table); diff --git a/docx-wasm/js/table-of-contents.ts b/docx-wasm/js/table-of-contents.ts index 689dd8a..ff65986 100644 --- a/docx-wasm/js/table-of-contents.ts +++ b/docx-wasm/js/table-of-contents.ts @@ -1,8 +1,8 @@ import { Paragraph } from "./paragraph"; import * as wasm from "./pkg"; import { Table } from "./table"; - import { TableOfContentsItem } from "./table-of-contents-item"; +import { build } from "./builder"; export class TableOfContents { _instrText?: string; @@ -132,7 +132,7 @@ export class TableOfContents { for (const c of this._beforeContents) { if (c instanceof Paragraph) { - toc = toc.add_before_paragraph(c.build()); + toc = toc.add_before_paragraph(build(c)); } else if (c instanceof Table) { toc = toc.add_before_table(c.build()); } @@ -140,7 +140,7 @@ export class TableOfContents { for (const c of this._afterContents) { if (c instanceof Paragraph) { - toc = toc.add_after_paragraph(c.build()); + toc = toc.add_after_paragraph(build(c)); } else if (c instanceof Table) { toc = toc.add_after_table(c.build()); }