UNPKG

2.46 kBJavaScriptView Raw
1/*
2 Copyright 2012-2015, Yahoo Inc.
3 Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
4 */
5var INDENT = ' ';
6
7/**
8 * a utility class to produce well-formed, indented XML
9 * @param {ContentWriter} contentWriter the content writer that this utility wraps
10 * @constructor
11 */
12function XMLWriter(contentWriter) {
13 this.cw = contentWriter;
14 this.stack = [];
15}
16
17function attrString(attrs) {
18 if (!attrs) {
19 return '';
20 }
21 var ret = [];
22 Object.keys(attrs).forEach(function (k) {
23 var v = attrs[k];
24 ret.push(k + '="' + v + '"');
25 });
26 return ret.length === 0 ? '' : ' ' + ret.join(' ');
27}
28
29XMLWriter.prototype.indent = function (str) {
30 return this.stack.map(function () { return INDENT; }).join('') + str;
31};
32
33/**
34 * writes the opening XML tag with the supplied attributes
35 * @param {String} name tag name
36 * @param {Object} [attrs=null] attrs attributes for the tag
37 */
38XMLWriter.prototype.openTag = function (name, attrs) {
39 var str = this.indent('<' + name + attrString(attrs) + '>');
40 this.cw.println(str);
41 this.stack.push(name);
42};
43
44/**
45 * closes an open XML tag.
46 * @param {String} name - tag name to close. This must match the writer's
47 * notion of the tag that is currently open.
48 */
49XMLWriter.prototype.closeTag = function (name) {
50 if (this.stack.length === 0) {
51 throw new Error('Attempt to close tag ' + name + ' when not opened');
52 }
53 var stashed = this.stack.pop(),
54 str = '</' + name + '>';
55
56 if (stashed !== name) {
57 throw new Error('Attempt to close tag ' + name + ' when ' + stashed + ' was the one open');
58 }
59 this.cw.println(this.indent(str));
60};
61/**
62 * writes a tag and its value opening and closing it at the same time
63 * @param {String} name tag name
64 * @param {Object} [attrs=null] attrs tag attributes
65 * @param {String} [content=null] content optional tag content
66 */
67XMLWriter.prototype.inlineTag = function (name, attrs, content) {
68 var str = '<' + name + attrString(attrs);
69 if (content) {
70 str += '>' + content + '</' + name + '>';
71 } else {
72 str += '/>';
73 }
74 str = this.indent(str);
75 this.cw.println(str);
76};
77/**
78 * closes all open tags and ends the document
79 */
80XMLWriter.prototype.closeAll = function () {
81 var that = this;
82 this.stack.slice().reverse().forEach(function (name) {
83 that.closeTag(name);
84 });
85};
86
87module.exports = XMLWriter;