read-excel-file 9.2.0 → 9.3.0

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.
Files changed (205) hide show
  1. package/.gitlab-ci.yml +1 -1
  2. package/CHANGELOG.md +5 -0
  3. package/README.md +153 -50
  4. package/bundle/read-excel-file.min.js +1 -1
  5. package/bundle/read-excel-file.min.js.map +1 -1
  6. package/bundle/read-excel-file.min.old.js +2 -0
  7. package/bundle/read-excel-file.min.old.js.map +1 -0
  8. package/commonjs/export/convertValuesFromUint8ArraysToStrings.js +3 -0
  9. package/commonjs/export/convertValuesFromUint8ArraysToStrings.js.map +1 -1
  10. package/commonjs/export/parseSheet.js +12 -9
  11. package/commonjs/export/parseSheet.js.map +1 -1
  12. package/commonjs/export/readSheetBrowser.js +6 -2
  13. package/commonjs/export/readSheetBrowser.js.map +1 -1
  14. package/commonjs/export/readSheetNode.js +6 -2
  15. package/commonjs/export/readSheetNode.js.map +1 -1
  16. package/commonjs/export/readSheetUniversal.js +14 -2
  17. package/commonjs/export/readSheetUniversal.js.map +1 -1
  18. package/commonjs/export/readSheetWebWorker.js +12 -2
  19. package/commonjs/export/readSheetWebWorker.js.map +1 -1
  20. package/commonjs/export/readXlsxFileBrowser.js +6 -2
  21. package/commonjs/export/readXlsxFileBrowser.js.map +1 -1
  22. package/commonjs/export/readXlsxFileNode.js +6 -2
  23. package/commonjs/export/readXlsxFileNode.js.map +1 -1
  24. package/commonjs/export/readXlsxFileUniversal.js +14 -2
  25. package/commonjs/export/readXlsxFileUniversal.js.map +1 -1
  26. package/commonjs/export/readXlsxFileWebWorker.js +12 -2
  27. package/commonjs/export/readXlsxFileWebWorker.js.map +1 -1
  28. package/commonjs/export/unpackXlsxFileBrowser.js +29 -6
  29. package/commonjs/export/unpackXlsxFileBrowser.js.map +1 -1
  30. package/commonjs/export/unpackXlsxFileNode.js +6 -0
  31. package/commonjs/export/unpackXlsxFileNode.js.map +1 -1
  32. package/commonjs/export/unpackXlsxFileUniversal.js +6 -0
  33. package/commonjs/export/unpackXlsxFileUniversal.js.map +1 -1
  34. package/commonjs/export/unpackXlsxFileWebWorker.js +14 -0
  35. package/commonjs/export/unpackXlsxFileWebWorker.js.map +1 -0
  36. package/commonjs/parseSheetData/parseSheetData.js +6 -6
  37. package/commonjs/parseSheetData/parseSheetData.js.map +1 -1
  38. package/commonjs/utility/checkpoint.js +33 -0
  39. package/commonjs/utility/checkpoint.js.map +1 -0
  40. package/commonjs/utility/isObject.js +15 -0
  41. package/commonjs/utility/isObject.js.map +1 -0
  42. package/commonjs/utility/isPromise.js +18 -0
  43. package/commonjs/utility/isPromise.js.map +1 -0
  44. package/commonjs/xlsx/convertCellsToData2dArray.js +0 -3
  45. package/commonjs/xlsx/convertCellsToData2dArray.js.map +1 -1
  46. package/commonjs/xlsx/isDateFormatStyle.js +2 -2
  47. package/commonjs/xlsx/isDateFormatStyle.js.map +1 -1
  48. package/commonjs/xlsx/parseCell.js +89 -24
  49. package/commonjs/xlsx/parseCell.js.map +1 -1
  50. package/{modules/xlsx/parseCellCoordinates.js → commonjs/xlsx/parseCellAddress.js} +18 -7
  51. package/commonjs/xlsx/parseCellAddress.js.map +1 -0
  52. package/commonjs/xlsx/parseCellValue.js +7 -23
  53. package/commonjs/xlsx/parseCellValue.js.map +1 -1
  54. package/commonjs/xlsx/parseFilePaths.js +31 -32
  55. package/commonjs/xlsx/parseFilePaths.js.map +1 -1
  56. package/commonjs/xlsx/parseNumber.js +20 -0
  57. package/commonjs/xlsx/parseNumber.js.map +1 -0
  58. package/commonjs/xlsx/parseSharedString.js +64 -0
  59. package/commonjs/xlsx/parseSharedString.js.map +1 -0
  60. package/commonjs/xlsx/parseSharedStrings.js +45 -5
  61. package/commonjs/xlsx/parseSharedStrings.js.map +1 -1
  62. package/commonjs/xlsx/parseSheet.js +93 -9
  63. package/commonjs/xlsx/parseSheet.js.map +1 -1
  64. package/commonjs/xlsx/parseSheetData.js +68 -0
  65. package/commonjs/xlsx/parseSheetData.js.map +1 -0
  66. package/commonjs/xlsx/parseSpreadsheetContents.js +244 -43
  67. package/commonjs/xlsx/parseSpreadsheetContents.js.map +1 -1
  68. package/commonjs/xlsx/parseSpreadsheetInfo.js +67 -36
  69. package/commonjs/xlsx/parseSpreadsheetInfo.js.map +1 -1
  70. package/commonjs/xlsx/parseStyles.js +89 -36
  71. package/commonjs/xlsx/parseStyles.js.map +1 -1
  72. package/commonjs/xml/dom.js +2 -1
  73. package/commonjs/xml/dom.js.map +1 -1
  74. package/commonjs/xml/parseXmlStream.js +14 -0
  75. package/commonjs/xml/parseXmlStream.js.map +1 -0
  76. package/commonjs/xml/parseXmlStream.sax.js +109 -0
  77. package/commonjs/xml/parseXmlStream.sax.js.map +1 -0
  78. package/commonjs/xml/parseXmlStream.saxen.code.js +953 -0
  79. package/commonjs/xml/parseXmlStream.saxen.code.js.map +1 -0
  80. package/commonjs/xml/parseXmlStream.saxen.js +85 -0
  81. package/commonjs/xml/parseXmlStream.saxen.js.map +1 -0
  82. package/commonjs/xml/xlsx.js +75 -40
  83. package/commonjs/xml/xlsx.js.map +1 -1
  84. package/commonjs/zip/unzipFromArrayBuffer.js +5 -14
  85. package/commonjs/zip/unzipFromArrayBuffer.js.map +1 -1
  86. package/commonjs/zip/unzipFromStream.fflate.js +154 -25
  87. package/commonjs/zip/unzipFromStream.fflate.js.map +1 -1
  88. package/commonjs/zip/unzipFromStream.js.map +1 -1
  89. package/commonjs/zip/unzipFromStream.unzipper.js +37 -26
  90. package/commonjs/zip/unzipFromStream.unzipper.js.map +1 -1
  91. package/modules/export/convertValuesFromUint8ArraysToStrings.js +2 -0
  92. package/modules/export/convertValuesFromUint8ArraysToStrings.js.map +1 -1
  93. package/modules/export/parseSheet.js +12 -9
  94. package/modules/export/parseSheet.js.map +1 -1
  95. package/modules/export/readSheetBrowser.js +5 -2
  96. package/modules/export/readSheetBrowser.js.map +1 -1
  97. package/modules/export/readSheetNode.js +5 -2
  98. package/modules/export/readSheetNode.js.map +1 -1
  99. package/modules/export/readSheetUniversal.js +14 -2
  100. package/modules/export/readSheetUniversal.js.map +1 -1
  101. package/modules/export/readSheetWebWorker.js +12 -2
  102. package/modules/export/readSheetWebWorker.js.map +1 -1
  103. package/modules/export/readXlsxFileBrowser.js +5 -2
  104. package/modules/export/readXlsxFileBrowser.js.map +1 -1
  105. package/modules/export/readXlsxFileNode.js +5 -2
  106. package/modules/export/readXlsxFileNode.js.map +1 -1
  107. package/modules/export/readXlsxFileUniversal.js +14 -2
  108. package/modules/export/readXlsxFileUniversal.js.map +1 -1
  109. package/modules/export/readXlsxFileWebWorker.js +12 -2
  110. package/modules/export/readXlsxFileWebWorker.js.map +1 -1
  111. package/modules/export/unpackXlsxFileBrowser.js +26 -6
  112. package/modules/export/unpackXlsxFileBrowser.js.map +1 -1
  113. package/modules/export/unpackXlsxFileNode.js +3 -0
  114. package/modules/export/unpackXlsxFileNode.js.map +1 -1
  115. package/modules/export/unpackXlsxFileUniversal.js +3 -0
  116. package/modules/export/unpackXlsxFileUniversal.js.map +1 -1
  117. package/modules/export/unpackXlsxFileWebWorker.js +6 -0
  118. package/modules/export/unpackXlsxFileWebWorker.js.map +1 -0
  119. package/modules/parseSheetData/parseSheetData.js +4 -4
  120. package/modules/parseSheetData/parseSheetData.js.map +1 -1
  121. package/modules/utility/checkpoint.js +25 -0
  122. package/modules/utility/checkpoint.js.map +1 -0
  123. package/modules/utility/isObject.js +9 -0
  124. package/modules/utility/isObject.js.map +1 -0
  125. package/modules/utility/isPromise.js +12 -0
  126. package/modules/utility/isPromise.js.map +1 -0
  127. package/modules/xlsx/convertCellsToData2dArray.js +0 -3
  128. package/modules/xlsx/convertCellsToData2dArray.js.map +1 -1
  129. package/modules/xlsx/isDateFormatStyle.js +2 -2
  130. package/modules/xlsx/isDateFormatStyle.js.map +1 -1
  131. package/modules/xlsx/parseCell.js +85 -24
  132. package/modules/xlsx/parseCell.js.map +1 -1
  133. package/{commonjs/xlsx/parseCellCoordinates.js → modules/xlsx/parseCellAddress.js} +12 -13
  134. package/modules/xlsx/parseCellAddress.js.map +1 -0
  135. package/modules/xlsx/parseCellValue.js +7 -23
  136. package/modules/xlsx/parseCellValue.js.map +1 -1
  137. package/modules/xlsx/parseFilePaths.js +31 -33
  138. package/modules/xlsx/parseFilePaths.js.map +1 -1
  139. package/modules/xlsx/parseNumber.js +14 -0
  140. package/modules/xlsx/parseNumber.js.map +1 -0
  141. package/modules/xlsx/parseSharedString.js +55 -0
  142. package/modules/xlsx/parseSharedString.js.map +1 -0
  143. package/modules/xlsx/parseSharedStrings.js +46 -5
  144. package/modules/xlsx/parseSharedStrings.js.map +1 -1
  145. package/modules/xlsx/parseSheet.js +91 -9
  146. package/modules/xlsx/parseSheet.js.map +1 -1
  147. package/modules/xlsx/parseSheetData.js +55 -0
  148. package/modules/xlsx/parseSheetData.js.map +1 -0
  149. package/modules/xlsx/parseSpreadsheetContents.js +242 -43
  150. package/modules/xlsx/parseSpreadsheetContents.js.map +1 -1
  151. package/modules/xlsx/parseSpreadsheetInfo.js +67 -37
  152. package/modules/xlsx/parseSpreadsheetInfo.js.map +1 -1
  153. package/modules/xlsx/parseStyles.js +88 -36
  154. package/modules/xlsx/parseStyles.js.map +1 -1
  155. package/modules/xml/dom.js +2 -1
  156. package/modules/xml/dom.js.map +1 -1
  157. package/modules/xml/parseXmlStream.js +18 -0
  158. package/modules/xml/parseXmlStream.js.map +1 -0
  159. package/modules/xml/parseXmlStream.sax.js +103 -0
  160. package/modules/xml/parseXmlStream.sax.js.map +1 -0
  161. package/modules/xml/parseXmlStream.saxen.code.js +947 -0
  162. package/modules/xml/parseXmlStream.saxen.code.js.map +1 -0
  163. package/modules/xml/parseXmlStream.saxen.js +79 -0
  164. package/modules/xml/parseXmlStream.saxen.js.map +1 -0
  165. package/modules/xml/xlsx.js +72 -36
  166. package/modules/xml/xlsx.js.map +1 -1
  167. package/modules/zip/unzipFromArrayBuffer.js +5 -14
  168. package/modules/zip/unzipFromArrayBuffer.js.map +1 -1
  169. package/modules/zip/unzipFromStream.fflate.js +157 -24
  170. package/modules/zip/unzipFromStream.fflate.js.map +1 -1
  171. package/modules/zip/unzipFromStream.js +56 -2
  172. package/modules/zip/unzipFromStream.js.map +1 -1
  173. package/modules/zip/unzipFromStream.unzipper.js +38 -26
  174. package/modules/zip/unzipFromStream.unzipper.js.map +1 -1
  175. package/package.json +4 -6
  176. package/commonjs/xlsx/parseCellCoordinates.js.map +0 -1
  177. package/commonjs/xlsx/parseCells.js +0 -34
  178. package/commonjs/xlsx/parseCells.js.map +0 -1
  179. package/commonjs/xlsx/parseSheetDimensions.js +0 -43
  180. package/commonjs/xlsx/parseSheetDimensions.js.map +0 -1
  181. package/commonjs/xml/xml.js +0 -13
  182. package/commonjs/xml/xml.js.map +0 -1
  183. package/commonjs/xml/xmlBrowser.js +0 -17
  184. package/commonjs/xml/xmlBrowser.js.map +0 -1
  185. package/commonjs/xml/xpath/xlsx-xpath.js +0 -92
  186. package/commonjs/xml/xpath/xlsx-xpath.js.map +0 -1
  187. package/commonjs/xml/xpath/xpathBrowser.js +0 -33
  188. package/commonjs/xml/xpath/xpathBrowser.js.map +0 -1
  189. package/commonjs/xml/xpath/xpathNode.js +0 -16
  190. package/commonjs/xml/xpath/xpathNode.js.map +0 -1
  191. package/modules/xlsx/parseCellCoordinates.js.map +0 -1
  192. package/modules/xlsx/parseCells.js +0 -27
  193. package/modules/xlsx/parseCells.js.map +0 -1
  194. package/modules/xlsx/parseSheetDimensions.js +0 -37
  195. package/modules/xlsx/parseSheetDimensions.js.map +0 -1
  196. package/modules/xml/xml.js +0 -7
  197. package/modules/xml/xml.js.map +0 -1
  198. package/modules/xml/xmlBrowser.js +0 -11
  199. package/modules/xml/xmlBrowser.js.map +0 -1
  200. package/modules/xml/xpath/xlsx-xpath.js +0 -73
  201. package/modules/xml/xpath/xlsx-xpath.js.map +0 -1
  202. package/modules/xml/xpath/xpathBrowser.js +0 -27
  203. package/modules/xml/xpath/xpathBrowser.js.map +0 -1
  204. package/modules/xml/xpath/xpathNode.js +0 -9
  205. package/modules/xml/xpath/xpathNode.js.map +0 -1
@@ -0,0 +1,953 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.Parser = Parser;
7
+ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
8
+ // Here it uses a copy-paste of `saxen` source code instead of importing the `saxen` package itself.
9
+ // The reason is that `worker-f` package is used to run this XML parser in a separate thread,
10
+ // and doing that requires the entire code to reside in a single "self-contained" function.
11
+ // import { Parser } from 'saxen'
12
+
13
+ // This code was copy-pasted from `saxen` repository on Jun 23rd, 2026.
14
+ // The reason is that `worker-f` package is used to run `saxen` XML parser in a separate thread,
15
+ // and doing that requires the entire `saxen` code to reside in a single "self-contained" function.
16
+
17
+ function Parser(options) {
18
+ // Copy-pasted from file: decode.js
19
+
20
+ var fromCharCode = String.fromCharCode;
21
+ var hasOwnProperty = Object.prototype.hasOwnProperty;
22
+ var ENTITY_PATTERN = /&#(\d+);|&#x([0-9a-f]+);|&(\w+);/ig;
23
+ var ENTITY_MAPPING = {
24
+ 'amp': '&',
25
+ 'apos': '\'',
26
+ 'gt': '>',
27
+ 'lt': '<',
28
+ 'quot': '"'
29
+ };
30
+
31
+ // map UPPERCASE variants of supported special chars
32
+ Object.keys(ENTITY_MAPPING).forEach(function (k) {
33
+ ENTITY_MAPPING[k.toUpperCase()] = ENTITY_MAPPING[k];
34
+ });
35
+ function replaceEntities(_, d, x, z) {
36
+ // reserved names, i.e. &nbsp;
37
+ if (z) {
38
+ if (hasOwnProperty.call(ENTITY_MAPPING, z)) {
39
+ return ENTITY_MAPPING[z];
40
+ } else {
41
+ // fall back to original value
42
+ return '&' + z + ';';
43
+ }
44
+ }
45
+
46
+ // decimal encoded char
47
+ if (d) {
48
+ return fromCharCode(d);
49
+ }
50
+
51
+ // hex encoded char
52
+ return fromCharCode(parseInt(x, 16));
53
+ }
54
+
55
+ /**
56
+ * A basic entity decoder that can decode a minimal
57
+ * sub-set of reserved names (&amp;) as well as
58
+ * hex (&#xaaf;) and decimal (&#1231;) encoded characters.
59
+ *
60
+ * @param {string} s
61
+ *
62
+ * @return {string} decoded string
63
+ */
64
+ function decodeEntities(s) {
65
+ if (s.length > 3 && s.indexOf('&') !== -1) {
66
+ return s.replace(ENTITY_PATTERN, replaceEntities);
67
+ }
68
+ return s;
69
+ }
70
+
71
+ // Copy-pasted from file: parser.js
72
+
73
+ var NON_WHITESPACE_OUTSIDE_ROOT_NODE = 'non-whitespace outside of root node';
74
+ function error(msg) {
75
+ return new Error(msg);
76
+ }
77
+ function missingNamespaceForPrefix(prefix) {
78
+ return 'missing namespace for prefix <' + prefix + '>';
79
+ }
80
+ function getter(getFn) {
81
+ return {
82
+ 'get': getFn,
83
+ 'enumerable': true
84
+ };
85
+ }
86
+ function cloneNsMatrix(nsMatrix) {
87
+ var clone = {},
88
+ key;
89
+ for (key in nsMatrix) {
90
+ clone[key] = nsMatrix[key];
91
+ }
92
+ return clone;
93
+ }
94
+ function uriPrefix(prefix) {
95
+ return prefix + '$uri';
96
+ }
97
+ function buildNsMatrix(nsUriToPrefix) {
98
+ var nsMatrix = {},
99
+ uri,
100
+ prefix;
101
+ for (uri in nsUriToPrefix) {
102
+ prefix = nsUriToPrefix[uri];
103
+ nsMatrix[prefix] = prefix;
104
+ nsMatrix[uriPrefix(prefix)] = uri;
105
+ }
106
+ return nsMatrix;
107
+ }
108
+ function noopGetContext() {
109
+ return {
110
+ line: 0,
111
+ column: 0
112
+ };
113
+ }
114
+ function throwFunc(err) {
115
+ throw err;
116
+ }
117
+
118
+ /**
119
+ * Creates a new parser with the given options.
120
+ *
121
+ * @constructor
122
+ *
123
+ * @param {!Object<string, ?>=} options
124
+ */
125
+ function Parser(options) {
126
+ if (!this) {
127
+ return new Parser(options);
128
+ }
129
+ var proxy = options && options['proxy'];
130
+ var onText,
131
+ onOpenTag,
132
+ onCloseTag,
133
+ onCDATA,
134
+ onError = throwFunc,
135
+ onWarning,
136
+ onComment,
137
+ onQuestion,
138
+ onAttention;
139
+ var getContext = noopGetContext;
140
+
141
+ /**
142
+ * Do we need to parse the current elements attributes for namespaces?
143
+ *
144
+ * @type {boolean}
145
+ */
146
+ var maybeNS = false;
147
+
148
+ /**
149
+ * Do we process namespaces at all?
150
+ *
151
+ * @type {boolean}
152
+ */
153
+ var isNamespace = false;
154
+
155
+ /**
156
+ * The caught error returned on parse end
157
+ *
158
+ * @type {Error}
159
+ */
160
+ var returnError = null;
161
+
162
+ /**
163
+ * Should we stop parsing?
164
+ *
165
+ * @type {boolean}
166
+ */
167
+ var parseStop = false;
168
+
169
+ /**
170
+ * A map of { uri: prefix } used by the parser.
171
+ *
172
+ * This map will ensure we can normalize prefixes during processing;
173
+ * for each uri, only one prefix will be exposed to the handlers.
174
+ *
175
+ * @type {!Object<string, string>}}
176
+ */
177
+ var nsUriToPrefix;
178
+
179
+ /**
180
+ * Handle parse error.
181
+ *
182
+ * @param {string|Error} err
183
+ */
184
+ function handleError(err) {
185
+ if (!(err instanceof Error)) {
186
+ err = error(err);
187
+ }
188
+ returnError = err;
189
+ onError(err, getContext);
190
+ }
191
+
192
+ /**
193
+ * Handle parse error.
194
+ *
195
+ * @param {string|Error} err
196
+ */
197
+ function handleWarning(err) {
198
+ if (!onWarning) {
199
+ return;
200
+ }
201
+ if (!(err instanceof Error)) {
202
+ err = error(err);
203
+ }
204
+ onWarning(err, getContext);
205
+ }
206
+
207
+ /**
208
+ * Register parse listener.
209
+ *
210
+ * @param {string} name
211
+ * @param {Function} cb
212
+ *
213
+ * @return {Parser}
214
+ */
215
+ this['on'] = function (name, cb) {
216
+ if (typeof cb !== 'function') {
217
+ throw error('required args <name, cb>');
218
+ }
219
+ switch (name) {
220
+ case 'openTag':
221
+ onOpenTag = cb;
222
+ break;
223
+ case 'text':
224
+ onText = cb;
225
+ break;
226
+ case 'closeTag':
227
+ onCloseTag = cb;
228
+ break;
229
+ case 'error':
230
+ onError = cb;
231
+ break;
232
+ case 'warn':
233
+ onWarning = cb;
234
+ break;
235
+ case 'cdata':
236
+ onCDATA = cb;
237
+ break;
238
+ case 'attention':
239
+ onAttention = cb;
240
+ break;
241
+ // <!XXXXX zzzz="eeee">
242
+ case 'question':
243
+ onQuestion = cb;
244
+ break;
245
+ // <? .... ?>
246
+ case 'comment':
247
+ onComment = cb;
248
+ break;
249
+ default:
250
+ throw error('unsupported event: ' + name);
251
+ }
252
+ return this;
253
+ };
254
+
255
+ /**
256
+ * Set the namespace to prefix mapping.
257
+ *
258
+ * @example
259
+ *
260
+ * parser.ns({
261
+ * 'http://foo': 'foo',
262
+ * 'http://bar': 'bar'
263
+ * });
264
+ *
265
+ * @param {!Object<string, string>} nsMap
266
+ *
267
+ * @return {Parser}
268
+ */
269
+ this['ns'] = function (nsMap) {
270
+ if (typeof nsMap === 'undefined') {
271
+ nsMap = {};
272
+ }
273
+ if (_typeof(nsMap) !== 'object') {
274
+ throw error('required args <nsMap={}>');
275
+ }
276
+ var _nsUriToPrefix = {},
277
+ k;
278
+ for (k in nsMap) {
279
+ _nsUriToPrefix[k] = nsMap[k];
280
+ }
281
+ isNamespace = true;
282
+ nsUriToPrefix = _nsUriToPrefix;
283
+ return this;
284
+ };
285
+
286
+ /**
287
+ * Parse xml string.
288
+ *
289
+ * @param {string} xml
290
+ *
291
+ * @return {Error} returnError, if not thrown
292
+ */
293
+ this['parse'] = function (xml) {
294
+ if (typeof xml !== 'string') {
295
+ throw error('required args <xml=string>');
296
+ }
297
+ returnError = null;
298
+ parse(xml);
299
+ getContext = noopGetContext;
300
+ parseStop = false;
301
+ return returnError;
302
+ };
303
+
304
+ /**
305
+ * Stop parsing.
306
+ */
307
+ this['stop'] = function () {
308
+ parseStop = true;
309
+ };
310
+
311
+ /**
312
+ * Parse string, invoking configured listeners on element.
313
+ *
314
+ * @param {string} xml
315
+ */
316
+ function parse(xml) {
317
+ var nsMatrixStack = isNamespace ? [] : null,
318
+ nsMatrix = isNamespace ? buildNsMatrix(nsUriToPrefix) : null,
319
+ _nsMatrix,
320
+ nodeStack = [],
321
+ anonymousNsCount = 0,
322
+ tagStart = false,
323
+ tagEnd = false,
324
+ i = 0,
325
+ j = 0,
326
+ x,
327
+ y,
328
+ q,
329
+ w,
330
+ v,
331
+ xmlns,
332
+ elementName,
333
+ _elementName,
334
+ elementProxy;
335
+ var attrsString = '',
336
+ attrsStart = 0,
337
+ cachedAttrs // false = parsed with errors, null = needs parsing
338
+ ;
339
+
340
+ /**
341
+ * Parse attributes on demand and returns the parsed attributes.
342
+ *
343
+ * Return semantics: (1) `false` on attribute parse error,
344
+ * (2) object hash on extracted attrs.
345
+ *
346
+ * @return {boolean|Object}
347
+ */
348
+ function getAttrs() {
349
+ if (cachedAttrs !== null) {
350
+ return cachedAttrs;
351
+ }
352
+ var nsUri,
353
+ nsUriPrefix,
354
+ nsName,
355
+ defaultAlias = isNamespace && nsMatrix['xmlns'],
356
+ attrList = isNamespace && maybeNS ? [] : null,
357
+ i = attrsStart,
358
+ s = attrsString,
359
+ l = s.length,
360
+ hasNewMatrix,
361
+ newalias,
362
+ value,
363
+ alias,
364
+ name,
365
+ attrs = {},
366
+ seenAttrs = {},
367
+ skipAttr,
368
+ w,
369
+ j;
370
+ parseAttr: for (; i < l; i++) {
371
+ skipAttr = false;
372
+ w = s.charCodeAt(i);
373
+ if (w === 32 || w < 14 && w > 8) {
374
+ // WHITESPACE={ \f\n\r\t\v}
375
+ continue;
376
+ }
377
+
378
+ // wait for non whitespace character
379
+ if (w < 65 || w > 122 || w > 90 && w < 97) {
380
+ if (w !== 95 && w !== 58) {
381
+ // char 95"_" 58":"
382
+ handleWarning('illegal first char attribute name');
383
+ skipAttr = true;
384
+ }
385
+ }
386
+
387
+ // parse attribute name
388
+ for (j = i + 1; j < l; j++) {
389
+ w = s.charCodeAt(j);
390
+ if (w > 96 && w < 123 || w > 64 && w < 91 || w > 47 && w < 59 || w === 46 ||
391
+ // '.'
392
+ w === 45 ||
393
+ // '-'
394
+ w === 95 // '_'
395
+ ) {
396
+ continue;
397
+ }
398
+
399
+ // unexpected whitespace
400
+ if (w === 32 || w < 14 && w > 8) {
401
+ // WHITESPACE
402
+ handleWarning('missing attribute value');
403
+ i = j;
404
+ continue parseAttr;
405
+ }
406
+
407
+ // expected "="
408
+ if (w === 61) {
409
+ // "=" == 61
410
+ break;
411
+ }
412
+ handleWarning('illegal attribute name char');
413
+ skipAttr = true;
414
+ }
415
+ name = s.substring(i, j);
416
+ if (name === 'xmlns:xmlns') {
417
+ handleWarning('illegal declaration of xmlns');
418
+ skipAttr = true;
419
+ }
420
+ w = s.charCodeAt(j + 1);
421
+ if (w === 34) {
422
+ // '"'
423
+ j = s.indexOf('"', i = j + 2);
424
+ if (j === -1) {
425
+ j = s.indexOf('\'', i);
426
+ if (j !== -1) {
427
+ handleWarning('attribute value quote missmatch');
428
+ skipAttr = true;
429
+ }
430
+ }
431
+ } else if (w === 39) {
432
+ // "'"
433
+ j = s.indexOf('\'', i = j + 2);
434
+ if (j === -1) {
435
+ j = s.indexOf('"', i);
436
+ if (j !== -1) {
437
+ handleWarning('attribute value quote missmatch');
438
+ skipAttr = true;
439
+ }
440
+ }
441
+ } else {
442
+ handleWarning('missing attribute value quotes');
443
+ skipAttr = true;
444
+
445
+ // skip to next space
446
+ for (j = j + 1; j < l; j++) {
447
+ w = s.charCodeAt(j + 1);
448
+ if (w === 32 || w < 14 && w > 8) {
449
+ // WHITESPACE
450
+ break;
451
+ }
452
+ }
453
+ }
454
+ if (j === -1) {
455
+ handleWarning('missing closing quotes');
456
+ j = l;
457
+ skipAttr = true;
458
+ }
459
+ if (!skipAttr) {
460
+ value = s.substring(i, j);
461
+ }
462
+ i = j;
463
+
464
+ // ensure SPACE follows attribute
465
+ // skip illegal content otherwise
466
+ // example a="b"c
467
+ for (; j + 1 < l; j++) {
468
+ w = s.charCodeAt(j + 1);
469
+ if (w === 32 || w < 14 && w > 8) {
470
+ // WHITESPACE
471
+ break;
472
+ }
473
+
474
+ // FIRST ILLEGAL CHAR
475
+ if (i === j) {
476
+ handleWarning('illegal character after attribute end');
477
+ skipAttr = true;
478
+ }
479
+ }
480
+
481
+ // advance cursor to next attribute
482
+ i = j + 1;
483
+ if (skipAttr) {
484
+ continue parseAttr;
485
+ }
486
+
487
+ // check attribute re-declaration
488
+ if (name in seenAttrs) {
489
+ handleWarning('attribute <' + name + '> already defined');
490
+ continue;
491
+ }
492
+ seenAttrs[name] = true;
493
+ if (!isNamespace) {
494
+ attrs[name] = value;
495
+ continue;
496
+ }
497
+
498
+ // try to extract namespace information
499
+ if (maybeNS) {
500
+ newalias = name === 'xmlns' ? 'xmlns' : name.charCodeAt(0) === 120 && name.substr(0, 6) === 'xmlns:' ? name.substr(6) : null;
501
+
502
+ // handle xmlns(:alias) assignment
503
+ if (newalias !== null) {
504
+ nsUri = decodeEntities(value);
505
+ nsUriPrefix = uriPrefix(newalias);
506
+ alias = nsUriToPrefix[nsUri];
507
+ if (!alias) {
508
+ // no prefix defined or prefix collision
509
+ if (newalias === 'xmlns' || nsUriPrefix in nsMatrix && nsMatrix[nsUriPrefix] !== nsUri) {
510
+ // alocate free ns prefix
511
+ do {
512
+ alias = 'ns' + anonymousNsCount++;
513
+ } while (typeof nsMatrix[alias] !== 'undefined');
514
+ } else {
515
+ alias = newalias;
516
+ }
517
+ nsUriToPrefix[nsUri] = alias;
518
+ }
519
+ if (nsMatrix[newalias] !== alias) {
520
+ if (!hasNewMatrix) {
521
+ nsMatrix = cloneNsMatrix(nsMatrix);
522
+ hasNewMatrix = true;
523
+ }
524
+ nsMatrix[newalias] = alias;
525
+ if (newalias === 'xmlns') {
526
+ nsMatrix[uriPrefix(alias)] = nsUri;
527
+ defaultAlias = alias;
528
+ }
529
+ nsMatrix[nsUriPrefix] = nsUri;
530
+ }
531
+
532
+ // expose xmlns(:asd)="..." in attributes
533
+ attrs[name] = value;
534
+ continue;
535
+ }
536
+
537
+ // collect attributes until all namespace
538
+ // declarations are processed
539
+ attrList.push(name, value);
540
+ continue;
541
+ } /** end if (maybeNs) */
542
+
543
+ // handle attributes on element without
544
+ // namespace declarations
545
+ w = name.indexOf(':');
546
+ if (w === -1) {
547
+ attrs[name] = value;
548
+ continue;
549
+ }
550
+
551
+ // normalize ns attribute name
552
+ if (!(nsName = nsMatrix[name.substring(0, w)])) {
553
+ handleWarning(missingNamespaceForPrefix(name.substring(0, w)));
554
+ continue;
555
+ }
556
+ name = defaultAlias === nsName ? name.substr(w + 1) : nsName + name.substr(w);
557
+
558
+ // end: normalize ns attribute name
559
+
560
+ attrs[name] = value;
561
+ }
562
+
563
+ // handle deferred, possibly namespaced attributes
564
+ if (maybeNS) {
565
+ // normalize captured attributes
566
+ for (i = 0, l = attrList.length; i < l; i++) {
567
+ name = attrList[i++];
568
+ value = attrList[i];
569
+ w = name.indexOf(':');
570
+ if (w !== -1) {
571
+ // normalize ns attribute name
572
+ if (!(nsName = nsMatrix[name.substring(0, w)])) {
573
+ handleWarning(missingNamespaceForPrefix(name.substring(0, w)));
574
+ continue;
575
+ }
576
+ name = defaultAlias === nsName ? name.substr(w + 1) : nsName + name.substr(w);
577
+
578
+ // end: normalize ns attribute name
579
+ }
580
+
581
+ attrs[name] = value;
582
+ }
583
+
584
+ // end: normalize captured attributes
585
+ }
586
+
587
+ return cachedAttrs = attrs;
588
+ }
589
+
590
+ /**
591
+ * Extract the parse context { line, column, part }
592
+ * from the current parser position.
593
+ *
594
+ * @return {Object} parse context
595
+ */
596
+ function getParseContext() {
597
+ var splitsRe = /(\r\n|\r|\n)/g;
598
+ var line = 0;
599
+ var column = 0;
600
+ var startOfLine = 0;
601
+ var endOfLine = j;
602
+ var match;
603
+ var data;
604
+ while (i >= startOfLine) {
605
+ match = splitsRe.exec(xml);
606
+ if (!match) {
607
+ break;
608
+ }
609
+
610
+ // end of line = (break idx + break chars)
611
+ endOfLine = match[0].length + match.index;
612
+ if (endOfLine > i) {
613
+ break;
614
+ }
615
+
616
+ // advance to next line
617
+ line += 1;
618
+ startOfLine = endOfLine;
619
+ }
620
+
621
+ // EOF errors
622
+ if (i == -1) {
623
+ column = endOfLine;
624
+ data = xml.substring(j);
625
+ } else
626
+ // start errors
627
+ if (j === 0) {
628
+ data = xml.substring(j, i);
629
+ }
630
+
631
+ // other errors
632
+ else {
633
+ column = i - startOfLine;
634
+ data = j == -1 ? xml.substring(i) : xml.substring(i, j + 1);
635
+ }
636
+ return {
637
+ 'data': data,
638
+ 'line': line,
639
+ 'column': column
640
+ };
641
+ }
642
+ getContext = getParseContext;
643
+ if (proxy) {
644
+ elementProxy = Object.create({}, {
645
+ 'name': getter(function () {
646
+ return elementName;
647
+ }),
648
+ 'originalName': getter(function () {
649
+ return _elementName;
650
+ }),
651
+ 'attrs': getter(getAttrs),
652
+ 'ns': getter(function () {
653
+ return nsMatrix;
654
+ })
655
+ });
656
+ }
657
+
658
+ // actual parse logic
659
+ while (j !== -1) {
660
+ if (xml.charCodeAt(j) === 60) {
661
+ // "<"
662
+ i = j;
663
+ } else {
664
+ i = xml.indexOf('<', j);
665
+ }
666
+
667
+ // parse end
668
+ if (i === -1) {
669
+ if (nodeStack.length) {
670
+ return handleError('unexpected end of file');
671
+ }
672
+ if (j === 0) {
673
+ return handleError('missing start tag');
674
+ }
675
+ if (j < xml.length) {
676
+ if (xml.substring(j).trim()) {
677
+ handleWarning(NON_WHITESPACE_OUTSIDE_ROOT_NODE);
678
+ }
679
+ }
680
+ return;
681
+ }
682
+
683
+ // parse text
684
+ if (j !== i) {
685
+ if (nodeStack.length) {
686
+ if (onText) {
687
+ onText(xml.substring(j, i), decodeEntities, getContext);
688
+ if (parseStop) {
689
+ return;
690
+ }
691
+ }
692
+ } else {
693
+ if (xml.substring(j, i).trim()) {
694
+ handleWarning(NON_WHITESPACE_OUTSIDE_ROOT_NODE);
695
+ if (parseStop) {
696
+ return;
697
+ }
698
+ }
699
+ }
700
+ }
701
+ w = xml.charCodeAt(i + 1);
702
+
703
+ // parse comments + CDATA
704
+ if (w === 33) {
705
+ // "!"
706
+ q = xml.charCodeAt(i + 2);
707
+
708
+ // CDATA section
709
+ if (q === 91 && xml.substr(i + 3, 6) === 'CDATA[') {
710
+ // 91 == "["
711
+ j = xml.indexOf(']]>', i);
712
+ if (j === -1) {
713
+ return handleError('unclosed cdata');
714
+ }
715
+ if (onCDATA) {
716
+ onCDATA(xml.substring(i + 9, j), getContext);
717
+ if (parseStop) {
718
+ return;
719
+ }
720
+ }
721
+ j += 3;
722
+ continue;
723
+ }
724
+
725
+ // comment
726
+ if (q === 45 && xml.charCodeAt(i + 3) === 45) {
727
+ // 45 == "-"
728
+ j = xml.indexOf('-->', i);
729
+ if (j === -1) {
730
+ return handleError('unclosed comment');
731
+ }
732
+ if (onComment) {
733
+ onComment(xml.substring(i + 4, j), decodeEntities, getContext);
734
+ if (parseStop) {
735
+ return;
736
+ }
737
+ }
738
+ j += 3;
739
+ continue;
740
+ }
741
+ }
742
+
743
+ // parse question <? ... ?>
744
+ if (w === 63) {
745
+ // "?"
746
+ j = xml.indexOf('?>', i);
747
+ if (j === -1) {
748
+ return handleError('unclosed question');
749
+ }
750
+ if (onQuestion) {
751
+ onQuestion(xml.substring(i, j + 2), getContext);
752
+ if (parseStop) {
753
+ return;
754
+ }
755
+ }
756
+ j += 2;
757
+ continue;
758
+ }
759
+
760
+ // find matching closing tag for attention or standard tags
761
+ // for that we must skip through attribute values
762
+ // (enclosed in single or double quotes)
763
+ for (x = i + 1;; x++) {
764
+ v = xml.charCodeAt(x);
765
+ if (isNaN(v)) {
766
+ j = -1;
767
+ return handleError('unclosed tag');
768
+ }
769
+
770
+ // [10] AttValue ::= '"' ([^<&"] | Reference)* '"' | "'" ([^<&'] | Reference)* "'"
771
+ // skips the quoted string
772
+ // (double quotes) does not appear in a literal enclosed by (double quotes)
773
+ // (single quote) does not appear in a literal enclosed by (single quote)
774
+ if (v === 34) {
775
+ // '"'
776
+ q = xml.indexOf('"', x + 1);
777
+ x = q !== -1 ? q : x;
778
+ } else if (v === 39) {
779
+ // "'"
780
+ q = xml.indexOf("'", x + 1);
781
+ x = q !== -1 ? q : x;
782
+ } else if (v === 62) {
783
+ // '>'
784
+ j = x;
785
+ break;
786
+ }
787
+ }
788
+
789
+ // parse attention <! ...>
790
+ // previously comment and CDATA have already been parsed
791
+ if (w === 33) {
792
+ // "!"
793
+
794
+ if (onAttention) {
795
+ onAttention(xml.substring(i, j + 1), decodeEntities, getContext);
796
+ if (parseStop) {
797
+ return;
798
+ }
799
+ }
800
+ j += 1;
801
+ continue;
802
+ }
803
+
804
+ // don't process attributes;
805
+ // there are none
806
+ cachedAttrs = {};
807
+
808
+ // if (xml.charCodeAt(i+1) === 47) { // </...
809
+ if (w === 47) {
810
+ // </...
811
+ tagStart = false;
812
+ tagEnd = true;
813
+ if (!nodeStack.length) {
814
+ return handleError('missing open tag');
815
+ }
816
+
817
+ // verify open <-> close tag match
818
+ x = elementName = nodeStack.pop();
819
+ q = i + 2 + x.length;
820
+ if (xml.substring(i + 2, q) !== x) {
821
+ return handleError('closing tag mismatch');
822
+ }
823
+
824
+ // verify chars in close tag
825
+ for (; q < j; q++) {
826
+ w = xml.charCodeAt(q);
827
+ if (w === 32 || w > 8 && w < 14) {
828
+ // \f\n\r\t\v space
829
+ continue;
830
+ }
831
+ return handleError('close tag');
832
+ }
833
+ } else {
834
+ if (xml.charCodeAt(j - 1) === 47) {
835
+ // .../>
836
+ x = elementName = xml.substring(i + 1, j - 1);
837
+ tagStart = true;
838
+ tagEnd = true;
839
+ } else {
840
+ x = elementName = xml.substring(i + 1, j);
841
+ tagStart = true;
842
+ tagEnd = false;
843
+ }
844
+ if (!(w > 96 && w < 123 || w > 64 && w < 91 || w === 95 || w === 58)) {
845
+ // char 95"_" 58":"
846
+ return handleError('illegal first char nodeName');
847
+ }
848
+ for (q = 1, y = x.length; q < y; q++) {
849
+ w = x.charCodeAt(q);
850
+ if (w > 96 && w < 123 || w > 64 && w < 91 || w > 47 && w < 59 || w === 45 || w === 95 || w == 46) {
851
+ continue;
852
+ }
853
+ if (w === 32 || w < 14 && w > 8) {
854
+ // \f\n\r\t\v space
855
+ elementName = x.substring(0, q);
856
+
857
+ // maybe there are attributes
858
+ cachedAttrs = null;
859
+ break;
860
+ }
861
+ return handleError('invalid nodeName');
862
+ }
863
+ if (!tagEnd) {
864
+ nodeStack.push(elementName);
865
+ }
866
+ }
867
+ if (isNamespace) {
868
+ _nsMatrix = nsMatrix;
869
+ if (tagStart) {
870
+ // remember old namespace
871
+ // unless we're self-closing
872
+ if (!tagEnd) {
873
+ nsMatrixStack.push(_nsMatrix);
874
+ }
875
+ if (cachedAttrs === null) {
876
+ // quick check, whether there may be namespace
877
+ // declarations on the node; if that is the case
878
+ // we need to eagerly parse the node attributes
879
+ if (maybeNS = x.indexOf('xmlns', q) !== -1) {
880
+ attrsStart = q;
881
+ attrsString = x;
882
+ getAttrs();
883
+ maybeNS = false;
884
+ }
885
+ }
886
+ }
887
+ _elementName = elementName;
888
+ w = elementName.indexOf(':');
889
+ if (w !== -1) {
890
+ xmlns = nsMatrix[elementName.substring(0, w)];
891
+
892
+ // prefix given; namespace must exist
893
+ if (!xmlns) {
894
+ return handleError('missing namespace on <' + _elementName + '>');
895
+ }
896
+ elementName = elementName.substr(w + 1);
897
+ } else {
898
+ xmlns = nsMatrix['xmlns'];
899
+
900
+ // if no default namespace is defined,
901
+ // we'll import the element as anonymous.
902
+ //
903
+ // it is up to users to correct that to the document defined
904
+ // targetNamespace, or whatever their undersanding of the
905
+ // XML spec mandates.
906
+ }
907
+
908
+ // adjust namespace prefixs as configured
909
+ if (xmlns) {
910
+ elementName = xmlns + ':' + elementName;
911
+ }
912
+ }
913
+ if (tagStart) {
914
+ attrsStart = q;
915
+ attrsString = x;
916
+ if (onOpenTag) {
917
+ if (proxy) {
918
+ onOpenTag(elementProxy, decodeEntities, tagEnd, getContext);
919
+ } else {
920
+ onOpenTag(elementName, getAttrs, decodeEntities, tagEnd, getContext);
921
+ }
922
+ if (parseStop) {
923
+ return;
924
+ }
925
+ }
926
+ }
927
+ if (tagEnd) {
928
+ if (onCloseTag) {
929
+ onCloseTag(proxy ? elementProxy : elementName, decodeEntities, tagStart, getContext);
930
+ if (parseStop) {
931
+ return;
932
+ }
933
+ }
934
+
935
+ // restore old namespace
936
+ if (isNamespace) {
937
+ if (!tagStart) {
938
+ nsMatrix = nsMatrixStack.pop();
939
+ } else {
940
+ nsMatrix = _nsMatrix;
941
+ }
942
+ }
943
+ }
944
+ j += 1;
945
+ }
946
+ } /** end parse */
947
+ }
948
+
949
+ // Returns:
950
+
951
+ return Parser(options);
952
+ }
953
+ //# sourceMappingURL=parseXmlStream.saxen.code.js.map