befly 0.1.26

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.
@@ -0,0 +1,114 @@
1
+ 'use strict';
2
+
3
+ import XmlNode from './xmlNode.js';
4
+
5
+ const METADATA_SYMBOL = XmlNode.getMetaDataSymbol();
6
+
7
+ /**
8
+ *
9
+ * @param {array} node
10
+ * @param {any} options
11
+ * @returns
12
+ */
13
+ export default function prettify(node, options) {
14
+ return compress(node, options);
15
+ }
16
+
17
+ /**
18
+ *
19
+ * @param {array} arr
20
+ * @param {object} options
21
+ * @param {string} jPath
22
+ * @returns object
23
+ */
24
+ function compress(arr, options, jPath) {
25
+ let text;
26
+ const compressedObj = {};
27
+ for (let i = 0; i < arr.length; i++) {
28
+ const tagObj = arr[i];
29
+ const property = propName(tagObj);
30
+ let newJpath = '';
31
+ if (jPath === undefined) newJpath = property;
32
+ else newJpath = jPath + '.' + property;
33
+
34
+ if (property === options.textNodeName) {
35
+ if (text === undefined) text = tagObj[property];
36
+ else text += '' + tagObj[property];
37
+ } else if (property === undefined) {
38
+ continue;
39
+ } else if (tagObj[property]) {
40
+ let val = compress(tagObj[property], options, newJpath);
41
+ const isLeaf = isLeafTag(val, options);
42
+ if (tagObj[METADATA_SYMBOL] !== undefined) {
43
+ val[METADATA_SYMBOL] = tagObj[METADATA_SYMBOL]; // copy over metadata
44
+ }
45
+
46
+ if (tagObj[':@']) {
47
+ assignAttributes(val, tagObj[':@'], newJpath, options);
48
+ } else if (Object.keys(val).length === 1 && val[options.textNodeName] !== undefined && !options.alwaysCreateTextNode) {
49
+ val = val[options.textNodeName];
50
+ } else if (Object.keys(val).length === 0) {
51
+ if (options.alwaysCreateTextNode) val[options.textNodeName] = '';
52
+ else val = '';
53
+ }
54
+
55
+ if (compressedObj[property] !== undefined && compressedObj.hasOwnProperty(property)) {
56
+ if (!Array.isArray(compressedObj[property])) {
57
+ compressedObj[property] = [compressedObj[property]];
58
+ }
59
+ compressedObj[property].push(val);
60
+ } else {
61
+ //TODO: if a node is not an array, then check if it should be an array
62
+ //also determine if it is a leaf node
63
+ if (options.isArray(property, newJpath, isLeaf)) {
64
+ compressedObj[property] = [val];
65
+ } else {
66
+ compressedObj[property] = val;
67
+ }
68
+ }
69
+ }
70
+ }
71
+ // if(text && text.length > 0) compressedObj[options.textNodeName] = text;
72
+ if (typeof text === 'string') {
73
+ if (text.length > 0) compressedObj[options.textNodeName] = text;
74
+ } else if (text !== undefined) compressedObj[options.textNodeName] = text;
75
+ return compressedObj;
76
+ }
77
+
78
+ function propName(obj) {
79
+ const keys = Object.keys(obj);
80
+ for (let i = 0; i < keys.length; i++) {
81
+ const key = keys[i];
82
+ if (key !== ':@') return key;
83
+ }
84
+ }
85
+
86
+ function assignAttributes(obj, attrMap, jpath, options) {
87
+ if (attrMap) {
88
+ const keys = Object.keys(attrMap);
89
+ const len = keys.length; //don't make it inline
90
+ for (let i = 0; i < len; i++) {
91
+ const atrrName = keys[i];
92
+ if (options.isArray(atrrName, jpath + '.' + atrrName, true, true)) {
93
+ obj[atrrName] = [attrMap[atrrName]];
94
+ } else {
95
+ obj[atrrName] = attrMap[atrrName];
96
+ }
97
+ }
98
+ }
99
+ }
100
+
101
+ function isLeafTag(obj, options) {
102
+ const { textNodeName } = options;
103
+ const propCount = Object.keys(obj).length;
104
+
105
+ if (propCount === 0) {
106
+ return true;
107
+ }
108
+
109
+ if (propCount === 1 && (obj[textNodeName] || typeof obj[textNodeName] === 'boolean' || obj[textNodeName] === 0)) {
110
+ return true;
111
+ }
112
+
113
+ return false;
114
+ }
@@ -0,0 +1,134 @@
1
+ const hexRegex = /^[-+]?0x[a-fA-F0-9]+$/;
2
+ const numRegex = /^([\-\+])?(0*)([0-9]*(\.[0-9]*)?)$/;
3
+ // const octRegex = /^0x[a-z0-9]+/;
4
+ // const binRegex = /0x[a-z0-9]+/;
5
+
6
+ const consider = {
7
+ hex: true,
8
+ // oct: false,
9
+ leadingZeros: true,
10
+ decimalPoint: '.',
11
+ eNotation: true
12
+ //skipLike: /regex/
13
+ };
14
+
15
+ export default function toNumber(str, options = {}) {
16
+ options = Object.assign({}, consider, options);
17
+ if (!str || typeof str !== 'string') return str;
18
+
19
+ let trimmedStr = str.trim();
20
+
21
+ if (options.skipLike !== undefined && options.skipLike.test(trimmedStr)) return str;
22
+ else if (str === '0') return 0;
23
+ else if (options.hex && hexRegex.test(trimmedStr)) {
24
+ return parse_int(trimmedStr, 16);
25
+ // }else if (options.oct && octRegex.test(str)) {
26
+ // return Number.parseInt(val, 8);
27
+ } else if (trimmedStr.search(/.+[eE].+/) !== -1) {
28
+ //eNotation
29
+ return resolveEnotation(str, trimmedStr, options);
30
+ // }else if (options.parseBin && binRegex.test(str)) {
31
+ // return Number.parseInt(val, 2);
32
+ } else {
33
+ //separate negative sign, leading zeros, and rest number
34
+ const match = numRegex.exec(trimmedStr);
35
+ // +00.123 => [ , '+', '00', '.123', ..
36
+ if (match) {
37
+ const sign = match[1] || '';
38
+ const leadingZeros = match[2];
39
+ let numTrimmedByZeros = trimZeros(match[3]); //complete num without leading zeros
40
+ const decimalAdjacentToLeadingZeros = sign // 0., -00., 000.
41
+ ? str[leadingZeros.length + 1] === '.'
42
+ : str[leadingZeros.length] === '.';
43
+
44
+ //trim ending zeros for floating number
45
+ if (
46
+ !options.leadingZeros && //leading zeros are not allowed
47
+ (leadingZeros.length > 1 || (leadingZeros.length === 1 && !decimalAdjacentToLeadingZeros))
48
+ ) {
49
+ // 00, 00.3, +03.24, 03, 03.24
50
+ return str;
51
+ } else {
52
+ //no leading zeros or leading zeros are allowed
53
+ const num = Number(trimmedStr);
54
+ const parsedStr = String(num);
55
+
56
+ if (num === 0) return num;
57
+ if (parsedStr.search(/[eE]/) !== -1) {
58
+ //given number is long and parsed to eNotation
59
+ if (options.eNotation) return num;
60
+ else return str;
61
+ } else if (trimmedStr.indexOf('.') !== -1) {
62
+ //floating number
63
+ if (parsedStr === '0') return num; //0.0
64
+ else if (parsedStr === numTrimmedByZeros) return num; //0.456. 0.79000
65
+ else if (parsedStr === `${sign}${numTrimmedByZeros}`) return num;
66
+ else return str;
67
+ }
68
+
69
+ let n = leadingZeros ? numTrimmedByZeros : trimmedStr;
70
+ if (leadingZeros) {
71
+ // -009 => -9
72
+ return n === parsedStr || sign + n === parsedStr ? num : str;
73
+ } else {
74
+ // +9
75
+ return n === parsedStr || n === sign + parsedStr ? num : str;
76
+ }
77
+ }
78
+ } else {
79
+ //non-numeric string
80
+ return str;
81
+ }
82
+ }
83
+ }
84
+
85
+ const eNotationRegx = /^([-+])?(0*)(\d*(\.\d*)?[eE][-\+]?\d+)$/;
86
+ function resolveEnotation(str, trimmedStr, options) {
87
+ if (!options.eNotation) return str;
88
+ const notation = trimmedStr.match(eNotationRegx);
89
+ if (notation) {
90
+ let sign = notation[1] || '';
91
+ const eChar = notation[3].indexOf('e') === -1 ? 'E' : 'e';
92
+ const leadingZeros = notation[2];
93
+ const eAdjacentToLeadingZeros = sign // 0E.
94
+ ? str[leadingZeros.length + 1] === eChar
95
+ : str[leadingZeros.length] === eChar;
96
+
97
+ if (leadingZeros.length > 1 && eAdjacentToLeadingZeros) return str;
98
+ else if (leadingZeros.length === 1 && (notation[3].startsWith(`.${eChar}`) || notation[3][0] === eChar)) {
99
+ return Number(trimmedStr);
100
+ } else if (options.leadingZeros && !eAdjacentToLeadingZeros) {
101
+ //accept with leading zeros
102
+ //remove leading 0s
103
+ trimmedStr = (notation[1] || '') + notation[3];
104
+ return Number(trimmedStr);
105
+ } else return str;
106
+ } else {
107
+ return str;
108
+ }
109
+ }
110
+
111
+ /**
112
+ *
113
+ * @param {string} numStr without leading zeros
114
+ * @returns
115
+ */
116
+ function trimZeros(numStr) {
117
+ if (numStr && numStr.indexOf('.') !== -1) {
118
+ //float
119
+ numStr = numStr.replace(/0+$/, ''); //remove ending zeros
120
+ if (numStr === '.') numStr = '0';
121
+ else if (numStr[0] === '.') numStr = '0' + numStr;
122
+ else if (numStr[numStr.length - 1] === '.') numStr = numStr.substring(0, numStr.length - 1);
123
+ return numStr;
124
+ }
125
+ return numStr;
126
+ }
127
+
128
+ function parse_int(numStr, base) {
129
+ //polyfill
130
+ if (parseInt) return parseInt(numStr, base);
131
+ else if (Number.parseInt) return Number.parseInt(numStr, base);
132
+ else if (window && window.parseInt) return window.parseInt(numStr, base);
133
+ else throw new Error('parseInt, Number.parseInt, window.parseInt are not supported');
134
+ }
@@ -0,0 +1,68 @@
1
+ 'use strict';
2
+
3
+ const nameStartChar = ':A-Za-z_\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD';
4
+ const nameChar = nameStartChar + '\\-.\\d\\u00B7\\u0300-\\u036F\\u203F-\\u2040';
5
+ export const nameRegexp = '[' + nameStartChar + '][' + nameChar + ']*';
6
+ const regexName = new RegExp('^' + nameRegexp + '$');
7
+
8
+ export function getAllMatches(string, regex) {
9
+ const matches = [];
10
+ let match = regex.exec(string);
11
+ while (match) {
12
+ const allmatches = [];
13
+ allmatches.startIndex = regex.lastIndex - match[0].length;
14
+ const len = match.length;
15
+ for (let index = 0; index < len; index++) {
16
+ allmatches.push(match[index]);
17
+ }
18
+ matches.push(allmatches);
19
+ match = regex.exec(string);
20
+ }
21
+ return matches;
22
+ }
23
+
24
+ export const isName = function(string) {
25
+ const match = regexName.exec(string);
26
+ return !(match === null || typeof match === 'undefined');
27
+ }
28
+
29
+ export function isExist(v) {
30
+ return typeof v !== 'undefined';
31
+ }
32
+
33
+ export function isEmptyObject(obj) {
34
+ return Object.keys(obj).length === 0;
35
+ }
36
+
37
+ /**
38
+ * Copy all the properties of a into b.
39
+ * @param {*} target
40
+ * @param {*} a
41
+ */
42
+ export function merge(target, a, arrayMode) {
43
+ if (a) {
44
+ const keys = Object.keys(a); // will return an array of own properties
45
+ const len = keys.length; //don't make it inline
46
+ for (let i = 0; i < len; i++) {
47
+ if (arrayMode === 'strict') {
48
+ target[keys[i]] = [ a[keys[i]] ];
49
+ } else {
50
+ target[keys[i]] = a[keys[i]];
51
+ }
52
+ }
53
+ }
54
+ }
55
+ /* exports.merge =function (b,a){
56
+ return Object.assign(b,a);
57
+ } */
58
+
59
+ export function getValue(v) {
60
+ if (exports.isExist(v)) {
61
+ return v;
62
+ } else {
63
+ return '';
64
+ }
65
+ }
66
+
67
+ // const fakeCall = function(a) {return a;};
68
+ // const fakeCallNoReturn = function() {};