You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							95 lines
						
					
					
						
							2.5 KiB
						
					
					
				
			
		
		
	
	
							95 lines
						
					
					
						
							2.5 KiB
						
					
					
				/* | 
						|
 Copyright 2012-2015, Yahoo Inc. | 
						|
 Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. | 
						|
 */ | 
						|
const INDENT = '  '; | 
						|
 | 
						|
/** | 
						|
 * a utility class to produce well-formed, indented XML | 
						|
 * @param {ContentWriter} contentWriter the content writer that this utility wraps | 
						|
 * @constructor | 
						|
 */ | 
						|
function XMLWriter(contentWriter) { | 
						|
    this.cw = contentWriter; | 
						|
    this.stack = []; | 
						|
} | 
						|
 | 
						|
function attrString(attrs) { | 
						|
    if (!attrs) { | 
						|
        return ''; | 
						|
    } | 
						|
    const ret = []; | 
						|
    Object.keys(attrs).forEach(k => { | 
						|
        const v = attrs[k]; | 
						|
        ret.push(k + '="' + v + '"'); | 
						|
    }); | 
						|
    return ret.length === 0 ? '' : ' ' + ret.join(' '); | 
						|
} | 
						|
 | 
						|
XMLWriter.prototype.indent = function(str) { | 
						|
    return this.stack.map(() => INDENT).join('') + str; | 
						|
}; | 
						|
 | 
						|
/** | 
						|
 * writes the opening XML tag with the supplied attributes | 
						|
 * @param {String} name tag name | 
						|
 * @param {Object} [attrs=null] attrs attributes for the tag | 
						|
 */ | 
						|
XMLWriter.prototype.openTag = function(name, attrs) { | 
						|
    const str = this.indent('<' + name + attrString(attrs) + '>'); | 
						|
    this.cw.println(str); | 
						|
    this.stack.push(name); | 
						|
}; | 
						|
 | 
						|
/** | 
						|
 * closes an open XML tag. | 
						|
 * @param {String} name - tag name to close. This must match the writer's | 
						|
 *  notion of the tag that is currently open. | 
						|
 */ | 
						|
XMLWriter.prototype.closeTag = function(name) { | 
						|
    if (this.stack.length === 0) { | 
						|
        throw new Error('Attempt to close tag ' + name + ' when not opened'); | 
						|
    } | 
						|
    const stashed = this.stack.pop(); | 
						|
    const str = '</' + name + '>'; | 
						|
 | 
						|
    if (stashed !== name) { | 
						|
        throw new Error( | 
						|
            'Attempt to close tag ' + | 
						|
                name + | 
						|
                ' when ' + | 
						|
                stashed + | 
						|
                ' was the one open' | 
						|
        ); | 
						|
    } | 
						|
    this.cw.println(this.indent(str)); | 
						|
}; | 
						|
/** | 
						|
 * writes a tag and its value opening and closing it at the same time | 
						|
 * @param {String} name tag name | 
						|
 * @param {Object} [attrs=null] attrs tag attributes | 
						|
 * @param {String} [content=null] content optional tag content | 
						|
 */ | 
						|
XMLWriter.prototype.inlineTag = function(name, attrs, content) { | 
						|
    let str = '<' + name + attrString(attrs); | 
						|
    if (content) { | 
						|
        str += '>' + content + '</' + name + '>'; | 
						|
    } else { | 
						|
        str += '/>'; | 
						|
    } | 
						|
    str = this.indent(str); | 
						|
    this.cw.println(str); | 
						|
}; | 
						|
/** | 
						|
 * closes all open tags and ends the document | 
						|
 */ | 
						|
XMLWriter.prototype.closeAll = function() { | 
						|
    this.stack | 
						|
        .slice() | 
						|
        .reverse() | 
						|
        .forEach(name => { | 
						|
            this.closeTag(name); | 
						|
        }); | 
						|
}; | 
						|
 | 
						|
module.exports = XMLWriter;
 | 
						|
 |