UNPKG

@randevcx/ranui

Version:

UI Component library based on `Web Component`

1,677 lines 119 kB
import { J as JSZip } from "./jszip.min-DD9Dc6z4.js"; var RelationshipTypes; (function(RelationshipTypes2) { RelationshipTypes2["OfficeDocument"] = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument"; RelationshipTypes2["FontTable"] = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable"; RelationshipTypes2["Image"] = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image"; RelationshipTypes2["Numbering"] = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering"; RelationshipTypes2["Styles"] = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles"; RelationshipTypes2["StylesWithEffects"] = "http://schemas.microsoft.com/office/2007/relationships/stylesWithEffects"; RelationshipTypes2["Theme"] = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme"; RelationshipTypes2["Settings"] = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings"; RelationshipTypes2["WebSettings"] = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/webSettings"; RelationshipTypes2["Hyperlink"] = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink"; RelationshipTypes2["Footnotes"] = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes"; RelationshipTypes2["Endnotes"] = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/endnotes"; RelationshipTypes2["Footer"] = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer"; RelationshipTypes2["Header"] = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/header"; RelationshipTypes2["ExtendedProperties"] = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties"; RelationshipTypes2["CoreProperties"] = "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties"; RelationshipTypes2["CustomProperties"] = "http://schemas.openxmlformats.org/package/2006/relationships/metadata/custom-properties"; })(RelationshipTypes || (RelationshipTypes = {})); function parseRelationships(root, xml) { return xml.elements(root).map((e) => ({ id: xml.attr(e, "Id"), type: xml.attr(e, "Type"), target: xml.attr(e, "Target"), targetMode: xml.attr(e, "TargetMode") })); } const ns$1 = { wordml: "http://schemas.openxmlformats.org/wordprocessingml/2006/main", drawingml: "http://schemas.openxmlformats.org/drawingml/2006/main", picture: "http://schemas.openxmlformats.org/drawingml/2006/picture", compatibility: "http://schemas.openxmlformats.org/markup-compatibility/2006", math: "http://schemas.openxmlformats.org/officeDocument/2006/math" }; const LengthUsage = { Dxa: { mul: 0.05, unit: "pt" }, Emu: { mul: 1 / 12700, unit: "pt" }, FontSize: { mul: 0.5, unit: "pt" }, Border: { mul: 0.125, unit: "pt" }, Point: { mul: 1, unit: "pt" }, Percent: { mul: 0.02, unit: "%" }, LineHeight: { mul: 1 / 240, unit: "" }, VmlEmu: { mul: 1 / 12700, unit: "" } }; function convertLength(val, usage = LengthUsage.Dxa) { if (val == null || /.+(p[xt]|[%])$/.test(val)) { return val; } return `${(parseInt(val) * usage.mul).toFixed(2)}${usage.unit}`; } function convertBoolean(v, defaultValue = false) { switch (v) { case "1": return true; case "0": return false; case "on": return true; case "off": return false; case "true": return true; case "false": return false; default: return defaultValue; } } function parseCommonProperty(elem, props, xml) { if (elem.namespaceURI != ns$1.wordml) return false; switch (elem.localName) { case "color": props.color = xml.attr(elem, "val"); break; case "sz": props.fontSize = xml.lengthAttr(elem, "val", LengthUsage.FontSize); break; default: return false; } return true; } function parseXmlString(xmlString, trimXmlDeclaration = false) { if (trimXmlDeclaration) xmlString = xmlString.replace(/<[?].*[?]>/, ""); xmlString = removeUTF8BOM(xmlString); const result = new DOMParser().parseFromString(xmlString, "application/xml"); const errorText = hasXmlParserError(result); if (errorText) throw new Error(errorText); return result; } function hasXmlParserError(doc) { var _a; return (_a = doc.getElementsByTagName("parsererror")[0]) == null ? void 0 : _a.textContent; } function removeUTF8BOM(data) { return data.charCodeAt(0) === 65279 ? data.substring(1) : data; } function serializeXmlString(elem) { return new XMLSerializer().serializeToString(elem); } class XmlParser { elements(elem, localName = null) { const result = []; for (let i = 0, l = elem.childNodes.length; i < l; i++) { let c = elem.childNodes.item(i); if (c.nodeType == 1 && (localName == null || c.localName == localName)) result.push(c); } return result; } element(elem, localName) { for (let i = 0, l = elem.childNodes.length; i < l; i++) { let c = elem.childNodes.item(i); if (c.nodeType == 1 && c.localName == localName) return c; } return null; } elementAttr(elem, localName, attrLocalName) { var el = this.element(elem, localName); return el ? this.attr(el, attrLocalName) : void 0; } attrs(elem) { return Array.from(elem.attributes); } attr(elem, localName) { for (let i = 0, l = elem.attributes.length; i < l; i++) { let a = elem.attributes.item(i); if (a.localName == localName) return a.value; } return null; } intAttr(node, attrName, defaultValue = null) { var val = this.attr(node, attrName); return val ? parseInt(val) : defaultValue; } hexAttr(node, attrName, defaultValue = null) { var val = this.attr(node, attrName); return val ? parseInt(val, 16) : defaultValue; } floatAttr(node, attrName, defaultValue = null) { var val = this.attr(node, attrName); return val ? parseFloat(val) : defaultValue; } boolAttr(node, attrName, defaultValue = null) { return convertBoolean(this.attr(node, attrName), defaultValue); } lengthAttr(node, attrName, usage = LengthUsage.Dxa) { return convertLength(this.attr(node, attrName), usage); } } const globalXmlParser = new XmlParser(); class Part { constructor(_package, path) { this._package = _package; this.path = path; } async load() { this.rels = await this._package.loadRelationships(this.path); const xmlText = await this._package.load(this.path); const xmlDoc = this._package.parseXmlDocument(xmlText); if (this._package.options.keepOrigin) { this._xmlDocument = xmlDoc; } this.parseXml(xmlDoc.firstElementChild); } save() { this._package.update(this.path, serializeXmlString(this._xmlDocument)); } parseXml(root) { } } const embedFontTypeMap = { embedRegular: "regular", embedBold: "bold", embedItalic: "italic", embedBoldItalic: "boldItalic" }; function parseFonts(root, xml) { return xml.elements(root).map((el) => parseFont(el, xml)); } function parseFont(elem, xml) { let result = { name: xml.attr(elem, "name"), embedFontRefs: [] }; for (let el of xml.elements(elem)) { switch (el.localName) { case "family": result.family = xml.attr(el, "val"); break; case "altName": result.altName = xml.attr(el, "val"); break; case "embedRegular": case "embedBold": case "embedItalic": case "embedBoldItalic": result.embedFontRefs.push(parseEmbedFontRef(el, xml)); break; } } return result; } function parseEmbedFontRef(elem, xml) { return { id: xml.attr(elem, "id"), key: xml.attr(elem, "fontKey"), type: embedFontTypeMap[elem.localName] }; } class FontTablePart extends Part { parseXml(root) { this.fonts = parseFonts(root, this._package.xmlParser); } } function escapeClassName(className) { return className == null ? void 0 : className.replace(/[ .]+/g, "-").replace(/[&]+/g, "and").toLowerCase(); } function splitPath(path) { let si = path.lastIndexOf("/") + 1; let folder = si == 0 ? "" : path.substring(0, si); let fileName = si == 0 ? path : path.substring(si); return [folder, fileName]; } function resolvePath(path, base) { try { const prefix = "http://docx/"; const url = new URL(path, prefix + base).toString(); return url.substring(prefix.length); } catch { return `${base}${path}`; } } function keyBy(array, by) { return array.reduce((a, x) => { a[by(x)] = x; return a; }, {}); } function blobToBase64(blob) { return new Promise((resolve, reject) => { const reader = new FileReader(); reader.onloadend = () => resolve(reader.result); reader.onerror = () => reject(); reader.readAsDataURL(blob); }); } function isObject(item) { return item && typeof item === "object" && !Array.isArray(item); } function isString(item) { return typeof item === "string" || item instanceof String; } function mergeDeep(target, ...sources) { if (!sources.length) return target; const source = sources.shift(); if (isObject(target) && isObject(source)) { for (const key in source) { if (isObject(source[key])) { const val = target[key] ?? (target[key] = {}); mergeDeep(val, source[key]); } else { target[key] = source[key]; } } } return mergeDeep(target, ...sources); } function asArray(val) { return Array.isArray(val) ? val : [val]; } class OpenXmlPackage { constructor(_zip, options) { this._zip = _zip; this.options = options; this.xmlParser = new XmlParser(); } get(path) { return this._zip.files[normalizePath(path)]; } update(path, content) { this._zip.file(path, content); } static async load(input, options) { const zip = await JSZip.loadAsync(input); return new OpenXmlPackage(zip, options); } save(type = "blob") { return this._zip.generateAsync({ type }); } load(path, type = "string") { var _a; return ((_a = this.get(path)) == null ? void 0 : _a.async(type)) ?? Promise.resolve(null); } async loadRelationships(path = null) { let relsPath = `_rels/.rels`; if (path != null) { const [f, fn] = splitPath(path); relsPath = `${f}_rels/${fn}.rels`; } const txt = await this.load(relsPath); return txt ? parseRelationships(this.parseXmlDocument(txt).firstElementChild, this.xmlParser) : null; } parseXmlDocument(txt) { return parseXmlString(txt, this.options.trimXmlDeclaration); } } function normalizePath(path) { return path.startsWith("/") ? path.substr(1) : path; } class DocumentPart extends Part { constructor(pkg, path, parser) { super(pkg, path); this._documentParser = parser; } parseXml(root) { this.body = this._documentParser.parseDocumentFile(root); } } function parseBorder(elem, xml) { return { type: xml.attr(elem, "val"), color: xml.attr(elem, "color"), size: xml.lengthAttr(elem, "sz", LengthUsage.Border), offset: xml.lengthAttr(elem, "space", LengthUsage.Point), frame: xml.boolAttr(elem, "frame"), shadow: xml.boolAttr(elem, "shadow") }; } function parseBorders(elem, xml) { var result = {}; for (let e of xml.elements(elem)) { switch (e.localName) { case "left": result.left = parseBorder(e, xml); break; case "top": result.top = parseBorder(e, xml); break; case "right": result.right = parseBorder(e, xml); break; case "bottom": result.bottom = parseBorder(e, xml); break; } } return result; } var SectionType; (function(SectionType2) { SectionType2["Continuous"] = "continuous"; SectionType2["NextPage"] = "nextPage"; SectionType2["NextColumn"] = "nextColumn"; SectionType2["EvenPage"] = "evenPage"; SectionType2["OddPage"] = "oddPage"; })(SectionType || (SectionType = {})); function parseSectionProperties(elem, xml = globalXmlParser) { var section = {}; for (let e of xml.elements(elem)) { switch (e.localName) { case "pgSz": section.pageSize = { width: xml.lengthAttr(e, "w"), height: xml.lengthAttr(e, "h"), orientation: xml.attr(e, "orient") }; break; case "type": section.type = xml.attr(e, "val"); break; case "pgMar": section.pageMargins = { left: xml.lengthAttr(e, "left"), right: xml.lengthAttr(e, "right"), top: xml.lengthAttr(e, "top"), bottom: xml.lengthAttr(e, "bottom"), header: xml.lengthAttr(e, "header"), footer: xml.lengthAttr(e, "footer"), gutter: xml.lengthAttr(e, "gutter") }; break; case "cols": section.columns = parseColumns(e, xml); break; case "headerReference": (section.headerRefs ?? (section.headerRefs = [])).push(parseFooterHeaderReference(e, xml)); break; case "footerReference": (section.footerRefs ?? (section.footerRefs = [])).push(parseFooterHeaderReference(e, xml)); break; case "titlePg": section.titlePage = xml.boolAttr(e, "val", true); break; case "pgBorders": section.pageBorders = parseBorders(e, xml); break; case "pgNumType": section.pageNumber = parsePageNumber(e, xml); break; } } return section; } function parseColumns(elem, xml) { return { numberOfColumns: xml.intAttr(elem, "num"), space: xml.lengthAttr(elem, "space"), separator: xml.boolAttr(elem, "sep"), equalWidth: xml.boolAttr(elem, "equalWidth", true), columns: xml.elements(elem, "col").map((e) => ({ width: xml.lengthAttr(e, "w"), space: xml.lengthAttr(e, "space") })) }; } function parsePageNumber(elem, xml) { return { chapSep: xml.attr(elem, "chapSep"), chapStyle: xml.attr(elem, "chapStyle"), format: xml.attr(elem, "fmt"), start: xml.intAttr(elem, "start") }; } function parseFooterHeaderReference(elem, xml) { return { id: xml.attr(elem, "id"), type: xml.attr(elem, "type") }; } function parseLineSpacing(elem, xml) { return { before: xml.lengthAttr(elem, "before"), after: xml.lengthAttr(elem, "after"), line: xml.intAttr(elem, "line"), lineRule: xml.attr(elem, "lineRule") }; } function parseRunProperties(elem, xml) { let result = {}; for (let el of xml.elements(elem)) { parseRunProperty(el, result, xml); } return result; } function parseRunProperty(elem, props, xml) { if (parseCommonProperty(elem, props, xml)) return true; return false; } function parseParagraphProperties(elem, xml) { let result = {}; for (let el of xml.elements(elem)) { parseParagraphProperty(el, result, xml); } return result; } function parseParagraphProperty(elem, props, xml) { if (elem.namespaceURI != ns$1.wordml) return false; if (parseCommonProperty(elem, props, xml)) return true; switch (elem.localName) { case "tabs": props.tabs = parseTabs(elem, xml); break; case "sectPr": props.sectionProps = parseSectionProperties(elem, xml); break; case "numPr": props.numbering = parseNumbering$1(elem, xml); break; case "spacing": props.lineSpacing = parseLineSpacing(elem, xml); return false; case "textAlignment": props.textAlignment = xml.attr(elem, "val"); return false; case "keepLines": props.keepLines = xml.boolAttr(elem, "val", true); break; case "keepNext": props.keepNext = xml.boolAttr(elem, "val", true); break; case "pageBreakBefore": props.pageBreakBefore = xml.boolAttr(elem, "val", true); break; case "outlineLvl": props.outlineLevel = xml.intAttr(elem, "val"); break; case "pStyle": props.styleName = xml.attr(elem, "val"); break; case "rPr": props.runProps = parseRunProperties(elem, xml); break; default: return false; } return true; } function parseTabs(elem, xml) { return xml.elements(elem, "tab").map((e) => ({ position: xml.lengthAttr(e, "pos"), leader: xml.attr(e, "leader"), style: xml.attr(e, "val") })); } function parseNumbering$1(elem, xml) { var result = {}; for (let e of xml.elements(elem)) { switch (e.localName) { case "numId": result.id = xml.attr(e, "val"); break; case "ilvl": result.level = xml.intAttr(e, "val"); break; } } return result; } function parseNumberingPart(elem, xml) { let result = { numberings: [], abstractNumberings: [], bulletPictures: [] }; for (let e of xml.elements(elem)) { switch (e.localName) { case "num": result.numberings.push(parseNumbering(e, xml)); break; case "abstractNum": result.abstractNumberings.push(parseAbstractNumbering(e, xml)); break; case "numPicBullet": result.bulletPictures.push(parseNumberingBulletPicture(e, xml)); break; } } return result; } function parseNumbering(elem, xml) { let result = { id: xml.attr(elem, "numId"), overrides: [] }; for (let e of xml.elements(elem)) { switch (e.localName) { case "abstractNumId": result.abstractId = xml.attr(e, "val"); break; case "lvlOverride": result.overrides.push(parseNumberingLevelOverrride(e, xml)); break; } } return result; } function parseAbstractNumbering(elem, xml) { let result = { id: xml.attr(elem, "abstractNumId"), levels: [] }; for (let e of xml.elements(elem)) { switch (e.localName) { case "name": result.name = xml.attr(e, "val"); break; case "multiLevelType": result.multiLevelType = xml.attr(e, "val"); break; case "numStyleLink": result.numberingStyleLink = xml.attr(e, "val"); break; case "styleLink": result.styleLink = xml.attr(e, "val"); break; case "lvl": result.levels.push(parseNumberingLevel(e, xml)); break; } } return result; } function parseNumberingLevel(elem, xml) { let result = { level: xml.intAttr(elem, "ilvl") }; for (let e of xml.elements(elem)) { switch (e.localName) { case "start": result.start = xml.attr(e, "val"); break; case "lvlRestart": result.restart = xml.intAttr(e, "val"); break; case "numFmt": result.format = xml.attr(e, "val"); break; case "lvlText": result.text = xml.attr(e, "val"); break; case "lvlJc": result.justification = xml.attr(e, "val"); break; case "lvlPicBulletId": result.bulletPictureId = xml.attr(e, "val"); break; case "pStyle": result.paragraphStyle = xml.attr(e, "val"); break; case "pPr": result.paragraphProps = parseParagraphProperties(e, xml); break; case "rPr": result.runProps = parseRunProperties(e, xml); break; } } return result; } function parseNumberingLevelOverrride(elem, xml) { let result = { level: xml.intAttr(elem, "ilvl") }; for (let e of xml.elements(elem)) { switch (e.localName) { case "startOverride": result.start = xml.intAttr(e, "val"); break; case "lvl": result.numberingLevel = parseNumberingLevel(e, xml); break; } } return result; } function parseNumberingBulletPicture(elem, xml) { var pict = xml.element(elem, "pict"); var shape = pict && xml.element(pict, "shape"); var imagedata = shape && xml.element(shape, "imagedata"); return imagedata ? { id: xml.attr(elem, "numPicBulletId"), referenceId: xml.attr(imagedata, "id"), style: xml.attr(shape, "style") } : null; } class NumberingPart extends Part { constructor(pkg, path, parser) { super(pkg, path); this._documentParser = parser; } parseXml(root) { Object.assign(this, parseNumberingPart(root, this._package.xmlParser)); this.domNumberings = this._documentParser.parseNumberingFile(root); } } class StylesPart extends Part { constructor(pkg, path, parser) { super(pkg, path); this._documentParser = parser; } parseXml(root) { this.styles = this._documentParser.parseStylesFile(root); } } var DomType; (function(DomType2) { DomType2["Document"] = "document"; DomType2["Paragraph"] = "paragraph"; DomType2["Run"] = "run"; DomType2["Break"] = "break"; DomType2["NoBreakHyphen"] = "noBreakHyphen"; DomType2["Table"] = "table"; DomType2["Row"] = "row"; DomType2["Cell"] = "cell"; DomType2["Hyperlink"] = "hyperlink"; DomType2["Drawing"] = "drawing"; DomType2["Image"] = "image"; DomType2["Text"] = "text"; DomType2["Tab"] = "tab"; DomType2["Symbol"] = "symbol"; DomType2["BookmarkStart"] = "bookmarkStart"; DomType2["BookmarkEnd"] = "bookmarkEnd"; DomType2["Footer"] = "footer"; DomType2["Header"] = "header"; DomType2["FootnoteReference"] = "footnoteReference"; DomType2["EndnoteReference"] = "endnoteReference"; DomType2["Footnote"] = "footnote"; DomType2["Endnote"] = "endnote"; DomType2["SimpleField"] = "simpleField"; DomType2["ComplexField"] = "complexField"; DomType2["Instruction"] = "instruction"; DomType2["VmlPicture"] = "vmlPicture"; DomType2["MmlMath"] = "mmlMath"; DomType2["MmlMathParagraph"] = "mmlMathParagraph"; DomType2["MmlFraction"] = "mmlFraction"; DomType2["MmlFunction"] = "mmlFunction"; DomType2["MmlFunctionName"] = "mmlFunctionName"; DomType2["MmlNumerator"] = "mmlNumerator"; DomType2["MmlDenominator"] = "mmlDenominator"; DomType2["MmlRadical"] = "mmlRadical"; DomType2["MmlBase"] = "mmlBase"; DomType2["MmlDegree"] = "mmlDegree"; DomType2["MmlSuperscript"] = "mmlSuperscript"; DomType2["MmlSubscript"] = "mmlSubscript"; DomType2["MmlPreSubSuper"] = "mmlPreSubSuper"; DomType2["MmlSubArgument"] = "mmlSubArgument"; DomType2["MmlSuperArgument"] = "mmlSuperArgument"; DomType2["MmlNary"] = "mmlNary"; DomType2["MmlDelimiter"] = "mmlDelimiter"; DomType2["MmlRun"] = "mmlRun"; DomType2["MmlEquationArray"] = "mmlEquationArray"; DomType2["MmlLimit"] = "mmlLimit"; DomType2["MmlLimitLower"] = "mmlLimitLower"; DomType2["MmlMatrix"] = "mmlMatrix"; DomType2["MmlMatrixRow"] = "mmlMatrixRow"; DomType2["MmlBox"] = "mmlBox"; DomType2["MmlBar"] = "mmlBar"; DomType2["MmlGroupChar"] = "mmlGroupChar"; DomType2["VmlElement"] = "vmlElement"; DomType2["Inserted"] = "inserted"; DomType2["Deleted"] = "deleted"; DomType2["DeletedText"] = "deletedText"; })(DomType || (DomType = {})); class OpenXmlElementBase { constructor() { this.children = []; this.cssStyle = {}; } } class WmlHeader extends OpenXmlElementBase { constructor() { super(...arguments); this.type = DomType.Header; } } class WmlFooter extends OpenXmlElementBase { constructor() { super(...arguments); this.type = DomType.Footer; } } class BaseHeaderFooterPart extends Part { constructor(pkg, path, parser) { super(pkg, path); this._documentParser = parser; } parseXml(root) { this.rootElement = this.createRootElement(); this.rootElement.children = this._documentParser.parseBodyElements(root); } } class HeaderPart extends BaseHeaderFooterPart { createRootElement() { return new WmlHeader(); } } class FooterPart extends BaseHeaderFooterPart { createRootElement() { return new WmlFooter(); } } function parseExtendedProps(root, xmlParser) { const result = {}; for (let el of xmlParser.elements(root)) { switch (el.localName) { case "Template": result.template = el.textContent; break; case "Pages": result.pages = safeParseToInt(el.textContent); break; case "Words": result.words = safeParseToInt(el.textContent); break; case "Characters": result.characters = safeParseToInt(el.textContent); break; case "Application": result.application = el.textContent; break; case "Lines": result.lines = safeParseToInt(el.textContent); break; case "Paragraphs": result.paragraphs = safeParseToInt(el.textContent); break; case "Company": result.company = el.textContent; break; case "AppVersion": result.appVersion = el.textContent; break; } } return result; } function safeParseToInt(value) { if (typeof value === "undefined") return; return parseInt(value); } class ExtendedPropsPart extends Part { parseXml(root) { this.props = parseExtendedProps(root, this._package.xmlParser); } } function parseCoreProps(root, xmlParser) { const result = {}; for (let el of xmlParser.elements(root)) { switch (el.localName) { case "title": result.title = el.textContent; break; case "description": result.description = el.textContent; break; case "subject": result.subject = el.textContent; break; case "creator": result.creator = el.textContent; break; case "keywords": result.keywords = el.textContent; break; case "language": result.language = el.textContent; break; case "lastModifiedBy": result.lastModifiedBy = el.textContent; break; case "revision": el.textContent && (result.revision = parseInt(el.textContent)); break; } } return result; } class CorePropsPart extends Part { parseXml(root) { this.props = parseCoreProps(root, this._package.xmlParser); } } class DmlTheme { } function parseTheme(elem, xml) { var result = new DmlTheme(); var themeElements = xml.element(elem, "themeElements"); for (let el of xml.elements(themeElements)) { switch (el.localName) { case "clrScheme": result.colorScheme = parseColorScheme(el, xml); break; case "fontScheme": result.fontScheme = parseFontScheme(el, xml); break; } } return result; } function parseColorScheme(elem, xml) { var result = { name: xml.attr(elem, "name"), colors: {} }; for (let el of xml.elements(elem)) { var srgbClr = xml.element(el, "srgbClr"); var sysClr = xml.element(el, "sysClr"); if (srgbClr) { result.colors[el.localName] = xml.attr(srgbClr, "val"); } else if (sysClr) { result.colors[el.localName] = xml.attr(sysClr, "lastClr"); } } return result; } function parseFontScheme(elem, xml) { var result = { name: xml.attr(elem, "name") }; for (let el of xml.elements(elem)) { switch (el.localName) { case "majorFont": result.majorFont = parseFontInfo(el, xml); break; case "minorFont": result.minorFont = parseFontInfo(el, xml); break; } } return result; } function parseFontInfo(elem, xml) { return { latinTypeface: xml.elementAttr(elem, "latin", "typeface"), eaTypeface: xml.elementAttr(elem, "ea", "typeface"), csTypeface: xml.elementAttr(elem, "cs", "typeface") }; } class ThemePart extends Part { constructor(pkg, path) { super(pkg, path); } parseXml(root) { this.theme = parseTheme(root, this._package.xmlParser); } } class WmlBaseNote { } class WmlFootnote extends WmlBaseNote { constructor() { super(...arguments); this.type = DomType.Footnote; } } class WmlEndnote extends WmlBaseNote { constructor() { super(...arguments); this.type = DomType.Endnote; } } class BaseNotePart extends Part { constructor(pkg, path, parser) { super(pkg, path); this._documentParser = parser; } } class FootnotesPart extends BaseNotePart { constructor(pkg, path, parser) { super(pkg, path, parser); } parseXml(root) { this.notes = this._documentParser.parseNotes(root, "footnote", WmlFootnote); } } class EndnotesPart extends BaseNotePart { constructor(pkg, path, parser) { super(pkg, path, parser); } parseXml(root) { this.notes = this._documentParser.parseNotes(root, "endnote", WmlEndnote); } } function parseSettings(elem, xml) { var result = {}; for (let el of xml.elements(elem)) { switch (el.localName) { case "defaultTabStop": result.defaultTabStop = xml.lengthAttr(el, "val"); break; case "footnotePr": result.footnoteProps = parseNoteProperties(el, xml); break; case "endnotePr": result.endnoteProps = parseNoteProperties(el, xml); break; case "autoHyphenation": result.autoHyphenation = xml.boolAttr(el, "val"); break; } } return result; } function parseNoteProperties(elem, xml) { var result = { defaultNoteIds: [] }; for (let el of xml.elements(elem)) { switch (el.localName) { case "numFmt": result.nummeringFormat = xml.attr(el, "val"); break; case "footnote": case "endnote": result.defaultNoteIds.push(xml.attr(el, "id")); break; } } return result; } class SettingsPart extends Part { constructor(pkg, path) { super(pkg, path); } parseXml(root) { this.settings = parseSettings(root, this._package.xmlParser); } } function parseCustomProps(root, xml) { return xml.elements(root, "property").map((e) => { const firstChild = e.firstChild; return { formatId: xml.attr(e, "fmtid"), name: xml.attr(e, "name"), type: firstChild.nodeName, value: firstChild.textContent }; }); } class CustomPropsPart extends Part { parseXml(root) { this.props = parseCustomProps(root, this._package.xmlParser); } } const topLevelRels = [ { type: RelationshipTypes.OfficeDocument, target: "word/document.xml" }, { type: RelationshipTypes.ExtendedProperties, target: "docProps/app.xml" }, { type: RelationshipTypes.CoreProperties, target: "docProps/core.xml" }, { type: RelationshipTypes.CustomProperties, target: "docProps/custom.xml" } ]; class WordDocument { constructor() { this.parts = []; this.partsMap = {}; } static async load(blob, parser, options) { var d = new WordDocument(); d._options = options; d._parser = parser; d._package = await OpenXmlPackage.load(blob, options); d.rels = await d._package.loadRelationships(); await Promise.all(topLevelRels.map((rel) => { const r = d.rels.find((x) => x.type === rel.type) ?? rel; return d.loadRelationshipPart(r.target, r.type); })); return d; } save(type = "blob") { return this._package.save(type); } async loadRelationshipPart(path, type) { var _a; if (this.partsMap[path]) return this.partsMap[path]; if (!this._package.get(path)) return null; let part = null; switch (type) { case RelationshipTypes.OfficeDocument: this.documentPart = part = new DocumentPart(this._package, path, this._parser); break; case RelationshipTypes.FontTable: this.fontTablePart = part = new FontTablePart(this._package, path); break; case RelationshipTypes.Numbering: this.numberingPart = part = new NumberingPart(this._package, path, this._parser); break; case RelationshipTypes.Styles: this.stylesPart = part = new StylesPart(this._package, path, this._parser); break; case RelationshipTypes.Theme: this.themePart = part = new ThemePart(this._package, path); break; case RelationshipTypes.Footnotes: this.footnotesPart = part = new FootnotesPart(this._package, path, this._parser); break; case RelationshipTypes.Endnotes: this.endnotesPart = part = new EndnotesPart(this._package, path, this._parser); break; case RelationshipTypes.Footer: part = new FooterPart(this._package, path, this._parser); break; case RelationshipTypes.Header: part = new HeaderPart(this._package, path, this._parser); break; case RelationshipTypes.CoreProperties: this.corePropsPart = part = new CorePropsPart(this._package, path); break; case RelationshipTypes.ExtendedProperties: this.extendedPropsPart = part = new ExtendedPropsPart(this._package, path); break; case RelationshipTypes.CustomProperties: part = new CustomPropsPart(this._package, path); break; case RelationshipTypes.Settings: this.settingsPart = part = new SettingsPart(this._package, path); break; } if (part == null) return Promise.resolve(null); this.partsMap[path] = part; this.parts.push(part); await part.load(); if (((_a = part.rels) == null ? void 0 : _a.length) > 0) { const [folder] = splitPath(part.path); await Promise.all(part.rels.map((rel) => this.loadRelationshipPart(resolvePath(rel.target, folder), rel.type))); } return part; } async loadDocumentImage(id, part) { const x = await this.loadResource(part ?? this.documentPart, id, "blob"); return this.blobToURL(x); } async loadNumberingImage(id) { const x = await this.loadResource(this.numberingPart, id, "blob"); return this.blobToURL(x); } async loadFont(id, key) { const x = await this.loadResource(this.fontTablePart, id, "uint8array"); return x ? this.blobToURL(new Blob([deobfuscate(x, key)])) : x; } blobToURL(blob) { if (!blob) return null; if (this._options.useBase64URL) { return blobToBase64(blob); } return URL.createObjectURL(blob); } findPartByRelId(id, basePart = null) { var rel = (basePart.rels ?? this.rels).find((r) => r.id == id); const folder = basePart ? splitPath(basePart.path)[0] : ""; return rel ? this.partsMap[resolvePath(rel.target, folder)] : null; } getPathById(part, id) { const rel = part.rels.find((x) => x.id == id); const [folder] = splitPath(part.path); return rel ? resolvePath(rel.target, folder) : null; } loadResource(part, id, outputType) { const path = this.getPathById(part, id); return path ? this._package.load(path, outputType) : Promise.resolve(null); } } function deobfuscate(data, guidKey) { const len = 16; const trimmed = guidKey.replace(/{|}|-/g, ""); const numbers = new Array(len); for (let i = 0; i < len; i++) numbers[len - i - 1] = parseInt(trimmed.substr(i * 2, 2), 16); for (let i = 0; i < 32; i++) data[i] = data[i] ^ numbers[i % len]; return data; } function parseBookmarkStart(elem, xml) { return { type: DomType.BookmarkStart, id: xml.attr(elem, "id"), name: xml.attr(elem, "name"), colFirst: xml.intAttr(elem, "colFirst"), colLast: xml.intAttr(elem, "colLast") }; } function parseBookmarkEnd(elem, xml) { return { type: DomType.BookmarkEnd, id: xml.attr(elem, "id") }; } class VmlElement extends OpenXmlElementBase { constructor() { super(...arguments); this.type = DomType.VmlElement; this.attrs = {}; } } function parseVmlElement(elem, parser) { var result = new VmlElement(); switch (elem.localName) { case "rect": result.tagName = "rect"; Object.assign(result.attrs, { width: "100%", height: "100%" }); break; case "oval": result.tagName = "ellipse"; Object.assign(result.attrs, { cx: "50%", cy: "50%", rx: "50%", ry: "50%" }); break; case "line": result.tagName = "line"; break; case "shape": result.tagName = "g"; break; case "textbox": result.tagName = "foreignObject"; Object.assign(result.attrs, { width: "100%", height: "100%" }); break; default: return null; } for (const at of globalXmlParser.attrs(elem)) { switch (at.localName) { case "style": result.cssStyleText = at.value; break; case "fillcolor": result.attrs.fill = at.value; break; case "from": const [x1, y1] = parsePoint(at.value); Object.assign(result.attrs, { x1, y1 }); break; case "to": const [x2, y2] = parsePoint(at.value); Object.assign(result.attrs, { x2, y2 }); break; } } for (const el of globalXmlParser.elements(elem)) { switch (el.localName) { case "stroke": Object.assign(result.attrs, parseStroke(el)); break; case "fill": Object.assign(result.attrs, parseFill()); break; case "imagedata": result.tagName = "image"; Object.assign(result.attrs, { width: "100%", height: "100%" }); result.imageHref = { id: globalXmlParser.attr(el, "id"), title: globalXmlParser.attr(el, "title") }; break; case "txbxContent": result.children.push(...parser.parseBodyElements(el)); break; default: const child = parseVmlElement(el, parser); child && result.children.push(child); break; } } return result; } function parseStroke(el) { return { "stroke": globalXmlParser.attr(el, "color"), "stroke-width": globalXmlParser.lengthAttr(el, "weight", LengthUsage.Emu) ?? "1px" }; } function parseFill(el) { return {}; } function parsePoint(val) { return val.split(","); } var autos = { shd: "inherit", color: "black", borderColor: "black", highlight: "transparent" }; const supportedNamespaceURIs = []; const mmlTagMap = { "oMath": DomType.MmlMath, "oMathPara": DomType.MmlMathParagraph, "f": DomType.MmlFraction, "func": DomType.MmlFunction, "fName": DomType.MmlFunctionName, "num": DomType.MmlNumerator, "den": DomType.MmlDenominator, "rad": DomType.MmlRadical, "deg": DomType.MmlDegree, "e": DomType.MmlBase, "sSup": DomType.MmlSuperscript, "sSub": DomType.MmlSubscript, "sPre": DomType.MmlPreSubSuper, "sup": DomType.MmlSuperArgument, "sub": DomType.MmlSubArgument, "d": DomType.MmlDelimiter, "nary": DomType.MmlNary, "eqArr": DomType.MmlEquationArray, "lim": DomType.MmlLimit, "limLow": DomType.MmlLimitLower, "m": DomType.MmlMatrix, "mr": DomType.MmlMatrixRow, "box": DomType.MmlBox, "bar": DomType.MmlBar, "groupChr": DomType.MmlGroupChar }; class DocumentParser { constructor(options) { this.options = { ignoreWidth: false, debug: false, ...options }; } parseNotes(xmlDoc, elemName, elemClass) { var result = []; for (let el of globalXmlParser.elements(xmlDoc, elemName)) { const node = new elemClass(); node.id = globalXmlParser.attr(el, "id"); node.noteType = globalXmlParser.attr(el, "type"); node.children = this.parseBodyElements(el); result.push(node); } return result; } parseDocumentFile(xmlDoc) { var xbody = globalXmlParser.element(xmlDoc, "body"); var background = globalXmlParser.element(xmlDoc, "background"); var sectPr = globalXmlParser.element(xbody, "sectPr"); return { type: DomType.Document, children: this.parseBodyElements(xbody), props: sectPr ? parseSectionProperties(sectPr, globalXmlParser) : {}, cssStyle: background ? this.parseBackground(background) : {} }; } parseBackground(elem) { var result = {}; var color = xmlUtil.colorAttr(elem, "color"); if (color) { result["background-color"] = color; } return result; } parseBodyElements(element) { var children = []; for (let elem of globalXmlParser.elements(element)) { switch (elem.localName) { case "p": children.push(this.parseParagraph(elem)); break; case "tbl": children.push(this.parseTable(elem)); break; case "sdt": children.push(...this.parseSdt(elem, (e) => this.parseBodyElements(e))); break; } } return children; } parseStylesFile(xstyles) { var result = []; xmlUtil.foreach(xstyles, (n) => { switch (n.localName) { case "style": result.push(this.parseStyle(n)); break; case "docDefaults": result.push(this.parseDefaultStyles(n)); break; } }); return result; } parseDefaultStyles(node) { var result = { id: null, name: null, target: null, basedOn: null, styles: [] }; xmlUtil.foreach(node, (c) => { switch (c.localName) { case "rPrDefault": var rPr = globalXmlParser.element(c, "rPr"); if (rPr) result.styles.push({ target: "span", values: this.parseDefaultProperties(rPr, {}) }); break; case "pPrDefault": var pPr = globalXmlParser.element(c, "pPr"); if (pPr) result.styles.push({ target: "p", values: this.parseDefaultProperties(pPr, {}) }); break; } }); return result; } parseStyle(node) { var result = { id: globalXmlParser.attr(node, "styleId"), isDefault: globalXmlParser.boolAttr(node, "default"), name: null, target: null, basedOn: null, styles: [], linked: null }; switch (globalXmlParser.attr(node, "type")) { case "paragraph": result.target = "p"; break; case "table": result.target = "table"; break; case "character": result.target = "span"; break; } xmlUtil.foreach(node, (n) => { switch (n.localName) { case "basedOn": result.basedOn = globalXmlParser.attr(n, "val"); break; case "name": result.name = globalXmlParser.attr(n, "val"); break; case "link": result.linked = globalXmlParser.attr(n, "val"); break; case "next": result.next = globalXmlParser.attr(n, "val"); break; case "aliases": result.aliases = globalXmlParser.attr(n, "val").split(","); break; case "pPr": result.styles.push({ target: "p", values: this.parseDefaultProperties(n, {}) }); result.paragraphProps = parseParagraphProperties(n, globalXmlParser); break; case "rPr": result.styles.push({ target: "span", values: this.parseDefaultProperties(n, {}) }); result.runProps = parseRunProperties(n, globalXmlParser); break; case "tblPr": case "tcPr": result.styles.push({ target: "td", values: this.parseDefaultProperties(n, {}) }); break; case "tblStylePr": for (let s of this.parseTableStyle(n)) result.styles.push(s); break; case "rsid": case "qFormat": case "hidden": case "semiHidden": case "unhideWhenUsed": case "autoRedefine": case "uiPriority": break; default: this.options.debug && console.warn(`DOCX: Unknown style element: ${n.localName}`); } }); return result; } parseTableStyle(node) { var result = []; var type = globalXmlParser.attr(node, "type"); var selector = ""; var modificator = ""; switch (type) { case "firstRow": modificator = ".first-row"; selector = "tr.first-row td"; break; case "lastRow": modificator = ".last-row"; selector = "tr.last-row td"; break; case "firstCol": modificator = ".first-col"; selector = "td.first-col"; break; case "lastCol": modificator = ".last-col"; selector = "td.last-col"; break; case "band1Vert": modificator = ":not(.no-vband)"; selector = "td.odd-col"; break; case "band2Vert": modificator = ":not(.no-vband)"; selector = "td.even-col"; break; case "band1Horz": modificator = ":not(.no-hband)"; selector = "tr.odd-row"; break; case "band2Horz": modificator = ":not(.no-hband)"; selector = "tr.even-row"; break; default: return []; } xmlUtil.foreach(node, (n) => { switch (n.localName) { case "pPr": result.push({ target: `${selector} p`, mod: modificator, values: this.parseDefaultProperties(n, {}) }); break; case "rPr": result.push({ target: `${selector} span`, mod: modificator, values: this.parseDefaultProperties(n, {}) }); break; case "tblPr": case "tcPr": result.push({ target: selector, mod: modificator, values: this.parseDefaultProperties(n, {}) }); break; } }); return result; } parseNumberingFile(xnums) { var result = []; var mapping = {}; var bullets = []; xmlUtil.foreach(xnums, (n) => { switch (n.localName) { case "abstractNum": this.parseAbstractNumbering(n, bullets).forEach((x) => result.push(x)); break; case "numPicBullet": bullets.push(this.parseNumberingPicBullet(n)); break; case "num": var numId = globalXmlParser.attr(n, "numId"); var abstractNumId = globalXmlParser.elementAttr(n, "abstractNumId", "val"); mapping[abstractNumId] = numId; break; } }); result.forEach((x) => x.id = mapping[x.id]); return result; } parseNumberingPicBullet(elem) { var pict = globalXmlParser.element(elem, "pict"); var shape = pict && globalXmlParser.element(pict, "shape"); var imagedata = shape && globalXmlParser.element(shape, "imagedata"); return imagedata ? { id: globalXmlParser.intAttr(elem, "numPicBulletId"), src: globalXmlParser.attr(imagedata, "id"), style: globalXmlParser.attr(shape, "style") } : null; } parseAbstractNumbering(node, bullets) { var result = []; var id = globalXmlParser.attr(node, "abstractNumId"); xmlUtil.foreach(node, (n) => { switch (n.localName) { case "lvl": result.push(this.parseNumberingLevel(id, n, bullets)); break; } }); return result; } parseNumberingLevel(id, node, bullets) { var result = { id, level: globalXmlParser.intAttr(node, "ilvl"), start: 1, pStyleName: void 0, pStyle: {}, rStyle: {}, suff: "tab" }; xmlUtil.foreach(node, (n) => { switch (n.localName) { case "start": result.start = globalXmlParser.intAttr(n, "val"); break; case "pPr": this.parseDefaultProperties(n, result.pStyle); break; case "rPr": this.parseDefaultProperties(n, result.rStyle); break; case "lvlPicBulletId": var id2 = globalXmlParser.intAttr(n, "val"); result.bullet = bullets.find((x) => x.id == id2); break; case "lvlText": result.levelText = globalXmlParser.attr(n, "val"); break; case "pStyle": result.pStyleName = globalXmlParser.attr(n, "val"); break; case "numFmt": result.format = globalXmlParser.attr(n, "val"); break; case "suff": result.suff = globalXmlParser.attr(n, "val"); break; } }); return result; } parseSdt(node, parser) { const sdtContent = globalXmlParser.element(node, "sdtContent"); return sdtContent ? parser(sdtContent) : []; } parseInserted(node, parentParser) { var _a; return { type: DomType.Inserted, children: ((_a = parentParser(node)) == null ? void 0 : _a.children) ?? [] }; } parseDeleted(node, parentParser) { var _a; return { type: DomType.Deleted, children: ((_a = parentParser(node)) == null ? void 0 : _a.children) ?? [] }; } parseParagraph(node) { var result = { type: DomType.Paragraph, children: [] }; for (let el of globalXmlParser.elements(node)) { switch (el.localName) { case "pPr": this.parseParagraphProperties(el, result); break; case "r": result.children.push(this.parseRun(el, result)); break; case "hyperlink": result.children.push(this.parseHyperlink(el, result)); break; case "bookmarkStart": result.children.push(parseBookmarkStart(el, globalXmlParser)); break; case "bookmarkEnd": result.children.push(parseBookmarkEnd(el, globalXmlParser)); break; case "oMath": case "oMathPara": result.children.push(this.parseMathElement(el)); break; case "sdt": result.children.push(...this.parseSdt(el, (e) => this.parseParagraph(e).children)); break; case "ins": result.children.push(this.parseInserted(el, (e) => this.parseParagraph(e))); break; case "del": result.children.push(this.parseDeleted(el, (e) => this.parseParagraph(e))); break; } } return result; } parseParagraphProperties(elem, paragraph) { this.parseDefaultProperties(elem, paragraph.cssStyle = {}, null, (c) => { if (parseParagraphProperty(c, paragraph, globalXmlParser)) return true; switch (c.localName) { case "pStyle": paragraph.styleName = globalXmlParser.attr(c, "val"); break; case "cnfStyle": paragraph.className = values.classNameOfCnfStyle