// Module: @xmldom/xmldom@0.8.6 // License: MIT // // Module: base64-js@1.5.1 // License: MIT // // Module: bluebird@3.4.7 // License: MIT // // Module: buffer@4.9.1 // License: MIT // // Module: dingbat-to-unicode@1.0.1 // License: BSD-2-Clause // // Module: ieee754@1.1.8 // License: BSD-3-Clause // // Module: inherits@2.0.1 // License: ISC // // Module: isarray@1.0.0 // License: MIT // // Module: jszip@3.7.1 // License: (MIT OR GPL-3.0-or-later) // // Module: lop@0.4.1 // License: BSD-2-Clause // // Module: mammoth@1.6.0 // License: BSD-2-Clause // // Module: option@0.2.4 // License: BSD-2-Clause // // Module: path-browserify@0.0.0 // License: MIT // // Module: process@0.11.9 // License: MIT // // Module: underscore@1.13.1 // License: MIT // // Module: util@0.10.3 // License: MIT // // Module: xmlbuilder@10.0.0 // License: MIT // (function (f) { if (typeof exports === "object" && typeof module !== "undefined") { module.exports = f() } else if (typeof define === "function" && define.amd) { define([], f) } else { var g; if (typeof window !== "undefined") { g = window } else if (typeof global !== "undefined") { g = global } else if (typeof self !== "undefined") { g = self } else { g = this } g.mammoth = f() } })(function () { var define, module, exports; return (function e(t, n, r) { function s(o, u) { if (!n[o]) { if (!t[o]) { var a = typeof require == "function" && require; if (!u && a) return a(o, !0); if (i) return i(o, !0); var f = new Error("Cannot find module '" + o + "'"); throw f.code = "MODULE_NOT_FOUND", f } var l = n[o] = { exports: {} }; t[o][0].call(l.exports, function (e) { var n = t[o][1][e]; return s(n ? n : e) }, l, l.exports, e, t, n, r) } return n[o].exports } var i = typeof require == "function" && require; for (var o = 0; o < r.length; o++)s(r[o]); return s })({ 1: [function (require, module, exports) { var promises = require("../../lib/promises"); exports.Files = Files; function Files() { function read(uri) { return promises.reject(new Error("could not open external image: '" + uri + "'\ncannot open linked files from a web browser")); } return { read: read }; } }, { "../../lib/promises": 23 }], 2: [function (require, module, exports) { var promises = require("../lib/promises"); var zipfile = require("../lib/zipfile"); exports.openZip = openZip; function openZip(options) { if (options.arrayBuffer) { return promises.resolve(zipfile.openArrayBuffer(options.arrayBuffer)); } else { return promises.reject(new Error("Could not find file in options")); } } }, { "../lib/promises": 23, "../lib/zipfile": 40 }], 3: [function (require, module, exports) { var _ = require("underscore"); var promises = require("./promises"); var documents = require("./documents"); var htmlPaths = require("./styles/html-paths"); var results = require("./results"); var images = require("./images"); var Html = require("./html"); var writers = require("./writers"); exports.DocumentConverter = DocumentConverter; function DocumentConverter(options) { return { convertToHtml: function (element) { var comments = _.indexBy( element.type === documents.types.document ? element.comments : [], "commentId" ); var conversion = new DocumentConversion(options, comments); return conversion.convertToHtml(element); } }; } function DocumentConversion(options, comments) { var noteNumber = 1; var noteReferences = []; var referencedComments = []; options = _.extend({ ignoreEmptyParagraphs: true }, options); var idPrefix = options.idPrefix === undefined ? "" : options.idPrefix; var ignoreEmptyParagraphs = options.ignoreEmptyParagraphs; var defaultParagraphStyle = htmlPaths.topLevelElement("p"); var styleMap = options.styleMap || []; function convertToHtml(document) { var messages = []; var html = elementToHtml(document, messages, {}); var deferredNodes = []; walkHtml(html, function (node) { if (node.type === "deferred") { deferredNodes.push(node); } }); var deferredValues = {}; return promises.mapSeries(deferredNodes, function (deferred) { return deferred.value().then(function (value) { deferredValues[deferred.id] = value; }); }).then(function () { function replaceDeferred(nodes) { return flatMap(nodes, function (node) { if (node.type === "deferred") { return deferredValues[node.id]; } else if (node.children) { return [ _.extend({}, node, { children: replaceDeferred(node.children) }) ]; } else { return [node]; } }); } var writer = writers.writer({ prettyPrint: options.prettyPrint, outputFormat: options.outputFormat }); Html.write(writer, Html.simplify(replaceDeferred(html))); return new results.Result(writer.asString(), messages); }); } function convertElements(elements, messages, options) { return flatMap(elements, function (element) { return elementToHtml(element, messages, options); }); } function elementToHtml(element, messages, options) { if (!options) { throw new Error("options not set"); } var handler = elementConverters[element.type]; if (handler) { return handler(element, messages, options); } else { return []; } } function convertParagraph(element, messages, options) { return htmlPathForParagraph(element, messages).wrap(function () { var content = convertElements(element.children, messages, options); if (ignoreEmptyParagraphs) { return content; } else { return [Html.forceWrite].concat(content); } }); } function htmlPathForParagraph(element, messages) { var style = findStyle(element); if (style) { return style.to; } else { if (element.styleId) { messages.push(unrecognisedStyleWarning("paragraph", element)); } return defaultParagraphStyle; } } function convertRun(run, messages, options) { var nodes = function () { return convertElements(run.children, messages, options); }; var paths = []; if (run.isSmallCaps) { paths.push(findHtmlPathForRunProperty("smallCaps")); } if (run.isAllCaps) { paths.push(findHtmlPathForRunProperty("allCaps")); } if (run.isStrikethrough) { paths.push(findHtmlPathForRunProperty("strikethrough", "s")); } if (run.isUnderline) { paths.push(findHtmlPathForRunProperty("underline")); } if (run.verticalAlignment === documents.verticalAlignment.subscript) { paths.push(htmlPaths.element("sub", {}, { fresh: false })); } if (run.verticalAlignment === documents.verticalAlignment.superscript) { paths.push(htmlPaths.element("sup", {}, { fresh: false })); } if (run.isItalic) { paths.push(findHtmlPathForRunProperty("italic", "em")); } if (run.isBold) { paths.push(findHtmlPathForRunProperty("bold", "strong")); } var stylePath = htmlPaths.empty; var style = findStyle(run); if (style) { stylePath = style.to; } else if (run.styleId) { messages.push(unrecognisedStyleWarning("run", run)); } paths.push(stylePath); paths.forEach(function (path) { nodes = path.wrap.bind(path, nodes); }); return nodes(); } function findHtmlPathForRunProperty(elementType, defaultTagName) { var path = findHtmlPath({ type: elementType }); if (path) { return path; } else if (defaultTagName) { return htmlPaths.element(defaultTagName, {}, { fresh: false }); } else { return htmlPaths.empty; } } function findHtmlPath(element, defaultPath) { var style = findStyle(element); return style ? style.to : defaultPath; } function findStyle(element) { for (var i = 0; i < styleMap.length; i++) { if (styleMap[i].from.matches(element)) { return styleMap[i]; } } } function recoveringConvertImage(convertImage) { return function (image, messages) { return promises.attempt(function () { return convertImage(image, messages); }).caught(function (error) { messages.push(results.error(error)); return []; }); }; } function noteHtmlId(note) { return referentHtmlId(note.noteType, note.noteId); } function noteRefHtmlId(note) { return referenceHtmlId(note.noteType, note.noteId); } function referentHtmlId(referenceType, referenceId) { return htmlId(referenceType + "-" + referenceId); } function referenceHtmlId(referenceType, referenceId) { return htmlId(referenceType + "-ref-" + referenceId); } function htmlId(suffix) { return idPrefix + suffix; } var defaultTablePath = htmlPaths.elements([ htmlPaths.element("table", {}, { fresh: true }) ]); function convertTable(element, messages, options) { return findHtmlPath(element, defaultTablePath).wrap(function () { return convertTableChildren(element, messages, options); }); } function convertTableChildren(element, messages, options) { var bodyIndex = _.findIndex(element.children, function (child) { return !child.type === documents.types.tableRow || !child.isHeader; }); if (bodyIndex === -1) { bodyIndex = element.children.length; } var children; if (bodyIndex === 0) { children = convertElements( element.children, messages, _.extend({}, options, { isTableHeader: false }) ); } else { var headRows = convertElements( element.children.slice(0, bodyIndex), messages, _.extend({}, options, { isTableHeader: true }) ); var bodyRows = convertElements( element.children.slice(bodyIndex), messages, _.extend({}, options, { isTableHeader: false }) ); children = [ Html.freshElement("thead", {}, headRows), Html.freshElement("tbody", {}, bodyRows) ]; } return [Html.forceWrite].concat(children); } function convertTableRow(element, messages, options) { var children = convertElements(element.children, messages, options); return [ Html.freshElement("tr", {}, [Html.forceWrite].concat(children)) ]; } function convertTableCell(element, messages, options) { var tagName = options.isTableHeader ? "th" : "td"; var children = convertElements(element.children, messages, options); var attributes = {}; if (element.colSpan !== 1) { attributes.colspan = element.colSpan.toString(); } if (element.rowSpan !== 1) { attributes.rowspan = element.rowSpan.toString(); } return [ Html.freshElement(tagName, attributes, [Html.forceWrite].concat(children)) ]; } function convertCommentReference(reference, messages, options) { return findHtmlPath(reference, htmlPaths.ignore).wrap(function () { var comment = comments[reference.commentId]; var count = referencedComments.length + 1; var label = "[" + commentAuthorLabel(comment) + count + "]"; referencedComments.push({ label: label, comment: comment }); // TODO: remove duplication with note references return [ Html.freshElement("a", { href: "#" + referentHtmlId("comment", reference.commentId), id: referenceHtmlId("comment", reference.commentId) }, [Html.text(label)]) ]; }); } function convertComment(referencedComment, messages, options) { // TODO: remove duplication with note references var label = referencedComment.label; var comment = referencedComment.comment; var body = convertElements(comment.body, messages, options).concat([ Html.nonFreshElement("p", {}, [ Html.text(" "), Html.freshElement("a", { "href": "#" + referenceHtmlId("comment", comment.commentId) }, [ Html.text("↑") ]) ]) ]); return [ Html.freshElement( "dt", { "id": referentHtmlId("comment", comment.commentId) }, [Html.text("Comment " + label)] ), Html.freshElement("dd", {}, body) ]; } function convertBreak(element, messages, options) { return htmlPathForBreak(element).wrap(function () { return []; }); } function htmlPathForBreak(element) { var style = findStyle(element); if (style) { return style.to; } else if (element.breakType === "line") { return htmlPaths.topLevelElement("br"); } else { return htmlPaths.empty; } } var elementConverters = { "document": function (document, messages, options) { var children = convertElements(document.children, messages, options); var notes = noteReferences.map(function (noteReference) { return document.notes.resolve(noteReference); }); var notesNodes = convertElements(notes, messages, options); return children.concat([ Html.freshElement("ol", {}, notesNodes), Html.freshElement("dl", {}, flatMap(referencedComments, function (referencedComment) { return convertComment(referencedComment, messages, options); })) ]); }, "paragraph": convertParagraph, "run": convertRun, "text": function (element, messages, options) { return [Html.text(element.value)]; }, "tab": function (element, messages, options) { return [Html.text("\t")]; }, "hyperlink": function (element, messages, options) { var href = element.anchor ? "#" + htmlId(element.anchor) : element.href; var attributes = { href: href }; if (element.targetFrame != null) { attributes.target = element.targetFrame; } var children = convertElements(element.children, messages, options); return [Html.nonFreshElement("a", attributes, children)]; }, "bookmarkStart": function (element, messages, options) { var anchor = Html.freshElement("a", { id: htmlId(element.name) }, [Html.forceWrite]); return [anchor]; }, "noteReference": function (element, messages, options) { noteReferences.push(element); var anchor = Html.freshElement("a", { href: "#" + noteHtmlId(element), id: noteRefHtmlId(element) }, [Html.text("[" + (noteNumber++) + "]")]); return [Html.freshElement("sup", {}, [anchor])]; }, "note": function (element, messages, options) { var children = convertElements(element.body, messages, options); var backLink = Html.elementWithTag(htmlPaths.element("p", {}, { fresh: false }), [ Html.text(" "), Html.freshElement("a", { href: "#" + noteRefHtmlId(element) }, [Html.text("↑")]) ]); var body = children.concat([backLink]); return Html.freshElement("li", { id: noteHtmlId(element) }, body); }, "commentReference": convertCommentReference, "comment": convertComment, "image": deferredConversion(recoveringConvertImage(options.convertImage || images.dataUri)), "table": convertTable, "tableRow": convertTableRow, "tableCell": convertTableCell, "break": convertBreak }; return { convertToHtml: convertToHtml }; } var deferredId = 1; function deferredConversion(func) { return function (element, messages, options) { return [ { type: "deferred", id: deferredId++, value: function () { return func(element, messages, options); } } ]; }; } function unrecognisedStyleWarning(type, element) { return results.warning( "Unrecognised " + type + " style: '" + element.styleName + "'" + " (Style ID: " + element.styleId + ")" ); } function flatMap(values, func) { return _.flatten(values.map(func), true); } function walkHtml(nodes, callback) { nodes.forEach(function (node) { callback(node); if (node.children) { walkHtml(node.children, callback); } }); } var commentAuthorLabel = exports.commentAuthorLabel = function commentAuthorLabel(comment) { return comment.authorInitials || ""; }; }, { "./documents": 4, "./html": 18, "./images": 20, "./promises": 23, "./results": 25, "./styles/html-paths": 28, "./writers": 33, "underscore": 103 }], 4: [function (require, module, exports) { (function (Buffer) { var _ = require("underscore"); var types = exports.types = { document: "document", paragraph: "paragraph", run: "run", text: "text", tab: "tab", hyperlink: "hyperlink", noteReference: "noteReference", image: "image", note: "note", commentReference: "commentReference", comment: "comment", table: "table", tableRow: "tableRow", tableCell: "tableCell", "break": "break", bookmarkStart: "bookmarkStart" }; function Document(children, options) { options = options || {}; return { type: types.document, children: children, notes: options.notes || new Notes({}), comments: options.comments || [] }; } function Paragraph(children, properties) { properties = properties || {}; var indent = properties.indent || {}; return { type: types.paragraph, children: children, styleId: properties.styleId || null, styleName: properties.styleName || null, numbering: properties.numbering || null, alignment: properties.alignment || null, indent: { start: indent.start || null, end: indent.end || null, firstLine: indent.firstLine || null, hanging: indent.hanging || null } }; } function Run(children, properties) { properties = properties || {}; return { type: types.run, children: children, styleId: properties.styleId || null, styleName: properties.styleName || null, isBold: !!properties.isBold, isUnderline: !!properties.isUnderline, isItalic: !!properties.isItalic, isStrikethrough: !!properties.isStrikethrough, isAllCaps: !!properties.isAllCaps, isSmallCaps: !!properties.isSmallCaps, verticalAlignment: properties.verticalAlignment || verticalAlignment.baseline, font: properties.font || null, fontSize: properties.fontSize || null }; } var verticalAlignment = { baseline: "baseline", superscript: "superscript", subscript: "subscript" }; function Text(value) { return { type: types.text, value: value }; } function Tab() { return { type: types.tab }; } function Hyperlink(children, options) { return { type: types.hyperlink, children: children, href: options.href, anchor: options.anchor, targetFrame: options.targetFrame }; } function NoteReference(options) { return { type: types.noteReference, noteType: options.noteType, noteId: options.noteId }; } function Notes(notes) { this._notes = _.indexBy(notes, function (note) { return noteKey(note.noteType, note.noteId); }); } Notes.prototype.resolve = function (reference) { return this.findNoteByKey(noteKey(reference.noteType, reference.noteId)); }; Notes.prototype.findNoteByKey = function (key) { return this._notes[key] || null; }; function Note(options) { return { type: types.note, noteType: options.noteType, noteId: options.noteId, body: options.body }; } function commentReference(options) { return { type: types.commentReference, commentId: options.commentId }; } function comment(options) { return { type: types.comment, commentId: options.commentId, body: options.body, authorName: options.authorName, authorInitials: options.authorInitials }; } function noteKey(noteType, id) { return noteType + "-" + id; } function Image(options) { return { type: types.image, // `read` is retained for backwards compatibility, but other read // methods should be preferred. read: function (encoding) { if (encoding) { return options.readImage(encoding); } else { return options.readImage().then(function (arrayBuffer) { return Buffer.from(arrayBuffer); }); } }, readAsArrayBuffer: function () { return options.readImage(); }, readAsBase64String: function () { return options.readImage("base64"); }, readAsBuffer: function () { return options.readImage().then(function (arrayBuffer) { return Buffer.from(arrayBuffer); }); }, altText: options.altText, contentType: options.contentType }; } function Table(children, properties) { properties = properties || {}; return { type: types.table, children: children, styleId: properties.styleId || null, styleName: properties.styleName || null }; } function TableRow(children, options) { options = options || {}; return { type: types.tableRow, children: children, isHeader: options.isHeader || false }; } function TableCell(children, options) { options = options || {}; return { type: types.tableCell, children: children, colSpan: options.colSpan == null ? 1 : options.colSpan, rowSpan: options.rowSpan == null ? 1 : options.rowSpan }; } function Break(breakType) { return { type: types["break"], breakType: breakType }; } function BookmarkStart(options) { return { type: types.bookmarkStart, name: options.name }; } exports.document = exports.Document = Document; exports.paragraph = exports.Paragraph = Paragraph; exports.run = exports.Run = Run; exports.text = exports.Text = Text; exports.tab = exports.Tab = Tab; exports.Hyperlink = Hyperlink; exports.noteReference = exports.NoteReference = NoteReference; exports.Notes = Notes; exports.Note = Note; exports.commentReference = commentReference; exports.comment = comment; exports.Image = Image; exports.Table = Table; exports.TableRow = TableRow; exports.TableCell = TableCell; exports.lineBreak = Break("line"); exports.pageBreak = Break("page"); exports.columnBreak = Break("column"); exports.BookmarkStart = BookmarkStart; exports.verticalAlignment = verticalAlignment; }).call(this, require("buffer").Buffer) }, { "buffer": 83, "underscore": 103 }], 5: [function (require, module, exports) { exports.createBodyReader = createBodyReader; exports._readNumberingProperties = readNumberingProperties; var dingbatToUnicode = require("dingbat-to-unicode"); var _ = require("underscore"); var documents = require("../documents"); var Result = require("../results").Result; var warning = require("../results").warning; var uris = require("./uris"); function createBodyReader(options) { return { readXmlElement: function (element) { return new BodyReader(options).readXmlElement(element); }, readXmlElements: function (elements) { return new BodyReader(options).readXmlElements(elements); } }; } function BodyReader(options) { var complexFieldStack = []; var currentInstrText = []; // When a paragraph is marked as deleted, its contents should be combined // with the following paragraph. See 17.13.5.15 del (Deleted Paragraph) of // ECMA-376 4th edition Part 1. var deletedParagraphContents = []; var relationships = options.relationships; var contentTypes = options.contentTypes; var docxFile = options.docxFile; var files = options.files; var numbering = options.numbering; var styles = options.styles; function readXmlElements(elements) { var results = elements.map(readXmlElement); return combineResults(results); } function readXmlElement(element) { if (element.type === "element") { var handler = xmlElementReaders[element.name]; if (handler) { return handler(element); } else if (!Object.prototype.hasOwnProperty.call(ignoreElements, element.name)) { var message = warning("An unrecognised element was ignored: " + element.name); return emptyResultWithMessages([message]); } } return emptyResult(); } function readParagraphProperties(element) { return readParagraphStyle(element).map(function (style) { return { type: "paragraphProperties", styleId: style.styleId, styleName: style.name, alignment: element.firstOrEmpty("w:jc").attributes["w:val"], numbering: readNumberingProperties(style.styleId, element.firstOrEmpty("w:numPr"), numbering), indent: readParagraphIndent(element.firstOrEmpty("w:ind")) }; }); } function readParagraphIndent(element) { return { start: element.attributes["w:start"] || element.attributes["w:left"], end: element.attributes["w:end"] || element.attributes["w:right"], firstLine: element.attributes["w:firstLine"], hanging: element.attributes["w:hanging"] }; } function readRunProperties(element) { return readRunStyle(element).map(function (style) { var fontSizeString = element.firstOrEmpty("w:sz").attributes["w:val"]; // w:sz gives the font size in half points, so halve the value to get the size in points var fontSize = /^[0-9]+$/.test(fontSizeString) ? parseInt(fontSizeString, 10) / 2 : null; return { type: "runProperties", styleId: style.styleId, styleName: style.name, verticalAlignment: element.firstOrEmpty("w:vertAlign").attributes["w:val"], font: element.firstOrEmpty("w:rFonts").attributes["w:ascii"], fontSize: fontSize, isBold: readBooleanElement(element.first("w:b")), isUnderline: readUnderline(element.first("w:u")), isItalic: readBooleanElement(element.first("w:i")), isStrikethrough: readBooleanElement(element.first("w:strike")), isAllCaps: readBooleanElement(element.first("w:caps")), isSmallCaps: readBooleanElement(element.first("w:smallCaps")) }; }); } function readUnderline(element) { if (element) { var value = element.attributes["w:val"]; return value !== undefined && value !== "false" && value !== "0" && value !== "none"; } else { return false; } } function readBooleanElement(element) { if (element) { var value = element.attributes["w:val"]; return value !== "false" && value !== "0"; } else { return false; } } function readParagraphStyle(element) { return readStyle(element, "w:pStyle", "Paragraph", styles.findParagraphStyleById); } function readRunStyle(element) { return readStyle(element, "w:rStyle", "Run", styles.findCharacterStyleById); } function readTableStyle(element) { return readStyle(element, "w:tblStyle", "Table", styles.findTableStyleById); } function readStyle(element, styleTagName, styleType, findStyleById) { var messages = []; var styleElement = element.first(styleTagName); var styleId = null; var name = null; if (styleElement) { styleId = styleElement.attributes["w:val"]; if (styleId) { var style = findStyleById(styleId); if (style) { name = style.name; } else { messages.push(undefinedStyleWarning(styleType, styleId)); } } } return elementResultWithMessages({ styleId: styleId, name: name }, messages); } var unknownComplexField = { type: "unknown" }; function readFldChar(element) { var type = element.attributes["w:fldCharType"]; if (type === "begin") { complexFieldStack.push(unknownComplexField); currentInstrText = []; } else if (type === "end") { complexFieldStack.pop(); } else if (type === "separate") { var hyperlinkOptions = parseHyperlinkFieldCode(currentInstrText.join('')); var complexField = hyperlinkOptions === null ? unknownComplexField : { type: "hyperlink", options: hyperlinkOptions }; complexFieldStack.pop(); complexFieldStack.push(complexField); } return emptyResult(); } function currentHyperlinkOptions() { var topHyperlink = _.last(complexFieldStack.filter(function (complexField) { return complexField.type === "hyperlink"; })); return topHyperlink ? topHyperlink.options : null; } function parseHyperlinkFieldCode(code) { var externalLinkResult = /\s*HYPERLINK "(.*)"/.exec(code); if (externalLinkResult) { return { href: externalLinkResult[1] }; } var internalLinkResult = /\s*HYPERLINK\s+\\l\s+"(.*)"/.exec(code); if (internalLinkResult) { return { anchor: internalLinkResult[1] }; } return null; } function readInstrText(element) { currentInstrText.push(element.text()); return emptyResult(); } function readSymbol(element) { // See 17.3.3.30 sym (Symbol Character) of ECMA-376 4th edition Part 1 var font = element.attributes["w:font"]; var char = element.attributes["w:char"]; var unicodeCharacter = dingbatToUnicode.hex(font, char); if (unicodeCharacter == null && /^F0..$/.test(char)) { unicodeCharacter = dingbatToUnicode.hex(font, char.substring(2)); } if (unicodeCharacter == null) { return emptyResultWithMessages([warning( "A w:sym element with an unsupported character was ignored: char " + char + " in font " + font )]); } else { return elementResult(new documents.Text(unicodeCharacter.string)); } } function noteReferenceReader(noteType) { return function (element) { var noteId = element.attributes["w:id"]; return elementResult(new documents.NoteReference({ noteType: noteType, noteId: noteId })); }; } function readCommentReference(element) { return elementResult(documents.commentReference({ commentId: element.attributes["w:id"] })); } function readChildElements(element) { return readXmlElements(element.children); } var xmlElementReaders = { "w:p": function (element) { var paragraphPropertiesElement = element.firstOrEmpty("w:pPr"); var isDeleted = !!paragraphPropertiesElement .firstOrEmpty("w:rPr") .first("w:del"); if (isDeleted) { element.children.forEach(function (child) { deletedParagraphContents.push(child); }); return emptyResult(); } else { var childrenXml = element.children; if (deletedParagraphContents.length > 0) { childrenXml = deletedParagraphContents.concat(childrenXml); deletedParagraphContents = []; } return ReadResult.map( readParagraphProperties(paragraphPropertiesElement), readXmlElements(childrenXml), function (properties, children) { return new documents.Paragraph(children, properties); } ).insertExtra(); } }, "w:r": function (element) { return ReadResult.map( readRunProperties(element.firstOrEmpty("w:rPr")), readXmlElements(element.children), function (properties, children) { var hyperlinkOptions = currentHyperlinkOptions(); if (hyperlinkOptions !== null) { children = [new documents.Hyperlink(children, hyperlinkOptions)]; } return new documents.Run(children, properties); } ); }, "w:fldChar": readFldChar, "w:instrText": readInstrText, "w:t": function (element) { return elementResult(new documents.Text(element.text())); }, "w:tab": function (element) { return elementResult(new documents.Tab()); }, "w:noBreakHyphen": function () { return elementResult(new documents.Text("\u2011")); }, "w:softHyphen": function (element) { return elementResult(new documents.Text("\u00AD")); }, "w:sym": readSymbol, "w:hyperlink": function (element) { var relationshipId = element.attributes["r:id"]; var anchor = element.attributes["w:anchor"]; return readXmlElements(element.children).map(function (children) { function create(options) { var targetFrame = element.attributes["w:tgtFrame"] || null; return new documents.Hyperlink( children, _.extend({ targetFrame: targetFrame }, options) ); } if (relationshipId) { var href = relationships.findTargetByRelationshipId(relationshipId); if (anchor) { href = uris.replaceFragment(href, anchor); } return create({ href: href }); } else if (anchor) { return create({ anchor: anchor }); } else { return children; } }); }, "w:tbl": readTable, "w:tr": readTableRow, "w:tc": readTableCell, "w:footnoteReference": noteReferenceReader("footnote"), "w:endnoteReference": noteReferenceReader("endnote"), "w:commentReference": readCommentReference, "w:br": function (element) { var breakType = element.attributes["w:type"]; if (breakType == null || breakType === "textWrapping") { return elementResult(documents.lineBreak); } else if (breakType === "page") { return elementResult(documents.pageBreak); } else if (breakType === "column") { return elementResult(documents.columnBreak); } else { return emptyResultWithMessages([warning("Unsupported break type: " + breakType)]); } }, "w:bookmarkStart": function (element) { var name = element.attributes["w:name"]; if (name === "_GoBack") { return emptyResult(); } else { return elementResult(new documents.BookmarkStart({ name: name })); } }, "mc:AlternateContent": function (element) { return readChildElements(element.first("mc:Fallback")); }, "w:sdt": function (element) { return readXmlElements(element.firstOrEmpty("w:sdtContent").children); }, "w:ins": readChildElements, "w:object": readChildElements, "w:smartTag": readChildElements, "w:drawing": readChildElements, "w:pict": function (element) { return readChildElements(element).toExtra(); }, "v:roundrect": readChildElements, "v:shape": readChildElements, "v:textbox": readChildElements, "w:txbxContent": readChildElements, "wp:inline": readDrawingElement, "wp:anchor": readDrawingElement, "v:imagedata": readImageData, "v:group": readChildElements, "v:rect": readChildElements }; return { readXmlElement: readXmlElement, readXmlElements: readXmlElements }; function readTable(element) { var propertiesResult = readTableProperties(element.firstOrEmpty("w:tblPr")); return readXmlElements(element.children) .flatMap(calculateRowSpans) .flatMap(function (children) { return propertiesResult.map(function (properties) { return documents.Table(children, properties); }); }); } function readTableProperties(element) { return readTableStyle(element).map(function (style) { return { styleId: style.styleId, styleName: style.name }; }); } function readTableRow(element) { var properties = element.firstOrEmpty("w:trPr"); var isHeader = !!properties.first("w:tblHeader"); return readXmlElements(element.children).map(function (children) { return documents.TableRow(children, { isHeader: isHeader }); }); } function readTableCell(element) { return readXmlElements(element.children).map(function (children) { var properties = element.firstOrEmpty("w:tcPr"); var gridSpan = properties.firstOrEmpty("w:gridSpan").attributes["w:val"]; var colSpan = gridSpan ? parseInt(gridSpan, 10) : 1; var cell = documents.TableCell(children, { colSpan: colSpan }); cell._vMerge = readVMerge(properties); return cell; }); } function readVMerge(properties) { var element = properties.first("w:vMerge"); if (element) { var val = element.attributes["w:val"]; return val === "continue" || !val; } else { return null; } } function calculateRowSpans(rows) { var unexpectedNonRows = _.any(rows, function (row) { return row.type !== documents.types.tableRow; }); if (unexpectedNonRows) { return elementResultWithMessages(rows, [warning( "unexpected non-row element in table, cell merging may be incorrect" )]); } var unexpectedNonCells = _.any(rows, function (row) { return _.any(row.children, function (cell) { return cell.type !== documents.types.tableCell; }); }); if (unexpectedNonCells) { return elementResultWithMessages(rows, [warning( "unexpected non-cell element in table row, cell merging may be incorrect" )]); } var columns = {}; rows.forEach(function (row) { var cellIndex = 0; row.children.forEach(function (cell) { if (cell._vMerge && columns[cellIndex]) { columns[cellIndex].rowSpan++; } else { columns[cellIndex] = cell; cell._vMerge = false; } cellIndex += cell.colSpan; }); }); rows.forEach(function (row) { row.children = row.children.filter(function (cell) { return !cell._vMerge; }); row.children.forEach(function (cell) { delete cell._vMerge; }); }); return elementResult(rows); } function readDrawingElement(element) { var blips = element .getElementsByTagName("a:graphic") .getElementsByTagName("a:graphicData") .getElementsByTagName("pic:pic") .getElementsByTagName("pic:blipFill") .getElementsByTagName("a:blip"); return combineResults(blips.map(readBlip.bind(null, element))); } function readBlip(element, blip) { var properties = element.first("wp:docPr").attributes; var altText = isBlank(properties.descr) ? properties.title : properties.descr; var blipImageFile = findBlipImageFile(blip); if (blipImageFile === null) { return emptyResultWithMessages([warning("Could not find image file for a:blip element")]); } else { return readImage(blipImageFile, altText); } } function isBlank(value) { return value == null || /^\s*$/.test(value); } function findBlipImageFile(blip) { var embedRelationshipId = blip.attributes["r:embed"]; var linkRelationshipId = blip.attributes["r:link"]; if (embedRelationshipId) { return findEmbeddedImageFile(embedRelationshipId); } else if (linkRelationshipId) { var imagePath = relationships.findTargetByRelationshipId(linkRelationshipId); return { path: imagePath, read: files.read.bind(files, imagePath) }; } else { return null; } } function readImageData(element) { var relationshipId = element.attributes['r:id']; if (relationshipId) { return readImage( findEmbeddedImageFile(relationshipId), element.attributes["o:title"]); } else { return emptyResultWithMessages([warning("A v:imagedata element without a relationship ID was ignored")]); } } function findEmbeddedImageFile(relationshipId) { var path = uris.uriToZipEntryName("word", relationships.findTargetByRelationshipId(relationshipId)); return { path: path, read: docxFile.read.bind(docxFile, path) }; } function readImage(imageFile, altText) { var contentType = contentTypes.findContentType(imageFile.path); var image = documents.Image({ readImage: imageFile.read, altText: altText, contentType: contentType }); var warnings = supportedImageTypes[contentType] ? [] : warning("Image of type " + contentType + " is unlikely to display in web browsers"); return elementResultWithMessages(image, warnings); } function undefinedStyleWarning(type, styleId) { return warning( type + " style with ID " + styleId + " was referenced but not defined in the document"); } } function readNumberingProperties(styleId, element, numbering) { if (styleId != null) { var levelByStyleId = numbering.findLevelByParagraphStyleId(styleId); if (levelByStyleId != null) { return levelByStyleId; } } var level = element.firstOrEmpty("w:ilvl").attributes["w:val"]; var numId = element.firstOrEmpty("w:numId").attributes["w:val"]; if (level === undefined || numId === undefined) { return null; } else { return numbering.findLevel(numId, level); } } var supportedImageTypes = { "image/png": true, "image/gif": true, "image/jpeg": true, "image/svg+xml": true, "image/tiff": true }; var ignoreElements = { "office-word:wrap": true, "v:shadow": true, "v:shapetype": true, "w:annotationRef": true, "w:bookmarkEnd": true, "w:sectPr": true, "w:proofErr": true, "w:lastRenderedPageBreak": true, "w:commentRangeStart": true, "w:commentRangeEnd": true, "w:del": true, "w:footnoteRef": true, "w:endnoteRef": true, "w:pPr": true, "w:rPr": true, "w:tblPr": true, "w:tblGrid": true, "w:trPr": true, "w:tcPr": true }; function emptyResultWithMessages(messages) { return new ReadResult(null, null, messages); } function emptyResult() { return new ReadResult(null); } function elementResult(element) { return new ReadResult(element); } function elementResultWithMessages(element, messages) { return new ReadResult(element, null, messages); } function ReadResult(element, extra, messages) { this.value = element || []; this.extra = extra || []; this._result = new Result({ element: this.value, extra: extra }, messages); this.messages = this._result.messages; } ReadResult.prototype.toExtra = function () { return new ReadResult(null, joinElements(this.extra, this.value), this.messages); }; ReadResult.prototype.insertExtra = function () { var extra = this.extra; if (extra && extra.length) { return new ReadResult(joinElements(this.value, extra), null, this.messages); } else { return this; } }; ReadResult.prototype.map = function (func) { var result = this._result.map(function (value) { return func(value.element); }); return new ReadResult(result.value, this.extra, result.messages); }; ReadResult.prototype.flatMap = function (func) { var result = this._result.flatMap(function (value) { return func(value.element)._result; }); return new ReadResult(result.value.element, joinElements(this.extra, result.value.extra), result.messages); }; ReadResult.map = function (first, second, func) { return new ReadResult( func(first.value, second.value), joinElements(first.extra, second.extra), first.messages.concat(second.messages) ); }; function combineResults(results) { var result = Result.combine(_.pluck(results, "_result")); return new ReadResult( _.flatten(_.pluck(result.value, "element")), _.filter(_.flatten(_.pluck(result.value, "extra")), identity), result.messages ); } function joinElements(first, second) { return _.flatten([first, second]); } function identity(value) { return value; } }, { "../documents": 4, "../results": 25, "./uris": 16, "dingbat-to-unicode": 85, "underscore": 103 }], 6: [function (require, module, exports) { var documents = require("../documents"); var Result = require("../results").Result; function createCommentsReader(bodyReader) { function readCommentsXml(element) { return Result.combine(element.getElementsByTagName("w:comment") .map(readCommentElement)); } function readCommentElement(element) { var id = element.attributes["w:id"]; function readOptionalAttribute(name) { return (element.attributes[name] || "").trim() || null; } return bodyReader.readXmlElements(element.children) .map(function (body) { return documents.comment({ commentId: id, body: body, authorName: readOptionalAttribute("w:author"), authorInitials: readOptionalAttribute("w:initials") }); }); } return readCommentsXml; } exports.createCommentsReader = createCommentsReader; }, { "../documents": 4, "../results": 25 }], 7: [function (require, module, exports) { exports.readContentTypesFromXml = readContentTypesFromXml; var fallbackContentTypes = { "png": "png", "gif": "gif", "jpeg": "jpeg", "jpg": "jpeg", "tif": "tiff", "tiff": "tiff", "bmp": "bmp" }; exports.defaultContentTypes = contentTypes({}, {}); function readContentTypesFromXml(element) { var extensionDefaults = {}; var overrides = {}; element.children.forEach(function (child) { if (child.name === "content-types:Default") { extensionDefaults[child.attributes.Extension] = child.attributes.ContentType; } if (child.name === "content-types:Override") { var name = child.attributes.PartName; if (name.charAt(0) === "/") { name = name.substring(1); } overrides[name] = child.attributes.ContentType; } }); return contentTypes(overrides, extensionDefaults); } function contentTypes(overrides, extensionDefaults) { return { findContentType: function (path) { var overrideContentType = overrides[path]; if (overrideContentType) { return overrideContentType; } else { var pathParts = path.split("."); var extension = pathParts[pathParts.length - 1]; if (extensionDefaults.hasOwnProperty(extension)) { return extensionDefaults[extension]; } else { var fallback = fallbackContentTypes[extension.toLowerCase()]; if (fallback) { return "image/" + fallback; } else { return null; } } } } }; } }, {}], 8: [function (require, module, exports) { exports.DocumentXmlReader = DocumentXmlReader; var documents = require("../documents"); var Result = require("../results").Result; function DocumentXmlReader(options) { var bodyReader = options.bodyReader; function convertXmlToDocument(element) { var body = element.first("w:body"); var result = bodyReader.readXmlElements(body.children) .map(function (children) { return new documents.Document(children, { notes: options.notes, comments: options.comments }); }); return new Result(result.value, result.messages); } return { convertXmlToDocument: convertXmlToDocument }; } }, { "../documents": 4, "../results": 25 }], 9: [function (require, module, exports) { exports.read = read; exports._findPartPaths = findPartPaths; var path = require("path"); var promises = require("../promises"); var documents = require("../documents"); var Result = require("../results").Result; var zipfile = require("../zipfile"); var readXmlFromZipFile = require("./office-xml-reader").readXmlFromZipFile; var createBodyReader = require("./body-reader").createBodyReader; var DocumentXmlReader = require("./document-xml-reader").DocumentXmlReader; var relationshipsReader = require("./relationships-reader"); var contentTypesReader = require("./content-types-reader"); var numberingXml = require("./numbering-xml"); var stylesReader = require("./styles-reader"); var notesReader = require("./notes-reader"); var commentsReader = require("./comments-reader"); var Files = require("./files").Files; function read(docxFile, input) { input = input || {}; return promises.props({ contentTypes: readContentTypesFromZipFile(docxFile), partPaths: findPartPaths(docxFile), docxFile: docxFile, files: new Files(input.path ? path.dirname(input.path) : null) }).also(function (result) { return { styles: readStylesFromZipFile(docxFile, result.partPaths.styles) }; }).also(function (result) { return { numbering: readNumberingFromZipFile(docxFile, result.partPaths.numbering, result.styles) }; }).also(function (result) { return { footnotes: readXmlFileWithBody(result.partPaths.footnotes, result, function (bodyReader, xml) { if (xml) { return notesReader.createFootnotesReader(bodyReader)(xml); } else { return new Result([]); } }), endnotes: readXmlFileWithBody(result.partPaths.endnotes, result, function (bodyReader, xml) { if (xml) { return notesReader.createEndnotesReader(bodyReader)(xml); } else { return new Result([]); } }), comments: readXmlFileWithBody(result.partPaths.comments, result, function (bodyReader, xml) { if (xml) { return commentsReader.createCommentsReader(bodyReader)(xml); } else { return new Result([]); } }) }; }).also(function (result) { return { notes: result.footnotes.flatMap(function (footnotes) { return result.endnotes.map(function (endnotes) { return new documents.Notes(footnotes.concat(endnotes)); }); }) }; }).then(function (result) { return readXmlFileWithBody(result.partPaths.mainDocument, result, function (bodyReader, xml) { return result.notes.flatMap(function (notes) { return result.comments.flatMap(function (comments) { var reader = new DocumentXmlReader({ bodyReader: bodyReader, notes: notes, comments: comments }); return reader.convertXmlToDocument(xml); }); }); }); }); } function findPartPaths(docxFile) { return readPackageRelationships(docxFile).then(function (packageRelationships) { var mainDocumentPath = findPartPath({ docxFile: docxFile, relationships: packageRelationships, relationshipType: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument", basePath: "", fallbackPath: "word/document.xml" }); if (!docxFile.exists(mainDocumentPath)) { throw new Error("Could not find main document part. Are you sure this is a valid .docx file?"); } return xmlFileReader({ filename: relationshipsFilename(mainDocumentPath), readElement: relationshipsReader.readRelationships, defaultValue: relationshipsReader.defaultValue })(docxFile).then(function (documentRelationships) { function findPartRelatedToMainDocument(name) { return findPartPath({ docxFile: docxFile, relationships: documentRelationships, relationshipType: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/" + name, basePath: zipfile.splitPath(mainDocumentPath).dirname, fallbackPath: "word/" + name + ".xml" }); } return { mainDocument: mainDocumentPath, comments: findPartRelatedToMainDocument("comments"), endnotes: findPartRelatedToMainDocument("endnotes"), footnotes: findPartRelatedToMainDocument("footnotes"), numbering: findPartRelatedToMainDocument("numbering"), styles: findPartRelatedToMainDocument("styles") }; }); }); } function findPartPath(options) { var docxFile = options.docxFile; var relationships = options.relationships; var relationshipType = options.relationshipType; var basePath = options.basePath; var fallbackPath = options.fallbackPath; var targets = relationships.findTargetsByType(relationshipType); var normalisedTargets = targets.map(function (target) { return stripPrefix(zipfile.joinPath(basePath, target), "/"); }); var validTargets = normalisedTargets.filter(function (target) { return docxFile.exists(target); }); if (validTargets.length === 0) { return fallbackPath; } else { return validTargets[0]; } } function stripPrefix(value, prefix) { if (value.substring(0, prefix.length) === prefix) { return value.substring(prefix.length); } else { return value; } } function xmlFileReader(options) { return function (zipFile) { return readXmlFromZipFile(zipFile, options.filename) .then(function (element) { return element ? options.readElement(element) : options.defaultValue; }); }; } function readXmlFileWithBody(filename, options, func) { var readRelationshipsFromZipFile = xmlFileReader({ filename: relationshipsFilename(filename), readElement: relationshipsReader.readRelationships, defaultValue: relationshipsReader.defaultValue }); return readRelationshipsFromZipFile(options.docxFile).then(function (relationships) { var bodyReader = new createBodyReader({ relationships: relationships, contentTypes: options.contentTypes, docxFile: options.docxFile, numbering: options.numbering, styles: options.styles, files: options.files }); return readXmlFromZipFile(options.docxFile, filename) .then(function (xml) { return func(bodyReader, xml); }); }); } function relationshipsFilename(filename) { var split = zipfile.splitPath(filename); return zipfile.joinPath(split.dirname, "_rels", split.basename + ".rels"); } var readContentTypesFromZipFile = xmlFileReader({ filename: "[Content_Types].xml", readElement: contentTypesReader.readContentTypesFromXml, defaultValue: contentTypesReader.defaultContentTypes }); function readNumberingFromZipFile(zipFile, path, styles) { return xmlFileReader({ filename: path, readElement: function (element) { return numberingXml.readNumberingXml(element, { styles: styles }); }, defaultValue: numberingXml.defaultNumbering })(zipFile); } function readStylesFromZipFile(zipFile, path) { return xmlFileReader({ filename: path, readElement: stylesReader.readStylesXml, defaultValue: stylesReader.defaultStyles })(zipFile); } var readPackageRelationships = xmlFileReader({ filename: "_rels/.rels", readElement: relationshipsReader.readRelationships, defaultValue: relationshipsReader.defaultValue }); }, { "../documents": 4, "../promises": 23, "../results": 25, "../zipfile": 40, "./body-reader": 5, "./comments-reader": 6, "./content-types-reader": 7, "./document-xml-reader": 8, "./files": 1, "./notes-reader": 10, "./numbering-xml": 11, "./office-xml-reader": 12, "./relationships-reader": 13, "./styles-reader": 15, "path": 101 }], 10: [function (require, module, exports) { var documents = require("../documents"); var Result = require("../results").Result; exports.createFootnotesReader = createReader.bind(this, "footnote"); exports.createEndnotesReader = createReader.bind(this, "endnote"); function createReader(noteType, bodyReader) { function readNotesXml(element) { return Result.combine(element.getElementsByTagName("w:" + noteType) .filter(isFootnoteElement) .map(readFootnoteElement)); } function isFootnoteElement(element) { var type = element.attributes["w:type"]; return type !== "continuationSeparator" && type !== "separator"; } function readFootnoteElement(footnoteElement) { var id = footnoteElement.attributes["w:id"]; return bodyReader.readXmlElements(footnoteElement.children) .map(function (body) { return documents.Note({ noteType: noteType, noteId: id, body: body }); }); } return readNotesXml; } }, { "../documents": 4, "../results": 25 }], 11: [function (require, module, exports) { var _ = require("underscore"); exports.readNumberingXml = readNumberingXml; exports.Numbering = Numbering; exports.defaultNumbering = new Numbering({}, {}); function Numbering(nums, abstractNums, styles) { var allLevels = _.flatten(_.values(abstractNums).map(function (abstractNum) { return _.values(abstractNum.levels); })); var levelsByParagraphStyleId = _.indexBy( allLevels.filter(function (level) { return level.paragraphStyleId != null; }), "paragraphStyleId" ); function findLevel(numId, level) { var num = nums[numId]; if (num) { var abstractNum = abstractNums[num.abstractNumId]; if (!abstractNum) { return null; } else if (abstractNum.numStyleLink == null) { return abstractNums[num.abstractNumId].levels[level]; } else { var style = styles.findNumberingStyleById(abstractNum.numStyleLink); return findLevel(style.numId, level); } } else { return null; } } function findLevelByParagraphStyleId(styleId) { return levelsByParagraphStyleId[styleId] || null; } return { findLevel: findLevel, findLevelByParagraphStyleId: findLevelByParagraphStyleId }; } function readNumberingXml(root, options) { if (!options || !options.styles) { throw new Error("styles is missing"); } var abstractNums = readAbstractNums(root); var nums = readNums(root, abstractNums); return new Numbering(nums, abstractNums, options.styles); } function readAbstractNums(root) { var abstractNums = {}; root.getElementsByTagName("w:abstractNum").forEach(function (element) { var id = element.attributes["w:abstractNumId"]; abstractNums[id] = readAbstractNum(element); }); return abstractNums; } function readAbstractNum(element) { var levels = {}; element.getElementsByTagName("w:lvl").forEach(function (levelElement) { var levelIndex = levelElement.attributes["w:ilvl"]; var numFmt = levelElement.first("w:numFmt").attributes["w:val"]; var paragraphStyleId = levelElement.firstOrEmpty("w:pStyle").attributes["w:val"]; levels[levelIndex] = { isOrdered: numFmt !== "bullet", level: levelIndex, paragraphStyleId: paragraphStyleId }; }); var numStyleLink = element.firstOrEmpty("w:numStyleLink").attributes["w:val"]; return { levels: levels, numStyleLink: numStyleLink }; } function readNums(root) { var nums = {}; root.getElementsByTagName("w:num").forEach(function (element) { var numId = element.attributes["w:numId"]; var abstractNumId = element.first("w:abstractNumId").attributes["w:val"]; nums[numId] = { abstractNumId: abstractNumId }; }); return nums; } }, { "underscore": 103 }], 12: [function (require, module, exports) { var _ = require("underscore"); var promises = require("../promises"); var xml = require("../xml"); exports.read = read; exports.readXmlFromZipFile = readXmlFromZipFile; var xmlNamespaceMap = { "http://schemas.openxmlformats.org/wordprocessingml/2006/main": "w", "http://schemas.openxmlformats.org/officeDocument/2006/relationships": "r", "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing": "wp", "http://schemas.openxmlformats.org/drawingml/2006/main": "a", "http://schemas.openxmlformats.org/drawingml/2006/picture": "pic", "http://schemas.openxmlformats.org/package/2006/content-types": "content-types", "urn:schemas-microsoft-com:vml": "v", "http://schemas.openxmlformats.org/markup-compatibility/2006": "mc", "urn:schemas-microsoft-com:office:word": "office-word" }; function read(xmlString) { return xml.readString(xmlString, xmlNamespaceMap) .then(function (document) { return collapseAlternateContent(document)[0]; }); } function readXmlFromZipFile(docxFile, path) { if (docxFile.exists(path)) { return docxFile.read(path, "utf-8") .then(stripUtf8Bom) .then(read); } else { return promises.resolve(null); } } function stripUtf8Bom(xmlString) { return xmlString.replace(/^\uFEFF/g, ''); } function collapseAlternateContent(node) { if (node.type === "element") { if (node.name === "mc:AlternateContent") { return node.first("mc:Fallback").children; } else { node.children = _.flatten(node.children.map(collapseAlternateContent, true)); return [node]; } } else { return [node]; } } }, { "../promises": 23, "../xml": 35, "underscore": 103 }], 13: [function (require, module, exports) { exports.readRelationships = readRelationships; exports.defaultValue = new Relationships([]); exports.Relationships = Relationships; function readRelationships(element) { var relationships = []; element.children.forEach(function (child) { if (child.name === "{http://schemas.openxmlformats.org/package/2006/relationships}Relationship") { var relationship = { relationshipId: child.attributes.Id, target: child.attributes.Target, type: child.attributes.Type }; relationships.push(relationship); } }); return new Relationships(relationships); } function Relationships(relationships) { var targetsByRelationshipId = {}; relationships.forEach(function (relationship) { targetsByRelationshipId[relationship.relationshipId] = relationship.target; }); var targetsByType = {}; relationships.forEach(function (relationship) { if (!targetsByType[relationship.type]) { targetsByType[relationship.type] = []; } targetsByType[relationship.type].push(relationship.target); }); return { findTargetByRelationshipId: function (relationshipId) { return targetsByRelationshipId[relationshipId]; }, findTargetsByType: function (type) { return targetsByType[type] || []; } }; } }, {}], 14: [function (require, module, exports) { var _ = require("underscore"); var promises = require("../promises"); var xml = require("../xml"); exports.writeStyleMap = writeStyleMap; exports.readStyleMap = readStyleMap; var schema = "http://schemas.zwobble.org/mammoth/style-map"; var styleMapPath = "mammoth/style-map"; var styleMapAbsolutePath = "/" + styleMapPath; function writeStyleMap(docxFile, styleMap) { docxFile.write(styleMapPath, styleMap); return updateRelationships(docxFile).then(function () { return updateContentTypes(docxFile); }); } function updateRelationships(docxFile) { var path = "word/_rels/document.xml.rels"; var relationshipsUri = "http://schemas.openxmlformats.org/package/2006/relationships"; var relationshipElementName = "{" + relationshipsUri + "}Relationship"; return docxFile.read(path, "utf8") .then(xml.readString) .then(function (relationshipsContainer) { var relationships = relationshipsContainer.children; addOrUpdateElement(relationships, relationshipElementName, "Id", { "Id": "rMammothStyleMap", "Type": schema, "Target": styleMapAbsolutePath }); var namespaces = { "": relationshipsUri }; return docxFile.write(path, xml.writeString(relationshipsContainer, namespaces)); }); } function updateContentTypes(docxFile) { var path = "[Content_Types].xml"; var contentTypesUri = "http://schemas.openxmlformats.org/package/2006/content-types"; var overrideName = "{" + contentTypesUri + "}Override"; return docxFile.read(path, "utf8") .then(xml.readString) .then(function (typesElement) { var children = typesElement.children; addOrUpdateElement(children, overrideName, "PartName", { "PartName": styleMapAbsolutePath, "ContentType": "text/prs.mammoth.style-map" }); var namespaces = { "": contentTypesUri }; return docxFile.write(path, xml.writeString(typesElement, namespaces)); }); } function addOrUpdateElement(elements, name, identifyingAttribute, attributes) { var existingElement = _.find(elements, function (element) { return element.name === name && element.attributes[identifyingAttribute] === attributes[identifyingAttribute]; }); if (existingElement) { existingElement.attributes = attributes; } else { elements.push(xml.element(name, attributes)); } } function readStyleMap(docxFile) { if (docxFile.exists(styleMapPath)) { return docxFile.read(styleMapPath, "utf8"); } else { return promises.resolve(null); } } }, { "../promises": 23, "../xml": 35, "underscore": 103 }], 15: [function (require, module, exports) { exports.readStylesXml = readStylesXml; exports.Styles = Styles; exports.defaultStyles = new Styles({}, {}); function Styles(paragraphStyles, characterStyles, tableStyles, numberingStyles) { return { findParagraphStyleById: function (styleId) { return paragraphStyles[styleId]; }, findCharacterStyleById: function (styleId) { return characterStyles[styleId]; }, findTableStyleById: function (styleId) { return tableStyles[styleId]; }, findNumberingStyleById: function (styleId) { return numberingStyles[styleId]; } }; } Styles.EMPTY = new Styles({}, {}, {}, {}); function readStylesXml(root) { var paragraphStyles = {}; var characterStyles = {}; var tableStyles = {}; var numberingStyles = {}; var styles = { "paragraph": paragraphStyles, "character": characterStyles, "table": tableStyles }; root.getElementsByTagName("w:style").forEach(function (styleElement) { var style = readStyleElement(styleElement); if (style.type === "numbering") { numberingStyles[style.styleId] = readNumberingStyleElement(styleElement); } else { var styleSet = styles[style.type]; if (styleSet) { styleSet[style.styleId] = style; } } }); return new Styles(paragraphStyles, characterStyles, tableStyles, numberingStyles); } function readStyleElement(styleElement) { var type = styleElement.attributes["w:type"]; var styleId = styleElement.attributes["w:styleId"]; var name = styleName(styleElement); return { type: type, styleId: styleId, name: name }; } function styleName(styleElement) { var nameElement = styleElement.first("w:name"); return nameElement ? nameElement.attributes["w:val"] : null; } function readNumberingStyleElement(styleElement) { var numId = styleElement .firstOrEmpty("w:pPr") .firstOrEmpty("w:numPr") .firstOrEmpty("w:numId") .attributes["w:val"]; return { numId: numId }; } }, {}], 16: [function (require, module, exports) { exports.uriToZipEntryName = uriToZipEntryName; exports.replaceFragment = replaceFragment; function uriToZipEntryName(base, uri) { if (uri.charAt(0) === "/") { return uri.substr(1); } else { // In general, we should check first and second for trailing and leading slashes, // but in our specific case this seems to be sufficient return base + "/" + uri; } } function replaceFragment(uri, fragment) { var hashIndex = uri.indexOf("#"); if (hashIndex !== -1) { uri = uri.substring(0, hashIndex); } return uri + "#" + fragment; } }, {}], 17: [function (require, module, exports) { var htmlPaths = require("../styles/html-paths"); function nonFreshElement(tagName, attributes, children) { return elementWithTag( htmlPaths.element(tagName, attributes, { fresh: false }), children); } function freshElement(tagName, attributes, children) { var tag = htmlPaths.element(tagName, attributes, { fresh: true }); return elementWithTag(tag, children); } function elementWithTag(tag, children) { return { type: "element", tag: tag, children: children || [] }; } function text(value) { return { type: "text", value: value }; } var forceWrite = { type: "forceWrite" }; exports.freshElement = freshElement; exports.nonFreshElement = nonFreshElement; exports.elementWithTag = elementWithTag; exports.text = text; exports.forceWrite = forceWrite; var voidTagNames = { "br": true, "hr": true, "img": true }; function isVoidElement(node) { return (node.children.length === 0) && voidTagNames[node.tag.tagName]; } exports.isVoidElement = isVoidElement; }, { "../styles/html-paths": 28 }], 18: [function (require, module, exports) { var ast = require("./ast"); exports.freshElement = ast.freshElement; exports.nonFreshElement = ast.nonFreshElement; exports.elementWithTag = ast.elementWithTag; exports.text = ast.text; exports.forceWrite = ast.forceWrite; exports.simplify = require("./simplify"); function write(writer, nodes) { nodes.forEach(function (node) { writeNode(writer, node); }); } function writeNode(writer, node) { toStrings[node.type](writer, node); } var toStrings = { element: generateElementString, text: generateTextString, forceWrite: function () { } }; function generateElementString(writer, node) { if (ast.isVoidElement(node)) { writer.selfClosing(node.tag.tagName, node.tag.attributes); } else { writer.open(node.tag.tagName, node.tag.attributes); write(writer, node.children); writer.close(node.tag.tagName); } } function generateTextString(writer, node) { writer.text(node.value); } exports.write = write; }, { "./ast": 17, "./simplify": 19 }], 19: [function (require, module, exports) { var _ = require("underscore"); var ast = require("./ast"); function simplify(nodes) { return collapse(removeEmpty(nodes)); } function collapse(nodes) { var children = []; nodes.map(collapseNode).forEach(function (child) { appendChild(children, child); }); return children; } function collapseNode(node) { return collapsers[node.type](node); } var collapsers = { element: collapseElement, text: identity, forceWrite: identity }; function collapseElement(node) { return ast.elementWithTag(node.tag, collapse(node.children)); } function identity(value) { return value; } function appendChild(children, child) { var lastChild = children[children.length - 1]; if (child.type === "element" && !child.tag.fresh && lastChild && lastChild.type === "element" && child.tag.matchesElement(lastChild.tag)) { if (child.tag.separator) { appendChild(lastChild.children, ast.text(child.tag.separator)); } child.children.forEach(function (grandChild) { // Mutation is fine since simplifying elements create a copy of the children. appendChild(lastChild.children, grandChild); }); } else { children.push(child); } } function removeEmpty(nodes) { return flatMap(nodes, function (node) { return emptiers[node.type](node); }); } function flatMap(values, func) { return _.flatten(_.map(values, func), true); } var emptiers = { element: elementEmptier, text: textEmptier, forceWrite: neverEmpty }; function neverEmpty(node) { return [node]; } function elementEmptier(element) { var children = removeEmpty(element.children); if (children.length === 0 && !ast.isVoidElement(element)) { return []; } else { return [ast.elementWithTag(element.tag, children)]; } } function textEmptier(node) { if (node.value.length === 0) { return []; } else { return [node]; } } module.exports = simplify; }, { "./ast": 17, "underscore": 103 }], 20: [function (require, module, exports) { var _ = require("underscore"); var promises = require("./promises"); var Html = require("./html"); exports.imgElement = imgElement; function imgElement(func) { return function (element, messages) { return promises.when(func(element)).then(function (result) { var attributes = {}; if (element.altText) { attributes.alt = element.altText; } _.extend(attributes, result); return [Html.freshElement("img", attributes)]; }); }; } // Undocumented, but retained for backwards-compatibility with 0.3.x exports.inline = exports.imgElement; exports.dataUri = imgElement(function (element) { return element.readAsBase64String().then(function (imageBuffer) { return { src: "data:" + element.contentType + ";base64," + imageBuffer }; }); }); }, { "./html": 18, "./promises": 23, "underscore": 103 }], 21: [function (require, module, exports) { (function (Buffer) { var _ = require("underscore"); var docxReader = require("./docx/docx-reader"); var docxStyleMap = require("./docx/style-map"); var DocumentConverter = require("./document-to-html").DocumentConverter; var convertElementToRawText = require("./raw-text").convertElementToRawText; var readStyle = require("./style-reader").readStyle; var readOptions = require("./options-reader").readOptions; var unzip = require("./unzip"); var Result = require("./results").Result; exports.convertToHtml = convertToHtml; exports.convertToMarkdown = convertToMarkdown; exports.convert = convert; exports.extractRawText = extractRawText; exports.images = require("./images"); exports.transforms = require("./transforms"); exports.underline = require("./underline"); exports.embedStyleMap = embedStyleMap; exports.readEmbeddedStyleMap = readEmbeddedStyleMap; function convertToHtml(input, options) { return convert(input, options); } function convertToMarkdown(input, options) { var markdownOptions = Object.create(options || {}); markdownOptions.outputFormat = "markdown"; return convert(input, markdownOptions); } function convert(input, options) { options = readOptions(options); return unzip.openZip(input) .tap(function (docxFile) { return docxStyleMap.readStyleMap(docxFile).then(function (styleMap) { options.embeddedStyleMap = styleMap; }); }) .then(function (docxFile) { return docxReader.read(docxFile, input) .then(function (documentResult) { return documentResult.map(options.transformDocument); }) .then(function (documentResult) { return convertDocumentToHtml(documentResult, options); }); }); } function readEmbeddedStyleMap(input) { return unzip.openZip(input) .then(docxStyleMap.readStyleMap); } function convertDocumentToHtml(documentResult, options) { var styleMapResult = parseStyleMap(options.readStyleMap()); var parsedOptions = _.extend({}, options, { styleMap: styleMapResult.value }); var documentConverter = new DocumentConverter(parsedOptions); return documentResult.flatMapThen(function (document) { return styleMapResult.flatMapThen(function (styleMap) { return documentConverter.convertToHtml(document); }); }); } function parseStyleMap(styleMap) { return Result.combine((styleMap || []).map(readStyle)) .map(function (styleMap) { return styleMap.filter(function (styleMapping) { return !!styleMapping; }); }); } function extractRawText(input) { return unzip.openZip(input) .then(docxReader.read) .then(function (documentResult) { return documentResult.map(convertElementToRawText); }); } function embedStyleMap(input, styleMap) { return unzip.openZip(input) .tap(function (docxFile) { return docxStyleMap.writeStyleMap(docxFile, styleMap); }) .then(function (docxFile) { return docxFile.toArrayBuffer(); }) .then(function (arrayBuffer) { return { toArrayBuffer: function () { return arrayBuffer; }, toBuffer: function () { return Buffer.from(arrayBuffer); } }; }); } exports.styleMapping = function () { throw new Error('Use a raw string instead of mammoth.styleMapping e.g. "p[style-name=\'Title\'] => h1" instead of mammoth.styleMapping("p[style-name=\'Title\'] => h1")'); }; }).call(this, require("buffer").Buffer) }, { "./document-to-html": 3, "./docx/docx-reader": 9, "./docx/style-map": 14, "./images": 20, "./options-reader": 22, "./raw-text": 24, "./results": 25, "./style-reader": 26, "./transforms": 30, "./underline": 31, "./unzip": 2, "buffer": 83, "underscore": 103 }], 22: [function (require, module, exports) { exports.readOptions = readOptions; var _ = require("underscore"); var defaultStyleMap = exports._defaultStyleMap = [ "p.Heading1 => h1:fresh", "p.Heading2 => h2:fresh", "p.Heading3 => h3:fresh", "p.Heading4 => h4:fresh", "p.Heading5 => h5:fresh", "p.Heading6 => h6:fresh", "p[style-name='Heading 1'] => h1:fresh", "p[style-name='Heading 2'] => h2:fresh", "p[style-name='Heading 3'] => h3:fresh", "p[style-name='Heading 4'] => h4:fresh", "p[style-name='Heading 5'] => h5:fresh", "p[style-name='Heading 6'] => h6:fresh", "p[style-name='heading 1'] => h1:fresh", "p[style-name='heading 2'] => h2:fresh", "p[style-name='heading 3'] => h3:fresh", "p[style-name='heading 4'] => h4:fresh", "p[style-name='heading 5'] => h5:fresh", "p[style-name='heading 6'] => h6:fresh", "r[style-name='Strong'] => strong", "p[style-name='footnote text'] => p:fresh", "r[style-name='footnote reference'] =>", "p[style-name='endnote text'] => p:fresh", "r[style-name='endnote reference'] =>", "p[style-name='annotation text'] => p:fresh", "r[style-name='annotation reference'] =>", // LibreOffice "p[style-name='Footnote'] => p:fresh", "r[style-name='Footnote anchor'] =>", "p[style-name='Endnote'] => p:fresh", "r[style-name='Endnote anchor'] =>", "p:unordered-list(1) => ul > li:fresh", "p:unordered-list(2) => ul|ol > li > ul > li:fresh", "p:unordered-list(3) => ul|ol > li > ul|ol > li > ul > li:fresh", "p:unordered-list(4) => ul|ol > li > ul|ol > li > ul|ol > li > ul > li:fresh", "p:unordered-list(5) => ul|ol > li > ul|ol > li > ul|ol > li > ul|ol > li > ul > li:fresh", "p:ordered-list(1) => ol > li:fresh", "p:ordered-list(2) => ul|ol > li > ol > li:fresh", "p:ordered-list(3) => ul|ol > li > ul|ol > li > ol > li:fresh", "p:ordered-list(4) => ul|ol > li > ul|ol > li > ul|ol > li > ol > li:fresh", "p:ordered-list(5) => ul|ol > li > ul|ol > li > ul|ol > li > ul|ol > li > ol > li:fresh", "r[style-name='Hyperlink'] =>", "p[style-name='Normal'] => p:fresh" ]; var standardOptions = exports._standardOptions = { transformDocument: identity, includeDefaultStyleMap: true, includeEmbeddedStyleMap: true }; function readOptions(options) { options = options || {}; return _.extend({}, standardOptions, options, { customStyleMap: readStyleMap(options.styleMap), readStyleMap: function () { var styleMap = this.customStyleMap; if (this.includeEmbeddedStyleMap) { styleMap = styleMap.concat(readStyleMap(this.embeddedStyleMap)); } if (this.includeDefaultStyleMap) { styleMap = styleMap.concat(defaultStyleMap); } return styleMap; } }); } function readStyleMap(styleMap) { if (!styleMap) { return []; } else if (_.isString(styleMap)) { return styleMap.split("\n") .map(function (line) { return line.trim(); }) .filter(function (line) { return line !== "" && line.charAt(0) !== "#"; }); } else { return styleMap; } } function identity(value) { return value; } }, { "underscore": 103 }], 23: [function (require, module, exports) { var _ = require("underscore"); var bluebird = require("bluebird/js/release/promise")(); exports.defer = defer; exports.when = bluebird.resolve; exports.resolve = bluebird.resolve; exports.all = bluebird.all; exports.props = bluebird.props; exports.reject = bluebird.reject; exports.promisify = bluebird.promisify; exports.mapSeries = bluebird.mapSeries; exports.attempt = bluebird.attempt; exports.nfcall = function (func) { var args = Array.prototype.slice.call(arguments, 1); var promisedFunc = bluebird.promisify(func); return promisedFunc.apply(null, args); }; bluebird.prototype.fail = bluebird.prototype.caught; bluebird.prototype.also = function (func) { return this.then(function (value) { var returnValue = _.extend({}, value, func(value)); return bluebird.props(returnValue); }); }; function defer() { var resolve; var reject; var promise = new bluebird.Promise(function (resolveArg, rejectArg) { resolve = resolveArg; reject = rejectArg; }); return { resolve: resolve, reject: reject, promise: promise }; } }, { "bluebird/js/release/promise": 68, "underscore": 103 }], 24: [function (require, module, exports) { var documents = require("./documents"); function convertElementToRawText(element) { if (element.type === "text") { return element.value; } else if (element.type === documents.types.tab) { return "\t"; } else { var tail = element.type === "paragraph" ? "\n\n" : ""; return (element.children || []).map(convertElementToRawText).join("") + tail; } } exports.convertElementToRawText = convertElementToRawText; }, { "./documents": 4 }], 25: [function (require, module, exports) { var _ = require("underscore"); exports.Result = Result; exports.success = success; exports.warning = warning; exports.error = error; function Result(value, messages) { this.value = value; this.messages = messages || []; } Result.prototype.map = function (func) { return new Result(func(this.value), this.messages); }; Result.prototype.flatMap = function (func) { var funcResult = func(this.value); return new Result(funcResult.value, combineMessages([this, funcResult])); }; Result.prototype.flatMapThen = function (func) { var that = this; return func(this.value).then(function (otherResult) { return new Result(otherResult.value, combineMessages([that, otherResult])); }); }; Result.combine = function (results) { var values = _.flatten(_.pluck(results, "value")); var messages = combineMessages(results); return new Result(values, messages); }; function success(value) { return new Result(value, []); } function warning(message) { return { type: "warning", message: message }; } function error(exception) { return { type: "error", message: exception.message, error: exception }; } function combineMessages(results) { var messages = []; _.flatten(_.pluck(results, "messages"), true).forEach(function (message) { if (!containsMessage(messages, message)) { messages.push(message); } }); return messages; } function containsMessage(messages, message) { return _.find(messages, isSameMessage.bind(null, message)) !== undefined; } function isSameMessage(first, second) { return first.type === second.type && first.message === second.message; } }, { "underscore": 103 }], 26: [function (require, module, exports) { var _ = require("underscore"); var lop = require("lop"); var documentMatchers = require("./styles/document-matchers"); var htmlPaths = require("./styles/html-paths"); var tokenise = require("./styles/parser/tokeniser").tokenise; var results = require("./results"); exports.readHtmlPath = readHtmlPath; exports.readDocumentMatcher = readDocumentMatcher; exports.readStyle = readStyle; function readStyle(string) { return parseString(styleRule, string); } function createStyleRule() { return lop.rules.sequence( lop.rules.sequence.capture(documentMatcherRule()), lop.rules.tokenOfType("whitespace"), lop.rules.tokenOfType("arrow"), lop.rules.sequence.capture(lop.rules.optional(lop.rules.sequence( lop.rules.tokenOfType("whitespace"), lop.rules.sequence.capture(htmlPathRule()) ).head())), lop.rules.tokenOfType("end") ).map(function (documentMatcher, htmlPath) { return { from: documentMatcher, to: htmlPath.valueOrElse(htmlPaths.empty) }; }); } function readDocumentMatcher(string) { return parseString(documentMatcherRule(), string); } function documentMatcherRule() { var sequence = lop.rules.sequence; var identifierToConstant = function (identifier, constant) { return lop.rules.then( lop.rules.token("identifier", identifier), function () { return constant; } ); }; var paragraphRule = identifierToConstant("p", documentMatchers.paragraph); var runRule = identifierToConstant("r", documentMatchers.run); var elementTypeRule = lop.rules.firstOf("p or r or table", paragraphRule, runRule ); var styleIdRule = lop.rules.then( classRule, function (styleId) { return { styleId: styleId }; } ); var styleNameMatcherRule = lop.rules.firstOf("style name matcher", lop.rules.then( lop.rules.sequence( lop.rules.tokenOfType("equals"), lop.rules.sequence.cut(), lop.rules.sequence.capture(stringRule) ).head(), function (styleName) { return { styleName: documentMatchers.equalTo(styleName) }; } ), lop.rules.then( lop.rules.sequence( lop.rules.tokenOfType("startsWith"), lop.rules.sequence.cut(), lop.rules.sequence.capture(stringRule) ).head(), function (styleName) { return { styleName: documentMatchers.startsWith(styleName) }; } ) ); var styleNameRule = lop.rules.sequence( lop.rules.tokenOfType("open-square-bracket"), lop.rules.sequence.cut(), lop.rules.token("identifier", "style-name"), lop.rules.sequence.capture(styleNameMatcherRule), lop.rules.tokenOfType("close-square-bracket") ).head(); var listTypeRule = lop.rules.firstOf("list type", identifierToConstant("ordered-list", { isOrdered: true }), identifierToConstant("unordered-list", { isOrdered: false }) ); var listRule = sequence( lop.rules.tokenOfType("colon"), sequence.capture(listTypeRule), sequence.cut(), lop.rules.tokenOfType("open-paren"), sequence.capture(integerRule), lop.rules.tokenOfType("close-paren") ).map(function (listType, levelNumber) { return { list: { isOrdered: listType.isOrdered, levelIndex: levelNumber - 1 } }; }); function createMatcherSuffixesRule(rules) { var matcherSuffix = lop.rules.firstOf.apply( lop.rules.firstOf, ["matcher suffix"].concat(rules) ); var matcherSuffixes = lop.rules.zeroOrMore(matcherSuffix); return lop.rules.then(matcherSuffixes, function (suffixes) { var matcherOptions = {}; suffixes.forEach(function (suffix) { _.extend(matcherOptions, suffix); }); return matcherOptions; }); } var paragraphOrRun = sequence( sequence.capture(elementTypeRule), sequence.capture(createMatcherSuffixesRule([ styleIdRule, styleNameRule, listRule ])) ).map(function (createMatcher, matcherOptions) { return createMatcher(matcherOptions); }); var table = sequence( lop.rules.token("identifier", "table"), sequence.capture(createMatcherSuffixesRule([ styleIdRule, styleNameRule ])) ).map(function (options) { return documentMatchers.table(options); }); var bold = identifierToConstant("b", documentMatchers.bold); var italic = identifierToConstant("i", documentMatchers.italic); var underline = identifierToConstant("u", documentMatchers.underline); var strikethrough = identifierToConstant("strike", documentMatchers.strikethrough); var allCaps = identifierToConstant("all-caps", documentMatchers.allCaps); var smallCaps = identifierToConstant("small-caps", documentMatchers.smallCaps); var commentReference = identifierToConstant("comment-reference", documentMatchers.commentReference); var breakMatcher = sequence( lop.rules.token("identifier", "br"), sequence.cut(), lop.rules.tokenOfType("open-square-bracket"), lop.rules.token("identifier", "type"), lop.rules.tokenOfType("equals"), sequence.capture(stringRule), lop.rules.tokenOfType("close-square-bracket") ).map(function (breakType) { switch (breakType) { case "line": return documentMatchers.lineBreak; case "page": return documentMatchers.pageBreak; case "column": return documentMatchers.columnBreak; default: // TODO: handle unknown document matchers } }); return lop.rules.firstOf("element type", paragraphOrRun, table, bold, italic, underline, strikethrough, allCaps, smallCaps, commentReference, breakMatcher ); } function readHtmlPath(string) { return parseString(htmlPathRule(), string); } function htmlPathRule() { var capture = lop.rules.sequence.capture; var whitespaceRule = lop.rules.tokenOfType("whitespace"); var freshRule = lop.rules.then( lop.rules.optional(lop.rules.sequence( lop.rules.tokenOfType("colon"), lop.rules.token("identifier", "fresh") )), function (option) { return option.map(function () { return true; }).valueOrElse(false); } ); var separatorRule = lop.rules.then( lop.rules.optional(lop.rules.sequence( lop.rules.tokenOfType("colon"), lop.rules.token("identifier", "separator"), lop.rules.tokenOfType("open-paren"), capture(stringRule), lop.rules.tokenOfType("close-paren") ).head()), function (option) { return option.valueOrElse(""); } ); var tagNamesRule = lop.rules.oneOrMoreWithSeparator( identifierRule, lop.rules.tokenOfType("choice") ); var styleElementRule = lop.rules.sequence( capture(tagNamesRule), capture(lop.rules.zeroOrMore(classRule)), capture(freshRule), capture(separatorRule) ).map(function (tagName, classNames, fresh, separator) { var attributes = {}; var options = {}; if (classNames.length > 0) { attributes["class"] = classNames.join(" "); } if (fresh) { options.fresh = true; } if (separator) { options.separator = separator; } return htmlPaths.element(tagName, attributes, options); }); return lop.rules.firstOf("html path", lop.rules.then(lop.rules.tokenOfType("bang"), function () { return htmlPaths.ignore; }), lop.rules.then( lop.rules.zeroOrMoreWithSeparator( styleElementRule, lop.rules.sequence( whitespaceRule, lop.rules.tokenOfType("gt"), whitespaceRule ) ), htmlPaths.elements ) ); } var identifierRule = lop.rules.then( lop.rules.tokenOfType("identifier"), decodeEscapeSequences ); var integerRule = lop.rules.tokenOfType("integer"); var stringRule = lop.rules.then( lop.rules.tokenOfType("string"), decodeEscapeSequences ); var escapeSequences = { "n": "\n", "r": "\r", "t": "\t" }; function decodeEscapeSequences(value) { return value.replace(/\\(.)/g, function (match, code) { return escapeSequences[code] || code; }); } var classRule = lop.rules.sequence( lop.rules.tokenOfType("dot"), lop.rules.sequence.cut(), lop.rules.sequence.capture(identifierRule) ).head(); function parseString(rule, string) { var tokens = tokenise(string); var parser = lop.Parser(); var parseResult = parser.parseTokens(rule, tokens); if (parseResult.isSuccess()) { return results.success(parseResult.value()); } else { return new results.Result(null, [results.warning(describeFailure(string, parseResult))]); } } function describeFailure(input, parseResult) { return "Did not understand this style mapping, so ignored it: " + input + "\n" + parseResult.errors().map(describeError).join("\n"); } function describeError(error) { return "Error was at character number " + error.characterNumber() + ": " + "Expected " + error.expected + " but got " + error.actual; } var styleRule = createStyleRule(); }, { "./results": 25, "./styles/document-matchers": 27, "./styles/html-paths": 28, "./styles/parser/tokeniser": 29, "lop": 89, "underscore": 103 }], 27: [function (require, module, exports) { exports.paragraph = paragraph; exports.run = run; exports.table = table; exports.bold = new Matcher("bold"); exports.italic = new Matcher("italic"); exports.underline = new Matcher("underline"); exports.strikethrough = new Matcher("strikethrough"); exports.allCaps = new Matcher("allCaps"); exports.smallCaps = new Matcher("smallCaps"); exports.commentReference = new Matcher("commentReference"); exports.lineBreak = new Matcher("break", { breakType: "line" }); exports.pageBreak = new Matcher("break", { breakType: "page" }); exports.columnBreak = new Matcher("break", { breakType: "column" }); exports.equalTo = equalTo; exports.startsWith = startsWith; function paragraph(options) { return new Matcher("paragraph", options); } function run(options) { return new Matcher("run", options); } function table(options) { return new Matcher("table", options); } function Matcher(elementType, options) { options = options || {}; this._elementType = elementType; this._styleId = options.styleId; this._styleName = options.styleName; if (options.list) { this._listIndex = options.list.levelIndex; this._listIsOrdered = options.list.isOrdered; } } Matcher.prototype.matches = function (element) { return element.type === this._elementType && (this._styleId === undefined || element.styleId === this._styleId) && (this._styleName === undefined || (element.styleName && this._styleName.operator(this._styleName.operand, element.styleName))) && (this._listIndex === undefined || isList(element, this._listIndex, this._listIsOrdered)) && (this._breakType === undefined || this._breakType === element.breakType); }; function isList(element, levelIndex, isOrdered) { return element.numbering && element.numbering.level == levelIndex && element.numbering.isOrdered == isOrdered; } function equalTo(value) { return { operator: operatorEqualTo, operand: value }; } function startsWith(value) { return { operator: operatorStartsWith, operand: value }; } function operatorEqualTo(first, second) { return first.toUpperCase() === second.toUpperCase(); } function operatorStartsWith(first, second) { return second.toUpperCase().indexOf(first.toUpperCase()) === 0; } }, {}], 28: [function (require, module, exports) { var _ = require("underscore"); var html = require("../html"); exports.topLevelElement = topLevelElement; exports.elements = elements; exports.element = element; function topLevelElement(tagName, attributes) { return elements([element(tagName, attributes, { fresh: true })]); } function elements(elementStyles) { return new HtmlPath(elementStyles.map(function (elementStyle) { if (_.isString(elementStyle)) { return element(elementStyle); } else { return elementStyle; } })); } function HtmlPath(elements) { this._elements = elements; } HtmlPath.prototype.wrap = function wrap(children) { var result = children(); for (var index = this._elements.length - 1; index >= 0; index--) { result = this._elements[index].wrapNodes(result); } return result; }; function element(tagName, attributes, options) { options = options || {}; return new Element(tagName, attributes, options); } function Element(tagName, attributes, options) { var tagNames = {}; if (_.isArray(tagName)) { tagName.forEach(function (tagName) { tagNames[tagName] = true; }); tagName = tagName[0]; } else { tagNames[tagName] = true; } this.tagName = tagName; this.tagNames = tagNames; this.attributes = attributes || {}; this.fresh = options.fresh; this.separator = options.separator; } Element.prototype.matchesElement = function (element) { return this.tagNames[element.tagName] && _.isEqual(this.attributes || {}, element.attributes || {}); }; Element.prototype.wrap = function wrap(generateNodes) { return this.wrapNodes(generateNodes()); }; Element.prototype.wrapNodes = function wrapNodes(nodes) { return [html.elementWithTag(this, nodes)]; }; exports.empty = elements([]); exports.ignore = { wrap: function () { return []; } }; }, { "../html": 18, "underscore": 103 }], 29: [function (require, module, exports) { var lop = require("lop"); var RegexTokeniser = lop.RegexTokeniser; exports.tokenise = tokenise; var stringPrefix = "'((?:\\\\.|[^'])*)"; function tokenise(string) { var identifierCharacter = "(?:[a-zA-Z\\-_]|\\\\.)"; var tokeniser = new RegexTokeniser([ { name: "identifier", regex: new RegExp("(" + identifierCharacter + "(?:" + identifierCharacter + "|[0-9])*)") }, { name: "dot", regex: /\./ }, { name: "colon", regex: /:/ }, { name: "gt", regex: />/ }, { name: "whitespace", regex: /\s+/ }, { name: "arrow", regex: /=>/ }, { name: "equals", regex: /=/ }, { name: "startsWith", regex: /\^=/ }, { name: "open-paren", regex: /\(/ }, { name: "close-paren", regex: /\)/ }, { name: "open-square-bracket", regex: /\[/ }, { name: "close-square-bracket", regex: /\]/ }, { name: "string", regex: new RegExp(stringPrefix + "'") }, { name: "unterminated-string", regex: new RegExp(stringPrefix) }, { name: "integer", regex: /([0-9]+)/ }, { name: "choice", regex: /\|/ }, { name: "bang", regex: /(!)/ } ]); return tokeniser.tokenise(string); } }, { "lop": 89 }], 30: [function (require, module, exports) { var _ = require("underscore"); exports.paragraph = paragraph; exports.run = run; exports._elements = elements; exports.getDescendantsOfType = getDescendantsOfType; exports.getDescendants = getDescendants; function paragraph(transform) { return elementsOfType("paragraph", transform); } function run(transform) { return elementsOfType("run", transform); } function elementsOfType(elementType, transform) { return elements(function (element) { if (element.type === elementType) { return transform(element); } else { return element; } }); } function elements(transform) { return function transformElement(element) { if (element.children) { var children = _.map(element.children, transformElement); element = _.extend(element, { children: children }); } return transform(element); }; } function getDescendantsOfType(element, type) { return getDescendants(element).filter(function (descendant) { return descendant.type === type; }); } function getDescendants(element) { var descendants = []; visitDescendants(element, function (descendant) { descendants.push(descendant); }); return descendants; } function visitDescendants(element, visit) { if (element.children) { element.children.forEach(function (child) { visitDescendants(child, visit); visit(child); }); } } }, { "underscore": 103 }], 31: [function (require, module, exports) { var htmlPaths = require("./styles/html-paths"); var Html = require("./html"); exports.element = element; function element(name) { return function (html) { return Html.elementWithTag(htmlPaths.element(name), [html]); }; } }, { "./html": 18, "./styles/html-paths": 28 }], 32: [function (require, module, exports) { var _ = require("underscore"); exports.writer = writer; function writer(options) { options = options || {}; if (options.prettyPrint) { return prettyWriter(); } else { return simpleWriter(); } } var indentedElements = { div: true, p: true, ul: true, li: true }; function prettyWriter() { var indentationLevel = 0; var indentation = " "; var stack = []; var start = true; var inText = false; var writer = simpleWriter(); function open(tagName, attributes) { if (indentedElements[tagName]) { indent(); } stack.push(tagName); writer.open(tagName, attributes); if (indentedElements[tagName]) { indentationLevel++; } start = false; } function close(tagName) { if (indentedElements[tagName]) { indentationLevel--; indent(); } stack.pop(); writer.close(tagName); } function text(value) { startText(); var text = isInPre() ? value : value.replace("\n", "\n" + indentation); writer.text(text); } function selfClosing(tagName, attributes) { indent(); writer.selfClosing(tagName, attributes); } function insideIndentedElement() { return stack.length === 0 || indentedElements[stack[stack.length - 1]]; } function startText() { if (!inText) { indent(); inText = true; } } function indent() { inText = false; if (!start && insideIndentedElement() && !isInPre()) { writer._append("\n"); for (var i = 0; i < indentationLevel; i++) { writer._append(indentation); } } } function isInPre() { return _.some(stack, function (tagName) { return tagName === "pre"; }); } return { asString: writer.asString, open: open, close: close, text: text, selfClosing: selfClosing }; } function simpleWriter() { var fragments = []; function open(tagName, attributes) { var attributeString = generateAttributeString(attributes); fragments.push("<" + tagName + attributeString + ">"); } function close(tagName) { fragments.push(""); } function selfClosing(tagName, attributes) { var attributeString = generateAttributeString(attributes); fragments.push("<" + tagName + attributeString + " />"); } function generateAttributeString(attributes) { return _.map(attributes, function (value, key) { return " " + key + '="' + escapeHtmlAttribute(value) + '"'; }).join(""); } function text(value) { fragments.push(escapeHtmlText(value)); } function append(html) { fragments.push(html); } function asString() { return fragments.join(""); } return { asString: asString, open: open, close: close, text: text, selfClosing: selfClosing, _append: append }; } function escapeHtmlText(value) { return value .replace(/&/g, '&') .replace(//g, '>'); } function escapeHtmlAttribute(value) { return value .replace(/&/g, '&') .replace(/"/g, '"') .replace(//g, '>'); } }, { "underscore": 103 }], 33: [function (require, module, exports) { var htmlWriter = require("./html-writer"); var markdownWriter = require("./markdown-writer"); exports.writer = writer; function writer(options) { options = options || {}; if (options.outputFormat === "markdown") { return markdownWriter.writer(); } else { return htmlWriter.writer(options); } } }, { "./html-writer": 32, "./markdown-writer": 34 }], 34: [function (require, module, exports) { var _ = require("underscore"); function symmetricMarkdownElement(end) { return markdownElement(end, end); } function markdownElement(start, end) { return function () { return { start: start, end: end }; }; } function markdownLink(attributes) { var href = attributes.href || ""; if (href) { return { start: "[", end: "](" + href + ")", anchorPosition: "before" }; } else { return {}; } } function markdownImage(attributes) { var src = attributes.src || ""; var altText = attributes.alt || ""; if (src || altText) { return { start: "![" + altText + "](" + src + ")" }; } else { return {}; } } function markdownList(options) { return function (attributes, list) { return { start: list ? "\n" : "", end: list ? "" : "\n", list: { isOrdered: options.isOrdered, indent: list ? list.indent + 1 : 0, count: 0 } }; }; } function markdownListItem(attributes, list, listItem) { list = list || { indent: 0, isOrdered: false, count: 0 }; list.count++; listItem.hasClosed = false; var bullet = list.isOrdered ? list.count + "." : "-"; var start = repeatString("\t", list.indent) + bullet + " "; return { start: start, end: function () { if (!listItem.hasClosed) { listItem.hasClosed = true; return "\n"; } } }; } var htmlToMarkdown = { "p": markdownElement("", "\n\n"), "br": markdownElement("", " \n"), "ul": markdownList({ isOrdered: false }), "ol": markdownList({ isOrdered: true }), "li": markdownListItem, "strong": symmetricMarkdownElement("__"), "em": symmetricMarkdownElement("*"), "a": markdownLink, "img": markdownImage }; (function () { for (var i = 1; i <= 6; i++) { htmlToMarkdown["h" + i] = markdownElement(repeatString("#", i) + " ", "\n\n"); } })(); function repeatString(value, count) { return new Array(count + 1).join(value); } function markdownWriter() { var fragments = []; var elementStack = []; var list = null; var listItem = {}; function open(tagName, attributes) { attributes = attributes || {}; var createElement = htmlToMarkdown[tagName] || function () { return {}; }; var element = createElement(attributes, list, listItem); elementStack.push({ end: element.end, list: list }); if (element.list) { list = element.list; } var anchorBeforeStart = element.anchorPosition === "before"; if (anchorBeforeStart) { writeAnchor(attributes); } fragments.push(element.start || ""); if (!anchorBeforeStart) { writeAnchor(attributes); } } function writeAnchor(attributes) { if (attributes.id) { fragments.push(''); } } function close(tagName) { var element = elementStack.pop(); list = element.list; var end = _.isFunction(element.end) ? element.end() : element.end; fragments.push(end || ""); } function selfClosing(tagName, attributes) { open(tagName, attributes); close(tagName); } function text(value) { fragments.push(escapeMarkdown(value)); } function asString() { return fragments.join(""); } return { asString: asString, open: open, close: close, text: text, selfClosing: selfClosing }; } exports.writer = markdownWriter; function escapeMarkdown(value) { return value .replace(/\\/g, '\\\\') .replace(/([\`\*_\{\}\[\]\(\)\#\+\-\.\!])/g, '\\$1'); } }, { "underscore": 103 }], 35: [function (require, module, exports) { var nodes = require("./nodes"); exports.Element = nodes.Element; exports.element = nodes.element; exports.text = nodes.text; exports.readString = require("./reader").readString; exports.writeString = require("./writer").writeString; }, { "./nodes": 36, "./reader": 37, "./writer": 38 }], 36: [function (require, module, exports) { var _ = require("underscore"); exports.Element = Element; exports.element = function (name, attributes, children) { return new Element(name, attributes, children); }; exports.text = function (value) { return { type: "text", value: value }; }; var emptyElement = { first: function () { return null; }, firstOrEmpty: function () { return emptyElement; }, attributes: {} }; function Element(name, attributes, children) { this.type = "element"; this.name = name; this.attributes = attributes || {}; this.children = children || []; } Element.prototype.first = function (name) { return _.find(this.children, function (child) { return child.name === name; }); }; Element.prototype.firstOrEmpty = function (name) { return this.first(name) || emptyElement; }; Element.prototype.getElementsByTagName = function (name) { var elements = _.filter(this.children, function (child) { return child.name === name; }); return toElementList(elements); }; Element.prototype.text = function () { if (this.children.length === 0) { return ""; } else if (this.children.length !== 1 || this.children[0].type !== "text") { throw new Error("Not implemented"); } return this.children[0].value; }; var elementListPrototype = { getElementsByTagName: function (name) { return toElementList(_.flatten(this.map(function (element) { return element.getElementsByTagName(name); }, true))); } }; function toElementList(array) { return _.extend(array, elementListPrototype); } }, { "underscore": 103 }], 37: [function (require, module, exports) { var promises = require("../promises"); var _ = require("underscore"); var xmldom = require("./xmldom"); var nodes = require("./nodes"); var Element = nodes.Element; exports.readString = readString; var Node = xmldom.Node; function readString(xmlString, namespaceMap) { namespaceMap = namespaceMap || {}; try { var document = xmldom.parseFromString(xmlString, "text/xml"); } catch (error) { return promises.reject(error); } if (document.documentElement.tagName === "parsererror") { return promises.resolve(new Error(document.documentElement.textContent)); } function convertNode(node) { switch (node.nodeType) { case Node.ELEMENT_NODE: return convertElement(node); case Node.TEXT_NODE: return nodes.text(node.nodeValue); } } function convertElement(element) { var convertedName = convertName(element); var convertedChildren = []; _.forEach(element.childNodes, function (childNode) { var convertedNode = convertNode(childNode); if (convertedNode) { convertedChildren.push(convertedNode); } }); var convertedAttributes = {}; _.forEach(element.attributes, function (attribute) { convertedAttributes[convertName(attribute)] = attribute.value; }); return new Element(convertedName, convertedAttributes, convertedChildren); } function convertName(node) { if (node.namespaceURI) { var mappedPrefix = namespaceMap[node.namespaceURI]; var prefix; if (mappedPrefix) { prefix = mappedPrefix + ":"; } else { prefix = "{" + node.namespaceURI + "}"; } return prefix + node.localName; } else { return node.localName; } } return promises.resolve(convertNode(document.documentElement)); } }, { "../promises": 23, "./nodes": 36, "./xmldom": 39, "underscore": 103 }], 38: [function (require, module, exports) { var _ = require("underscore"); var xmlbuilder = require("xmlbuilder"); exports.writeString = writeString; function writeString(root, namespaces) { var uriToPrefix = _.invert(namespaces); var nodeWriters = { element: writeElement, text: writeTextNode }; function writeNode(builder, node) { return nodeWriters[node.type](builder, node); } function writeElement(builder, element) { var elementBuilder = builder.element(mapElementName(element.name), element.attributes); element.children.forEach(function (child) { writeNode(elementBuilder, child); }); } function mapElementName(name) { var longFormMatch = /^\{(.*)\}(.*)$/.exec(name); if (longFormMatch) { var prefix = uriToPrefix[longFormMatch[1]]; return prefix + (prefix === "" ? "" : ":") + longFormMatch[2]; } else { return name; } } function writeDocument(root) { var builder = xmlbuilder .create(mapElementName(root.name), { version: '1.0', encoding: 'UTF-8', standalone: true }); _.forEach(namespaces, function (uri, prefix) { var key = "xmlns" + (prefix === "" ? "" : ":" + prefix); builder.attribute(key, uri); }); root.children.forEach(function (child) { writeNode(builder, child); }); return builder.end(); } return writeDocument(root); } function writeTextNode(builder, node) { builder.text(node.value); } }, { "underscore": 103, "xmlbuilder": 128 }], 39: [function (require, module, exports) { var xmldom = require("@xmldom/xmldom"); var dom = require("@xmldom/xmldom/lib/dom"); function parseFromString(string) { var error = null; var domParser = new xmldom.DOMParser({ errorHandler: function (level, message) { error = { level: level, message: message }; } }); var document = domParser.parseFromString(string); if (error === null) { return document; } else { throw new Error(error.level + ": " + error.message); } } exports.parseFromString = parseFromString; exports.Node = dom.Node; }, { "@xmldom/xmldom": 45, "@xmldom/xmldom/lib/dom": 43 }], 40: [function (require, module, exports) { var base64js = require("base64-js"); var JSZip = require("jszip"); exports.openArrayBuffer = openArrayBuffer; exports.splitPath = splitPath; exports.joinPath = joinPath; function openArrayBuffer(arrayBuffer) { return JSZip.loadAsync(arrayBuffer).then(function (zipFile) { function exists(name) { return zipFile.file(name) !== null; } function read(name, encoding) { return zipFile.file(name).async("uint8array").then(function (array) { if (encoding === "base64") { return base64js.fromByteArray(array); } else if (encoding) { var decoder = new TextDecoder(encoding); return decoder.decode(array); } else { return array; } }); } function write(name, contents) { zipFile.file(name, contents); } function toArrayBuffer() { return zipFile.generateAsync({ type: "arraybuffer" }); } return { exists: exists, read: read, write: write, toArrayBuffer: toArrayBuffer }; }); } function splitPath(path) { var lastIndex = path.lastIndexOf("/"); if (lastIndex === -1) { return { dirname: "", basename: path }; } else { return { dirname: path.substring(0, lastIndex), basename: path.substring(lastIndex + 1) }; } } function joinPath() { var nonEmptyPaths = Array.prototype.filter.call(arguments, function (path) { return path; }); var relevantPaths = []; nonEmptyPaths.forEach(function (path) { if (/^\//.test(path)) { relevantPaths = [path]; } else { relevantPaths.push(path); } }); return relevantPaths.join("/"); } }, { "base64-js": 47, "jszip": 88 }], 41: [function (require, module, exports) { 'use strict' /** * Ponyfill for `Array.prototype.find` which is only available in ES6 runtimes. * * Works with anything that has a `length` property and index access properties, including NodeList. * * @template {unknown} T * @param {Array | ({length:number, [number]: T})} list * @param {function (item: T, index: number, list:Array | ({length:number, [number]: T})):boolean} predicate * @param {Partial>?} ac `Array.prototype` by default, * allows injecting a custom implementation in tests * @returns {T | undefined} * * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find * @see https://tc39.es/ecma262/multipage/indexed-collections.html#sec-array.prototype.find */ function find(list, predicate, ac) { if (ac === undefined) { ac = Array.prototype; } if (list && typeof ac.find === 'function') { return ac.find.call(list, predicate); } for (var i = 0; i < list.length; i++) { if (Object.prototype.hasOwnProperty.call(list, i)) { var item = list[i]; if (predicate.call(undefined, item, i, list)) { return item; } } } } /** * "Shallow freezes" an object to render it immutable. * Uses `Object.freeze` if available, * otherwise the immutability is only in the type. * * Is used to create "enum like" objects. * * @template T * @param {T} object the object to freeze * @param {Pick = Object} oc `Object` by default, * allows to inject custom object constructor for tests * @returns {Readonly} * * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze */ function freeze(object, oc) { if (oc === undefined) { oc = Object } return oc && typeof oc.freeze === 'function' ? oc.freeze(object) : object } /** * Since we can not rely on `Object.assign` we provide a simplified version * that is sufficient for our needs. * * @param {Object} target * @param {Object | null | undefined} source * * @returns {Object} target * @throws TypeError if target is not an object * * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign * @see https://tc39.es/ecma262/multipage/fundamental-objects.html#sec-object.assign */ function assign(target, source) { if (target === null || typeof target !== 'object') { throw new TypeError('target is not an object') } for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key] } } return target } /** * All mime types that are allowed as input to `DOMParser.parseFromString` * * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMParser/parseFromString#Argument02 MDN * @see https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#domparsersupportedtype WHATWG HTML Spec * @see DOMParser.prototype.parseFromString */ var MIME_TYPE = freeze({ /** * `text/html`, the only mime type that triggers treating an XML document as HTML. * * @see DOMParser.SupportedType.isHTML * @see https://www.iana.org/assignments/media-types/text/html IANA MimeType registration * @see https://en.wikipedia.org/wiki/HTML Wikipedia * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMParser/parseFromString MDN * @see https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#dom-domparser-parsefromstring WHATWG HTML Spec */ HTML: 'text/html', /** * Helper method to check a mime type if it indicates an HTML document * * @param {string} [value] * @returns {boolean} * * @see https://www.iana.org/assignments/media-types/text/html IANA MimeType registration * @see https://en.wikipedia.org/wiki/HTML Wikipedia * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMParser/parseFromString MDN * @see https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#dom-domparser-parsefromstring */ isHTML: function (value) { return value === MIME_TYPE.HTML }, /** * `application/xml`, the standard mime type for XML documents. * * @see https://www.iana.org/assignments/media-types/application/xml IANA MimeType registration * @see https://tools.ietf.org/html/rfc7303#section-9.1 RFC 7303 * @see https://en.wikipedia.org/wiki/XML_and_MIME Wikipedia */ XML_APPLICATION: 'application/xml', /** * `text/html`, an alias for `application/xml`. * * @see https://tools.ietf.org/html/rfc7303#section-9.2 RFC 7303 * @see https://www.iana.org/assignments/media-types/text/xml IANA MimeType registration * @see https://en.wikipedia.org/wiki/XML_and_MIME Wikipedia */ XML_TEXT: 'text/xml', /** * `application/xhtml+xml`, indicates an XML document that has the default HTML namespace, * but is parsed as an XML document. * * @see https://www.iana.org/assignments/media-types/application/xhtml+xml IANA MimeType registration * @see https://dom.spec.whatwg.org/#dom-domimplementation-createdocument WHATWG DOM Spec * @see https://en.wikipedia.org/wiki/XHTML Wikipedia */ XML_XHTML_APPLICATION: 'application/xhtml+xml', /** * `image/svg+xml`, * * @see https://www.iana.org/assignments/media-types/image/svg+xml IANA MimeType registration * @see https://www.w3.org/TR/SVG11/ W3C SVG 1.1 * @see https://en.wikipedia.org/wiki/Scalable_Vector_Graphics Wikipedia */ XML_SVG_IMAGE: 'image/svg+xml', }) /** * Namespaces that are used in this code base. * * @see http://www.w3.org/TR/REC-xml-names */ var NAMESPACE = freeze({ /** * The XHTML namespace. * * @see http://www.w3.org/1999/xhtml */ HTML: 'http://www.w3.org/1999/xhtml', /** * Checks if `uri` equals `NAMESPACE.HTML`. * * @param {string} [uri] * * @see NAMESPACE.HTML */ isHTML: function (uri) { return uri === NAMESPACE.HTML }, /** * The SVG namespace. * * @see http://www.w3.org/2000/svg */ SVG: 'http://www.w3.org/2000/svg', /** * The `xml:` namespace. * * @see http://www.w3.org/XML/1998/namespace */ XML: 'http://www.w3.org/XML/1998/namespace', /** * The `xmlns:` namespace * * @see https://www.w3.org/2000/xmlns/ */ XMLNS: 'http://www.w3.org/2000/xmlns/', }) exports.assign = assign; exports.find = find; exports.freeze = freeze; exports.MIME_TYPE = MIME_TYPE; exports.NAMESPACE = NAMESPACE; }, {}], 42: [function (require, module, exports) { var conventions = require("./conventions"); var dom = require('./dom') var entities = require('./entities'); var sax = require('./sax'); var DOMImplementation = dom.DOMImplementation; var NAMESPACE = conventions.NAMESPACE; var ParseError = sax.ParseError; var XMLReader = sax.XMLReader; /** * Normalizes line ending according to https://www.w3.org/TR/xml11/#sec-line-ends: * * > XML parsed entities are often stored in computer files which, * > for editing convenience, are organized into lines. * > These lines are typically separated by some combination * > of the characters CARRIAGE RETURN (#xD) and LINE FEED (#xA). * > * > To simplify the tasks of applications, the XML processor must behave * > as if it normalized all line breaks in external parsed entities (including the document entity) * > on input, before parsing, by translating all of the following to a single #xA character: * > * > 1. the two-character sequence #xD #xA * > 2. the two-character sequence #xD #x85 * > 3. the single character #x85 * > 4. the single character #x2028 * > 5. any #xD character that is not immediately followed by #xA or #x85. * * @param {string} input * @returns {string} */ function normalizeLineEndings(input) { return input .replace(/\r[\n\u0085]/g, '\n') .replace(/[\r\u0085\u2028]/g, '\n') } /** * @typedef Locator * @property {number} [columnNumber] * @property {number} [lineNumber] */ /** * @typedef DOMParserOptions * @property {DOMHandler} [domBuilder] * @property {Function} [errorHandler] * @property {(string) => string} [normalizeLineEndings] used to replace line endings before parsing * defaults to `normalizeLineEndings` * @property {Locator} [locator] * @property {Record} [xmlns] * * @see normalizeLineEndings */ /** * The DOMParser interface provides the ability to parse XML or HTML source code * from a string into a DOM `Document`. * * _xmldom is different from the spec in that it allows an `options` parameter, * to override the default behavior._ * * @param {DOMParserOptions} [options] * @constructor * * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMParser * @see https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#dom-parsing-and-serialization */ function DOMParser(options) { this.options = options || { locator: {} }; } DOMParser.prototype.parseFromString = function (source, mimeType) { var options = this.options; var sax = new XMLReader(); var domBuilder = options.domBuilder || new DOMHandler();//contentHandler and LexicalHandler var errorHandler = options.errorHandler; var locator = options.locator; var defaultNSMap = options.xmlns || {}; var isHTML = /\/x?html?$/.test(mimeType);//mimeType.toLowerCase().indexOf('html') > -1; var entityMap = isHTML ? entities.HTML_ENTITIES : entities.XML_ENTITIES; if (locator) { domBuilder.setDocumentLocator(locator) } sax.errorHandler = buildErrorHandler(errorHandler, domBuilder, locator); sax.domBuilder = options.domBuilder || domBuilder; if (isHTML) { defaultNSMap[''] = NAMESPACE.HTML; } defaultNSMap.xml = defaultNSMap.xml || NAMESPACE.XML; var normalize = options.normalizeLineEndings || normalizeLineEndings; if (source && typeof source === 'string') { sax.parse( normalize(source), defaultNSMap, entityMap ) } else { sax.errorHandler.error('invalid doc source') } return domBuilder.doc; } function buildErrorHandler(errorImpl, domBuilder, locator) { if (!errorImpl) { if (domBuilder instanceof DOMHandler) { return domBuilder; } errorImpl = domBuilder; } var errorHandler = {} var isCallback = errorImpl instanceof Function; locator = locator || {} function build(key) { var fn = errorImpl[key]; if (!fn && isCallback) { fn = errorImpl.length == 2 ? function (msg) { errorImpl(key, msg) } : errorImpl; } errorHandler[key] = fn && function (msg) { fn('[xmldom ' + key + ']\t' + msg + _locator(locator)); } || function () { }; } build('warning'); build('error'); build('fatalError'); return errorHandler; } //console.log('#\n\n\n\n\n\n\n####') /** * +ContentHandler+ErrorHandler * +LexicalHandler+EntityResolver2 * -DeclHandler-DTDHandler * * DefaultHandler:EntityResolver, DTDHandler, ContentHandler, ErrorHandler * DefaultHandler2:DefaultHandler,LexicalHandler, DeclHandler, EntityResolver2 * @link http://www.saxproject.org/apidoc/org/xml/sax/helpers/DefaultHandler.html */ function DOMHandler() { this.cdata = false; } function position(locator, node) { node.lineNumber = locator.lineNumber; node.columnNumber = locator.columnNumber; } /** * @see org.xml.sax.ContentHandler#startDocument * @link http://www.saxproject.org/apidoc/org/xml/sax/ContentHandler.html */ DOMHandler.prototype = { startDocument: function () { this.doc = new DOMImplementation().createDocument(null, null, null); if (this.locator) { this.doc.documentURI = this.locator.systemId; } }, startElement: function (namespaceURI, localName, qName, attrs) { var doc = this.doc; var el = doc.createElementNS(namespaceURI, qName || localName); var len = attrs.length; appendElement(this, el); this.currentElement = el; this.locator && position(this.locator, el) for (var i = 0; i < len; i++) { var namespaceURI = attrs.getURI(i); var value = attrs.getValue(i); var qName = attrs.getQName(i); var attr = doc.createAttributeNS(namespaceURI, qName); this.locator && position(attrs.getLocator(i), attr); attr.value = attr.nodeValue = value; el.setAttributeNode(attr) } }, endElement: function (namespaceURI, localName, qName) { var current = this.currentElement var tagName = current.tagName; this.currentElement = current.parentNode; }, startPrefixMapping: function (prefix, uri) { }, endPrefixMapping: function (prefix) { }, processingInstruction: function (target, data) { var ins = this.doc.createProcessingInstruction(target, data); this.locator && position(this.locator, ins) appendElement(this, ins); }, ignorableWhitespace: function (ch, start, length) { }, characters: function (chars, start, length) { chars = _toString.apply(this, arguments) //console.log(chars) if (chars) { if (this.cdata) { var charNode = this.doc.createCDATASection(chars); } else { var charNode = this.doc.createTextNode(chars); } if (this.currentElement) { this.currentElement.appendChild(charNode); } else if (/^\s*$/.test(chars)) { this.doc.appendChild(charNode); //process xml } this.locator && position(this.locator, charNode) } }, skippedEntity: function (name) { }, endDocument: function () { this.doc.normalize(); }, setDocumentLocator: function (locator) { if (this.locator = locator) {// && !('lineNumber' in locator)){ locator.lineNumber = 0; } }, //LexicalHandler comment: function (chars, start, length) { chars = _toString.apply(this, arguments) var comm = this.doc.createComment(chars); this.locator && position(this.locator, comm) appendElement(this, comm); }, startCDATA: function () { //used in characters() methods this.cdata = true; }, endCDATA: function () { this.cdata = false; }, startDTD: function (name, publicId, systemId) { var impl = this.doc.implementation; if (impl && impl.createDocumentType) { var dt = impl.createDocumentType(name, publicId, systemId); this.locator && position(this.locator, dt) appendElement(this, dt); this.doc.doctype = dt; } }, /** * @see org.xml.sax.ErrorHandler * @link http://www.saxproject.org/apidoc/org/xml/sax/ErrorHandler.html */ warning: function (error) { console.warn('[xmldom warning]\t' + error, _locator(this.locator)); }, error: function (error) { console.error('[xmldom error]\t' + error, _locator(this.locator)); }, fatalError: function (error) { throw new ParseError(error, this.locator); } } function _locator(l) { if (l) { return '\n@' + (l.systemId || '') + '#[line:' + l.lineNumber + ',col:' + l.columnNumber + ']' } } function _toString(chars, start, length) { if (typeof chars == 'string') { return chars.substr(start, length) } else {//java sax connect width xmldom on rhino(what about: "? && !(chars instanceof String)") if (chars.length >= start + length || start) { return new java.lang.String(chars, start, length) + ''; } return chars; } } /* * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/LexicalHandler.html * used method of org.xml.sax.ext.LexicalHandler: * #comment(chars, start, length) * #startCDATA() * #endCDATA() * #startDTD(name, publicId, systemId) * * * IGNORED method of org.xml.sax.ext.LexicalHandler: * #endDTD() * #startEntity(name) * #endEntity(name) * * * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/DeclHandler.html * IGNORED method of org.xml.sax.ext.DeclHandler * #attributeDecl(eName, aName, type, mode, value) * #elementDecl(name, model) * #externalEntityDecl(name, publicId, systemId) * #internalEntityDecl(name, value) * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/EntityResolver2.html * IGNORED method of org.xml.sax.EntityResolver2 * #resolveEntity(String name,String publicId,String baseURI,String systemId) * #resolveEntity(publicId, systemId) * #getExternalSubset(name, baseURI) * @link http://www.saxproject.org/apidoc/org/xml/sax/DTDHandler.html * IGNORED method of org.xml.sax.DTDHandler * #notationDecl(name, publicId, systemId) {}; * #unparsedEntityDecl(name, publicId, systemId, notationName) {}; */ "endDTD,startEntity,endEntity,attributeDecl,elementDecl,externalEntityDecl,internalEntityDecl,resolveEntity,getExternalSubset,notationDecl,unparsedEntityDecl".replace(/\w+/g, function (key) { DOMHandler.prototype[key] = function () { return null } }) /* Private static helpers treated below as private instance methods, so don't need to add these to the public API; we might use a Relator to also get rid of non-standard public properties */ function appendElement(hander, node) { if (!hander.currentElement) { hander.doc.appendChild(node); } else { hander.currentElement.appendChild(node); } }//appendChild and setAttributeNS are preformance key exports.__DOMHandler = DOMHandler; exports.normalizeLineEndings = normalizeLineEndings; exports.DOMParser = DOMParser; }, { "./conventions": 41, "./dom": 43, "./entities": 44, "./sax": 46 }], 43: [function (require, module, exports) { var conventions = require("./conventions"); var find = conventions.find; var NAMESPACE = conventions.NAMESPACE; /** * A prerequisite for `[].filter`, to drop elements that are empty * @param {string} input * @returns {boolean} */ function notEmptyString(input) { return input !== '' } /** * @see https://infra.spec.whatwg.org/#split-on-ascii-whitespace * @see https://infra.spec.whatwg.org/#ascii-whitespace * * @param {string} input * @returns {string[]} (can be empty) */ function splitOnASCIIWhitespace(input) { // U+0009 TAB, U+000A LF, U+000C FF, U+000D CR, U+0020 SPACE return input ? input.split(/[\t\n\f\r ]+/).filter(notEmptyString) : [] } /** * Adds element as a key to current if it is not already present. * * @param {Record} current * @param {string} element * @returns {Record} */ function orderedSetReducer(current, element) { if (!current.hasOwnProperty(element)) { current[element] = true; } return current; } /** * @see https://infra.spec.whatwg.org/#ordered-set * @param {string} input * @returns {string[]} */ function toOrderedSet(input) { if (!input) return []; var list = splitOnASCIIWhitespace(input); return Object.keys(list.reduce(orderedSetReducer, {})) } /** * Uses `list.indexOf` to implement something like `Array.prototype.includes`, * which we can not rely on being available. * * @param {any[]} list * @returns {function(any): boolean} */ function arrayIncludes(list) { return function (element) { return list && list.indexOf(element) !== -1; } } function copy(src, dest) { for (var p in src) { if (Object.prototype.hasOwnProperty.call(src, p)) { dest[p] = src[p]; } } } /** ^\w+\.prototype\.([_\w]+)\s*=\s*((?:.*\{\s*?[\r\n][\s\S]*?^})|\S.*?(?=[;\r\n]));? ^\w+\.prototype\.([_\w]+)\s*=\s*(\S.*?(?=[;\r\n]));? */ function _extends(Class, Super) { var pt = Class.prototype; if (!(pt instanceof Super)) { function t() { }; t.prototype = Super.prototype; t = new t(); copy(pt, t); Class.prototype = pt = t; } if (pt.constructor != Class) { if (typeof Class != 'function') { console.error("unknown Class:" + Class) } pt.constructor = Class } } // Node Types var NodeType = {} var ELEMENT_NODE = NodeType.ELEMENT_NODE = 1; var ATTRIBUTE_NODE = NodeType.ATTRIBUTE_NODE = 2; var TEXT_NODE = NodeType.TEXT_NODE = 3; var CDATA_SECTION_NODE = NodeType.CDATA_SECTION_NODE = 4; var ENTITY_REFERENCE_NODE = NodeType.ENTITY_REFERENCE_NODE = 5; var ENTITY_NODE = NodeType.ENTITY_NODE = 6; var PROCESSING_INSTRUCTION_NODE = NodeType.PROCESSING_INSTRUCTION_NODE = 7; var COMMENT_NODE = NodeType.COMMENT_NODE = 8; var DOCUMENT_NODE = NodeType.DOCUMENT_NODE = 9; var DOCUMENT_TYPE_NODE = NodeType.DOCUMENT_TYPE_NODE = 10; var DOCUMENT_FRAGMENT_NODE = NodeType.DOCUMENT_FRAGMENT_NODE = 11; var NOTATION_NODE = NodeType.NOTATION_NODE = 12; // ExceptionCode var ExceptionCode = {} var ExceptionMessage = {}; var INDEX_SIZE_ERR = ExceptionCode.INDEX_SIZE_ERR = ((ExceptionMessage[1] = "Index size error"), 1); var DOMSTRING_SIZE_ERR = ExceptionCode.DOMSTRING_SIZE_ERR = ((ExceptionMessage[2] = "DOMString size error"), 2); var HIERARCHY_REQUEST_ERR = ExceptionCode.HIERARCHY_REQUEST_ERR = ((ExceptionMessage[3] = "Hierarchy request error"), 3); var WRONG_DOCUMENT_ERR = ExceptionCode.WRONG_DOCUMENT_ERR = ((ExceptionMessage[4] = "Wrong document"), 4); var INVALID_CHARACTER_ERR = ExceptionCode.INVALID_CHARACTER_ERR = ((ExceptionMessage[5] = "Invalid character"), 5); var NO_DATA_ALLOWED_ERR = ExceptionCode.NO_DATA_ALLOWED_ERR = ((ExceptionMessage[6] = "No data allowed"), 6); var NO_MODIFICATION_ALLOWED_ERR = ExceptionCode.NO_MODIFICATION_ALLOWED_ERR = ((ExceptionMessage[7] = "No modification allowed"), 7); var NOT_FOUND_ERR = ExceptionCode.NOT_FOUND_ERR = ((ExceptionMessage[8] = "Not found"), 8); var NOT_SUPPORTED_ERR = ExceptionCode.NOT_SUPPORTED_ERR = ((ExceptionMessage[9] = "Not supported"), 9); var INUSE_ATTRIBUTE_ERR = ExceptionCode.INUSE_ATTRIBUTE_ERR = ((ExceptionMessage[10] = "Attribute in use"), 10); //level2 var INVALID_STATE_ERR = ExceptionCode.INVALID_STATE_ERR = ((ExceptionMessage[11] = "Invalid state"), 11); var SYNTAX_ERR = ExceptionCode.SYNTAX_ERR = ((ExceptionMessage[12] = "Syntax error"), 12); var INVALID_MODIFICATION_ERR = ExceptionCode.INVALID_MODIFICATION_ERR = ((ExceptionMessage[13] = "Invalid modification"), 13); var NAMESPACE_ERR = ExceptionCode.NAMESPACE_ERR = ((ExceptionMessage[14] = "Invalid namespace"), 14); var INVALID_ACCESS_ERR = ExceptionCode.INVALID_ACCESS_ERR = ((ExceptionMessage[15] = "Invalid access"), 15); /** * DOM Level 2 * Object DOMException * @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/ecma-script-binding.html * @see http://www.w3.org/TR/REC-DOM-Level-1/ecma-script-language-binding.html */ function DOMException(code, message) { if (message instanceof Error) { var error = message; } else { error = this; Error.call(this, ExceptionMessage[code]); this.message = ExceptionMessage[code]; if (Error.captureStackTrace) Error.captureStackTrace(this, DOMException); } error.code = code; if (message) this.message = this.message + ": " + message; return error; }; DOMException.prototype = Error.prototype; copy(ExceptionCode, DOMException) /** * @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-536297177 * The NodeList interface provides the abstraction of an ordered collection of nodes, without defining or constraining how this collection is implemented. NodeList objects in the DOM are live. * The items in the NodeList are accessible via an integral index, starting from 0. */ function NodeList() { }; NodeList.prototype = { /** * The number of nodes in the list. The range of valid child node indices is 0 to length-1 inclusive. * @standard level1 */ length: 0, /** * Returns the indexth item in the collection. If index is greater than or equal to the number of nodes in the list, this returns null. * @standard level1 * @param index unsigned long * Index into the collection. * @return Node * The node at the indexth position in the NodeList, or null if that is not a valid index. */ item: function (index) { return this[index] || null; }, toString: function (isHTML, nodeFilter) { for (var buf = [], i = 0; i < this.length; i++) { serializeToString(this[i], buf, isHTML, nodeFilter); } return buf.join(''); }, /** * @private * @param {function (Node):boolean} predicate * @returns {Node[]} */ filter: function (predicate) { return Array.prototype.filter.call(this, predicate); }, /** * @private * @param {Node} item * @returns {number} */ indexOf: function (item) { return Array.prototype.indexOf.call(this, item); }, }; function LiveNodeList(node, refresh) { this._node = node; this._refresh = refresh _updateLiveList(this); } function _updateLiveList(list) { var inc = list._node._inc || list._node.ownerDocument._inc; if (list._inc != inc) { var ls = list._refresh(list._node); //console.log(ls.length) __set__(list, 'length', ls.length); copy(ls, list); list._inc = inc; } } LiveNodeList.prototype.item = function (i) { _updateLiveList(this); return this[i]; } _extends(LiveNodeList, NodeList); /** * Objects implementing the NamedNodeMap interface are used * to represent collections of nodes that can be accessed by name. * Note that NamedNodeMap does not inherit from NodeList; * NamedNodeMaps are not maintained in any particular order. * Objects contained in an object implementing NamedNodeMap may also be accessed by an ordinal index, * but this is simply to allow convenient enumeration of the contents of a NamedNodeMap, * and does not imply that the DOM specifies an order to these Nodes. * NamedNodeMap objects in the DOM are live. * used for attributes or DocumentType entities */ function NamedNodeMap() { }; function _findNodeIndex(list, node) { var i = list.length; while (i--) { if (list[i] === node) { return i } } } function _addNamedNode(el, list, newAttr, oldAttr) { if (oldAttr) { list[_findNodeIndex(list, oldAttr)] = newAttr; } else { list[list.length++] = newAttr; } if (el) { newAttr.ownerElement = el; var doc = el.ownerDocument; if (doc) { oldAttr && _onRemoveAttribute(doc, el, oldAttr); _onAddAttribute(doc, el, newAttr); } } } function _removeNamedNode(el, list, attr) { //console.log('remove attr:'+attr) var i = _findNodeIndex(list, attr); if (i >= 0) { var lastIndex = list.length - 1 while (i < lastIndex) { list[i] = list[++i] } list.length = lastIndex; if (el) { var doc = el.ownerDocument; if (doc) { _onRemoveAttribute(doc, el, attr); attr.ownerElement = null; } } } else { throw new DOMException(NOT_FOUND_ERR, new Error(el.tagName + '@' + attr)) } } NamedNodeMap.prototype = { length: 0, item: NodeList.prototype.item, getNamedItem: function (key) { // if(key.indexOf(':')>0 || key == 'xmlns'){ // return null; // } //console.log() var i = this.length; while (i--) { var attr = this[i]; //console.log(attr.nodeName,key) if (attr.nodeName == key) { return attr; } } }, setNamedItem: function (attr) { var el = attr.ownerElement; if (el && el != this._ownerElement) { throw new DOMException(INUSE_ATTRIBUTE_ERR); } var oldAttr = this.getNamedItem(attr.nodeName); _addNamedNode(this._ownerElement, this, attr, oldAttr); return oldAttr; }, /* returns Node */ setNamedItemNS: function (attr) {// raises: WRONG_DOCUMENT_ERR,NO_MODIFICATION_ALLOWED_ERR,INUSE_ATTRIBUTE_ERR var el = attr.ownerElement, oldAttr; if (el && el != this._ownerElement) { throw new DOMException(INUSE_ATTRIBUTE_ERR); } oldAttr = this.getNamedItemNS(attr.namespaceURI, attr.localName); _addNamedNode(this._ownerElement, this, attr, oldAttr); return oldAttr; }, /* returns Node */ removeNamedItem: function (key) { var attr = this.getNamedItem(key); _removeNamedNode(this._ownerElement, this, attr); return attr; },// raises: NOT_FOUND_ERR,NO_MODIFICATION_ALLOWED_ERR //for level2 removeNamedItemNS: function (namespaceURI, localName) { var attr = this.getNamedItemNS(namespaceURI, localName); _removeNamedNode(this._ownerElement, this, attr); return attr; }, getNamedItemNS: function (namespaceURI, localName) { var i = this.length; while (i--) { var node = this[i]; if (node.localName == localName && node.namespaceURI == namespaceURI) { return node; } } return null; } }; /** * The DOMImplementation interface represents an object providing methods * which are not dependent on any particular document. * Such an object is returned by the `Document.implementation` property. * * __The individual methods describe the differences compared to the specs.__ * * @constructor * * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMImplementation MDN * @see https://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html#ID-102161490 DOM Level 1 Core (Initial) * @see https://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-102161490 DOM Level 2 Core * @see https://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-102161490 DOM Level 3 Core * @see https://dom.spec.whatwg.org/#domimplementation DOM Living Standard */ function DOMImplementation() { } DOMImplementation.prototype = { /** * The DOMImplementation.hasFeature() method returns a Boolean flag indicating if a given feature is supported. * The different implementations fairly diverged in what kind of features were reported. * The latest version of the spec settled to force this method to always return true, where the functionality was accurate and in use. * * @deprecated It is deprecated and modern browsers return true in all cases. * * @param {string} feature * @param {string} [version] * @returns {boolean} always true * * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMImplementation/hasFeature MDN * @see https://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html#ID-5CED94D7 DOM Level 1 Core * @see https://dom.spec.whatwg.org/#dom-domimplementation-hasfeature DOM Living Standard */ hasFeature: function (feature, version) { return true; }, /** * Creates an XML Document object of the specified type with its document element. * * __It behaves slightly different from the description in the living standard__: * - There is no interface/class `XMLDocument`, it returns a `Document` instance. * - `contentType`, `encoding`, `mode`, `origin`, `url` fields are currently not declared. * - this implementation is not validating names or qualified names * (when parsing XML strings, the SAX parser takes care of that) * * @param {string|null} namespaceURI * @param {string} qualifiedName * @param {DocumentType=null} doctype * @returns {Document} * * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMImplementation/createDocument MDN * @see https://www.w3.org/TR/DOM-Level-2-Core/core.html#Level-2-Core-DOM-createDocument DOM Level 2 Core (initial) * @see https://dom.spec.whatwg.org/#dom-domimplementation-createdocument DOM Level 2 Core * * @see https://dom.spec.whatwg.org/#validate-and-extract DOM: Validate and extract * @see https://www.w3.org/TR/xml/#NT-NameStartChar XML Spec: Names * @see https://www.w3.org/TR/xml-names/#ns-qualnames XML Namespaces: Qualified names */ createDocument: function (namespaceURI, qualifiedName, doctype) { var doc = new Document(); doc.implementation = this; doc.childNodes = new NodeList(); doc.doctype = doctype || null; if (doctype) { doc.appendChild(doctype); } if (qualifiedName) { var root = doc.createElementNS(namespaceURI, qualifiedName); doc.appendChild(root); } return doc; }, /** * Returns a doctype, with the given `qualifiedName`, `publicId`, and `systemId`. * * __This behavior is slightly different from the in the specs__: * - this implementation is not validating names or qualified names * (when parsing XML strings, the SAX parser takes care of that) * * @param {string} qualifiedName * @param {string} [publicId] * @param {string} [systemId] * @returns {DocumentType} which can either be used with `DOMImplementation.createDocument` upon document creation * or can be put into the document via methods like `Node.insertBefore()` or `Node.replaceChild()` * * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMImplementation/createDocumentType MDN * @see https://www.w3.org/TR/DOM-Level-2-Core/core.html#Level-2-Core-DOM-createDocType DOM Level 2 Core * @see https://dom.spec.whatwg.org/#dom-domimplementation-createdocumenttype DOM Living Standard * * @see https://dom.spec.whatwg.org/#validate-and-extract DOM: Validate and extract * @see https://www.w3.org/TR/xml/#NT-NameStartChar XML Spec: Names * @see https://www.w3.org/TR/xml-names/#ns-qualnames XML Namespaces: Qualified names */ createDocumentType: function (qualifiedName, publicId, systemId) { var node = new DocumentType(); node.name = qualifiedName; node.nodeName = qualifiedName; node.publicId = publicId || ''; node.systemId = systemId || ''; return node; } }; /** * @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-1950641247 */ function Node() { }; Node.prototype = { firstChild: null, lastChild: null, previousSibling: null, nextSibling: null, attributes: null, parentNode: null, childNodes: null, ownerDocument: null, nodeValue: null, namespaceURI: null, prefix: null, localName: null, // Modified in DOM Level 2: insertBefore: function (newChild, refChild) {//raises return _insertBefore(this, newChild, refChild); }, replaceChild: function (newChild, oldChild) {//raises _insertBefore(this, newChild, oldChild, assertPreReplacementValidityInDocument); if (oldChild) { this.removeChild(oldChild); } }, removeChild: function (oldChild) { return _removeChild(this, oldChild); }, appendChild: function (newChild) { return this.insertBefore(newChild, null); }, hasChildNodes: function () { return this.firstChild != null; }, cloneNode: function (deep) { return cloneNode(this.ownerDocument || this, this, deep); }, // Modified in DOM Level 2: normalize: function () { var child = this.firstChild; while (child) { var next = child.nextSibling; if (next && next.nodeType == TEXT_NODE && child.nodeType == TEXT_NODE) { this.removeChild(next); child.appendData(next.data); } else { child.normalize(); child = next; } } }, // Introduced in DOM Level 2: isSupported: function (feature, version) { return this.ownerDocument.implementation.hasFeature(feature, version); }, // Introduced in DOM Level 2: hasAttributes: function () { return this.attributes.length > 0; }, /** * Look up the prefix associated to the given namespace URI, starting from this node. * **The default namespace declarations are ignored by this method.** * See Namespace Prefix Lookup for details on the algorithm used by this method. * * _Note: The implementation seems to be incomplete when compared to the algorithm described in the specs._ * * @param {string | null} namespaceURI * @returns {string | null} * @see https://www.w3.org/TR/DOM-Level-3-Core/core.html#Node3-lookupNamespacePrefix * @see https://www.w3.org/TR/DOM-Level-3-Core/namespaces-algorithms.html#lookupNamespacePrefixAlgo * @see https://dom.spec.whatwg.org/#dom-node-lookupprefix * @see https://github.com/xmldom/xmldom/issues/322 */ lookupPrefix: function (namespaceURI) { var el = this; while (el) { var map = el._nsMap; //console.dir(map) if (map) { for (var n in map) { if (Object.prototype.hasOwnProperty.call(map, n) && map[n] === namespaceURI) { return n; } } } el = el.nodeType == ATTRIBUTE_NODE ? el.ownerDocument : el.parentNode; } return null; }, // Introduced in DOM Level 3: lookupNamespaceURI: function (prefix) { var el = this; while (el) { var map = el._nsMap; //console.dir(map) if (map) { if (Object.prototype.hasOwnProperty.call(map, prefix)) { return map[prefix]; } } el = el.nodeType == ATTRIBUTE_NODE ? el.ownerDocument : el.parentNode; } return null; }, // Introduced in DOM Level 3: isDefaultNamespace: function (namespaceURI) { var prefix = this.lookupPrefix(namespaceURI); return prefix == null; } }; function _xmlEncoder(c) { return c == '<' && '<' || c == '>' && '>' || c == '&' && '&' || c == '"' && '"' || '&#' + c.charCodeAt() + ';' } copy(NodeType, Node); copy(NodeType, Node.prototype); /** * @param callback return true for continue,false for break * @return boolean true: break visit; */ function _visitNode(node, callback) { if (callback(node)) { return true; } if (node = node.firstChild) { do { if (_visitNode(node, callback)) { return true } } while (node = node.nextSibling) } } function Document() { this.ownerDocument = this; } function _onAddAttribute(doc, el, newAttr) { doc && doc._inc++; var ns = newAttr.namespaceURI; if (ns === NAMESPACE.XMLNS) { //update namespace el._nsMap[newAttr.prefix ? newAttr.localName : ''] = newAttr.value } } function _onRemoveAttribute(doc, el, newAttr, remove) { doc && doc._inc++; var ns = newAttr.namespaceURI; if (ns === NAMESPACE.XMLNS) { //update namespace delete el._nsMap[newAttr.prefix ? newAttr.localName : ''] } } /** * Updates `el.childNodes`, updating the indexed items and it's `length`. * Passing `newChild` means it will be appended. * Otherwise it's assumed that an item has been removed, * and `el.firstNode` and it's `.nextSibling` are used * to walk the current list of child nodes. * * @param {Document} doc * @param {Node} el * @param {Node} [newChild] * @private */ function _onUpdateChild(doc, el, newChild) { if (doc && doc._inc) { doc._inc++; //update childNodes var cs = el.childNodes; if (newChild) { cs[cs.length++] = newChild; } else { var child = el.firstChild; var i = 0; while (child) { cs[i++] = child; child = child.nextSibling; } cs.length = i; delete cs[cs.length]; } } } /** * Removes the connections between `parentNode` and `child` * and any existing `child.previousSibling` or `child.nextSibling`. * * @see https://github.com/xmldom/xmldom/issues/135 * @see https://github.com/xmldom/xmldom/issues/145 * * @param {Node} parentNode * @param {Node} child * @returns {Node} the child that was removed. * @private */ function _removeChild(parentNode, child) { var previous = child.previousSibling; var next = child.nextSibling; if (previous) { previous.nextSibling = next; } else { parentNode.firstChild = next; } if (next) { next.previousSibling = previous; } else { parentNode.lastChild = previous; } child.parentNode = null; child.previousSibling = null; child.nextSibling = null; _onUpdateChild(parentNode.ownerDocument, parentNode); return child; } /** * Returns `true` if `node` can be a parent for insertion. * @param {Node} node * @returns {boolean} */ function hasValidParentNodeType(node) { return ( node && (node.nodeType === Node.DOCUMENT_NODE || node.nodeType === Node.DOCUMENT_FRAGMENT_NODE || node.nodeType === Node.ELEMENT_NODE) ); } /** * Returns `true` if `node` can be inserted according to it's `nodeType`. * @param {Node} node * @returns {boolean} */ function hasInsertableNodeType(node) { return ( node && (isElementNode(node) || isTextNode(node) || isDocTypeNode(node) || node.nodeType === Node.DOCUMENT_FRAGMENT_NODE || node.nodeType === Node.COMMENT_NODE || node.nodeType === Node.PROCESSING_INSTRUCTION_NODE) ); } /** * Returns true if `node` is a DOCTYPE node * @param {Node} node * @returns {boolean} */ function isDocTypeNode(node) { return node && node.nodeType === Node.DOCUMENT_TYPE_NODE; } /** * Returns true if the node is an element * @param {Node} node * @returns {boolean} */ function isElementNode(node) { return node && node.nodeType === Node.ELEMENT_NODE; } /** * Returns true if `node` is a text node * @param {Node} node * @returns {boolean} */ function isTextNode(node) { return node && node.nodeType === Node.TEXT_NODE; } /** * Check if en element node can be inserted before `child`, or at the end if child is falsy, * according to the presence and position of a doctype node on the same level. * * @param {Document} doc The document node * @param {Node} child the node that would become the nextSibling if the element would be inserted * @returns {boolean} `true` if an element can be inserted before child * @private * https://dom.spec.whatwg.org/#concept-node-ensure-pre-insertion-validity */ function isElementInsertionPossible(doc, child) { var parentChildNodes = doc.childNodes || []; if (find(parentChildNodes, isElementNode) || isDocTypeNode(child)) { return false; } var docTypeNode = find(parentChildNodes, isDocTypeNode); return !(child && docTypeNode && parentChildNodes.indexOf(docTypeNode) > parentChildNodes.indexOf(child)); } /** * Check if en element node can be inserted before `child`, or at the end if child is falsy, * according to the presence and position of a doctype node on the same level. * * @param {Node} doc The document node * @param {Node} child the node that would become the nextSibling if the element would be inserted * @returns {boolean} `true` if an element can be inserted before child * @private * https://dom.spec.whatwg.org/#concept-node-ensure-pre-insertion-validity */ function isElementReplacementPossible(doc, child) { var parentChildNodes = doc.childNodes || []; function hasElementChildThatIsNotChild(node) { return isElementNode(node) && node !== child; } if (find(parentChildNodes, hasElementChildThatIsNotChild)) { return false; } var docTypeNode = find(parentChildNodes, isDocTypeNode); return !(child && docTypeNode && parentChildNodes.indexOf(docTypeNode) > parentChildNodes.indexOf(child)); } /** * @private * Steps 1-5 of the checks before inserting and before replacing a child are the same. * * @param {Node} parent the parent node to insert `node` into * @param {Node} node the node to insert * @param {Node=} child the node that should become the `nextSibling` of `node` * @returns {Node} * @throws DOMException for several node combinations that would create a DOM that is not well-formed. * @throws DOMException if `child` is provided but is not a child of `parent`. * @see https://dom.spec.whatwg.org/#concept-node-ensure-pre-insertion-validity * @see https://dom.spec.whatwg.org/#concept-node-replace */ function assertPreInsertionValidity1to5(parent, node, child) { // 1. If `parent` is not a Document, DocumentFragment, or Element node, then throw a "HierarchyRequestError" DOMException. if (!hasValidParentNodeType(parent)) { throw new DOMException(HIERARCHY_REQUEST_ERR, 'Unexpected parent node type ' + parent.nodeType); } // 2. If `node` is a host-including inclusive ancestor of `parent`, then throw a "HierarchyRequestError" DOMException. // not implemented! // 3. If `child` is non-null and its parent is not `parent`, then throw a "NotFoundError" DOMException. if (child && child.parentNode !== parent) { throw new DOMException(NOT_FOUND_ERR, 'child not in parent'); } if ( // 4. If `node` is not a DocumentFragment, DocumentType, Element, or CharacterData node, then throw a "HierarchyRequestError" DOMException. !hasInsertableNodeType(node) || // 5. If either `node` is a Text node and `parent` is a document, // the sax parser currently adds top level text nodes, this will be fixed in 0.9.0 // || (node.nodeType === Node.TEXT_NODE && parent.nodeType === Node.DOCUMENT_NODE) // or `node` is a doctype and `parent` is not a document, then throw a "HierarchyRequestError" DOMException. (isDocTypeNode(node) && parent.nodeType !== Node.DOCUMENT_NODE) ) { throw new DOMException( HIERARCHY_REQUEST_ERR, 'Unexpected node type ' + node.nodeType + ' for parent node type ' + parent.nodeType ); } } /** * @private * Step 6 of the checks before inserting and before replacing a child are different. * * @param {Document} parent the parent node to insert `node` into * @param {Node} node the node to insert * @param {Node | undefined} child the node that should become the `nextSibling` of `node` * @returns {Node} * @throws DOMException for several node combinations that would create a DOM that is not well-formed. * @throws DOMException if `child` is provided but is not a child of `parent`. * @see https://dom.spec.whatwg.org/#concept-node-ensure-pre-insertion-validity * @see https://dom.spec.whatwg.org/#concept-node-replace */ function assertPreInsertionValidityInDocument(parent, node, child) { var parentChildNodes = parent.childNodes || []; var nodeChildNodes = node.childNodes || []; // DocumentFragment if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) { var nodeChildElements = nodeChildNodes.filter(isElementNode); // If node has more than one element child or has a Text node child. if (nodeChildElements.length > 1 || find(nodeChildNodes, isTextNode)) { throw new DOMException(HIERARCHY_REQUEST_ERR, 'More than one element or text in fragment'); } // Otherwise, if `node` has one element child and either `parent` has an element child, // `child` is a doctype, or `child` is non-null and a doctype is following `child`. if (nodeChildElements.length === 1 && !isElementInsertionPossible(parent, child)) { throw new DOMException(HIERARCHY_REQUEST_ERR, 'Element in fragment can not be inserted before doctype'); } } // Element if (isElementNode(node)) { // `parent` has an element child, `child` is a doctype, // or `child` is non-null and a doctype is following `child`. if (!isElementInsertionPossible(parent, child)) { throw new DOMException(HIERARCHY_REQUEST_ERR, 'Only one element can be added and only after doctype'); } } // DocumentType if (isDocTypeNode(node)) { // `parent` has a doctype child, if (find(parentChildNodes, isDocTypeNode)) { throw new DOMException(HIERARCHY_REQUEST_ERR, 'Only one doctype is allowed'); } var parentElementChild = find(parentChildNodes, isElementNode); // `child` is non-null and an element is preceding `child`, if (child && parentChildNodes.indexOf(parentElementChild) < parentChildNodes.indexOf(child)) { throw new DOMException(HIERARCHY_REQUEST_ERR, 'Doctype can only be inserted before an element'); } // or `child` is null and `parent` has an element child. if (!child && parentElementChild) { throw new DOMException(HIERARCHY_REQUEST_ERR, 'Doctype can not be appended since element is present'); } } } /** * @private * Step 6 of the checks before inserting and before replacing a child are different. * * @param {Document} parent the parent node to insert `node` into * @param {Node} node the node to insert * @param {Node | undefined} child the node that should become the `nextSibling` of `node` * @returns {Node} * @throws DOMException for several node combinations that would create a DOM that is not well-formed. * @throws DOMException if `child` is provided but is not a child of `parent`. * @see https://dom.spec.whatwg.org/#concept-node-ensure-pre-insertion-validity * @see https://dom.spec.whatwg.org/#concept-node-replace */ function assertPreReplacementValidityInDocument(parent, node, child) { var parentChildNodes = parent.childNodes || []; var nodeChildNodes = node.childNodes || []; // DocumentFragment if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) { var nodeChildElements = nodeChildNodes.filter(isElementNode); // If `node` has more than one element child or has a Text node child. if (nodeChildElements.length > 1 || find(nodeChildNodes, isTextNode)) { throw new DOMException(HIERARCHY_REQUEST_ERR, 'More than one element or text in fragment'); } // Otherwise, if `node` has one element child and either `parent` has an element child that is not `child` or a doctype is following `child`. if (nodeChildElements.length === 1 && !isElementReplacementPossible(parent, child)) { throw new DOMException(HIERARCHY_REQUEST_ERR, 'Element in fragment can not be inserted before doctype'); } } // Element if (isElementNode(node)) { // `parent` has an element child that is not `child` or a doctype is following `child`. if (!isElementReplacementPossible(parent, child)) { throw new DOMException(HIERARCHY_REQUEST_ERR, 'Only one element can be added and only after doctype'); } } // DocumentType if (isDocTypeNode(node)) { function hasDoctypeChildThatIsNotChild(node) { return isDocTypeNode(node) && node !== child; } // `parent` has a doctype child that is not `child`, if (find(parentChildNodes, hasDoctypeChildThatIsNotChild)) { throw new DOMException(HIERARCHY_REQUEST_ERR, 'Only one doctype is allowed'); } var parentElementChild = find(parentChildNodes, isElementNode); // or an element is preceding `child`. if (child && parentChildNodes.indexOf(parentElementChild) < parentChildNodes.indexOf(child)) { throw new DOMException(HIERARCHY_REQUEST_ERR, 'Doctype can only be inserted before an element'); } } } /** * @private * @param {Node} parent the parent node to insert `node` into * @param {Node} node the node to insert * @param {Node=} child the node that should become the `nextSibling` of `node` * @returns {Node} * @throws DOMException for several node combinations that would create a DOM that is not well-formed. * @throws DOMException if `child` is provided but is not a child of `parent`. * @see https://dom.spec.whatwg.org/#concept-node-ensure-pre-insertion-validity */ function _insertBefore(parent, node, child, _inDocumentAssertion) { // To ensure pre-insertion validity of a node into a parent before a child, run these steps: assertPreInsertionValidity1to5(parent, node, child); // If parent is a document, and any of the statements below, switched on the interface node implements, // are true, then throw a "HierarchyRequestError" DOMException. if (parent.nodeType === Node.DOCUMENT_NODE) { (_inDocumentAssertion || assertPreInsertionValidityInDocument)(parent, node, child); } var cp = node.parentNode; if (cp) { cp.removeChild(node);//remove and update } if (node.nodeType === DOCUMENT_FRAGMENT_NODE) { var newFirst = node.firstChild; if (newFirst == null) { return node; } var newLast = node.lastChild; } else { newFirst = newLast = node; } var pre = child ? child.previousSibling : parent.lastChild; newFirst.previousSibling = pre; newLast.nextSibling = child; if (pre) { pre.nextSibling = newFirst; } else { parent.firstChild = newFirst; } if (child == null) { parent.lastChild = newLast; } else { child.previousSibling = newLast; } do { newFirst.parentNode = parent; } while (newFirst !== newLast && (newFirst = newFirst.nextSibling)) _onUpdateChild(parent.ownerDocument || parent, parent); //console.log(parent.lastChild.nextSibling == null) if (node.nodeType == DOCUMENT_FRAGMENT_NODE) { node.firstChild = node.lastChild = null; } return node; } /** * Appends `newChild` to `parentNode`. * If `newChild` is already connected to a `parentNode` it is first removed from it. * * @see https://github.com/xmldom/xmldom/issues/135 * @see https://github.com/xmldom/xmldom/issues/145 * @param {Node} parentNode * @param {Node} newChild * @returns {Node} * @private */ function _appendSingleChild(parentNode, newChild) { if (newChild.parentNode) { newChild.parentNode.removeChild(newChild); } newChild.parentNode = parentNode; newChild.previousSibling = parentNode.lastChild; newChild.nextSibling = null; if (newChild.previousSibling) { newChild.previousSibling.nextSibling = newChild; } else { parentNode.firstChild = newChild; } parentNode.lastChild = newChild; _onUpdateChild(parentNode.ownerDocument, parentNode, newChild); return newChild; } Document.prototype = { //implementation : null, nodeName: '#document', nodeType: DOCUMENT_NODE, /** * The DocumentType node of the document. * * @readonly * @type DocumentType */ doctype: null, documentElement: null, _inc: 1, insertBefore: function (newChild, refChild) {//raises if (newChild.nodeType == DOCUMENT_FRAGMENT_NODE) { var child = newChild.firstChild; while (child) { var next = child.nextSibling; this.insertBefore(child, refChild); child = next; } return newChild; } _insertBefore(this, newChild, refChild); newChild.ownerDocument = this; if (this.documentElement === null && newChild.nodeType === ELEMENT_NODE) { this.documentElement = newChild; } return newChild; }, removeChild: function (oldChild) { if (this.documentElement == oldChild) { this.documentElement = null; } return _removeChild(this, oldChild); }, replaceChild: function (newChild, oldChild) { //raises _insertBefore(this, newChild, oldChild, assertPreReplacementValidityInDocument); newChild.ownerDocument = this; if (oldChild) { this.removeChild(oldChild); } if (isElementNode(newChild)) { this.documentElement = newChild; } }, // Introduced in DOM Level 2: importNode: function (importedNode, deep) { return importNode(this, importedNode, deep); }, // Introduced in DOM Level 2: getElementById: function (id) { var rtv = null; _visitNode(this.documentElement, function (node) { if (node.nodeType == ELEMENT_NODE) { if (node.getAttribute('id') == id) { rtv = node; return true; } } }) return rtv; }, /** * The `getElementsByClassName` method of `Document` interface returns an array-like object * of all child elements which have **all** of the given class name(s). * * Returns an empty list if `classeNames` is an empty string or only contains HTML white space characters. * * * Warning: This is a live LiveNodeList. * Changes in the DOM will reflect in the array as the changes occur. * If an element selected by this array no longer qualifies for the selector, * it will automatically be removed. Be aware of this for iteration purposes. * * @param {string} classNames is a string representing the class name(s) to match; multiple class names are separated by (ASCII-)whitespace * * @see https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementsByClassName * @see https://dom.spec.whatwg.org/#concept-getelementsbyclassname */ getElementsByClassName: function (classNames) { var classNamesSet = toOrderedSet(classNames) return new LiveNodeList(this, function (base) { var ls = []; if (classNamesSet.length > 0) { _visitNode(base.documentElement, function (node) { if (node !== base && node.nodeType === ELEMENT_NODE) { var nodeClassNames = node.getAttribute('class') // can be null if the attribute does not exist if (nodeClassNames) { // before splitting and iterating just compare them for the most common case var matches = classNames === nodeClassNames; if (!matches) { var nodeClassNamesSet = toOrderedSet(nodeClassNames) matches = classNamesSet.every(arrayIncludes(nodeClassNamesSet)) } if (matches) { ls.push(node); } } } }); } return ls; }); }, //document factory method: createElement: function (tagName) { var node = new Element(); node.ownerDocument = this; node.nodeName = tagName; node.tagName = tagName; node.localName = tagName; node.childNodes = new NodeList(); var attrs = node.attributes = new NamedNodeMap(); attrs._ownerElement = node; return node; }, createDocumentFragment: function () { var node = new DocumentFragment(); node.ownerDocument = this; node.childNodes = new NodeList(); return node; }, createTextNode: function (data) { var node = new Text(); node.ownerDocument = this; node.appendData(data) return node; }, createComment: function (data) { var node = new Comment(); node.ownerDocument = this; node.appendData(data) return node; }, createCDATASection: function (data) { var node = new CDATASection(); node.ownerDocument = this; node.appendData(data) return node; }, createProcessingInstruction: function (target, data) { var node = new ProcessingInstruction(); node.ownerDocument = this; node.tagName = node.target = target; node.nodeValue = node.data = data; return node; }, createAttribute: function (name) { var node = new Attr(); node.ownerDocument = this; node.name = name; node.nodeName = name; node.localName = name; node.specified = true; return node; }, createEntityReference: function (name) { var node = new EntityReference(); node.ownerDocument = this; node.nodeName = name; return node; }, // Introduced in DOM Level 2: createElementNS: function (namespaceURI, qualifiedName) { var node = new Element(); var pl = qualifiedName.split(':'); var attrs = node.attributes = new NamedNodeMap(); node.childNodes = new NodeList(); node.ownerDocument = this; node.nodeName = qualifiedName; node.tagName = qualifiedName; node.namespaceURI = namespaceURI; if (pl.length == 2) { node.prefix = pl[0]; node.localName = pl[1]; } else { //el.prefix = null; node.localName = qualifiedName; } attrs._ownerElement = node; return node; }, // Introduced in DOM Level 2: createAttributeNS: function (namespaceURI, qualifiedName) { var node = new Attr(); var pl = qualifiedName.split(':'); node.ownerDocument = this; node.nodeName = qualifiedName; node.name = qualifiedName; node.namespaceURI = namespaceURI; node.specified = true; if (pl.length == 2) { node.prefix = pl[0]; node.localName = pl[1]; } else { //el.prefix = null; node.localName = qualifiedName; } return node; } }; _extends(Document, Node); function Element() { this._nsMap = {}; }; Element.prototype = { nodeType: ELEMENT_NODE, hasAttribute: function (name) { return this.getAttributeNode(name) != null; }, getAttribute: function (name) { var attr = this.getAttributeNode(name); return attr && attr.value || ''; }, getAttributeNode: function (name) { return this.attributes.getNamedItem(name); }, setAttribute: function (name, value) { var attr = this.ownerDocument.createAttribute(name); attr.value = attr.nodeValue = "" + value; this.setAttributeNode(attr) }, removeAttribute: function (name) { var attr = this.getAttributeNode(name) attr && this.removeAttributeNode(attr); }, //four real opeartion method appendChild: function (newChild) { if (newChild.nodeType === DOCUMENT_FRAGMENT_NODE) { return this.insertBefore(newChild, null); } else { return _appendSingleChild(this, newChild); } }, setAttributeNode: function (newAttr) { return this.attributes.setNamedItem(newAttr); }, setAttributeNodeNS: function (newAttr) { return this.attributes.setNamedItemNS(newAttr); }, removeAttributeNode: function (oldAttr) { //console.log(this == oldAttr.ownerElement) return this.attributes.removeNamedItem(oldAttr.nodeName); }, //get real attribute name,and remove it by removeAttributeNode removeAttributeNS: function (namespaceURI, localName) { var old = this.getAttributeNodeNS(namespaceURI, localName); old && this.removeAttributeNode(old); }, hasAttributeNS: function (namespaceURI, localName) { return this.getAttributeNodeNS(namespaceURI, localName) != null; }, getAttributeNS: function (namespaceURI, localName) { var attr = this.getAttributeNodeNS(namespaceURI, localName); return attr && attr.value || ''; }, setAttributeNS: function (namespaceURI, qualifiedName, value) { var attr = this.ownerDocument.createAttributeNS(namespaceURI, qualifiedName); attr.value = attr.nodeValue = "" + value; this.setAttributeNode(attr) }, getAttributeNodeNS: function (namespaceURI, localName) { return this.attributes.getNamedItemNS(namespaceURI, localName); }, getElementsByTagName: function (tagName) { return new LiveNodeList(this, function (base) { var ls = []; _visitNode(base, function (node) { if (node !== base && node.nodeType == ELEMENT_NODE && (tagName === '*' || node.tagName == tagName)) { ls.push(node); } }); return ls; }); }, getElementsByTagNameNS: function (namespaceURI, localName) { return new LiveNodeList(this, function (base) { var ls = []; _visitNode(base, function (node) { if (node !== base && node.nodeType === ELEMENT_NODE && (namespaceURI === '*' || node.namespaceURI === namespaceURI) && (localName === '*' || node.localName == localName)) { ls.push(node); } }); return ls; }); } }; Document.prototype.getElementsByTagName = Element.prototype.getElementsByTagName; Document.prototype.getElementsByTagNameNS = Element.prototype.getElementsByTagNameNS; _extends(Element, Node); function Attr() { }; Attr.prototype.nodeType = ATTRIBUTE_NODE; _extends(Attr, Node); function CharacterData() { }; CharacterData.prototype = { data: '', substringData: function (offset, count) { return this.data.substring(offset, offset + count); }, appendData: function (text) { text = this.data + text; this.nodeValue = this.data = text; this.length = text.length; }, insertData: function (offset, text) { this.replaceData(offset, 0, text); }, appendChild: function (newChild) { throw new Error(ExceptionMessage[HIERARCHY_REQUEST_ERR]) }, deleteData: function (offset, count) { this.replaceData(offset, count, ""); }, replaceData: function (offset, count, text) { var start = this.data.substring(0, offset); var end = this.data.substring(offset + count); text = start + text + end; this.nodeValue = this.data = text; this.length = text.length; } } _extends(CharacterData, Node); function Text() { }; Text.prototype = { nodeName: "#text", nodeType: TEXT_NODE, splitText: function (offset) { var text = this.data; var newText = text.substring(offset); text = text.substring(0, offset); this.data = this.nodeValue = text; this.length = text.length; var newNode = this.ownerDocument.createTextNode(newText); if (this.parentNode) { this.parentNode.insertBefore(newNode, this.nextSibling); } return newNode; } } _extends(Text, CharacterData); function Comment() { }; Comment.prototype = { nodeName: "#comment", nodeType: COMMENT_NODE } _extends(Comment, CharacterData); function CDATASection() { }; CDATASection.prototype = { nodeName: "#cdata-section", nodeType: CDATA_SECTION_NODE } _extends(CDATASection, CharacterData); function DocumentType() { }; DocumentType.prototype.nodeType = DOCUMENT_TYPE_NODE; _extends(DocumentType, Node); function Notation() { }; Notation.prototype.nodeType = NOTATION_NODE; _extends(Notation, Node); function Entity() { }; Entity.prototype.nodeType = ENTITY_NODE; _extends(Entity, Node); function EntityReference() { }; EntityReference.prototype.nodeType = ENTITY_REFERENCE_NODE; _extends(EntityReference, Node); function DocumentFragment() { }; DocumentFragment.prototype.nodeName = "#document-fragment"; DocumentFragment.prototype.nodeType = DOCUMENT_FRAGMENT_NODE; _extends(DocumentFragment, Node); function ProcessingInstruction() { } ProcessingInstruction.prototype.nodeType = PROCESSING_INSTRUCTION_NODE; _extends(ProcessingInstruction, Node); function XMLSerializer() { } XMLSerializer.prototype.serializeToString = function (node, isHtml, nodeFilter) { return nodeSerializeToString.call(node, isHtml, nodeFilter); } Node.prototype.toString = nodeSerializeToString; function nodeSerializeToString(isHtml, nodeFilter) { var buf = []; var refNode = this.nodeType == 9 && this.documentElement || this; var prefix = refNode.prefix; var uri = refNode.namespaceURI; if (uri && prefix == null) { //console.log(prefix) var prefix = refNode.lookupPrefix(uri); if (prefix == null) { //isHTML = true; var visibleNamespaces = [ { namespace: uri, prefix: null } //{namespace:uri,prefix:''} ] } } serializeToString(this, buf, isHtml, nodeFilter, visibleNamespaces); //console.log('###',this.nodeType,uri,prefix,buf.join('')) return buf.join(''); } function needNamespaceDefine(node, isHTML, visibleNamespaces) { var prefix = node.prefix || ''; var uri = node.namespaceURI; // According to [Namespaces in XML 1.0](https://www.w3.org/TR/REC-xml-names/#ns-using) , // and more specifically https://www.w3.org/TR/REC-xml-names/#nsc-NoPrefixUndecl : // > In a namespace declaration for a prefix [...], the attribute value MUST NOT be empty. // in a similar manner [Namespaces in XML 1.1](https://www.w3.org/TR/xml-names11/#ns-using) // and more specifically https://www.w3.org/TR/xml-names11/#nsc-NSDeclared : // > [...] Furthermore, the attribute value [...] must not be an empty string. // so serializing empty namespace value like xmlns:ds="" would produce an invalid XML document. if (!uri) { return false; } if (prefix === "xml" && uri === NAMESPACE.XML || uri === NAMESPACE.XMLNS) { return false; } var i = visibleNamespaces.length while (i--) { var ns = visibleNamespaces[i]; // get namespace prefix if (ns.prefix === prefix) { return ns.namespace !== uri; } } return true; } /** * Well-formed constraint: No < in Attribute Values * > The replacement text of any entity referred to directly or indirectly * > in an attribute value must not contain a <. * @see https://www.w3.org/TR/xml11/#CleanAttrVals * @see https://www.w3.org/TR/xml11/#NT-AttValue * * Literal whitespace other than space that appear in attribute values * are serialized as their entity references, so they will be preserved. * (In contrast to whitespace literals in the input which are normalized to spaces) * @see https://www.w3.org/TR/xml11/#AVNormalize * @see https://w3c.github.io/DOM-Parsing/#serializing-an-element-s-attributes */ function addSerializedAttribute(buf, qualifiedName, value) { buf.push(' ', qualifiedName, '="', value.replace(/[<>&"\t\n\r]/g, _xmlEncoder), '"') } function serializeToString(node, buf, isHTML, nodeFilter, visibleNamespaces) { if (!visibleNamespaces) { visibleNamespaces = []; } if (nodeFilter) { node = nodeFilter(node); if (node) { if (typeof node == 'string') { buf.push(node); return; } } else { return; } //buf.sort.apply(attrs, attributeSorter); } switch (node.nodeType) { case ELEMENT_NODE: var attrs = node.attributes; var len = attrs.length; var child = node.firstChild; var nodeName = node.tagName; isHTML = NAMESPACE.isHTML(node.namespaceURI) || isHTML var prefixedNodeName = nodeName if (!isHTML && !node.prefix && node.namespaceURI) { var defaultNS // lookup current default ns from `xmlns` attribute for (var ai = 0; ai < attrs.length; ai++) { if (attrs.item(ai).name === 'xmlns') { defaultNS = attrs.item(ai).value break } } if (!defaultNS) { // lookup current default ns in visibleNamespaces for (var nsi = visibleNamespaces.length - 1; nsi >= 0; nsi--) { var namespace = visibleNamespaces[nsi] if (namespace.prefix === '' && namespace.namespace === node.namespaceURI) { defaultNS = namespace.namespace break } } } if (defaultNS !== node.namespaceURI) { for (var nsi = visibleNamespaces.length - 1; nsi >= 0; nsi--) { var namespace = visibleNamespaces[nsi] if (namespace.namespace === node.namespaceURI) { if (namespace.prefix) { prefixedNodeName = namespace.prefix + ':' + nodeName } break } } } } buf.push('<', prefixedNodeName); for (var i = 0; i < len; i++) { // add namespaces for attributes var attr = attrs.item(i); if (attr.prefix == 'xmlns') { visibleNamespaces.push({ prefix: attr.localName, namespace: attr.value }); } else if (attr.nodeName == 'xmlns') { visibleNamespaces.push({ prefix: '', namespace: attr.value }); } } for (var i = 0; i < len; i++) { var attr = attrs.item(i); if (needNamespaceDefine(attr, isHTML, visibleNamespaces)) { var prefix = attr.prefix || ''; var uri = attr.namespaceURI; addSerializedAttribute(buf, prefix ? 'xmlns:' + prefix : "xmlns", uri); visibleNamespaces.push({ prefix: prefix, namespace: uri }); } serializeToString(attr, buf, isHTML, nodeFilter, visibleNamespaces); } // add namespace for current node if (nodeName === prefixedNodeName && needNamespaceDefine(node, isHTML, visibleNamespaces)) { var prefix = node.prefix || ''; var uri = node.namespaceURI; addSerializedAttribute(buf, prefix ? 'xmlns:' + prefix : "xmlns", uri); visibleNamespaces.push({ prefix: prefix, namespace: uri }); } if (child || isHTML && !/^(?:meta|link|img|br|hr|input)$/i.test(nodeName)) { buf.push('>'); //if is cdata child node if (isHTML && /^script$/i.test(nodeName)) { while (child) { if (child.data) { buf.push(child.data); } else { serializeToString(child, buf, isHTML, nodeFilter, visibleNamespaces.slice()); } child = child.nextSibling; } } else { while (child) { serializeToString(child, buf, isHTML, nodeFilter, visibleNamespaces.slice()); child = child.nextSibling; } } buf.push(''); } else { buf.push('/>'); } // remove added visible namespaces //visibleNamespaces.length = startVisibleNamespaces; return; case DOCUMENT_NODE: case DOCUMENT_FRAGMENT_NODE: var child = node.firstChild; while (child) { serializeToString(child, buf, isHTML, nodeFilter, visibleNamespaces.slice()); child = child.nextSibling; } return; case ATTRIBUTE_NODE: return addSerializedAttribute(buf, node.name, node.value); case TEXT_NODE: /** * The ampersand character (&) and the left angle bracket (<) must not appear in their literal form, * except when used as markup delimiters, or within a comment, a processing instruction, or a CDATA section. * If they are needed elsewhere, they must be escaped using either numeric character references or the strings * `&` and `<` respectively. * The right angle bracket (>) may be represented using the string " > ", and must, for compatibility, * be escaped using either `>` or a character reference when it appears in the string `]]>` in content, * when that string is not marking the end of a CDATA section. * * In the content of elements, character data is any string of characters * which does not contain the start-delimiter of any markup * and does not include the CDATA-section-close delimiter, `]]>`. * * @see https://www.w3.org/TR/xml/#NT-CharData * @see https://w3c.github.io/DOM-Parsing/#xml-serializing-a-text-node */ return buf.push(node.data .replace(/[<&>]/g, _xmlEncoder) ); case CDATA_SECTION_NODE: return buf.push(''); case COMMENT_NODE: return buf.push(""); case DOCUMENT_TYPE_NODE: var pubid = node.publicId; var sysid = node.systemId; buf.push(''); } else if (sysid && sysid != '.') { buf.push(' SYSTEM ', sysid, '>'); } else { var sub = node.internalSubset; if (sub) { buf.push(" [", sub, "]"); } buf.push(">"); } return; case PROCESSING_INSTRUCTION_NODE: return buf.push(""); case ENTITY_REFERENCE_NODE: return buf.push('&', node.nodeName, ';'); //case ENTITY_NODE: //case NOTATION_NODE: default: buf.push('??', node.nodeName); } } function importNode(doc, node, deep) { var node2; switch (node.nodeType) { case ELEMENT_NODE: node2 = node.cloneNode(false); node2.ownerDocument = doc; //var attrs = node2.attributes; //var len = attrs.length; //for(var i=0;i', lt: '<', quot: '"' }) /** * A map of currently 241 entities that are detected in an HTML document. * They contain all entries from `XML_ENTITIES`. * * @see XML_ENTITIES * @see DOMParser.parseFromString * @see DOMImplementation.prototype.createHTMLDocument * @see https://html.spec.whatwg.org/#named-character-references WHATWG HTML(5) Spec * @see https://www.w3.org/TR/xml-entity-names/ W3C XML Entity Names * @see https://www.w3.org/TR/html4/sgml/entities.html W3C HTML4/SGML * @see https://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references#Character_entity_references_in_HTML Wikipedia (HTML) * @see https://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references#Entities_representing_special_characters_in_XHTML Wikpedia (XHTML) */ exports.HTML_ENTITIES = freeze({ lt: '<', gt: '>', amp: '&', quot: '"', apos: "'", Agrave: "À", Aacute: "Á", Acirc: "Â", Atilde: "Ã", Auml: "Ä", Aring: "Å", AElig: "Æ", Ccedil: "Ç", Egrave: "È", Eacute: "É", Ecirc: "Ê", Euml: "Ë", Igrave: "Ì", Iacute: "Í", Icirc: "Î", Iuml: "Ï", ETH: "Ð", Ntilde: "Ñ", Ograve: "Ò", Oacute: "Ó", Ocirc: "Ô", Otilde: "Õ", Ouml: "Ö", Oslash: "Ø", Ugrave: "Ù", Uacute: "Ú", Ucirc: "Û", Uuml: "Ü", Yacute: "Ý", THORN: "Þ", szlig: "ß", agrave: "à", aacute: "á", acirc: "â", atilde: "ã", auml: "ä", aring: "å", aelig: "æ", ccedil: "ç", egrave: "è", eacute: "é", ecirc: "ê", euml: "ë", igrave: "ì", iacute: "í", icirc: "î", iuml: "ï", eth: "ð", ntilde: "ñ", ograve: "ò", oacute: "ó", ocirc: "ô", otilde: "õ", ouml: "ö", oslash: "ø", ugrave: "ù", uacute: "ú", ucirc: "û", uuml: "ü", yacute: "ý", thorn: "þ", yuml: "ÿ", nbsp: "\u00a0", iexcl: "¡", cent: "¢", pound: "£", curren: "¤", yen: "¥", brvbar: "¦", sect: "§", uml: "¨", copy: "©", ordf: "ª", laquo: "«", not: "¬", shy: "­­", reg: "®", macr: "¯", deg: "°", plusmn: "±", sup2: "²", sup3: "³", acute: "´", micro: "µ", para: "¶", middot: "·", cedil: "¸", sup1: "¹", ordm: "º", raquo: "»", frac14: "¼", frac12: "½", frac34: "¾", iquest: "¿", times: "×", divide: "÷", forall: "∀", part: "∂", exist: "∃", empty: "∅", nabla: "∇", isin: "∈", notin: "∉", ni: "∋", prod: "∏", sum: "∑", minus: "−", lowast: "∗", radic: "√", prop: "∝", infin: "∞", ang: "∠", and: "∧", or: "∨", cap: "∩", cup: "∪", 'int': "∫", there4: "∴", sim: "∼", cong: "≅", asymp: "≈", ne: "≠", equiv: "≡", le: "≤", ge: "≥", sub: "⊂", sup: "⊃", nsub: "⊄", sube: "⊆", supe: "⊇", oplus: "⊕", otimes: "⊗", perp: "⊥", sdot: "⋅", Alpha: "Α", Beta: "Β", Gamma: "Γ", Delta: "Δ", Epsilon: "Ε", Zeta: "Ζ", Eta: "Η", Theta: "Θ", Iota: "Ι", Kappa: "Κ", Lambda: "Λ", Mu: "Μ", Nu: "Ν", Xi: "Ξ", Omicron: "Ο", Pi: "Π", Rho: "Ρ", Sigma: "Σ", Tau: "Τ", Upsilon: "Υ", Phi: "Φ", Chi: "Χ", Psi: "Ψ", Omega: "Ω", alpha: "α", beta: "β", gamma: "γ", delta: "δ", epsilon: "ε", zeta: "ζ", eta: "η", theta: "θ", iota: "ι", kappa: "κ", lambda: "λ", mu: "μ", nu: "ν", xi: "ξ", omicron: "ο", pi: "π", rho: "ρ", sigmaf: "ς", sigma: "σ", tau: "τ", upsilon: "υ", phi: "φ", chi: "χ", psi: "ψ", omega: "ω", thetasym: "ϑ", upsih: "ϒ", piv: "ϖ", OElig: "Œ", oelig: "œ", Scaron: "Š", scaron: "š", Yuml: "Ÿ", fnof: "ƒ", circ: "ˆ", tilde: "˜", ensp: " ", emsp: " ", thinsp: " ", zwnj: "‌", zwj: "‍", lrm: "‎", rlm: "‏", ndash: "–", mdash: "—", lsquo: "‘", rsquo: "’", sbquo: "‚", ldquo: "“", rdquo: "”", bdquo: "„", dagger: "†", Dagger: "‡", bull: "•", hellip: "…", permil: "‰", prime: "′", Prime: "″", lsaquo: "‹", rsaquo: "›", oline: "‾", euro: "€", trade: "™", larr: "←", uarr: "↑", rarr: "→", darr: "↓", harr: "↔", crarr: "↵", lceil: "⌈", rceil: "⌉", lfloor: "⌊", rfloor: "⌋", loz: "◊", spades: "♠", clubs: "♣", hearts: "♥", diams: "♦" }); /** * @deprecated use `HTML_ENTITIES` instead * @see HTML_ENTITIES */ exports.entityMap = exports.HTML_ENTITIES }, { "./conventions": 41 }], 45: [function (require, module, exports) { var dom = require('./dom') exports.DOMImplementation = dom.DOMImplementation exports.XMLSerializer = dom.XMLSerializer exports.DOMParser = require('./dom-parser').DOMParser }, { "./dom": 43, "./dom-parser": 42 }], 46: [function (require, module, exports) { var NAMESPACE = require("./conventions").NAMESPACE; //[4] NameStartChar ::= ":" | [A-Z] | "_" | [a-z] | [#xC0-#xD6] | [#xD8-#xF6] | [#xF8-#x2FF] | [#x370-#x37D] | [#x37F-#x1FFF] | [#x200C-#x200D] | [#x2070-#x218F] | [#x2C00-#x2FEF] | [#x3001-#xD7FF] | [#xF900-#xFDCF] | [#xFDF0-#xFFFD] | [#x10000-#xEFFFF] //[4a] NameChar ::= NameStartChar | "-" | "." | [0-9] | #xB7 | [#x0300-#x036F] | [#x203F-#x2040] //[5] Name ::= NameStartChar (NameChar)* var nameStartChar = /[A-Z_a-z\xC0-\xD6\xD8-\xF6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]///\u10000-\uEFFFF var nameChar = new RegExp("[\\-\\.0-9" + nameStartChar.source.slice(1, -1) + "\\u00B7\\u0300-\\u036F\\u203F-\\u2040]"); var tagNamePattern = new RegExp('^' + nameStartChar.source + nameChar.source + '*(?:\:' + nameStartChar.source + nameChar.source + '*)?$'); //var tagNamePattern = /^[a-zA-Z_][\w\-\.]*(?:\:[a-zA-Z_][\w\-\.]*)?$/ //var handlers = 'resolveEntity,getExternalSubset,characters,endDocument,endElement,endPrefixMapping,ignorableWhitespace,processingInstruction,setDocumentLocator,skippedEntity,startDocument,startElement,startPrefixMapping,notationDecl,unparsedEntityDecl,error,fatalError,warning,attributeDecl,elementDecl,externalEntityDecl,internalEntityDecl,comment,endCDATA,endDTD,endEntity,startCDATA,startDTD,startEntity'.split(',') //S_TAG, S_ATTR, S_EQ, S_ATTR_NOQUOT_VALUE //S_ATTR_SPACE, S_ATTR_END, S_TAG_SPACE, S_TAG_CLOSE var S_TAG = 0;//tag name offerring var S_ATTR = 1;//attr name offerring var S_ATTR_SPACE = 2;//attr name end and space offer var S_EQ = 3;//=space? var S_ATTR_NOQUOT_VALUE = 4;//attr value(no quot value only) var S_ATTR_END = 5;//attr value end and no space(quot end) var S_TAG_SPACE = 6;//(attr value end || tag end ) && (space offer) var S_TAG_CLOSE = 7;//closed el /** * Creates an error that will not be caught by XMLReader aka the SAX parser. * * @param {string} message * @param {any?} locator Optional, can provide details about the location in the source * @constructor */ function ParseError(message, locator) { this.message = message this.locator = locator if (Error.captureStackTrace) Error.captureStackTrace(this, ParseError); } ParseError.prototype = new Error(); ParseError.prototype.name = ParseError.name function XMLReader() { } XMLReader.prototype = { parse: function (source, defaultNSMap, entityMap) { var domBuilder = this.domBuilder; domBuilder.startDocument(); _copy(defaultNSMap, defaultNSMap = {}) parse(source, defaultNSMap, entityMap, domBuilder, this.errorHandler); domBuilder.endDocument(); } } function parse(source, defaultNSMapCopy, entityMap, domBuilder, errorHandler) { function fixedFromCharCode(code) { // String.prototype.fromCharCode does not supports // > 2 bytes unicode chars directly if (code > 0xffff) { code -= 0x10000; var surrogate1 = 0xd800 + (code >> 10) , surrogate2 = 0xdc00 + (code & 0x3ff); return String.fromCharCode(surrogate1, surrogate2); } else { return String.fromCharCode(code); } } function entityReplacer(a) { var k = a.slice(1, -1); if (Object.hasOwnProperty.call(entityMap, k)) { return entityMap[k]; } else if (k.charAt(0) === '#') { return fixedFromCharCode(parseInt(k.substr(1).replace('x', '0x'))) } else { errorHandler.error('entity not found:' + a); return a; } } function appendText(end) {//has some bugs if (end > start) { var xt = source.substring(start, end).replace(/&#?\w+;/g, entityReplacer); locator && position(start); domBuilder.characters(xt, 0, end - start); start = end } } function position(p, m) { while (p >= lineEnd && (m = linePattern.exec(source))) { lineStart = m.index; lineEnd = lineStart + m[0].length; locator.lineNumber++; //console.log('line++:',locator,startPos,endPos) } locator.columnNumber = p - lineStart + 1; } var lineStart = 0; var lineEnd = 0; var linePattern = /.*(?:\r\n?|\n)|.*$/g var locator = domBuilder.locator; var parseStack = [{ currentNSMap: defaultNSMapCopy }] var closeMap = {}; var start = 0; while (true) { try { var tagStart = source.indexOf('<', start); if (tagStart < 0) { if (!source.substr(start).match(/^\s*$/)) { var doc = domBuilder.doc; var text = doc.createTextNode(source.substr(start)); doc.appendChild(text); domBuilder.currentElement = text; } return; } if (tagStart > start) { appendText(tagStart); } switch (source.charAt(tagStart + 1)) { case '/': var end = source.indexOf('>', tagStart + 3); var tagName = source.substring(tagStart + 2, end).replace(/[ \t\n\r]+$/g, ''); var config = parseStack.pop(); if (end < 0) { tagName = source.substring(tagStart + 2).replace(/[\s<].*/, ''); errorHandler.error("end tag name: " + tagName + ' is not complete:' + config.tagName); end = tagStart + 1 + tagName.length; } else if (tagName.match(/\s locator && position(tagStart); end = parseInstruction(source, tagStart, domBuilder); break; case '!':// start) { start = end; } else { //TODO: 这里有可能sax回退,有位置错误风险 appendText(Math.max(tagStart, start) + 1); } } } function copyLocator(f, t) { t.lineNumber = f.lineNumber; t.columnNumber = f.columnNumber; return t; } /** * @see #appendElement(source,elStartEnd,el,selfClosed,entityReplacer,domBuilder,parseStack); * @return end of the elementStartPart(end of elementEndPart for selfClosed el) */ function parseElementStartPart(source, start, el, currentNSMap, entityReplacer, errorHandler) { /** * @param {string} qname * @param {string} value * @param {number} startIndex */ function addAttribute(qname, value, startIndex) { if (el.attributeNames.hasOwnProperty(qname)) { errorHandler.fatalError('Attribute ' + qname + ' redefined') } el.addValue( qname, // @see https://www.w3.org/TR/xml/#AVNormalize // since the xmldom sax parser does not "interpret" DTD the following is not implemented: // - recursive replacement of (DTD) entity references // - trimming and collapsing multiple spaces into a single one for attributes that are not of type CDATA value.replace(/[\t\n\r]/g, ' ').replace(/&#?\w+;/g, entityReplacer), startIndex ) } var attrName; var value; var p = ++start; var s = S_TAG;//status while (true) { var c = source.charAt(p); switch (c) { case '=': if (s === S_ATTR) {//attrName attrName = source.slice(start, p); s = S_EQ; } else if (s === S_ATTR_SPACE) { s = S_EQ; } else { //fatalError: equal must after attrName or space after attrName throw new Error('attribute equal must after attrName'); // No known test case } break; case '\'': case '"': if (s === S_EQ || s === S_ATTR //|| s == S_ATTR_SPACE ) {//equal if (s === S_ATTR) { errorHandler.warning('attribute value must after "="') attrName = source.slice(start, p) } start = p + 1; p = source.indexOf(c, start) if (p > 0) { value = source.slice(start, p); addAttribute(attrName, value, start - 1); s = S_ATTR_END; } else { //fatalError: no end quot match throw new Error('attribute value no end \'' + c + '\' match'); } } else if (s == S_ATTR_NOQUOT_VALUE) { value = source.slice(start, p); addAttribute(attrName, value, start); errorHandler.warning('attribute "' + attrName + '" missed start quot(' + c + ')!!'); start = p + 1; s = S_ATTR_END } else { //fatalError: no equal before throw new Error('attribute value must after "="'); // No known test case } break; case '/': switch (s) { case S_TAG: el.setTagName(source.slice(start, p)); case S_ATTR_END: case S_TAG_SPACE: case S_TAG_CLOSE: s = S_TAG_CLOSE; el.closed = true; case S_ATTR_NOQUOT_VALUE: case S_ATTR: case S_ATTR_SPACE: break; //case S_EQ: default: throw new Error("attribute invalid close char('/')") // No known test case } break; case ''://end document errorHandler.error('unexpected end of input'); if (s == S_TAG) { el.setTagName(source.slice(start, p)); } return p; case '>': switch (s) { case S_TAG: el.setTagName(source.slice(start, p)); case S_ATTR_END: case S_TAG_SPACE: case S_TAG_CLOSE: break;//normal case S_ATTR_NOQUOT_VALUE://Compatible state case S_ATTR: value = source.slice(start, p); if (value.slice(-1) === '/') { el.closed = true; value = value.slice(0, -1) } case S_ATTR_SPACE: if (s === S_ATTR_SPACE) { value = attrName; } if (s == S_ATTR_NOQUOT_VALUE) { errorHandler.warning('attribute "' + value + '" missed quot(")!'); addAttribute(attrName, value, start) } else { if (!NAMESPACE.isHTML(currentNSMap['']) || !value.match(/^(?:disabled|checked|selected)$/i)) { errorHandler.warning('attribute "' + value + '" missed value!! "' + value + '" instead!!') } addAttribute(value, value, start) } break; case S_EQ: throw new Error('attribute value missed!!'); } // console.log(tagName,tagNamePattern,tagNamePattern.test(tagName)) return p; /*xml space '\x20' | #x9 | #xD | #xA; */ case '\u0080': c = ' '; default: if (c <= ' ') {//space switch (s) { case S_TAG: el.setTagName(source.slice(start, p));//tagName s = S_TAG_SPACE; break; case S_ATTR: attrName = source.slice(start, p) s = S_ATTR_SPACE; break; case S_ATTR_NOQUOT_VALUE: var value = source.slice(start, p); errorHandler.warning('attribute "' + value + '" missed quot(")!!'); addAttribute(attrName, value, start) case S_ATTR_END: s = S_TAG_SPACE; break; //case S_TAG_SPACE: //case S_EQ: //case S_ATTR_SPACE: // void();break; //case S_TAG_CLOSE: //ignore warning } } else {//not space //S_TAG, S_ATTR, S_EQ, S_ATTR_NOQUOT_VALUE //S_ATTR_SPACE, S_ATTR_END, S_TAG_SPACE, S_TAG_CLOSE switch (s) { //case S_TAG:void();break; //case S_ATTR:void();break; //case S_ATTR_NOQUOT_VALUE:void();break; case S_ATTR_SPACE: var tagName = el.tagName; if (!NAMESPACE.isHTML(currentNSMap['']) || !attrName.match(/^(?:disabled|checked|selected)$/i)) { errorHandler.warning('attribute "' + attrName + '" missed value!! "' + attrName + '" instead2!!') } addAttribute(attrName, attrName, start); start = p; s = S_ATTR; break; case S_ATTR_END: errorHandler.warning('attribute space is required"' + attrName + '"!!') case S_TAG_SPACE: s = S_ATTR; start = p; break; case S_EQ: s = S_ATTR_NOQUOT_VALUE; start = p; break; case S_TAG_CLOSE: throw new Error("elements closed character '/' and '>' must be connected to"); } } }//end outer switch //console.log('p++',p) p++; } } /** * @return true if has new namespace define */ function appendElement(el, domBuilder, currentNSMap) { var tagName = el.tagName; var localNSMap = null; //var currentNSMap = parseStack[parseStack.length-1].currentNSMap; var i = el.length; while (i--) { var a = el[i]; var qName = a.qName; var value = a.value; var nsp = qName.indexOf(':'); if (nsp > 0) { var prefix = a.prefix = qName.slice(0, nsp); var localName = qName.slice(nsp + 1); var nsPrefix = prefix === 'xmlns' && localName } else { localName = qName; prefix = null nsPrefix = qName === 'xmlns' && '' } //can not set prefix,because prefix !== '' a.localName = localName; //prefix == null for no ns prefix attribute if (nsPrefix !== false) {//hack!! if (localNSMap == null) { localNSMap = {} //console.log(currentNSMap,0) _copy(currentNSMap, currentNSMap = {}) //console.log(currentNSMap,1) } currentNSMap[nsPrefix] = localNSMap[nsPrefix] = value; a.uri = NAMESPACE.XMLNS domBuilder.startPrefixMapping(nsPrefix, value) } } var i = el.length; while (i--) { a = el[i]; var prefix = a.prefix; if (prefix) {//no prefix attribute has no namespace if (prefix === 'xml') { a.uri = NAMESPACE.XML; } if (prefix !== 'xmlns') { a.uri = currentNSMap[prefix || ''] //{console.log('###'+a.qName,domBuilder.locator.systemId+'',currentNSMap,a.uri)} } } } var nsp = tagName.indexOf(':'); if (nsp > 0) { prefix = el.prefix = tagName.slice(0, nsp); localName = el.localName = tagName.slice(nsp + 1); } else { prefix = null;//important!! localName = el.localName = tagName; } //no prefix element has default namespace var ns = el.uri = currentNSMap[prefix || '']; domBuilder.startElement(ns, localName, tagName, el); //endPrefixMapping and startPrefixMapping have not any help for dom builder //localNSMap = null if (el.closed) { domBuilder.endElement(ns, localName, tagName); if (localNSMap) { for (prefix in localNSMap) { if (Object.prototype.hasOwnProperty.call(localNSMap, prefix)) { domBuilder.endPrefixMapping(prefix); } } } } else { el.currentNSMap = currentNSMap; el.localNSMap = localNSMap; //parseStack.push(el); return true; } } function parseHtmlSpecialContent(source, elStartEnd, tagName, entityReplacer, domBuilder) { if (/^(?:script|textarea)$/i.test(tagName)) { var elEndStart = source.indexOf('', elStartEnd); var text = source.substring(elStartEnd + 1, elEndStart); if (/[&<]/.test(text)) { if (/^script$/i.test(tagName)) { //if(!/\]\]>/.test(text)){ //lexHandler.startCDATA(); domBuilder.characters(text, 0, text.length); //lexHandler.endCDATA(); return elEndStart; //} }//}else{//text area text = text.replace(/&#?\w+;/g, entityReplacer); domBuilder.characters(text, 0, text.length); return elEndStart; //} } } return elStartEnd + 1; } function fixSelfClosed(source, elStartEnd, tagName, closeMap) { //if(tagName in closeMap){ var pos = closeMap[tagName]; if (pos == null) { //console.log(tagName) pos = source.lastIndexOf('') if (pos < elStartEnd) {//忘记闭合 pos = source.lastIndexOf('', start + 4); //append comment source.substring(4,end)//' + this.endline(node)); }; XMLStreamWriter.prototype.declaration = function (node, level) { this.stream.write(this.space(level)); this.stream.write(''); return this.stream.write(this.endline(node)); }; XMLStreamWriter.prototype.docType = function (node, level) { var child, i, len, ref; level || (level = 0); this.stream.write(this.space(level)); this.stream.write(' 0) { this.stream.write(' ['); this.stream.write(this.endline(node)); ref = node.children; for (i = 0, len = ref.length; i < len; i++) { child = ref[i]; switch (false) { case !(child instanceof XMLDTDAttList): this.dtdAttList(child, level + 1); break; case !(child instanceof XMLDTDElement): this.dtdElement(child, level + 1); break; case !(child instanceof XMLDTDEntity): this.dtdEntity(child, level + 1); break; case !(child instanceof XMLDTDNotation): this.dtdNotation(child, level + 1); break; case !(child instanceof XMLCData): this.cdata(child, level + 1); break; case !(child instanceof XMLComment): this.comment(child, level + 1); break; case !(child instanceof XMLProcessingInstruction): this.processingInstruction(child, level + 1); break; default: throw new Error("Unknown DTD node type: " + child.constructor.name); } } this.stream.write(']'); } this.stream.write(this.spacebeforeslash + '>'); return this.stream.write(this.endline(node)); }; XMLStreamWriter.prototype.element = function (node, level) { var att, child, i, len, name, ref, ref1, space; level || (level = 0); space = this.space(level); this.stream.write(space + '<' + node.name); ref = node.attributes; for (name in ref) { if (!hasProp.call(ref, name)) continue; att = ref[name]; this.attribute(att); } if (node.children.length === 0 || node.children.every(function (e) { return e.value === ''; })) { if (this.allowEmpty) { this.stream.write('>'); } else { this.stream.write(this.spacebeforeslash + '/>'); } } else if (this.pretty && node.children.length === 1 && (node.children[0].value != null)) { this.stream.write('>'); this.stream.write(node.children[0].value); this.stream.write(''); } else { this.stream.write('>' + this.newline); ref1 = node.children; for (i = 0, len = ref1.length; i < len; i++) { child = ref1[i]; switch (false) { case !(child instanceof XMLCData): this.cdata(child, level + 1); break; case !(child instanceof XMLComment): this.comment(child, level + 1); break; case !(child instanceof XMLElement): this.element(child, level + 1); break; case !(child instanceof XMLRaw): this.raw(child, level + 1); break; case !(child instanceof XMLText): this.text(child, level + 1); break; case !(child instanceof XMLProcessingInstruction): this.processingInstruction(child, level + 1); break; default: throw new Error("Unknown XML node type: " + child.constructor.name); } } this.stream.write(space + ''); } return this.stream.write(this.endline(node)); }; XMLStreamWriter.prototype.processingInstruction = function (node, level) { this.stream.write(this.space(level) + '' + this.endline(node)); }; XMLStreamWriter.prototype.raw = function (node, level) { return this.stream.write(this.space(level) + node.value + this.endline(node)); }; XMLStreamWriter.prototype.text = function (node, level) { return this.stream.write(this.space(level) + node.value + this.endline(node)); }; XMLStreamWriter.prototype.dtdAttList = function (node, level) { this.stream.write(this.space(level) + '' + this.endline(node)); }; XMLStreamWriter.prototype.dtdElement = function (node, level) { this.stream.write(this.space(level) + '' + this.endline(node)); }; XMLStreamWriter.prototype.dtdEntity = function (node, level) { this.stream.write(this.space(level) + '' + this.endline(node)); }; XMLStreamWriter.prototype.dtdNotation = function (node, level) { this.stream.write(this.space(level) + '' + this.endline(node)); }; XMLStreamWriter.prototype.endline = function (node) { if (!node.isLastRootNode) { return this.newline; } else { return ''; } }; return XMLStreamWriter; })(XMLWriterBase); }).call(this); }, { "./XMLCData": 109, "./XMLComment": 110, "./XMLDTDAttList": 111, "./XMLDTDElement": 112, "./XMLDTDEntity": 113, "./XMLDTDNotation": 114, "./XMLDeclaration": 115, "./XMLDocType": 116, "./XMLElement": 119, "./XMLProcessingInstruction": 121, "./XMLRaw": 122, "./XMLText": 126, "./XMLWriterBase": 127 }], 124: [function (require, module, exports) { // Generated by CoffeeScript 1.12.7 (function () { var XMLCData, XMLComment, XMLDTDAttList, XMLDTDElement, XMLDTDEntity, XMLDTDNotation, XMLDeclaration, XMLDocType, XMLElement, XMLProcessingInstruction, XMLRaw, XMLStringWriter, XMLText, XMLWriterBase, extend = function (child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, hasProp = {}.hasOwnProperty; XMLDeclaration = require('./XMLDeclaration'); XMLDocType = require('./XMLDocType'); XMLCData = require('./XMLCData'); XMLComment = require('./XMLComment'); XMLElement = require('./XMLElement'); XMLRaw = require('./XMLRaw'); XMLText = require('./XMLText'); XMLProcessingInstruction = require('./XMLProcessingInstruction'); XMLDTDAttList = require('./XMLDTDAttList'); XMLDTDElement = require('./XMLDTDElement'); XMLDTDEntity = require('./XMLDTDEntity'); XMLDTDNotation = require('./XMLDTDNotation'); XMLWriterBase = require('./XMLWriterBase'); module.exports = XMLStringWriter = (function (superClass) { extend(XMLStringWriter, superClass); function XMLStringWriter(options) { XMLStringWriter.__super__.constructor.call(this, options); } XMLStringWriter.prototype.document = function (doc) { var child, i, len, r, ref; this.textispresent = false; r = ''; ref = doc.children; for (i = 0, len = ref.length; i < len; i++) { child = ref[i]; r += (function () { switch (false) { case !(child instanceof XMLDeclaration): return this.declaration(child); case !(child instanceof XMLDocType): return this.docType(child); case !(child instanceof XMLComment): return this.comment(child); case !(child instanceof XMLProcessingInstruction): return this.processingInstruction(child); default: return this.element(child, 0); } }).call(this); } if (this.pretty && r.slice(-this.newline.length) === this.newline) { r = r.slice(0, -this.newline.length); } return r; }; XMLStringWriter.prototype.attribute = function (att) { return ' ' + att.name + '="' + att.value + '"'; }; XMLStringWriter.prototype.cdata = function (node, level) { return this.space(level) + '' + this.newline; }; XMLStringWriter.prototype.comment = function (node, level) { return this.space(level) + '' + this.newline; }; XMLStringWriter.prototype.declaration = function (node, level) { var r; r = this.space(level); r += ''; r += this.newline; return r; }; XMLStringWriter.prototype.docType = function (node, level) { var child, i, len, r, ref; level || (level = 0); r = this.space(level); r += ' 0) { r += ' ['; r += this.newline; ref = node.children; for (i = 0, len = ref.length; i < len; i++) { child = ref[i]; r += (function () { switch (false) { case !(child instanceof XMLDTDAttList): return this.dtdAttList(child, level + 1); case !(child instanceof XMLDTDElement): return this.dtdElement(child, level + 1); case !(child instanceof XMLDTDEntity): return this.dtdEntity(child, level + 1); case !(child instanceof XMLDTDNotation): return this.dtdNotation(child, level + 1); case !(child instanceof XMLCData): return this.cdata(child, level + 1); case !(child instanceof XMLComment): return this.comment(child, level + 1); case !(child instanceof XMLProcessingInstruction): return this.processingInstruction(child, level + 1); default: throw new Error("Unknown DTD node type: " + child.constructor.name); } }).call(this); } r += ']'; } r += this.spacebeforeslash + '>'; r += this.newline; return r; }; XMLStringWriter.prototype.element = function (node, level) { var att, child, i, j, len, len1, name, r, ref, ref1, ref2, space, textispresentwasset; level || (level = 0); textispresentwasset = false; if (this.textispresent) { this.newline = ''; this.pretty = false; } else { this.newline = this.newlinedefault; this.pretty = this.prettydefault; } space = this.space(level); r = ''; r += space + '<' + node.name; ref = node.attributes; for (name in ref) { if (!hasProp.call(ref, name)) continue; att = ref[name]; r += this.attribute(att); } if (node.children.length === 0 || node.children.every(function (e) { return e.value === ''; })) { if (this.allowEmpty) { r += '>' + this.newline; } else { r += this.spacebeforeslash + '/>' + this.newline; } } else if (this.pretty && node.children.length === 1 && (node.children[0].value != null)) { r += '>'; r += node.children[0].value; r += '' + this.newline; } else { if (this.dontprettytextnodes) { ref1 = node.children; for (i = 0, len = ref1.length; i < len; i++) { child = ref1[i]; if (child.value != null) { this.textispresent++; textispresentwasset = true; break; } } } if (this.textispresent) { this.newline = ''; this.pretty = false; space = this.space(level); } r += '>' + this.newline; ref2 = node.children; for (j = 0, len1 = ref2.length; j < len1; j++) { child = ref2[j]; r += (function () { switch (false) { case !(child instanceof XMLCData): return this.cdata(child, level + 1); case !(child instanceof XMLComment): return this.comment(child, level + 1); case !(child instanceof XMLElement): return this.element(child, level + 1); case !(child instanceof XMLRaw): return this.raw(child, level + 1); case !(child instanceof XMLText): return this.text(child, level + 1); case !(child instanceof XMLProcessingInstruction): return this.processingInstruction(child, level + 1); default: throw new Error("Unknown XML node type: " + child.constructor.name); } }).call(this); } if (textispresentwasset) { this.textispresent--; } if (!this.textispresent) { this.newline = this.newlinedefault; this.pretty = this.prettydefault; } r += space + '' + this.newline; } return r; }; XMLStringWriter.prototype.processingInstruction = function (node, level) { var r; r = this.space(level) + '' + this.newline; return r; }; XMLStringWriter.prototype.raw = function (node, level) { return this.space(level) + node.value + this.newline; }; XMLStringWriter.prototype.text = function (node, level) { return this.space(level) + node.value + this.newline; }; XMLStringWriter.prototype.dtdAttList = function (node, level) { var r; r = this.space(level) + '' + this.newline; return r; }; XMLStringWriter.prototype.dtdElement = function (node, level) { return this.space(level) + '' + this.newline; }; XMLStringWriter.prototype.dtdEntity = function (node, level) { var r; r = this.space(level) + '' + this.newline; return r; }; XMLStringWriter.prototype.dtdNotation = function (node, level) { var r; r = this.space(level) + '' + this.newline; return r; }; XMLStringWriter.prototype.openNode = function (node, level) { var att, name, r, ref; level || (level = 0); if (node instanceof XMLElement) { r = this.space(level) + '<' + node.name; ref = node.attributes; for (name in ref) { if (!hasProp.call(ref, name)) continue; att = ref[name]; r += this.attribute(att); } r += (node.children ? '>' : '/>') + this.newline; return r; } else { r = this.space(level) + '') + this.newline; return r; } }; XMLStringWriter.prototype.closeNode = function (node, level) { level || (level = 0); switch (false) { case !(node instanceof XMLElement): return this.space(level) + '' + this.newline; case !(node instanceof XMLDocType): return this.space(level) + ']>' + this.newline; } }; return XMLStringWriter; })(XMLWriterBase); }).call(this); }, { "./XMLCData": 109, "./XMLComment": 110, "./XMLDTDAttList": 111, "./XMLDTDElement": 112, "./XMLDTDEntity": 113, "./XMLDTDNotation": 114, "./XMLDeclaration": 115, "./XMLDocType": 116, "./XMLElement": 119, "./XMLProcessingInstruction": 121, "./XMLRaw": 122, "./XMLText": 126, "./XMLWriterBase": 127 }], 125: [function (require, module, exports) { // Generated by CoffeeScript 1.12.7 (function () { var XMLStringifier, bind = function (fn, me) { return function () { return fn.apply(me, arguments); }; }, hasProp = {}.hasOwnProperty; module.exports = XMLStringifier = (function () { function XMLStringifier(options) { this.assertLegalChar = bind(this.assertLegalChar, this); var key, ref, value; options || (options = {}); this.noDoubleEncoding = options.noDoubleEncoding; ref = options.stringify || {}; for (key in ref) { if (!hasProp.call(ref, key)) continue; value = ref[key]; this[key] = value; } } XMLStringifier.prototype.eleName = function (val) { val = '' + val || ''; return this.assertLegalChar(val); }; XMLStringifier.prototype.eleText = function (val) { val = '' + val || ''; return this.assertLegalChar(this.elEscape(val)); }; XMLStringifier.prototype.cdata = function (val) { val = '' + val || ''; val = val.replace(']]>', ']]]]>'); return this.assertLegalChar(val); }; XMLStringifier.prototype.comment = function (val) { val = '' + val || ''; if (val.match(/--/)) { throw new Error("Comment text cannot contain double-hypen: " + val); } return this.assertLegalChar(val); }; XMLStringifier.prototype.raw = function (val) { return '' + val || ''; }; XMLStringifier.prototype.attName = function (val) { return val = '' + val || ''; }; XMLStringifier.prototype.attValue = function (val) { val = '' + val || ''; return this.attEscape(val); }; XMLStringifier.prototype.insTarget = function (val) { return '' + val || ''; }; XMLStringifier.prototype.insValue = function (val) { val = '' + val || ''; if (val.match(/\?>/)) { throw new Error("Invalid processing instruction value: " + val); } return val; }; XMLStringifier.prototype.xmlVersion = function (val) { val = '' + val || ''; if (!val.match(/1\.[0-9]+/)) { throw new Error("Invalid version number: " + val); } return val; }; XMLStringifier.prototype.xmlEncoding = function (val) { val = '' + val || ''; if (!val.match(/^[A-Za-z](?:[A-Za-z0-9._-])*$/)) { throw new Error("Invalid encoding: " + val); } return val; }; XMLStringifier.prototype.xmlStandalone = function (val) { if (val) { return "yes"; } else { return "no"; } }; XMLStringifier.prototype.dtdPubID = function (val) { return '' + val || ''; }; XMLStringifier.prototype.dtdSysID = function (val) { return '' + val || ''; }; XMLStringifier.prototype.dtdElementValue = function (val) { return '' + val || ''; }; XMLStringifier.prototype.dtdAttType = function (val) { return '' + val || ''; }; XMLStringifier.prototype.dtdAttDefault = function (val) { if (val != null) { return '' + val || ''; } else { return val; } }; XMLStringifier.prototype.dtdEntityValue = function (val) { return '' + val || ''; }; XMLStringifier.prototype.dtdNData = function (val) { return '' + val || ''; }; XMLStringifier.prototype.convertAttKey = '@'; XMLStringifier.prototype.convertPIKey = '?'; XMLStringifier.prototype.convertTextKey = '#text'; XMLStringifier.prototype.convertCDataKey = '#cdata'; XMLStringifier.prototype.convertCommentKey = '#comment'; XMLStringifier.prototype.convertRawKey = '#raw'; XMLStringifier.prototype.assertLegalChar = function (str) { var res; res = str.match(/[\0\uFFFE\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/); if (res) { throw new Error("Invalid character in string: " + str + " at index " + res.index); } return str; }; XMLStringifier.prototype.elEscape = function (str) { var ampregex; ampregex = this.noDoubleEncoding ? /(?!&\S+;)&/g : /&/g; return str.replace(ampregex, '&').replace(//g, '>').replace(/\r/g, ' '); }; XMLStringifier.prototype.attEscape = function (str) { var ampregex; ampregex = this.noDoubleEncoding ? /(?!&\S+;)&/g : /&/g; return str.replace(ampregex, '&').replace(/ 0) { return new Array(indent).join(this.indent); } else { return ''; } } else { return ''; } }; return XMLWriterBase; })(); }).call(this); }, {}], 128: [function (require, module, exports) { // Generated by CoffeeScript 1.12.7 (function () { var XMLDocument, XMLDocumentCB, XMLStreamWriter, XMLStringWriter, assign, isFunction, ref; ref = require('./Utility'), assign = ref.assign, isFunction = ref.isFunction; XMLDocument = require('./XMLDocument'); XMLDocumentCB = require('./XMLDocumentCB'); XMLStringWriter = require('./XMLStringWriter'); XMLStreamWriter = require('./XMLStreamWriter'); module.exports.create = function (name, xmldec, doctype, options) { var doc, root; if (name == null) { throw new Error("Root element needs a name."); } options = assign({}, xmldec, doctype, options); doc = new XMLDocument(options); root = doc.element(name); if (!options.headless) { doc.declaration(options); if ((options.pubID != null) || (options.sysID != null)) { doc.doctype(options); } } return root; }; module.exports.begin = function (options, onData, onEnd) { var ref1; if (isFunction(options)) { ref1 = [options, onData], onData = ref1[0], onEnd = ref1[1]; options = {}; } if (onData) { return new XMLDocumentCB(options, onData, onEnd); } else { return new XMLDocument(options); } }; module.exports.stringWriter = function (options) { return new XMLStringWriter(options); }; module.exports.streamWriter = function (stream, options) { return new XMLStreamWriter(stream, options); }; }).call(this); }, { "./Utility": 107, "./XMLDocument": 117, "./XMLDocumentCB": 118, "./XMLStreamWriter": 123, "./XMLStringWriter": 124 }] }, {}, [21])(21) });