fast-xml-parser 5.3.7 → 5.3.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,16 +1,16 @@
1
- import {buildOptions,registerCommonValueParsers} from './ParserOptionsBuilder.js';
1
+ import { buildOptions, registerCommonValueParsers } from './ParserOptionsBuilder.js';
2
2
 
3
- export default class OutputBuilder{
4
- constructor(options){
3
+ export default class OutputBuilder {
4
+ constructor(options) {
5
5
  this.options = buildOptions(options);
6
- this.registeredParsers = registerCommonValueParsers(this.options);
7
- }
8
-
9
- registerValueParser(name,parserInstance){//existing name will override the parser without warning
10
- this.registeredParsers[name] = parserInstance;
11
- }
6
+ this.registeredParsers = registerCommonValueParsers(this.options);
7
+ }
8
+
9
+ registerValueParser(name, parserInstance) {//existing name will override the parser without warning
10
+ this.registeredParsers[name] = parserInstance;
11
+ }
12
12
 
13
- getInstance(parserOptions){
13
+ getInstance(parserOptions) {
14
14
  return new JsArrBuilder(parserOptions, this.options, this.registeredParsers);
15
15
  }
16
16
  }
@@ -18,9 +18,9 @@ export default class OutputBuilder{
18
18
  const rootName = '!js_arr';
19
19
  import BaseOutputBuilder from './BaseOutputBuilder.js';
20
20
 
21
- class JsArrBuilder extends BaseOutputBuilder{
21
+ class JsArrBuilder extends BaseOutputBuilder {
22
22
 
23
- constructor(parserOptions, options,registeredParsers) {
23
+ constructor(parserOptions, options, registeredParsers) {
24
24
  super();
25
25
  this.tagsStack = [];
26
26
  this.parserOptions = parserOptions;
@@ -32,10 +32,10 @@ class JsArrBuilder extends BaseOutputBuilder{
32
32
  this.attributes = {};
33
33
  }
34
34
 
35
- addTag(tag){
35
+ addTag(tag) {
36
36
  //when a new tag is added, it should be added as child of current node
37
37
  //TODO: shift this check to the parser
38
- if(tag.name === "__proto__") tag.name = "#__proto__";
38
+ if (tag.name === "__proto__") tag.name = "#__proto__";
39
39
 
40
40
  this.tagsStack.push(this.currentNode);
41
41
  this.currentNode = new Node(tag.name, this.attributes);
@@ -47,23 +47,23 @@ class JsArrBuilder extends BaseOutputBuilder{
47
47
  * @param {Node} node
48
48
  * @returns boolean: true if the node should not be added
49
49
  */
50
- closeTag(){
50
+ closeTag() {
51
51
  const node = this.currentNode;
52
52
  this.currentNode = this.tagsStack.pop(); //set parent node in scope
53
- if(this.options.onClose !== undefined){
53
+ if (this.options.onClose !== undefined) {
54
54
  //TODO TagPathMatcher
55
- const resultTag = this.options.onClose(node,
56
- new TagPathMatcher(this.tagsStack,node));
55
+ const resultTag = this.options.onClose(node,
56
+ new TagPathMatcher(this.tagsStack, node));
57
57
 
58
- if(resultTag) return;
58
+ if (resultTag) return;
59
59
  }
60
60
  this.currentNode.child.push(node); //to parent node
61
61
  }
62
62
 
63
63
  //Called by parent class methods
64
- _addChild(key, val){
64
+ _addChild(key, val) {
65
65
  // if(key === "__proto__") tagName = "#__proto__";
66
- this.currentNode.child.push( {[key]: val });
66
+ this.currentNode.child.push({ [key]: val });
67
67
  // this.currentNode.leafType = false;
68
68
  }
69
69
 
@@ -71,31 +71,31 @@ class JsArrBuilder extends BaseOutputBuilder{
71
71
  * Add text value child node
72
72
  * @param {string} text
73
73
  */
74
- addValue(text){
75
- this.currentNode.child.push( {[this.options.nameFor.text]: this.parseValue(text, this.options.tags.valueParsers) });
74
+ addValue(text) {
75
+ this.currentNode.child.push({ [this.options.nameFor.text]: this.parseValue(text, this.options.tags.valueParsers) });
76
76
  }
77
77
 
78
- addPi(name){
78
+ addPi(name) {
79
79
  //TODO: set pi flag
80
- if(!this.options.ignorePiTags){
80
+ if (!this.options.ignorePiTags) {
81
81
  const node = new Node(name, this.attributes);
82
82
  this.currentNode[":@"] = this.attributes;
83
83
  this.currentNode.child.push(node);
84
84
  }
85
85
  this.attributes = {};
86
86
  }
87
- getOutput(){
87
+ getOutput() {
88
88
  return this.root.child[0];
89
89
  }
90
90
  }
91
91
 
92
92
 
93
93
 
94
- class Node{
95
- constructor(tagname, attributes){
94
+ class Node {
95
+ constructor(tagname, attributes) {
96
96
  this.tagname = tagname;
97
97
  this.child = []; //nested tags, text, cdata, comments
98
- if(attributes && Object.keys(attributes).length > 0)
98
+ if (attributes && Object.keys(attributes).length > 0)
99
99
  this[":@"] = attributes;
100
100
  }
101
101
  }
@@ -1,18 +1,18 @@
1
1
 
2
2
 
3
- import {buildOptions,registerCommonValueParsers} from './ParserOptionsBuilder.js';
3
+ import { buildOptions, registerCommonValueParsers } from './ParserOptionsBuilder.js';
4
4
 
5
- export default class OutputBuilder{
6
- constructor(builderOptions){
7
- this.options = buildOptions(builderOptions);
8
- this.registeredParsers = registerCommonValueParsers(this.options);
5
+ export default class OutputBuilder {
6
+ constructor(builderOptions) {
7
+ this.options = buildOptions(builderOptions);
8
+ this.registeredParsers = registerCommonValueParsers(this.options);
9
9
  }
10
10
 
11
- registerValueParser(name,parserInstance){//existing name will override the parser without warning
11
+ registerValueParser(name, parserInstance) {//existing name will override the parser without warning
12
12
  this.registeredParsers[name] = parserInstance;
13
13
  }
14
14
 
15
- getInstance(parserOptions){
15
+ getInstance(parserOptions) {
16
16
  return new JsObjBuilder(parserOptions, this.options, this.registeredParsers);
17
17
  }
18
18
  }
@@ -20,9 +20,9 @@ export default class OutputBuilder{
20
20
  import BaseOutputBuilder from './BaseOutputBuilder.js';
21
21
  const rootName = '^';
22
22
 
23
- class JsObjBuilder extends BaseOutputBuilder{
23
+ class JsObjBuilder extends BaseOutputBuilder {
24
24
 
25
- constructor(parserOptions, builderOptions,registeredParsers) {
25
+ constructor(parserOptions, builderOptions, registeredParsers) {
26
26
  super();
27
27
  //hold the raw detail of a tag and sequence with reference to the output
28
28
  this.tagsStack = [];
@@ -38,14 +38,14 @@ class JsObjBuilder extends BaseOutputBuilder{
38
38
  this.attributes = {};
39
39
  }
40
40
 
41
- addTag(tag){
41
+ addTag(tag) {
42
42
 
43
43
  let value = "";
44
- if( !isEmpty(this.attributes)){
44
+ if (!isEmpty(this.attributes)) {
45
45
  value = {};
46
- if(this.options.attributes.groupBy){
46
+ if (this.options.attributes.groupBy) {
47
47
  value[this.options.attributes.groupBy] = this.attributes;
48
- }else{
48
+ } else {
49
49
  value = this.attributes;
50
50
  }
51
51
  }
@@ -62,44 +62,44 @@ class JsObjBuilder extends BaseOutputBuilder{
62
62
  * @param {Node} node
63
63
  * @returns boolean: true if the node should not be added
64
64
  */
65
- closeTag(){
65
+ closeTag() {
66
66
  const tagName = this.tagName;
67
67
  let value = this.value;
68
68
  let textValue = this.textValue;
69
69
 
70
70
  //update tag text value
71
- if(typeof value !== "object" && !Array.isArray(value)){
71
+ if (typeof value !== "object" && !Array.isArray(value)) {
72
72
  value = this.parseValue(textValue.trim(), this.options.tags.valueParsers);
73
- }else if(textValue.length > 0){
73
+ } else if (textValue.length > 0) {
74
74
  value[this.options.nameFor.text] = this.parseValue(textValue.trim(), this.options.tags.valueParsers);
75
75
  }
76
76
 
77
-
78
- let resultTag= {
77
+
78
+ let resultTag = {
79
79
  tagName: tagName,
80
80
  value: value
81
81
  };
82
82
 
83
- if(this.options.onTagClose !== undefined){
83
+ if (this.options.onTagClose !== undefined) {
84
84
  //TODO TagPathMatcher
85
- resultTag = this.options.onClose(tagName, value, this.textValue, new TagPathMatcher(this.tagsStack,node));
85
+ resultTag = this.options.onClose(tagName, value, this.textValue, new TagPathMatcher(this.tagsStack, node));
86
86
 
87
- if(!resultTag) return;
87
+ if (!resultTag) return;
88
88
  }
89
89
 
90
90
  //set parent node in scope
91
- let arr = this.tagsStack.pop();
91
+ let arr = this.tagsStack.pop();
92
92
  let parentTag = arr[2];
93
- parentTag=this._addChildTo(resultTag.tagName, resultTag.value, parentTag);
93
+ parentTag = this._addChildTo(resultTag.tagName, resultTag.value, parentTag);
94
94
 
95
95
  this.tagName = arr[0];
96
96
  this.textValue = arr[1];
97
97
  this.value = parentTag;
98
98
  }
99
99
 
100
- _addChild(key, val){
101
- if(typeof this.value === "string"){
102
- this.value = { [this.options.nameFor.text] : this.value };
100
+ _addChild(key, val) {
101
+ if (typeof this.value === "string") {
102
+ this.value = { [this.options.nameFor.text]: this.value };
103
103
  }
104
104
 
105
105
  this._addChildTo(key, val, this.value);
@@ -107,12 +107,12 @@ class JsObjBuilder extends BaseOutputBuilder{
107
107
  this.attributes = {};
108
108
  }
109
109
 
110
- _addChildTo(key, val, node){
111
- if(typeof node === 'string') node = {};
112
- if(!node[key]){
110
+ _addChildTo(key, val, node) {
111
+ if (typeof node === 'string') node = {};
112
+ if (!node[key]) {
113
113
  node[key] = val;
114
- }else{ //Repeated
115
- if(!Array.isArray(node[key])){ //but not stored as array
114
+ } else { //Repeated
115
+ if (!Array.isArray(node[key])) { //but not stored as array
116
116
  node[key] = [node[key]];
117
117
  }
118
118
  node[key].push(val);
@@ -125,26 +125,26 @@ class JsObjBuilder extends BaseOutputBuilder{
125
125
  * Add text value child node
126
126
  * @param {string} text
127
127
  */
128
- addValue(text){
128
+ addValue(text) {
129
129
  //TODO: use bytes join
130
- if(this.textValue.length > 0) this.textValue += " " + text;
130
+ if (this.textValue.length > 0) this.textValue += " " + text;
131
131
  else this.textValue = text;
132
132
  }
133
133
 
134
- addPi(name){
134
+ addPi(name) {
135
135
  let value = "";
136
- if( !isEmpty(this.attributes)){
136
+ if (!isEmpty(this.attributes)) {
137
137
  value = {};
138
- if(this.options.attributes.groupBy){
138
+ if (this.options.attributes.groupBy) {
139
139
  value[this.options.attributes.groupBy] = this.attributes;
140
- }else{
140
+ } else {
141
141
  value = this.attributes;
142
142
  }
143
143
  }
144
144
  this._addChild(name, value);
145
-
145
+
146
146
  }
147
- getOutput(){
147
+ getOutput() {
148
148
  return this.value;
149
149
  }
150
150
  }
@@ -3,8 +3,8 @@ import booleanParser from "../valueParsers/booleanParser.js";
3
3
  import currencyParser from "../valueParsers/currency.js";
4
4
  import numberParser from "../valueParsers/number.js";
5
5
 
6
- const defaultOptions={
7
- nameFor:{
6
+ const defaultOptions = {
7
+ nameFor: {
8
8
  text: "#text",
9
9
  comment: "",
10
10
  cdata: "",
@@ -22,11 +22,11 @@ const defaultOptions={
22
22
  // "date",
23
23
  ]
24
24
  },
25
- attributes:{
25
+ attributes: {
26
26
  prefix: "@_",
27
27
  suffix: "",
28
28
  groupBy: "",
29
-
29
+
30
30
  valueParsers: [
31
31
  // "trim",
32
32
  // "boolean",
@@ -35,35 +35,35 @@ const defaultOptions={
35
35
  // "date",
36
36
  ]
37
37
  },
38
- dataType:{
38
+ dataType: {
39
39
 
40
40
  }
41
41
  }
42
42
 
43
43
  //TODO
44
- const withJoin = ["trim","join", /*"entities",*/"number","boolean","currency"/*, "date"*/]
45
- const withoutJoin = ["trim", /*"entities",*/"number","boolean","currency"/*, "date"*/]
44
+ const withJoin = ["trim", "join", /*"entities",*/"number", "boolean", "currency"/*, "date"*/]
45
+ const withoutJoin = ["trim", /*"entities",*/"number", "boolean", "currency"/*, "date"*/]
46
46
 
47
- export function buildOptions(options){
47
+ export function buildOptions(options) {
48
48
  //clone
49
- const finalOptions = { ... defaultOptions};
49
+ const finalOptions = { ...defaultOptions };
50
50
 
51
51
  //add config missed in cloning
52
52
  finalOptions.tags.valueParsers.push(...withJoin)
53
- if(!this.preserveOrder)
53
+ if (!this.preserveOrder)
54
54
  finalOptions.tags.valueParsers.push(...withoutJoin);
55
55
 
56
56
  //add config missed in cloning
57
57
  finalOptions.attributes.valueParsers.push(...withJoin)
58
58
 
59
59
  //override configuration
60
- copyProperties(finalOptions,options);
60
+ copyProperties(finalOptions, options);
61
61
  return finalOptions;
62
62
  }
63
63
 
64
64
  function copyProperties(target, source) {
65
65
  for (let key in source) {
66
- if (source.hasOwnProperty(key)) {
66
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
67
67
  if (typeof source[key] === 'object' && !Array.isArray(source[key])) {
68
68
  // Recursively copy nested properties
69
69
  if (typeof target[key] === 'undefined') {
@@ -78,16 +78,16 @@ function copyProperties(target, source) {
78
78
  }
79
79
  }
80
80
 
81
- export function registerCommonValueParsers(options){
81
+ export function registerCommonValueParsers(options) {
82
82
  return {
83
83
  "trim": new trimParser(),
84
84
  // "join": this.entityParser.parse,
85
85
  "boolean": new booleanParser(),
86
86
  "number": new numberParser({
87
- hex: true,
88
- leadingZeros: true,
89
- eNotation: true
90
- }),
87
+ hex: true,
88
+ leadingZeros: true,
89
+ eNotation: true
90
+ }),
91
91
  "currency": new currencyParser(),
92
92
  // "date": this.entityParser.parse,
93
93
  }
@@ -1,9 +1,9 @@
1
- import { buildOptions} from './OptionsBuilder.js';
1
+ import { buildOptions } from './OptionsBuilder.js';
2
2
  import Xml2JsParser from './Xml2JsParser.js';
3
3
 
4
- export default class XMLParser{
5
-
6
- constructor(options){
4
+ export default class XMLParser {
5
+
6
+ constructor(options) {
7
7
  this.externalEntities = {};
8
8
  this.options = buildOptions(options);
9
9
  // console.log(this.options)
@@ -13,17 +13,17 @@ export default class XMLParser{
13
13
  * @param {string|Buffer} xmlData
14
14
  * @param {boolean|Object} validationOption
15
15
  */
16
- parse(xmlData){
17
- if(Array.isArray(xmlData) && xmlData.byteLength !== undefined){
16
+ parse(xmlData) {
17
+ if (Array.isArray(xmlData) && xmlData.byteLength !== undefined) {
18
18
  return this.parse(xmlData);
19
- }else if( xmlData.toString){
19
+ } else if (xmlData.toString) {
20
20
  xmlData = xmlData.toString();
21
- }else{
21
+ } else {
22
22
  throw new Error("XML data is accepted in String or Bytes[] form.")
23
23
  }
24
24
  // if( validationOption){
25
25
  // if(validationOption === true) validationOption = {}; //validate with default options
26
-
26
+
27
27
  // const result = validator.validate(xmlData, validationOption);
28
28
  // if (result !== true) {
29
29
  // throw Error( `${result.err.msg}:${result.err.line}:${result.err.col}` )
@@ -38,9 +38,9 @@ export default class XMLParser{
38
38
  * @param {string|Buffer} xmlData
39
39
  * @param {boolean|Object} validationOption
40
40
  */
41
- parseBytesArr(xmlData){
42
- if(Array.isArray(xmlData) && xmlData.byteLength !== undefined){
43
- }else{
41
+ parseBytesArr(xmlData) {
42
+ if (Array.isArray(xmlData) && xmlData.byteLength !== undefined) {
43
+ } else {
44
44
  throw new Error("XML data is accepted in Bytes[] form.")
45
45
  }
46
46
  const parser = new Xml2JsParser(this.options);
@@ -51,9 +51,9 @@ export default class XMLParser{
51
51
  * Parse XML data stream to JS object
52
52
  * @param {fs.ReadableStream} xmlDataStream
53
53
  */
54
- parseStream(xmlDataStream){
55
- if(!isStream(xmlDataStream)) throw new Error("FXP: Invalid stream input");
56
-
54
+ parseStream(xmlDataStream) {
55
+ if (!isStream(xmlDataStream)) throw new Error("FXP: Invalid stream input");
56
+
57
57
  const orderedObjParser = new Xml2JsParser(this.options);
58
58
  orderedObjParser.entityParser.addExternalEntities(this.externalEntities);
59
59
  return orderedObjParser.parseStream(xmlDataStream);
@@ -64,20 +64,20 @@ export default class XMLParser{
64
64
  * @param {string} key
65
65
  * @param {string} value
66
66
  */
67
- addEntity(key, value){
68
- if(value.indexOf("&") !== -1){
67
+ addEntity(key, value) {
68
+ if (value.indexOf("&") !== -1) {
69
69
  throw new Error("Entity value can't have '&'")
70
- }else if(key.indexOf("&") !== -1 || key.indexOf(";") !== -1){
70
+ } else if (key.indexOf("&") !== -1 || key.indexOf(";") !== -1) {
71
71
  throw new Error("An entity must be set without '&' and ';'. Eg. use '#xD' for '
'")
72
- }else if(value === "&"){
72
+ } else if (value === "&") {
73
73
  throw new Error("An entity with value '&' is not permitted");
74
- }else{
74
+ } else {
75
75
  this.externalEntities[key] = value;
76
76
  }
77
77
  }
78
78
  }
79
79
 
80
- function isStream(stream){
81
- if(stream && typeof stream.read === "function" && typeof stream.on === "function" && typeof stream.readableEnded === "boolean") return true;
80
+ function isStream(stream) {
81
+ if (stream && typeof stream.read === "function" && typeof stream.on === "function" && typeof stream.readableEnded === "boolean") return true;
82
82
  return false;
83
83
  }
@@ -1,105 +1,105 @@
1
- const ampEntity = { regex: /&(amp|#38|#x26);/g, val : "&"};
1
+ const ampEntity = { regex: /&(amp|#38|#x26);/g, val: "&" };
2
2
  const htmlEntities = {
3
- "space": { regex: /&(nbsp|#160);/g, val: " " },
4
- // "lt" : { regex: /&(lt|#60);/g, val: "<" },
5
- // "gt" : { regex: /&(gt|#62);/g, val: ">" },
6
- // "amp" : { regex: /&(amp|#38);/g, val: "&" },
7
- // "quot" : { regex: /&(quot|#34);/g, val: "\"" },
8
- // "apos" : { regex: /&(apos|#39);/g, val: "'" },
9
- "cent" : { regex: /&(cent|#162);/g, val: "¢" },
10
- "pound" : { regex: /&(pound|#163);/g, val: "£" },
11
- "yen" : { regex: /&(yen|#165);/g, val: "¥" },
12
- "euro" : { regex: /&(euro|#8364);/g, val: "€" },
13
- "copyright" : { regex: /&(copy|#169);/g, val: "©" },
14
- "reg" : { regex: /&(reg|#174);/g, val: "®" },
15
- "inr" : { regex: /&(inr|#8377);/g, val: "₹" },
16
- "num_dec": { regex: /&#([0-9]{1,7});/g, val : (_, str) => String.fromCodePoint(Number.parseInt(str, 10)) },
17
- "num_hex": { regex: /&#x([0-9a-fA-F]{1,6});/g, val : (_, str) => String.fromCodePoint(Number.parseInt(str, 16)) },
3
+ "space": { regex: /&(nbsp|#160);/g, val: " " },
4
+ // "lt" : { regex: /&(lt|#60);/g, val: "<" },
5
+ // "gt" : { regex: /&(gt|#62);/g, val: ">" },
6
+ // "amp" : { regex: /&(amp|#38);/g, val: "&" },
7
+ // "quot" : { regex: /&(quot|#34);/g, val: "\"" },
8
+ // "apos" : { regex: /&(apos|#39);/g, val: "'" },
9
+ "cent": { regex: /&(cent|#162);/g, val: "¢" },
10
+ "pound": { regex: /&(pound|#163);/g, val: "£" },
11
+ "yen": { regex: /&(yen|#165);/g, val: "¥" },
12
+ "euro": { regex: /&(euro|#8364);/g, val: "€" },
13
+ "copyright": { regex: /&(copy|#169);/g, val: "©" },
14
+ "reg": { regex: /&(reg|#174);/g, val: "®" },
15
+ "inr": { regex: /&(inr|#8377);/g, val: "₹" },
16
+ "num_dec": { regex: /&#([0-9]{1,7});/g, val: (_, str) => String.fromCodePoint(Number.parseInt(str, 10)) },
17
+ "num_hex": { regex: /&#x([0-9a-fA-F]{1,6});/g, val: (_, str) => String.fromCodePoint(Number.parseInt(str, 16)) },
18
18
  };
19
19
 
20
- export default class EntitiesParser{
21
- constructor(replaceHtmlEntities) {
22
- this.replaceHtmlEntities = replaceHtmlEntities;
23
- this.docTypeEntities = {};
24
- this.lastEntities = {
25
- "apos" : { regex: /&(apos|#39|#x27);/g, val : "'"},
26
- "gt" : { regex: /&(gt|#62|#x3E);/g, val : ">"},
27
- "lt" : { regex: /&(lt|#60|#x3C);/g, val : "<"},
28
- "quot" : { regex: /&(quot|#34|#x22);/g, val : "\""},
29
- };
30
- }
20
+ export default class EntitiesParser {
21
+ constructor(replaceHtmlEntities) {
22
+ this.replaceHtmlEntities = replaceHtmlEntities;
23
+ this.docTypeEntities = {};
24
+ this.lastEntities = {
25
+ "apos": { regex: /&(apos|#39|#x27);/g, val: "'" },
26
+ "gt": { regex: /&(gt|#62|#x3E);/g, val: ">" },
27
+ "lt": { regex: /&(lt|#60|#x3C);/g, val: "<" },
28
+ "quot": { regex: /&(quot|#34|#x22);/g, val: "\"" },
29
+ };
30
+ }
31
31
 
32
- addExternalEntities(externalEntities){
33
- const entKeys = Object.keys(externalEntities);
34
- for (let i = 0; i < entKeys.length; i++) {
35
- const ent = entKeys[i];
36
- this.addExternalEntity(ent,externalEntities[ent])
37
- }
32
+ addExternalEntities(externalEntities) {
33
+ const entKeys = Object.keys(externalEntities);
34
+ for (let i = 0; i < entKeys.length; i++) {
35
+ const ent = entKeys[i];
36
+ this.addExternalEntity(ent, externalEntities[ent])
38
37
  }
39
- addExternalEntity(key,val){
40
- validateEntityName(key);
41
- if(val.indexOf("&") !== -1) {
42
- reportWarning(`Entity ${key} is not added as '&' is found in value;`)
43
- return;
44
- }else{
45
- this.lastEntities[ent] = {
46
- regex: new RegExp("&"+key+";","g"),
47
- val : val
48
- }
38
+ }
39
+ addExternalEntity(key, val) {
40
+ validateEntityName(key);
41
+ if (val.indexOf("&") !== -1) {
42
+ reportWarning(`Entity ${key} is not added as '&' is found in value;`)
43
+ return;
44
+ } else {
45
+ this.lastEntities[ent] = {
46
+ regex: new RegExp("&" + key + ";", "g"),
47
+ val: val
49
48
  }
50
49
  }
50
+ }
51
51
 
52
- addDocTypeEntities(entities){
53
- const entKeys = Object.keys(entities);
54
- for (let i = 0; i < entKeys.length; i++) {
55
- const ent = entKeys[i];
56
- this.docTypeEntities[ent] = {
57
- regex: new RegExp("&"+ent+";","g"),
58
- val : entities[ent]
59
- }
60
- }
52
+ addDocTypeEntities(entities) {
53
+ const entKeys = Object.keys(entities);
54
+ for (let i = 0; i < entKeys.length; i++) {
55
+ const ent = entKeys[i];
56
+ this.docTypeEntities[ent] = {
57
+ regex: new RegExp("&" + ent + ";", "g"),
58
+ val: entities[ent]
59
+ }
61
60
  }
61
+ }
62
62
 
63
- parse(val){
64
- return this.replaceEntitiesValue(val)
65
- }
63
+ parse(val) {
64
+ return this.replaceEntitiesValue(val)
65
+ }
66
66
 
67
- /**
68
- * 1. Replace DOCTYPE entities
69
- * 2. Replace external entities
70
- * 3. Replace HTML entities if asked
71
- * @param {string} val
72
- */
73
- replaceEntitiesValue(val){
74
- if(typeof val === "string" && val.length > 0){
75
- for(let entityName in this.docTypeEntities){
76
- const entity = this.docTypeEntities[entityName];
77
- val = val.replace( entity.regx, entity.val);
78
- }
79
- for(let entityName in this.lastEntities){
80
- const entity = this.lastEntities[entityName];
81
- val = val.replace( entity.regex, entity.val);
82
- }
83
- if(this.replaceHtmlEntities){
84
- for(let entityName in htmlEntities){
85
- const entity = htmlEntities[entityName];
86
- val = val.replace( entity.regex, entity.val);
87
- }
88
- }
89
- val = val.replace( ampEntity.regex, ampEntity.val);
67
+ /**
68
+ * 1. Replace DOCTYPE entities
69
+ * 2. Replace external entities
70
+ * 3. Replace HTML entities if asked
71
+ * @param {string} val
72
+ */
73
+ replaceEntitiesValue(val) {
74
+ if (typeof val === "string" && val.length > 0) {
75
+ for (let entityName in this.docTypeEntities) {
76
+ const entity = this.docTypeEntities[entityName];
77
+ val = val.replace(entity.regx, entity.val);
78
+ }
79
+ for (let entityName in this.lastEntities) {
80
+ const entity = this.lastEntities[entityName];
81
+ val = val.replace(entity.regex, entity.val);
82
+ }
83
+ if (this.replaceHtmlEntities) {
84
+ for (let entityName in htmlEntities) {
85
+ const entity = htmlEntities[entityName];
86
+ val = val.replace(entity.regex, entity.val);
90
87
  }
91
- return val;
88
+ }
89
+ val = val.replace(ampEntity.regex, ampEntity.val);
92
90
  }
91
+ return val;
92
+ }
93
93
  };
94
94
 
95
95
  //an entity name should not contains special characters that may be used in regex
96
96
  //Eg !?\\\/[]$%{}^&*()<>
97
97
  const specialChar = "!?\\\/[]$%{}^&*()<>|+";
98
98
 
99
- function validateEntityName(name){
100
- for (let i = 0; i < specialChar.length; i++) {
101
- const ch = specialChar[i];
102
- if(name.indexOf(ch) !== -1) throw new Error(`Invalid character ${ch} in entity name`);
103
- }
104
- return name;
99
+ function validateEntityName(name) {
100
+ for (let i = 0; i < specialChar.length; i++) {
101
+ const ch = specialChar[i];
102
+ if (name.indexOf(ch) !== -1) throw new Error(`Invalid character ${ch} in entity name`);
103
+ }
104
+ return name;
105
105
  }