@zonos/elements 1.3.87 → 1.3.88

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.
@@ -16,6 +16,1002 @@ const isDarkColor = require('./isDarkColor-5efc8367.js');
16
16
  const isColorVariable = require('./isColorVariable-6f5a9608.js');
17
17
  const containsNonLatinChars = require('./containsNonLatinChars-2be5129b.js');
18
18
 
19
+ function extend (destination) {
20
+ for (var i = 1; i < arguments.length; i++) {
21
+ var source = arguments[i];
22
+ for (var key in source) {
23
+ if (source.hasOwnProperty(key)) destination[key] = source[key];
24
+ }
25
+ }
26
+ return destination
27
+ }
28
+
29
+ function repeat (character, count) {
30
+ return Array(count + 1).join(character)
31
+ }
32
+
33
+ function trimLeadingNewlines (string) {
34
+ return string.replace(/^\n*/, '')
35
+ }
36
+
37
+ function trimTrailingNewlines (string) {
38
+ // avoid match-at-end regexp bottleneck, see #370
39
+ var indexEnd = string.length;
40
+ while (indexEnd > 0 && string[indexEnd - 1] === '\n') indexEnd--;
41
+ return string.substring(0, indexEnd)
42
+ }
43
+
44
+ var blockElements = [
45
+ 'ADDRESS', 'ARTICLE', 'ASIDE', 'AUDIO', 'BLOCKQUOTE', 'BODY', 'CANVAS',
46
+ 'CENTER', 'DD', 'DIR', 'DIV', 'DL', 'DT', 'FIELDSET', 'FIGCAPTION', 'FIGURE',
47
+ 'FOOTER', 'FORM', 'FRAMESET', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6', 'HEADER',
48
+ 'HGROUP', 'HR', 'HTML', 'ISINDEX', 'LI', 'MAIN', 'MENU', 'NAV', 'NOFRAMES',
49
+ 'NOSCRIPT', 'OL', 'OUTPUT', 'P', 'PRE', 'SECTION', 'TABLE', 'TBODY', 'TD',
50
+ 'TFOOT', 'TH', 'THEAD', 'TR', 'UL'
51
+ ];
52
+
53
+ function isBlock (node) {
54
+ return is(node, blockElements)
55
+ }
56
+
57
+ var voidElements = [
58
+ 'AREA', 'BASE', 'BR', 'COL', 'COMMAND', 'EMBED', 'HR', 'IMG', 'INPUT',
59
+ 'KEYGEN', 'LINK', 'META', 'PARAM', 'SOURCE', 'TRACK', 'WBR'
60
+ ];
61
+
62
+ function isVoid (node) {
63
+ return is(node, voidElements)
64
+ }
65
+
66
+ function hasVoid (node) {
67
+ return has(node, voidElements)
68
+ }
69
+
70
+ var meaningfulWhenBlankElements = [
71
+ 'A', 'TABLE', 'THEAD', 'TBODY', 'TFOOT', 'TH', 'TD', 'IFRAME', 'SCRIPT',
72
+ 'AUDIO', 'VIDEO'
73
+ ];
74
+
75
+ function isMeaningfulWhenBlank (node) {
76
+ return is(node, meaningfulWhenBlankElements)
77
+ }
78
+
79
+ function hasMeaningfulWhenBlank (node) {
80
+ return has(node, meaningfulWhenBlankElements)
81
+ }
82
+
83
+ function is (node, tagNames) {
84
+ return tagNames.indexOf(node.nodeName) >= 0
85
+ }
86
+
87
+ function has (node, tagNames) {
88
+ return (
89
+ node.getElementsByTagName &&
90
+ tagNames.some(function (tagName) {
91
+ return node.getElementsByTagName(tagName).length
92
+ })
93
+ )
94
+ }
95
+
96
+ var rules = {};
97
+
98
+ rules.paragraph = {
99
+ filter: 'p',
100
+
101
+ replacement: function (content) {
102
+ return '\n\n' + content + '\n\n'
103
+ }
104
+ };
105
+
106
+ rules.lineBreak = {
107
+ filter: 'br',
108
+
109
+ replacement: function (content, node, options) {
110
+ return options.br + '\n'
111
+ }
112
+ };
113
+
114
+ rules.heading = {
115
+ filter: ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'],
116
+
117
+ replacement: function (content, node, options) {
118
+ var hLevel = Number(node.nodeName.charAt(1));
119
+
120
+ if (options.headingStyle === 'setext' && hLevel < 3) {
121
+ var underline = repeat((hLevel === 1 ? '=' : '-'), content.length);
122
+ return (
123
+ '\n\n' + content + '\n' + underline + '\n\n'
124
+ )
125
+ } else {
126
+ return '\n\n' + repeat('#', hLevel) + ' ' + content + '\n\n'
127
+ }
128
+ }
129
+ };
130
+
131
+ rules.blockquote = {
132
+ filter: 'blockquote',
133
+
134
+ replacement: function (content) {
135
+ content = content.replace(/^\n+|\n+$/g, '');
136
+ content = content.replace(/^/gm, '> ');
137
+ return '\n\n' + content + '\n\n'
138
+ }
139
+ };
140
+
141
+ rules.list = {
142
+ filter: ['ul', 'ol'],
143
+
144
+ replacement: function (content, node) {
145
+ var parent = node.parentNode;
146
+ if (parent.nodeName === 'LI' && parent.lastElementChild === node) {
147
+ return '\n' + content
148
+ } else {
149
+ return '\n\n' + content + '\n\n'
150
+ }
151
+ }
152
+ };
153
+
154
+ rules.listItem = {
155
+ filter: 'li',
156
+
157
+ replacement: function (content, node, options) {
158
+ content = content
159
+ .replace(/^\n+/, '') // remove leading newlines
160
+ .replace(/\n+$/, '\n') // replace trailing newlines with just a single one
161
+ .replace(/\n/gm, '\n '); // indent
162
+ var prefix = options.bulletListMarker + ' ';
163
+ var parent = node.parentNode;
164
+ if (parent.nodeName === 'OL') {
165
+ var start = parent.getAttribute('start');
166
+ var index = Array.prototype.indexOf.call(parent.children, node);
167
+ prefix = (start ? Number(start) + index : index + 1) + '. ';
168
+ }
169
+ return (
170
+ prefix + content + (node.nextSibling && !/\n$/.test(content) ? '\n' : '')
171
+ )
172
+ }
173
+ };
174
+
175
+ rules.indentedCodeBlock = {
176
+ filter: function (node, options) {
177
+ return (
178
+ options.codeBlockStyle === 'indented' &&
179
+ node.nodeName === 'PRE' &&
180
+ node.firstChild &&
181
+ node.firstChild.nodeName === 'CODE'
182
+ )
183
+ },
184
+
185
+ replacement: function (content, node, options) {
186
+ return (
187
+ '\n\n ' +
188
+ node.firstChild.textContent.replace(/\n/g, '\n ') +
189
+ '\n\n'
190
+ )
191
+ }
192
+ };
193
+
194
+ rules.fencedCodeBlock = {
195
+ filter: function (node, options) {
196
+ return (
197
+ options.codeBlockStyle === 'fenced' &&
198
+ node.nodeName === 'PRE' &&
199
+ node.firstChild &&
200
+ node.firstChild.nodeName === 'CODE'
201
+ )
202
+ },
203
+
204
+ replacement: function (content, node, options) {
205
+ var className = node.firstChild.getAttribute('class') || '';
206
+ var language = (className.match(/language-(\S+)/) || [null, ''])[1];
207
+ var code = node.firstChild.textContent;
208
+
209
+ var fenceChar = options.fence.charAt(0);
210
+ var fenceSize = 3;
211
+ var fenceInCodeRegex = new RegExp('^' + fenceChar + '{3,}', 'gm');
212
+
213
+ var match;
214
+ while ((match = fenceInCodeRegex.exec(code))) {
215
+ if (match[0].length >= fenceSize) {
216
+ fenceSize = match[0].length + 1;
217
+ }
218
+ }
219
+
220
+ var fence = repeat(fenceChar, fenceSize);
221
+
222
+ return (
223
+ '\n\n' + fence + language + '\n' +
224
+ code.replace(/\n$/, '') +
225
+ '\n' + fence + '\n\n'
226
+ )
227
+ }
228
+ };
229
+
230
+ rules.horizontalRule = {
231
+ filter: 'hr',
232
+
233
+ replacement: function (content, node, options) {
234
+ return '\n\n' + options.hr + '\n\n'
235
+ }
236
+ };
237
+
238
+ rules.inlineLink = {
239
+ filter: function (node, options) {
240
+ return (
241
+ options.linkStyle === 'inlined' &&
242
+ node.nodeName === 'A' &&
243
+ node.getAttribute('href')
244
+ )
245
+ },
246
+
247
+ replacement: function (content, node) {
248
+ var href = node.getAttribute('href');
249
+ if (href) href = href.replace(/([()])/g, '\\$1');
250
+ var title = cleanAttribute(node.getAttribute('title'));
251
+ if (title) title = ' "' + title.replace(/"/g, '\\"') + '"';
252
+ return '[' + content + '](' + href + title + ')'
253
+ }
254
+ };
255
+
256
+ rules.referenceLink = {
257
+ filter: function (node, options) {
258
+ return (
259
+ options.linkStyle === 'referenced' &&
260
+ node.nodeName === 'A' &&
261
+ node.getAttribute('href')
262
+ )
263
+ },
264
+
265
+ replacement: function (content, node, options) {
266
+ var href = node.getAttribute('href');
267
+ var title = cleanAttribute(node.getAttribute('title'));
268
+ if (title) title = ' "' + title + '"';
269
+ var replacement;
270
+ var reference;
271
+
272
+ switch (options.linkReferenceStyle) {
273
+ case 'collapsed':
274
+ replacement = '[' + content + '][]';
275
+ reference = '[' + content + ']: ' + href + title;
276
+ break
277
+ case 'shortcut':
278
+ replacement = '[' + content + ']';
279
+ reference = '[' + content + ']: ' + href + title;
280
+ break
281
+ default:
282
+ var id = this.references.length + 1;
283
+ replacement = '[' + content + '][' + id + ']';
284
+ reference = '[' + id + ']: ' + href + title;
285
+ }
286
+
287
+ this.references.push(reference);
288
+ return replacement
289
+ },
290
+
291
+ references: [],
292
+
293
+ append: function (options) {
294
+ var references = '';
295
+ if (this.references.length) {
296
+ references = '\n\n' + this.references.join('\n') + '\n\n';
297
+ this.references = []; // Reset references
298
+ }
299
+ return references
300
+ }
301
+ };
302
+
303
+ rules.emphasis = {
304
+ filter: ['em', 'i'],
305
+
306
+ replacement: function (content, node, options) {
307
+ if (!content.trim()) return ''
308
+ return options.emDelimiter + content + options.emDelimiter
309
+ }
310
+ };
311
+
312
+ rules.strong = {
313
+ filter: ['strong', 'b'],
314
+
315
+ replacement: function (content, node, options) {
316
+ if (!content.trim()) return ''
317
+ return options.strongDelimiter + content + options.strongDelimiter
318
+ }
319
+ };
320
+
321
+ rules.code = {
322
+ filter: function (node) {
323
+ var hasSiblings = node.previousSibling || node.nextSibling;
324
+ var isCodeBlock = node.parentNode.nodeName === 'PRE' && !hasSiblings;
325
+
326
+ return node.nodeName === 'CODE' && !isCodeBlock
327
+ },
328
+
329
+ replacement: function (content) {
330
+ if (!content) return ''
331
+ content = content.replace(/\r?\n|\r/g, ' ');
332
+
333
+ var extraSpace = /^`|^ .*?[^ ].* $|`$/.test(content) ? ' ' : '';
334
+ var delimiter = '`';
335
+ var matches = content.match(/`+/gm) || [];
336
+ while (matches.indexOf(delimiter) !== -1) delimiter = delimiter + '`';
337
+
338
+ return delimiter + extraSpace + content + extraSpace + delimiter
339
+ }
340
+ };
341
+
342
+ rules.image = {
343
+ filter: 'img',
344
+
345
+ replacement: function (content, node) {
346
+ var alt = cleanAttribute(node.getAttribute('alt'));
347
+ var src = node.getAttribute('src') || '';
348
+ var title = cleanAttribute(node.getAttribute('title'));
349
+ var titlePart = title ? ' "' + title + '"' : '';
350
+ return src ? '![' + alt + ']' + '(' + src + titlePart + ')' : ''
351
+ }
352
+ };
353
+
354
+ function cleanAttribute (attribute) {
355
+ return attribute ? attribute.replace(/(\n+\s*)+/g, '\n') : ''
356
+ }
357
+
358
+ /**
359
+ * Manages a collection of rules used to convert HTML to Markdown
360
+ */
361
+
362
+ function Rules (options) {
363
+ this.options = options;
364
+ this._keep = [];
365
+ this._remove = [];
366
+
367
+ this.blankRule = {
368
+ replacement: options.blankReplacement
369
+ };
370
+
371
+ this.keepReplacement = options.keepReplacement;
372
+
373
+ this.defaultRule = {
374
+ replacement: options.defaultReplacement
375
+ };
376
+
377
+ this.array = [];
378
+ for (var key in options.rules) this.array.push(options.rules[key]);
379
+ }
380
+
381
+ Rules.prototype = {
382
+ add: function (key, rule) {
383
+ this.array.unshift(rule);
384
+ },
385
+
386
+ keep: function (filter) {
387
+ this._keep.unshift({
388
+ filter: filter,
389
+ replacement: this.keepReplacement
390
+ });
391
+ },
392
+
393
+ remove: function (filter) {
394
+ this._remove.unshift({
395
+ filter: filter,
396
+ replacement: function () {
397
+ return ''
398
+ }
399
+ });
400
+ },
401
+
402
+ forNode: function (node) {
403
+ if (node.isBlank) return this.blankRule
404
+ var rule;
405
+
406
+ if ((rule = findRule(this.array, node, this.options))) return rule
407
+ if ((rule = findRule(this._keep, node, this.options))) return rule
408
+ if ((rule = findRule(this._remove, node, this.options))) return rule
409
+
410
+ return this.defaultRule
411
+ },
412
+
413
+ forEach: function (fn) {
414
+ for (var i = 0; i < this.array.length; i++) fn(this.array[i], i);
415
+ }
416
+ };
417
+
418
+ function findRule (rules, node, options) {
419
+ for (var i = 0; i < rules.length; i++) {
420
+ var rule = rules[i];
421
+ if (filterValue(rule, node, options)) return rule
422
+ }
423
+ return void 0
424
+ }
425
+
426
+ function filterValue (rule, node, options) {
427
+ var filter = rule.filter;
428
+ if (typeof filter === 'string') {
429
+ if (filter === node.nodeName.toLowerCase()) return true
430
+ } else if (Array.isArray(filter)) {
431
+ if (filter.indexOf(node.nodeName.toLowerCase()) > -1) return true
432
+ } else if (typeof filter === 'function') {
433
+ if (filter.call(rule, node, options)) return true
434
+ } else {
435
+ throw new TypeError('`filter` needs to be a string, array, or function')
436
+ }
437
+ }
438
+
439
+ /**
440
+ * The collapseWhitespace function is adapted from collapse-whitespace
441
+ * by Luc Thevenard.
442
+ *
443
+ * The MIT License (MIT)
444
+ *
445
+ * Copyright (c) 2014 Luc Thevenard <lucthevenard@gmail.com>
446
+ *
447
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
448
+ * of this software and associated documentation files (the "Software"), to deal
449
+ * in the Software without restriction, including without limitation the rights
450
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
451
+ * copies of the Software, and to permit persons to whom the Software is
452
+ * furnished to do so, subject to the following conditions:
453
+ *
454
+ * The above copyright notice and this permission notice shall be included in
455
+ * all copies or substantial portions of the Software.
456
+ *
457
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
458
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
459
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
460
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
461
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
462
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
463
+ * THE SOFTWARE.
464
+ */
465
+
466
+ /**
467
+ * collapseWhitespace(options) removes extraneous whitespace from an the given element.
468
+ *
469
+ * @param {Object} options
470
+ */
471
+ function collapseWhitespace (options) {
472
+ var element = options.element;
473
+ var isBlock = options.isBlock;
474
+ var isVoid = options.isVoid;
475
+ var isPre = options.isPre || function (node) {
476
+ return node.nodeName === 'PRE'
477
+ };
478
+
479
+ if (!element.firstChild || isPre(element)) return
480
+
481
+ var prevText = null;
482
+ var keepLeadingWs = false;
483
+
484
+ var prev = null;
485
+ var node = next(prev, element, isPre);
486
+
487
+ while (node !== element) {
488
+ if (node.nodeType === 3 || node.nodeType === 4) { // Node.TEXT_NODE or Node.CDATA_SECTION_NODE
489
+ var text = node.data.replace(/[ \r\n\t]+/g, ' ');
490
+
491
+ if ((!prevText || / $/.test(prevText.data)) &&
492
+ !keepLeadingWs && text[0] === ' ') {
493
+ text = text.substr(1);
494
+ }
495
+
496
+ // `text` might be empty at this point.
497
+ if (!text) {
498
+ node = remove(node);
499
+ continue
500
+ }
501
+
502
+ node.data = text;
503
+
504
+ prevText = node;
505
+ } else if (node.nodeType === 1) { // Node.ELEMENT_NODE
506
+ if (isBlock(node) || node.nodeName === 'BR') {
507
+ if (prevText) {
508
+ prevText.data = prevText.data.replace(/ $/, '');
509
+ }
510
+
511
+ prevText = null;
512
+ keepLeadingWs = false;
513
+ } else if (isVoid(node) || isPre(node)) {
514
+ // Avoid trimming space around non-block, non-BR void elements and inline PRE.
515
+ prevText = null;
516
+ keepLeadingWs = true;
517
+ } else if (prevText) {
518
+ // Drop protection if set previously.
519
+ keepLeadingWs = false;
520
+ }
521
+ } else {
522
+ node = remove(node);
523
+ continue
524
+ }
525
+
526
+ var nextNode = next(prev, node, isPre);
527
+ prev = node;
528
+ node = nextNode;
529
+ }
530
+
531
+ if (prevText) {
532
+ prevText.data = prevText.data.replace(/ $/, '');
533
+ if (!prevText.data) {
534
+ remove(prevText);
535
+ }
536
+ }
537
+ }
538
+
539
+ /**
540
+ * remove(node) removes the given node from the DOM and returns the
541
+ * next node in the sequence.
542
+ *
543
+ * @param {Node} node
544
+ * @return {Node} node
545
+ */
546
+ function remove (node) {
547
+ var next = node.nextSibling || node.parentNode;
548
+
549
+ node.parentNode.removeChild(node);
550
+
551
+ return next
552
+ }
553
+
554
+ /**
555
+ * next(prev, current, isPre) returns the next node in the sequence, given the
556
+ * current and previous nodes.
557
+ *
558
+ * @param {Node} prev
559
+ * @param {Node} current
560
+ * @param {Function} isPre
561
+ * @return {Node}
562
+ */
563
+ function next (prev, current, isPre) {
564
+ if ((prev && prev.parentNode === current) || isPre(current)) {
565
+ return current.nextSibling || current.parentNode
566
+ }
567
+
568
+ return current.firstChild || current.nextSibling || current.parentNode
569
+ }
570
+
571
+ /*
572
+ * Set up window for Node.js
573
+ */
574
+
575
+ var root = (typeof window !== 'undefined' ? window : {});
576
+
577
+ /*
578
+ * Parsing HTML strings
579
+ */
580
+
581
+ function canParseHTMLNatively () {
582
+ var Parser = root.DOMParser;
583
+ var canParse = false;
584
+
585
+ // Adapted from https://gist.github.com/1129031
586
+ // Firefox/Opera/IE throw errors on unsupported types
587
+ try {
588
+ // WebKit returns null on unsupported types
589
+ if (new Parser().parseFromString('', 'text/html')) {
590
+ canParse = true;
591
+ }
592
+ } catch (e) {}
593
+
594
+ return canParse
595
+ }
596
+
597
+ function createHTMLParser () {
598
+ var Parser = function () {};
599
+
600
+ {
601
+ if (shouldUseActiveX()) {
602
+ Parser.prototype.parseFromString = function (string) {
603
+ var doc = new window.ActiveXObject('htmlfile');
604
+ doc.designMode = 'on'; // disable on-page scripts
605
+ doc.open();
606
+ doc.write(string);
607
+ doc.close();
608
+ return doc
609
+ };
610
+ } else {
611
+ Parser.prototype.parseFromString = function (string) {
612
+ var doc = document.implementation.createHTMLDocument('');
613
+ doc.open();
614
+ doc.write(string);
615
+ doc.close();
616
+ return doc
617
+ };
618
+ }
619
+ }
620
+ return Parser
621
+ }
622
+
623
+ function shouldUseActiveX () {
624
+ var useActiveX = false;
625
+ try {
626
+ document.implementation.createHTMLDocument('').open();
627
+ } catch (e) {
628
+ if (root.ActiveXObject) useActiveX = true;
629
+ }
630
+ return useActiveX
631
+ }
632
+
633
+ var HTMLParser = canParseHTMLNatively() ? root.DOMParser : createHTMLParser();
634
+
635
+ function RootNode (input, options) {
636
+ var root;
637
+ if (typeof input === 'string') {
638
+ var doc = htmlParser().parseFromString(
639
+ // DOM parsers arrange elements in the <head> and <body>.
640
+ // Wrapping in a custom element ensures elements are reliably arranged in
641
+ // a single element.
642
+ '<x-turndown id="turndown-root">' + input + '</x-turndown>',
643
+ 'text/html'
644
+ );
645
+ root = doc.getElementById('turndown-root');
646
+ } else {
647
+ root = input.cloneNode(true);
648
+ }
649
+ collapseWhitespace({
650
+ element: root,
651
+ isBlock: isBlock,
652
+ isVoid: isVoid,
653
+ isPre: options.preformattedCode ? isPreOrCode : null
654
+ });
655
+
656
+ return root
657
+ }
658
+
659
+ var _htmlParser;
660
+ function htmlParser () {
661
+ _htmlParser = _htmlParser || new HTMLParser();
662
+ return _htmlParser
663
+ }
664
+
665
+ function isPreOrCode (node) {
666
+ return node.nodeName === 'PRE' || node.nodeName === 'CODE'
667
+ }
668
+
669
+ function Node (node, options) {
670
+ node.isBlock = isBlock(node);
671
+ node.isCode = node.nodeName === 'CODE' || node.parentNode.isCode;
672
+ node.isBlank = isBlank(node);
673
+ node.flankingWhitespace = flankingWhitespace(node, options);
674
+ return node
675
+ }
676
+
677
+ function isBlank (node) {
678
+ return (
679
+ !isVoid(node) &&
680
+ !isMeaningfulWhenBlank(node) &&
681
+ /^\s*$/i.test(node.textContent) &&
682
+ !hasVoid(node) &&
683
+ !hasMeaningfulWhenBlank(node)
684
+ )
685
+ }
686
+
687
+ function flankingWhitespace (node, options) {
688
+ if (node.isBlock || (options.preformattedCode && node.isCode)) {
689
+ return { leading: '', trailing: '' }
690
+ }
691
+
692
+ var edges = edgeWhitespace(node.textContent);
693
+
694
+ // abandon leading ASCII WS if left-flanked by ASCII WS
695
+ if (edges.leadingAscii && isFlankedByWhitespace('left', node, options)) {
696
+ edges.leading = edges.leadingNonAscii;
697
+ }
698
+
699
+ // abandon trailing ASCII WS if right-flanked by ASCII WS
700
+ if (edges.trailingAscii && isFlankedByWhitespace('right', node, options)) {
701
+ edges.trailing = edges.trailingNonAscii;
702
+ }
703
+
704
+ return { leading: edges.leading, trailing: edges.trailing }
705
+ }
706
+
707
+ function edgeWhitespace (string) {
708
+ var m = string.match(/^(([ \t\r\n]*)(\s*))(?:(?=\S)[\s\S]*\S)?((\s*?)([ \t\r\n]*))$/);
709
+ return {
710
+ leading: m[1], // whole string for whitespace-only strings
711
+ leadingAscii: m[2],
712
+ leadingNonAscii: m[3],
713
+ trailing: m[4], // empty for whitespace-only strings
714
+ trailingNonAscii: m[5],
715
+ trailingAscii: m[6]
716
+ }
717
+ }
718
+
719
+ function isFlankedByWhitespace (side, node, options) {
720
+ var sibling;
721
+ var regExp;
722
+ var isFlanked;
723
+
724
+ if (side === 'left') {
725
+ sibling = node.previousSibling;
726
+ regExp = / $/;
727
+ } else {
728
+ sibling = node.nextSibling;
729
+ regExp = /^ /;
730
+ }
731
+
732
+ if (sibling) {
733
+ if (sibling.nodeType === 3) {
734
+ isFlanked = regExp.test(sibling.nodeValue);
735
+ } else if (options.preformattedCode && sibling.nodeName === 'CODE') {
736
+ isFlanked = false;
737
+ } else if (sibling.nodeType === 1 && !isBlock(sibling)) {
738
+ isFlanked = regExp.test(sibling.textContent);
739
+ }
740
+ }
741
+ return isFlanked
742
+ }
743
+
744
+ var reduce = Array.prototype.reduce;
745
+ var escapes = [
746
+ [/\\/g, '\\\\'],
747
+ [/\*/g, '\\*'],
748
+ [/^-/g, '\\-'],
749
+ [/^\+ /g, '\\+ '],
750
+ [/^(=+)/g, '\\$1'],
751
+ [/^(#{1,6}) /g, '\\$1 '],
752
+ [/`/g, '\\`'],
753
+ [/^~~~/g, '\\~~~'],
754
+ [/\[/g, '\\['],
755
+ [/\]/g, '\\]'],
756
+ [/^>/g, '\\>'],
757
+ [/_/g, '\\_'],
758
+ [/^(\d+)\. /g, '$1\\. ']
759
+ ];
760
+
761
+ function TurndownService (options) {
762
+ if (!(this instanceof TurndownService)) return new TurndownService(options)
763
+
764
+ var defaults = {
765
+ rules: rules,
766
+ headingStyle: 'setext',
767
+ hr: '* * *',
768
+ bulletListMarker: '*',
769
+ codeBlockStyle: 'indented',
770
+ fence: '```',
771
+ emDelimiter: '_',
772
+ strongDelimiter: '**',
773
+ linkStyle: 'inlined',
774
+ linkReferenceStyle: 'full',
775
+ br: ' ',
776
+ preformattedCode: false,
777
+ blankReplacement: function (content, node) {
778
+ return node.isBlock ? '\n\n' : ''
779
+ },
780
+ keepReplacement: function (content, node) {
781
+ return node.isBlock ? '\n\n' + node.outerHTML + '\n\n' : node.outerHTML
782
+ },
783
+ defaultReplacement: function (content, node) {
784
+ return node.isBlock ? '\n\n' + content + '\n\n' : content
785
+ }
786
+ };
787
+ this.options = extend({}, defaults, options);
788
+ this.rules = new Rules(this.options);
789
+ }
790
+
791
+ TurndownService.prototype = {
792
+ /**
793
+ * The entry point for converting a string or DOM node to Markdown
794
+ * @public
795
+ * @param {String|HTMLElement} input The string or DOM node to convert
796
+ * @returns A Markdown representation of the input
797
+ * @type String
798
+ */
799
+
800
+ turndown: function (input) {
801
+ if (!canConvert(input)) {
802
+ throw new TypeError(
803
+ input + ' is not a string, or an element/document/fragment node.'
804
+ )
805
+ }
806
+
807
+ if (input === '') return ''
808
+
809
+ var output = process.call(this, new RootNode(input, this.options));
810
+ return postProcess.call(this, output)
811
+ },
812
+
813
+ /**
814
+ * Add one or more plugins
815
+ * @public
816
+ * @param {Function|Array} plugin The plugin or array of plugins to add
817
+ * @returns The Turndown instance for chaining
818
+ * @type Object
819
+ */
820
+
821
+ use: function (plugin) {
822
+ if (Array.isArray(plugin)) {
823
+ for (var i = 0; i < plugin.length; i++) this.use(plugin[i]);
824
+ } else if (typeof plugin === 'function') {
825
+ plugin(this);
826
+ } else {
827
+ throw new TypeError('plugin must be a Function or an Array of Functions')
828
+ }
829
+ return this
830
+ },
831
+
832
+ /**
833
+ * Adds a rule
834
+ * @public
835
+ * @param {String} key The unique key of the rule
836
+ * @param {Object} rule The rule
837
+ * @returns The Turndown instance for chaining
838
+ * @type Object
839
+ */
840
+
841
+ addRule: function (key, rule) {
842
+ this.rules.add(key, rule);
843
+ return this
844
+ },
845
+
846
+ /**
847
+ * Keep a node (as HTML) that matches the filter
848
+ * @public
849
+ * @param {String|Array|Function} filter The unique key of the rule
850
+ * @returns The Turndown instance for chaining
851
+ * @type Object
852
+ */
853
+
854
+ keep: function (filter) {
855
+ this.rules.keep(filter);
856
+ return this
857
+ },
858
+
859
+ /**
860
+ * Remove a node that matches the filter
861
+ * @public
862
+ * @param {String|Array|Function} filter The unique key of the rule
863
+ * @returns The Turndown instance for chaining
864
+ * @type Object
865
+ */
866
+
867
+ remove: function (filter) {
868
+ this.rules.remove(filter);
869
+ return this
870
+ },
871
+
872
+ /**
873
+ * Escapes Markdown syntax
874
+ * @public
875
+ * @param {String} string The string to escape
876
+ * @returns A string with Markdown syntax escaped
877
+ * @type String
878
+ */
879
+
880
+ escape: function (string) {
881
+ return escapes.reduce(function (accumulator, escape) {
882
+ return accumulator.replace(escape[0], escape[1])
883
+ }, string)
884
+ }
885
+ };
886
+
887
+ /**
888
+ * Reduces a DOM node down to its Markdown string equivalent
889
+ * @private
890
+ * @param {HTMLElement} parentNode The node to convert
891
+ * @returns A Markdown representation of the node
892
+ * @type String
893
+ */
894
+
895
+ function process (parentNode) {
896
+ var self = this;
897
+ return reduce.call(parentNode.childNodes, function (output, node) {
898
+ node = new Node(node, self.options);
899
+
900
+ var replacement = '';
901
+ if (node.nodeType === 3) {
902
+ replacement = node.isCode ? node.nodeValue : self.escape(node.nodeValue);
903
+ } else if (node.nodeType === 1) {
904
+ replacement = replacementForNode.call(self, node);
905
+ }
906
+
907
+ return join(output, replacement)
908
+ }, '')
909
+ }
910
+
911
+ /**
912
+ * Appends strings as each rule requires and trims the output
913
+ * @private
914
+ * @param {String} output The conversion output
915
+ * @returns A trimmed version of the ouput
916
+ * @type String
917
+ */
918
+
919
+ function postProcess (output) {
920
+ var self = this;
921
+ this.rules.forEach(function (rule) {
922
+ if (typeof rule.append === 'function') {
923
+ output = join(output, rule.append(self.options));
924
+ }
925
+ });
926
+
927
+ return output.replace(/^[\t\r\n]+/, '').replace(/[\t\r\n\s]+$/, '')
928
+ }
929
+
930
+ /**
931
+ * Converts an element node to its Markdown equivalent
932
+ * @private
933
+ * @param {HTMLElement} node The node to convert
934
+ * @returns A Markdown representation of the node
935
+ * @type String
936
+ */
937
+
938
+ function replacementForNode (node) {
939
+ var rule = this.rules.forNode(node);
940
+ var content = process.call(this, node);
941
+ var whitespace = node.flankingWhitespace;
942
+ if (whitespace.leading || whitespace.trailing) content = content.trim();
943
+ return (
944
+ whitespace.leading +
945
+ rule.replacement(content, node, this.options) +
946
+ whitespace.trailing
947
+ )
948
+ }
949
+
950
+ /**
951
+ * Joins replacement to the current output with appropriate number of new lines
952
+ * @private
953
+ * @param {String} output The current conversion output
954
+ * @param {String} replacement The string to append to the output
955
+ * @returns Joined output
956
+ * @type String
957
+ */
958
+
959
+ function join (output, replacement) {
960
+ var s1 = trimTrailingNewlines(output);
961
+ var s2 = trimLeadingNewlines(replacement);
962
+ var nls = Math.max(output.length - s1.length, replacement.length - s2.length);
963
+ var separator = '\n\n'.substring(0, nls);
964
+
965
+ return s1 + separator + s2
966
+ }
967
+
968
+ /**
969
+ * Determines whether an input can be converted
970
+ * @private
971
+ * @param {String|HTMLElement} input Describe this parameter
972
+ * @returns Describe what it returns
973
+ * @type String|Object|Array|Boolean|Number
974
+ */
975
+
976
+ function canConvert (input) {
977
+ return (
978
+ input != null && (
979
+ typeof input === 'string' ||
980
+ (input.nodeType && (
981
+ input.nodeType === 1 || input.nodeType === 9 || input.nodeType === 11
982
+ ))
983
+ )
984
+ )
985
+ }
986
+
987
+ const turndownService = new TurndownService();
988
+ /**
989
+ * Converts an HTML string to Markdown format, strips unnecessary Markdown tags,
990
+ * and returns an array of cleaned Markdown text blocks..
991
+ *
992
+ * This utility function is useful for transforming HTML into Markdown and cleaning
993
+ * it by removing extra or unwanted Markdown elements, resulting in an array of
994
+ * plain Markdown text segments.
995
+ *
996
+ * @param {string} htmlString - The input HTML string to be converted and cleaned.
997
+ *
998
+ * @example
999
+ * const htmlInput = "<h1>Hello World</h1><p>This is a paragraph.</p>";
1000
+ * const result = cleanHtmlMarkdown(htmlInput);
1001
+ * console.log(result); // Outputs cleaned HTML after conversion and processing
1002
+ */
1003
+ const cleanHtmlMarkdown = (htmlString) => {
1004
+ const mdString = turndownService.turndown(htmlString);
1005
+ const sanitizedMdString =
1006
+ // remove header tags
1007
+ mdString.replace(/^\#+\s+/gm, '').trim();
1008
+ if (!sanitizedMdString) {
1009
+ return [];
1010
+ }
1011
+ const mdBlocks = sanitizedMdString.split(/[\n\r]+/gm);
1012
+ return mdBlocks;
1013
+ };
1014
+
19
1015
  const zonosCartItemsCss = ":host{font-family:var(--font-family, Inter), Inter;display:block;white-space:normal}:host *{font-family:var(--font-family, Inter), Inter}:host img{max-width:100%}:host dl,:host dd,:host h1,:host h2,:host h3,:host h4,:host h5,:host h6,:host hr,:host figure,:host p,:host pre{margin:0}:host{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased}:host .zonos--cart-table{width:100%;border:none;border-collapse:collapse;overflow:auto;font-size:var(--zonos-elements-font-size-base)}:host .zonos--cart-table .zonos--column{padding:8px;font-size:var(--zonos-elements-font-size-base)}:host .zonos--cart-table .zonos--column:last-child{text-align:right}:host .zonos--cart-table .zonos--column:first-child{width:60px}:host .zonos--cart-table td{vertical-align:top}:host .zonos--cart-item-name{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;gap:12px}:host .zonos--cart-item-name .zonos--cart-item-quantity>*{display:inline-block}:host .zonos--cart-item-price zonos-text{white-space:nowrap}:host img{min-width:40px;margin-top:6px}";
20
1016
  const ZonosCartItemsStyle0 = zonosCartItemsCss;
21
1017
 
@@ -29,15 +1025,14 @@ const ZonosCartItems = class {
29
1025
  const emptyItemImg = index.getAssetPath('./assets/empty-item.jpeg');
30
1026
  const rate = ((_a = cart.cartStore.exchangeRate) === null || _a === void 0 ? void 0 : _a.rate) || 1;
31
1027
  const nonRestrictedItems = cart.cartStore.items.filter(item => !item.isRestricted);
32
- return (index.h(index.Host, { key: '7bdf8d1972edb2d11669441b3d8ec6643fca1f4b', class: "zonos--cart-items zonos--elements" }, index.h("table", { key: '1c2fe6d444ea93e40b981a8935d16192bf61928c', class: "zonos--cart-table" }, index.h("tbody", { key: '84279bea6821077bf117a7a13ca497155276c622' }, nonRestrictedItems.map(item => {
1028
+ return (index.h(index.Host, { key: '5bb1ea08c13ffd9521ed1ef3934a0e02bdce3317', class: "zonos--cart-items zonos--elements" }, index.h("table", { key: '54c1dcf71a22e9fa1108350c272ee5267832f2e3', class: "zonos--cart-table" }, index.h("tbody", { key: 'f1c426a5cf7db0b4198a25bfb9cb99a2d67908ab' }, nonRestrictedItems.map(item => {
33
1029
  const itemImg = item.imageUrl;
34
- // Split the name by <br> tag
35
- const namesWithNewLine = item.name.split(/<br\s*\/*>/);
1030
+ const cleanedItemNames = cleanHtmlMarkdown(item.name);
36
1031
  return (index.h("tr", { class: "zonos--cart-item" }, index.h("td", { class: "zonos--column zonos--cart-item-image" }, itemImg && !this.errorImages.includes(itemImg) ? (index.h("img", { alt: item.name, onError: () => {
37
1032
  this.errorImages = [...this.errorImages, itemImg];
38
1033
  }, src: item.imageUrl, style: {
39
1034
  'min-width': '40px',
40
- }, width: 40 })) : (index.h("img", { alt: item.name, src: emptyItemImg, width: 40 }))), index.h("td", { class: "zonos--column zonos--cart-item-name" }, index.h("div", null, namesWithNewLine.map(name => (index.h("zonos-text", { type: "label" }, name)))), index.h("zonos-text", { textColor: "gray-600", type: "caption" }, cart.translate('Quantity'), ": ", item.quantity)), index.h("td", { class: "zonos--column zonos--cart-item-price" }, index.h("zonos-text", { type: "semiBoldLabel", weight: 600 }, cart.currencyFormat({
1035
+ }, width: 40 })) : (index.h("img", { alt: item.name, src: emptyItemImg, width: 40 }))), index.h("td", { class: "zonos--column zonos--cart-item-name" }, index.h("div", null, cleanedItemNames.map(name => (index.h("zonos-text", { type: "label" }, name)))), index.h("zonos-text", { textColor: "gray-600", type: "caption" }, cart.translate('Quantity'), ": ", item.quantity)), index.h("td", { class: "zonos--column zonos--cart-item-price" }, index.h("zonos-text", { type: "semiBoldLabel", weight: 600 }, cart.currencyFormat({
41
1036
  amount: item.amount * rate * item.quantity,
42
1037
  currency: cart.cartStore.currency,
43
1038
  })))));
@@ -293,13 +1288,29 @@ const ZonosCheckoutFinish = class {
293
1288
  };
294
1289
  // TODO: This method of pulling orders is temporary. Once we have a working event registry system, we will rely on that to tell us when the order is ready to trigger onOrderSuccess
295
1290
  this.getPullOrder = async (attempts = 0) => {
1291
+ var _a, _b, _c;
296
1292
  const { baseUrl, order } = await this.pullOrder();
297
- if (order) {
1293
+ const legacyOrderNumberExist = !!((_c = (_b = (_a = this.order) === null || _a === void 0 ? void 0 : _a.references) === null || _b === void 0 ? void 0 : _b.find(entry => (entry === null || entry === void 0 ? void 0 : entry.key) === 'zonosOrderNumber')) === null || _c === void 0 ? void 0 : _c.value);
1294
+ // legacy customers are still using the old order number so we need to wait for legacy order number to attach to dgs order before redirecting
1295
+ if ((order && attempts >= 5) || legacyOrderNumberExist) {
1296
+ if (!legacyOrderNumberExist) {
1297
+ const checkoutSessionId = cart.cartStore.checkoutSessionId;
1298
+ void handleFetch.sendErrorLog({
1299
+ endpoint: `${baseUrl}/api/zonos-elements/get-order?checkoutSessionId=${checkoutSessionId}&orderId=${order === null || order === void 0 ? void 0 : order.id}`,
1300
+ errors: [`Order found but legacy order number doesn’t exist`],
1301
+ metadata: {
1302
+ checkoutSessionId: cart.cartStore.checkoutSessionId || '',
1303
+ domain: window.location.hostname,
1304
+ orderId: (order === null || order === void 0 ? void 0 : order.id) || '',
1305
+ storeId: zonosStore.zonosStore.storeId,
1306
+ },
1307
+ });
1308
+ }
298
1309
  void createCustomEvent.trackConversionEvent('checkout_orderCompleted');
299
1310
  this.order = order;
300
1311
  this.handleSuccessBehavior();
301
1312
  }
302
- else if (!order && attempts < 5) {
1313
+ else if ((!order || !legacyOrderNumberExist) && attempts < 5) {
303
1314
  // Wait for 1 second before the next attempt
304
1315
  await new Promise(resolve => setTimeout(resolve, 1000));
305
1316
  await this.getPullOrder(attempts + 1);
@@ -435,11 +1446,11 @@ const ZonosCheckoutFinish = class {
435
1446
  var _a, _b;
436
1447
  const orderId = ((_a = this.order) === null || _a === void 0 ? void 0 : _a.accountOrderNumber) || getGraphQlShortId((_b = this.order) === null || _b === void 0 ? void 0 : _b.id);
437
1448
  const isTestMode = createCustomEvent.getIsTestMode();
438
- return (index.h(index.Host, { key: '9939772d4ce4213978ae6b02b4cd5345d15dbdfd', class: "zonos--checkout-finish zonos--elements", style: {
1449
+ return (index.h(index.Host, { key: '3c6c69c59622b7b2731f9bc6eb1cc8a7f3491572', class: "zonos--checkout-finish zonos--elements", style: {
439
1450
  '--border-radius': getBorderRadius.getBorderRadius({
440
1451
  overrideBorderStyle: this.borderRadius,
441
1452
  }),
442
- } }, this.isLoading && (index.h("div", { key: '491d4d0ba3dc487d448606009a30a5ce8d3bb86e', class: "loading-wrapper" }, index.h("zonos-spinner", { key: '3179aeb472d3e70628d3f1e3e2b76ed3d622145d' }))), !this.isLoading && (index.h("div", { key: '6044c9d1ac7599d9168f944dcf82028669fd1f37', class: "zonos--finish-details" }, index.h("div", { key: 'd22ec981a73db08e4871c8babe29f9a09a5bc29d', class: "zonos--group" }, this.notificationType === 'success' ? (index.h("zonos-icon", { "aria-label": "Order success", content: SuccessIcon, iconColor: 'blue-800', size: 50 })) : (index.h("zonos-icon", { "aria-label": "Order failed", content: RemoveIcon, iconColor: 'red-800', size: 50 })), index.h("zonos-text", { key: 'bfef33fd319456253e07c3ef3f81da1b85414df9', class: "zonos--title", type: "semiBoldSubheader" }, this.notificationTitle), orderId && (index.h("div", { key: 'f056c93644d1f9defa263f59111874f154293b51', class: "zonos--order-number" }, "Order #", orderId)), index.h("zonos-text", { key: '69d38c4640943a5cfdcef5ea6951ddec9c7b8a84', textColor: "gray-600" }, this.notificationMessages.map(message => (index.h(index.Fragment, null, message, index.h("br", null))))), index.h("zonos-button", { key: 'fbb2d1cc0baab99a3312f2077c28cb9d51b4eb44', onClick: () => this.closeClickHandler(), size: "md", variant: "primary" }, this.notificationActionText)), isTestMode && cart.cartStore.step === 'finish' && (index.h("div", { key: '7b63fd838f850ce6a5acf4970fa66657ca05e235', class: "zonos--finish-button-wrapper" }, index.h("zonos-button", { key: '85035826e36d52ccf8c77aa6ba6e27173fccdaa6', backgroundColor: "gray-0", buttonColor: "gray-1200", onClick: () => this.closeClickHandler(), size: "lg", variant: "outline" }, "New test cart"), index.h("zonos-button", { key: 'd3848fdbdf1380dce49fcbc2b2903d99ce65247d', onClick: () => this.redirectToUrl(`/orders/all`), size: "lg", variant: "primary" }, "View order in Dashboard")))))));
1453
+ } }, this.isLoading && (index.h("div", { key: '45ce0e608dca725237abc09295656c8b6471d26c', class: "loading-wrapper" }, index.h("zonos-spinner", { key: 'fd1a193d34ecf41af9bb6eff082c192c6a8d46db' }))), !this.isLoading && (index.h("div", { key: '64f652a419330967f13b9d01a172fcc52f6dfd5b', class: "zonos--finish-details" }, index.h("div", { key: '945cb9e55b418de79921c1995604572e6e009459', class: "zonos--group" }, this.notificationType === 'success' ? (index.h("zonos-icon", { "aria-label": "Order success", content: SuccessIcon, iconColor: 'blue-800', size: 50 })) : (index.h("zonos-icon", { "aria-label": "Order failed", content: RemoveIcon, iconColor: 'red-800', size: 50 })), index.h("zonos-text", { key: '241bd7034c5ab5e83e4cedd526a181120a743ad0', class: "zonos--title", type: "semiBoldSubheader" }, this.notificationTitle), orderId && (index.h("div", { key: '959595c1be3f65aa6cd2e00e4398c5bb4df702b6', class: "zonos--order-number" }, "Order #", orderId)), index.h("zonos-text", { key: 'a23dce69391c3abf49eb512e715af454c971977e', textColor: "gray-600" }, this.notificationMessages.map(message => (index.h(index.Fragment, null, message, index.h("br", null))))), index.h("zonos-button", { key: 'ce87734e2d46e8a044bc0ded7a6ed6a4a705685d', onClick: () => this.closeClickHandler(), size: "md", variant: "primary" }, this.notificationActionText)), isTestMode && cart.cartStore.step === 'finish' && (index.h("div", { key: 'a46cee8819c83fb76a54dbe049ee2452b7fc150a', class: "zonos--finish-button-wrapper" }, index.h("zonos-button", { key: '514fdff77f5aff9f4b9657a0579ab843833af7b0', backgroundColor: "gray-0", buttonColor: "gray-1200", onClick: () => this.closeClickHandler(), size: "lg", variant: "outline" }, "New test cart"), index.h("zonos-button", { key: '59630cf7504c1ef9d24854d041b063bbfdc3a1a4', onClick: () => this.redirectToUrl(`/orders/all`), size: "lg", variant: "primary" }, "View order in Dashboard")))))));
443
1454
  }
444
1455
  static get assetsDirs() { return ["assets"]; }
445
1456
  };