Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

xml-formatter

Package Overview
Dependencies
Maintainers
1
Versions
39
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

xml-formatter - npm Package Compare versions

Comparing version 2.1.3 to 2.2.0

142

dist/browser/xml-formatter.js

@@ -245,36 +245,50 @@ require=(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){

* @typedef {Object} XMLFormatterOptions
* @property {string} [indentation=' '] The value used for indentation
* @property {String} [indentation=' '] The value used for indentation
* @property {function(node): boolean} [filter] Return false to exclude the node.
* @property {boolean} [collapseContent=false] True to keep content in the same line as the element. Only works if element contains at least one text node
* @property {string} [lineSeparator='\r\n'] The line separator to use
* @property {string} [whiteSpaceAtEndOfSelfclosingTag=false] to either end ad self closing tag with `<tag/>` or `<tag />`
* @property {Boolean} [collapseContent=false] True to keep content in the same line as the element. Only works if element contains at least one text node
* @property {String} [lineSeparator='\r\n'] The line separator to use
* @property {String} [whiteSpaceAtEndOfSelfclosingTag=false] to either end ad self closing tag with `<tag/>` or `<tag />`
*/
/**
* @typedef {Object} XMLFormatterState
* @param {String} content
* @param {Number} level
* @param {XMLFormatterOptions} options
*/
/**
*
* @param {*} output
* @param {XMLFormatterState} state
* @return {void}
*/
function newLine(output) {
output.content += output.options.lineSeparator;
function newLine(state) {
state.content += state.options.lineSeparator;
let i;
for (i = 0; i < output.level; i++) {
output.content += output.options.indentation;
for (i = 0; i < state.level; i++) {
state.content += state.options.indentation;
}
}
function appendContent(output, content) {
output.content += content;
/**
* @param {XMLFormatterState} state
* @param {String} content
* @return {void}
*/
function appendContent(state, content) {
state.content += content;
}
/**
* @param {XMLFormatterOptions} options
* @param {Object} node
* @param {XMLFormatterState} state
* @param {Boolean} preserveSpace
* @return {void}
*/
function processNode(node, output, preserveSpace, options) {
function processNode(node, state, preserveSpace) {
if (typeof node.content === 'string') {
processContentNode(node, output, preserveSpace);
processContentNode(node, state, preserveSpace);
} else if (node.type === 'Element') {
processElement(node, output, preserveSpace, options);
processElementNode(node, state, preserveSpace);
} else if (node.type === 'ProcessingInstruction') {
processProcessingIntruction(node, output, preserveSpace);
processProcessingIntruction(node, state, preserveSpace);
} else {

@@ -285,3 +299,9 @@ throw new Error('Unknown node type: ' + node.type);

function processContentNode(node, output, preserveSpace) {
/**
* @param {Object} node
* @param {XMLFormatterState} state
* @param {Boolean} preserveSpace
* @return {void}
*/
function processContentNode(node, state, preserveSpace) {
if (!preserveSpace) {

@@ -291,6 +311,6 @@ node.content = node.content.trim();

if (node.content.length > 0) {
if (!preserveSpace && output.content.length > 0) {
newLine(output);
if (!preserveSpace && state.content.length > 0) {
newLine(state);
}
appendContent(output, node.content);
appendContent(state, node.content);
}

@@ -300,28 +320,31 @@ }

/**
* @param {XMLFormatterOptions} options
* @param {Object} node
* @param {XMLFormatterState} state
* @param {Boolean} preserveSpace
* @return {void}
*/
function processElement(node, output, preserveSpace, options) {
if (!preserveSpace && output.content.length > 0) {
newLine(output);
function processElementNode(node, state, preserveSpace) {
if (!preserveSpace && state.content.length > 0) {
newLine(state);
}
appendContent(output, '<' + node.name);
processAttributes(output, node.attributes);
appendContent(state, '<' + node.name);
processAttributes(state, node.attributes);
if (node.children === null) {
const selfClosingNodeClosingTag = options.whiteSpaceAtEndOfSelfclosingTag ? ' />' : '/>'
const selfClosingNodeClosingTag = state.options.whiteSpaceAtEndOfSelfclosingTag ? ' />' : '/>'
// self-closing node
appendContent(output, selfClosingNodeClosingTag);
appendContent(state, selfClosingNodeClosingTag);
} else if (node.children.length === 0) {
// empty node
appendContent(output, '></' + node.name + '>');
appendContent(state, '></' + node.name + '>');
} else {
appendContent(output, '>');
appendContent(state, '>');
output.level++;
state.level++;
let nodePreserveSpace = node.attributes['xml:space'] === 'preserve';
if (!nodePreserveSpace && output.options.collapseContent) {
if (!nodePreserveSpace && state.options.collapseContent) {

@@ -338,27 +361,37 @@ const containsTextNodes = node.children.some(function(child) {

node.children.forEach(function(child) {
processNode(child, output, preserveSpace || nodePreserveSpace, options);
processNode(child, state, preserveSpace || nodePreserveSpace, state.options);
});
output.level--;
state.level--;
if (!preserveSpace && !nodePreserveSpace) {
newLine(output);
newLine(state);
}
appendContent(output, '</' + node.name + '>');
appendContent(state, '</' + node.name + '>');
}
}
function processAttributes(output, attributes) {
/**
* @param {XMLFormatterState} state
* @param {Record<String, String>} attributes
* @return {void}
*/
function processAttributes(state, attributes) {
Object.keys(attributes).forEach(function(attr) {
appendContent(output, ' ' + attr + '="' + attributes[attr] + '"');
appendContent(state, ' ' + attr + '="' + attributes[attr] + '"');
});
}
function processProcessingIntruction(node, output) {
if (output.content.length > 0) {
newLine(output);
/**
* @param {Object} node
* @param {XMLFormatterState} state
* @return {void}
*/
function processProcessingIntruction(node, state) {
if (state.content.length > 0) {
newLine(state);
}
appendContent(output, '<?' + node.name);
processAttributes(output, node.attributes);
appendContent(output, '?>');
appendContent(state, '<?' + node.name);
processAttributes(state, node.attributes);
appendContent(state, '?>');
}

@@ -372,12 +405,5 @@

* @param {XMLFormatterOptions} options
* @config {String} [indentation=' '] The value used for indentation
* @config {function(node): boolean} [filter] Return false to exclude the node.
* @config {Boolean} [collapseContent=false] True to keep content in the same line as the element. Only works if element contains at least one text node
* @config {String} [lineSeparator='\r\n'] The line separator to use
* @config {string} [whiteSpaceAtEndOfSelfclosingTag=false] to either end with `<tag/>` or `<tag />`
* @returns {string}
*/
function format(xml, options = {}) {
options = options || {};
options.indentation = options.indentation || ' ';

@@ -388,15 +414,15 @@ options.collapseContent = options.collapseContent === true;

const parse = require('xml-parser-xo');
const parsedXml = parse(xml, {filter: options.filter});
const output = {content: '', level: 0, options: options};
const parser = require('xml-parser-xo');
const parsedXml = parser(xml, {filter: options.filter});
const state = {content: '', level: 0, options: options};
if (parsedXml.declaration) {
processProcessingIntruction(parsedXml.declaration, output);
processProcessingIntruction(parsedXml.declaration, state);
}
parsedXml.children.forEach(function(child) {
processNode(child, output, false, options);
processNode(child, state, false);
});
return output.content;
return state.content;
}

@@ -403,0 +429,0 @@

/**
* @typedef {Object} XMLFormatterOptions
* @property {string} [indentation=' '] The value used for indentation
* @property {String} [indentation=' '] The value used for indentation
* @property {function(node): boolean} [filter] Return false to exclude the node.
* @property {boolean} [collapseContent=false] True to keep content in the same line as the element. Only works if element contains at least one text node
* @property {string} [lineSeparator='\r\n'] The line separator to use
* @property {string} [whiteSpaceAtEndOfSelfclosingTag=false] to either end ad self closing tag with `<tag/>` or `<tag />`
* @property {Boolean} [collapseContent=false] True to keep content in the same line as the element. Only works if element contains at least one text node
* @property {String} [lineSeparator='\r\n'] The line separator to use
* @property {String} [whiteSpaceAtEndOfSelfclosingTag=false] to either end ad self closing tag with `<tag/>` or `<tag />`
*/
/**
* @typedef {Object} XMLFormatterState
* @param {String} content
* @param {Number} level
* @param {XMLFormatterOptions} options
*/
/**
*
* @param {*} output
* @param {XMLFormatterState} state
* @return {void}
*/
function newLine(output) {
output.content += output.options.lineSeparator;
function newLine(state) {
state.content += state.options.lineSeparator;
let i;
for (i = 0; i < output.level; i++) {
output.content += output.options.indentation;
for (i = 0; i < state.level; i++) {
state.content += state.options.indentation;
}
}
function appendContent(output, content) {
output.content += content;
/**
* @param {XMLFormatterState} state
* @param {String} content
* @return {void}
*/
function appendContent(state, content) {
state.content += content;
}
/**
* @param {XMLFormatterOptions} options
* @param {Object} node
* @param {XMLFormatterState} state
* @param {Boolean} preserveSpace
* @return {void}
*/
function processNode(node, output, preserveSpace, options) {
function processNode(node, state, preserveSpace) {
if (typeof node.content === 'string') {
processContentNode(node, output, preserveSpace);
processContentNode(node, state, preserveSpace);
} else if (node.type === 'Element') {
processElement(node, output, preserveSpace, options);
processElementNode(node, state, preserveSpace);
} else if (node.type === 'ProcessingInstruction') {
processProcessingIntruction(node, output, preserveSpace);
processProcessingIntruction(node, state, preserveSpace);
} else {

@@ -42,3 +56,9 @@ throw new Error('Unknown node type: ' + node.type);

function processContentNode(node, output, preserveSpace) {
/**
* @param {Object} node
* @param {XMLFormatterState} state
* @param {Boolean} preserveSpace
* @return {void}
*/
function processContentNode(node, state, preserveSpace) {
if (!preserveSpace) {

@@ -48,6 +68,6 @@ node.content = node.content.trim();

if (node.content.length > 0) {
if (!preserveSpace && output.content.length > 0) {
newLine(output);
if (!preserveSpace && state.content.length > 0) {
newLine(state);
}
appendContent(output, node.content);
appendContent(state, node.content);
}

@@ -57,28 +77,31 @@ }

/**
* @param {XMLFormatterOptions} options
* @param {Object} node
* @param {XMLFormatterState} state
* @param {Boolean} preserveSpace
* @return {void}
*/
function processElement(node, output, preserveSpace, options) {
if (!preserveSpace && output.content.length > 0) {
newLine(output);
function processElementNode(node, state, preserveSpace) {
if (!preserveSpace && state.content.length > 0) {
newLine(state);
}
appendContent(output, '<' + node.name);
processAttributes(output, node.attributes);
appendContent(state, '<' + node.name);
processAttributes(state, node.attributes);
if (node.children === null) {
const selfClosingNodeClosingTag = options.whiteSpaceAtEndOfSelfclosingTag ? ' />' : '/>'
const selfClosingNodeClosingTag = state.options.whiteSpaceAtEndOfSelfclosingTag ? ' />' : '/>'
// self-closing node
appendContent(output, selfClosingNodeClosingTag);
appendContent(state, selfClosingNodeClosingTag);
} else if (node.children.length === 0) {
// empty node
appendContent(output, '></' + node.name + '>');
appendContent(state, '></' + node.name + '>');
} else {
appendContent(output, '>');
appendContent(state, '>');
output.level++;
state.level++;
let nodePreserveSpace = node.attributes['xml:space'] === 'preserve';
if (!nodePreserveSpace && output.options.collapseContent) {
if (!nodePreserveSpace && state.options.collapseContent) {

@@ -95,27 +118,37 @@ const containsTextNodes = node.children.some(function(child) {

node.children.forEach(function(child) {
processNode(child, output, preserveSpace || nodePreserveSpace, options);
processNode(child, state, preserveSpace || nodePreserveSpace, state.options);
});
output.level--;
state.level--;
if (!preserveSpace && !nodePreserveSpace) {
newLine(output);
newLine(state);
}
appendContent(output, '</' + node.name + '>');
appendContent(state, '</' + node.name + '>');
}
}
function processAttributes(output, attributes) {
/**
* @param {XMLFormatterState} state
* @param {Record<String, String>} attributes
* @return {void}
*/
function processAttributes(state, attributes) {
Object.keys(attributes).forEach(function(attr) {
appendContent(output, ' ' + attr + '="' + attributes[attr] + '"');
appendContent(state, ' ' + attr + '="' + attributes[attr] + '"');
});
}
function processProcessingIntruction(node, output) {
if (output.content.length > 0) {
newLine(output);
/**
* @param {Object} node
* @param {XMLFormatterState} state
* @return {void}
*/
function processProcessingIntruction(node, state) {
if (state.content.length > 0) {
newLine(state);
}
appendContent(output, '<?' + node.name);
processAttributes(output, node.attributes);
appendContent(output, '?>');
appendContent(state, '<?' + node.name);
processAttributes(state, node.attributes);
appendContent(state, '?>');
}

@@ -129,12 +162,5 @@

* @param {XMLFormatterOptions} options
* @config {String} [indentation=' '] The value used for indentation
* @config {function(node): boolean} [filter] Return false to exclude the node.
* @config {Boolean} [collapseContent=false] True to keep content in the same line as the element. Only works if element contains at least one text node
* @config {String} [lineSeparator='\r\n'] The line separator to use
* @config {string} [whiteSpaceAtEndOfSelfclosingTag=false] to either end with `<tag/>` or `<tag />`
* @returns {string}
*/
function format(xml, options = {}) {
options = options || {};
options.indentation = options.indentation || ' ';

@@ -145,15 +171,15 @@ options.collapseContent = options.collapseContent === true;

const parse = require('xml-parser-xo');
const parsedXml = parse(xml, {filter: options.filter});
const output = {content: '', level: 0, options: options};
const parser = require('xml-parser-xo');
const parsedXml = parser(xml, {filter: options.filter});
const state = {content: '', level: 0, options: options};
if (parsedXml.declaration) {
processProcessingIntruction(parsedXml.declaration, output);
processProcessingIntruction(parsedXml.declaration, state);
}
parsedXml.children.forEach(function(child) {
processNode(child, output, false, options);
processNode(child, state, false);
});
return output.content;
return state.content;
}

@@ -160,0 +186,0 @@

{
"name": "xml-formatter",
"version": "2.1.3",
"version": "2.2.0",
"repository": "github:chrisbottin/xml-formatter",

@@ -34,3 +34,3 @@ "bugs": {

"dependencies": {
"xml-parser-xo": "^3.0.0"
"xml-parser-xo": "^3.1.0"
},

@@ -37,0 +37,0 @@ "devDependencies": {

@@ -24,3 +24,3 @@

var format = require('xml-formatter');
var xml = '<root>content><p xml:space="preserve">This is <b>some</b> content.</content></p>';
var xml = '<root><content><p xml:space="preserve">This is <b>some</b> content.</content></p>';

@@ -27,0 +27,0 @@ var formattedXml = format(xml);

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc