@randevcx/ranui
Version:
UI Component library based on `Web Component`
1,677 lines • 119 kB
JavaScript
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