simple-odf
Version:
Open Document Format made easy using pure JavaScript and Node.js
152 lines (151 loc) • 6.88 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.DomVisitor = void 0;
const fs_1 = require("fs");
const draw_1 = require("../api/draw");
const office_1 = require("../api/office");
const text_1 = require("../api/text");
const DrawElementName_1 = require("./DrawElementName");
const OdfAttributeName_1 = require("./OdfAttributeName");
const OdfElementName_1 = require("./OdfElementName");
const OdfTextElementWriter_1 = require("./OdfTextElementWriter");
const TextElementName_1 = require("./TextElementName");
const IMAGE_ENCODING = 'base64';
const HYPERLINK_LINK_TYPE = 'simple';
class DomVisitor {
constructor(commonStyles, automaticStyles) {
this.commonStyles = commonStyles;
this.automaticStyles = automaticStyles;
}
visit(odfElement, document, parent) {
let currentElement;
if (odfElement instanceof text_1.Heading) {
currentElement = this.visitHeading(odfElement, document, parent);
}
else if (odfElement instanceof text_1.Hyperlink) {
currentElement = this.visitHyperlink(odfElement, document, parent);
}
else if (odfElement instanceof draw_1.Image) {
currentElement = this.visitImage(odfElement, document, parent);
}
else if (odfElement instanceof text_1.List) {
currentElement = this.visitList(odfElement, document, parent);
}
else if (odfElement instanceof text_1.ListItem) {
currentElement = this.visitListItem(document, parent);
}
else if (odfElement instanceof text_1.OdfTextElement) {
currentElement = this.visitOdfText(odfElement, document, parent);
}
else if (odfElement instanceof text_1.Paragraph) {
currentElement = this.visitParagraph(odfElement, document, parent);
}
else if (odfElement instanceof office_1.TextBody) {
currentElement = this.visitTextBody(document, parent);
}
odfElement.getAll().forEach((odfChildElement) => {
this.visit(odfChildElement, document, currentElement);
});
}
visitHeading(heading, document, parent) {
const headingElement = document.createElement(TextElementName_1.TextElementName.TextHeading);
headingElement.setAttribute(OdfAttributeName_1.OdfAttributeName.TextOutlineLevel, heading.getLevel().toString(10));
parent.appendChild(headingElement);
this.setStyleName(heading, headingElement);
return headingElement;
}
visitHyperlink(hyperlink, document, parent) {
const hyperlinkElement = document.createElement(TextElementName_1.TextElementName.TextHyperlink);
hyperlinkElement.setAttribute(OdfAttributeName_1.OdfAttributeName.XlinkType, HYPERLINK_LINK_TYPE);
hyperlinkElement.setAttribute(OdfAttributeName_1.OdfAttributeName.XlinkHref, hyperlink.getURI());
parent.appendChild(hyperlinkElement);
this.visitOdfText(hyperlink, document, hyperlinkElement);
return hyperlinkElement;
}
visitImage(image, document, parent) {
const frameElement = document.createElement(DrawElementName_1.DrawElementName.DrawFrame);
frameElement.setAttribute(OdfAttributeName_1.OdfAttributeName.TextAnchorType, image.getAnchorType());
const width = image.getWidth();
if (width !== undefined) {
frameElement.setAttribute(OdfAttributeName_1.OdfAttributeName.SvgWidth, width + 'mm');
}
const height = image.getHeight();
if (height !== undefined) {
frameElement.setAttribute(OdfAttributeName_1.OdfAttributeName.SvgHeight, height + 'mm');
}
parent.appendChild(frameElement);
this.embedImage(document, frameElement, image);
return frameElement;
}
visitList(list, document, parent) {
if (list.size() === 0) {
return parent;
}
const listElement = document.createElement(TextElementName_1.TextElementName.TextList);
parent.appendChild(listElement);
this.setStyleName(list, listElement);
return listElement;
}
visitListItem(document, parent) {
const listItemElement = document.createElement(TextElementName_1.TextElementName.TextListItem);
parent.appendChild(listItemElement);
return listItemElement;
}
visitOdfText(odfText, document, parent) {
new OdfTextElementWriter_1.OdfTextElementWriter().write(odfText, document, parent);
return parent;
}
visitParagraph(paragraph, document, parent) {
const paragraphElement = document.createElement(TextElementName_1.TextElementName.TextParagraph);
parent.appendChild(paragraphElement);
this.setStyleName(paragraph, paragraphElement);
return paragraphElement;
}
visitTextBody(document, parent) {
const bodyElement = document.createElement(OdfElementName_1.OdfElementName.OfficeBody);
parent.appendChild(bodyElement);
const textElement = document.createElement(OdfElementName_1.OdfElementName.OfficeText);
bodyElement.appendChild(textElement);
return textElement;
}
setStyleName(odfElement, domElement) {
let styleName = this.getAutomaticStyleName(odfElement);
if (styleName === undefined) {
styleName = this.getCommonStyleName(odfElement);
}
if (styleName !== undefined) {
domElement.setAttribute(OdfAttributeName_1.OdfAttributeName.TextStyleName, styleName);
}
}
getAutomaticStyleName(odfElement) {
const style = odfElement.getStyle();
return style !== undefined
? this.automaticStyles.getName(style)
: undefined;
}
getCommonStyleName(odfElement) {
const styleName = odfElement.getStyleName();
return styleName !== undefined
? this.commonStyles.getName(styleName)
: undefined;
}
/**
* Creates the image element and embeds the denoted image base64 encoded binary data.
*
* @param {Document} document The XML document
* @param {Element} frameElement The parent node in the DOM (`draw:frame`)
* @param {Image} image The image
* @private
*/
embedImage(document, frameElement, image) {
const imageElement = document.createElement(DrawElementName_1.DrawElementName.DrawImage);
frameElement.appendChild(imageElement);
const binaryData = document.createElement(OdfElementName_1.OdfElementName.OfficeBinaryData);
imageElement.appendChild(binaryData);
const rawImage = (0, fs_1.readFileSync)(image.getPath());
const base64Image = rawImage.toString(IMAGE_ENCODING);
const textNode = document.createTextNode(base64Image);
binaryData.appendChild(textNode);
}
}
exports.DomVisitor = DomVisitor;