1 |
|
2 |
|
3 |
|
4 |
|
5 | var INDENT = ' ';
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 | function XMLWriter(contentWriter) {
|
13 | this.cw = contentWriter;
|
14 | this.stack = [];
|
15 | }
|
16 |
|
17 | function 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 |
|
29 | XMLWriter.prototype.indent = function (str) {
|
30 | return this.stack.map(function () { return INDENT; }).join('') + str;
|
31 | };
|
32 |
|
33 |
|
34 |
|
35 |
|
36 |
|
37 |
|
38 | XMLWriter.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 |
|
46 |
|
47 |
|
48 |
|
49 | XMLWriter.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 |
|
63 |
|
64 |
|
65 |
|
66 |
|
67 | XMLWriter.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 |
|
79 |
|
80 | XMLWriter.prototype.closeAll = function () {
|
81 | var that = this;
|
82 | this.stack.slice().reverse().forEach(function (name) {
|
83 | that.closeTag(name);
|
84 | });
|
85 | };
|
86 |
|
87 | module.exports = XMLWriter;
|