read-excel-file 9.3.1 → 9.3.2

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