@commercetools-uikit/rich-text-utils 20.3.0 → 20.4.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.
@@ -26,6 +26,7 @@ var _Object$getOwnPropertyDescriptors = require('@babel/runtime-corejs3/core-js-
26
26
  var _Object$defineProperties = require('@babel/runtime-corejs3/core-js-stable/object/define-properties');
27
27
  var _Object$defineProperty = require('@babel/runtime-corejs3/core-js-stable/object/define-property');
28
28
  var escapeHtml = require('escape-html');
29
+ var DOMPurify = require('dompurify');
29
30
  var slate = require('slate');
30
31
  var slateHyperscript = require('slate-hyperscript');
31
32
  var parse = require('style-to-object');
@@ -72,6 +73,7 @@ var _Object$getOwnPropertyDescriptors__default = /*#__PURE__*/_interopDefault(_O
72
73
  var _Object$defineProperties__default = /*#__PURE__*/_interopDefault(_Object$defineProperties);
73
74
  var _Object$defineProperty__default = /*#__PURE__*/_interopDefault(_Object$defineProperty);
74
75
  var escapeHtml__default = /*#__PURE__*/_interopDefault(escapeHtml);
76
+ var DOMPurify__default = /*#__PURE__*/_interopDefault(DOMPurify);
75
77
  var parse__default = /*#__PURE__*/_interopDefault(parse);
76
78
  var isEmpty__default = /*#__PURE__*/_interopDefault(isEmpty$2);
77
79
  var _includesInstanceProperty__default = /*#__PURE__*/_interopDefault(_includesInstanceProperty);
@@ -449,10 +451,33 @@ function _objectSpread$f(e) { for (var r = 1; r < arguments.length; r++) { var _
449
451
  // more: https://docs.slatejs.org/concepts/12-typescript
450
452
  // example: https://github.com/ianstormtaylor/slate/blob/main/packages/slate-react/src/custom-types.ts
451
453
 
454
+ /**
455
+ * Escapes HTML but preserves anchor tags with sanitized attributes.
456
+ * This allows <a> tags to remain as clickable links while preventing XSS from other tags.
457
+ * Uses DOMPurify for robust sanitization against XSS attacks.
458
+ */
459
+ const escapeHtmlExceptAnchors = text => {
460
+ // Use DOMPurify to sanitize the text, allowing only anchor tags
461
+ // This is much more secure than regex-based parsing
462
+ const sanitized = DOMPurify__default["default"].sanitize(text, {
463
+ ALLOWED_TAGS: ['a'],
464
+ ALLOWED_ATTR: ['href', 'title', 'target', 'rel'],
465
+ // Block dangerous URL schemes
466
+ ALLOWED_URI_REGEXP: /^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i,
467
+ // Prevent DOM clobbering
468
+ SANITIZE_DOM: true,
469
+ // Keep relative URLs
470
+ ALLOW_DATA_ATTR: false,
471
+ // Return a string, not a DOM node
472
+ RETURN_DOM: false,
473
+ RETURN_DOM_FRAGMENT: false
474
+ });
475
+ return sanitized;
476
+ };
452
477
  const serializeNode = node => {
453
478
  var _context, _context5, _context6;
454
479
  if (slate.Text.isText(node)) {
455
- let string = escapeHtml__default["default"](node.text);
480
+ let string = escapeHtmlExceptAnchors(node.text);
456
481
  if (node.bold) {
457
482
  string = "<strong>".concat(string, "</strong>");
458
483
  }
@@ -1462,109 +1487,151 @@ var Dropdown$1 = Dropdown;
1462
1487
 
1463
1488
  var messages = reactIntl.defineMessages({
1464
1489
  boldButtonLabel: {
1465
- id: 'UIKit.RichTextBody.boldButtonLabel',
1466
- description: 'Label for the bold button',
1467
- defaultMessage: 'Bold'
1490
+ id: "UIKit.RichTextBody.boldButtonLabel",
1491
+ defaultMessage: [{
1492
+ "type": 0,
1493
+ "value": "Bold"
1494
+ }]
1468
1495
  },
1469
1496
  expandButtonLabel: {
1470
- id: 'UIKit.RichTextBody.expandButtonLabel',
1471
- description: 'Label for the expand button',
1472
- defaultMessage: 'Expand'
1497
+ id: "UIKit.RichTextBody.expandButtonLabel",
1498
+ defaultMessage: [{
1499
+ "type": 0,
1500
+ "value": "Expand"
1501
+ }]
1473
1502
  },
1474
1503
  italicButtonLabel: {
1475
- id: 'UIKit.RichTextBody.italicButtonLabel',
1476
- description: 'Label for the italic button',
1477
- defaultMessage: 'Italic'
1504
+ id: "UIKit.RichTextBody.italicButtonLabel",
1505
+ defaultMessage: [{
1506
+ "type": 0,
1507
+ "value": "Italic"
1508
+ }]
1478
1509
  },
1479
1510
  moreStylesDropdownLabel: {
1480
- id: 'UIKit.RichTextBody.moreStylesDropdownLabel',
1481
- description: 'Label for the more styles dropdown',
1482
- defaultMessage: 'More styles'
1511
+ id: "UIKit.RichTextBody.moreStylesDropdownLabel",
1512
+ defaultMessage: [{
1513
+ "type": 0,
1514
+ "value": "More styles"
1515
+ }]
1483
1516
  },
1484
1517
  moreStylesDropdownOptionStrikethrough: {
1485
- id: 'UIKit.RichTextBody.moreStylesDropdownOptionStrikethrough',
1486
- description: 'label for the more styles `strikethrough` option',
1487
- defaultMessage: 'Strikethrough'
1518
+ id: "UIKit.RichTextBody.moreStylesDropdownOptionStrikethrough",
1519
+ defaultMessage: [{
1520
+ "type": 0,
1521
+ "value": "Strikethrough"
1522
+ }]
1488
1523
  },
1489
1524
  moreStylesDropdownOptionSuperscript: {
1490
- id: 'UIKit.RichTextBody.moreStylesDropdownOptionSuperscript',
1491
- description: 'label for the more styles `superscript` option',
1492
- defaultMessage: 'Superscript'
1525
+ id: "UIKit.RichTextBody.moreStylesDropdownOptionSuperscript",
1526
+ defaultMessage: [{
1527
+ "type": 0,
1528
+ "value": "Superscript"
1529
+ }]
1493
1530
  },
1494
1531
  moreStylesDropdownOptionSubscript: {
1495
- id: 'UIKit.RichTextBody.moreStylesDropdownOptionSubscript',
1496
- description: 'label for the more styles `subscript` option',
1497
- defaultMessage: 'Subscript'
1532
+ id: "UIKit.RichTextBody.moreStylesDropdownOptionSubscript",
1533
+ defaultMessage: [{
1534
+ "type": 0,
1535
+ "value": "Subscript"
1536
+ }]
1498
1537
  },
1499
1538
  orderedListButtonLabel: {
1500
- id: 'UIKit.RichTextBody.orderedListButtonLabel',
1501
- description: 'Label for the numbered list button',
1502
- defaultMessage: 'Numbered list'
1539
+ id: "UIKit.RichTextBody.orderedListButtonLabel",
1540
+ defaultMessage: [{
1541
+ "type": 0,
1542
+ "value": "Numbered list"
1543
+ }]
1503
1544
  },
1504
1545
  redoButtonLabel: {
1505
- id: 'UIKit.RichTextBody.redoButtonLabel',
1506
- description: 'Label for the redo button',
1507
- defaultMessage: 'Redo'
1546
+ id: "UIKit.RichTextBody.redoButtonLabel",
1547
+ defaultMessage: [{
1548
+ "type": 0,
1549
+ "value": "Redo"
1550
+ }]
1508
1551
  },
1509
1552
  styleDropdownLabel: {
1510
- id: 'UIKit.RichTextBody.styleDropdownLabel',
1511
- description: 'Label for the style dropdown',
1512
- defaultMessage: 'Text styles'
1553
+ id: "UIKit.RichTextBody.styleDropdownLabel",
1554
+ defaultMessage: [{
1555
+ "type": 0,
1556
+ "value": "Text styles"
1557
+ }]
1513
1558
  },
1514
1559
  styleDropdownOptionParagraph: {
1515
- id: 'UIKit.RichTextBody.styleDropdownOptionParagraph',
1516
- description: 'Label for the `paragraph` option',
1517
- defaultMessage: 'Paragraph'
1560
+ id: "UIKit.RichTextBody.styleDropdownOptionParagraph",
1561
+ defaultMessage: [{
1562
+ "type": 0,
1563
+ "value": "Paragraph"
1564
+ }]
1518
1565
  },
1519
1566
  styleDropdownOptionH1: {
1520
- id: 'UIKit.RichTextBody.styleDropdownOptionH1',
1521
- description: 'Label for the `headline-one` option',
1522
- defaultMessage: 'Headline H1'
1567
+ id: "UIKit.RichTextBody.styleDropdownOptionH1",
1568
+ defaultMessage: [{
1569
+ "type": 0,
1570
+ "value": "Headline H1"
1571
+ }]
1523
1572
  },
1524
1573
  styleDropdownOptionH2: {
1525
- id: 'UIKit.RichTextBody.styleDropdownOptionH2',
1526
- description: 'Label for the `headline-two` option',
1527
- defaultMessage: 'Headline H2'
1574
+ id: "UIKit.RichTextBody.styleDropdownOptionH2",
1575
+ defaultMessage: [{
1576
+ "type": 0,
1577
+ "value": "Headline H2"
1578
+ }]
1528
1579
  },
1529
1580
  styleDropdownOptionH3: {
1530
- id: 'UIKit.RichTextBody.styleDropdownOptionH3',
1531
- description: 'Label for the `headline-three` option',
1532
- defaultMessage: 'Headline H3'
1581
+ id: "UIKit.RichTextBody.styleDropdownOptionH3",
1582
+ defaultMessage: [{
1583
+ "type": 0,
1584
+ "value": "Headline H3"
1585
+ }]
1533
1586
  },
1534
1587
  styleDropdownOptionH4: {
1535
- id: 'UIKit.RichTextBody.styleDropdownOptionH4',
1536
- description: 'Label for the `headline-four` option',
1537
- defaultMessage: 'Headline H4'
1588
+ id: "UIKit.RichTextBody.styleDropdownOptionH4",
1589
+ defaultMessage: [{
1590
+ "type": 0,
1591
+ "value": "Headline H4"
1592
+ }]
1538
1593
  },
1539
1594
  styleDropdownOptionH5: {
1540
- id: 'UIKit.RichTextBody.styleDropdownOptionH5',
1541
- description: 'Label for the `headline-five` option',
1542
- defaultMessage: 'Headline H5'
1595
+ id: "UIKit.RichTextBody.styleDropdownOptionH5",
1596
+ defaultMessage: [{
1597
+ "type": 0,
1598
+ "value": "Headline H5"
1599
+ }]
1543
1600
  },
1544
1601
  styleDropdownOptionQuote: {
1545
- id: 'UIKit.RichTextBody.styleDropdownOptionQuote',
1546
- description: 'Label for the `quote` option',
1547
- defaultMessage: 'Quote'
1602
+ id: "UIKit.RichTextBody.styleDropdownOptionQuote",
1603
+ defaultMessage: [{
1604
+ "type": 0,
1605
+ "value": "Quote"
1606
+ }]
1548
1607
  },
1549
1608
  styleDropdownOptionPreformatted: {
1550
- id: 'UIKit.RichTextBody.styleDropdownOptionPreformatted',
1551
- description: 'Label for the `code` option',
1552
- defaultMessage: 'Preformatted'
1609
+ id: "UIKit.RichTextBody.styleDropdownOptionPreformatted",
1610
+ defaultMessage: [{
1611
+ "type": 0,
1612
+ "value": "Preformatted"
1613
+ }]
1553
1614
  },
1554
1615
  underlinedButtonLabel: {
1555
- id: 'UIKit.RichTextBody.underlinedButtonLabel',
1556
- description: 'Label for the underline button',
1557
- defaultMessage: 'Underline'
1616
+ id: "UIKit.RichTextBody.underlinedButtonLabel",
1617
+ defaultMessage: [{
1618
+ "type": 0,
1619
+ "value": "Underline"
1620
+ }]
1558
1621
  },
1559
1622
  undoButtonLabel: {
1560
- id: 'UIKit.RichTextBody.undoButtonLabel',
1561
- description: 'Label for the undo button',
1562
- defaultMessage: 'Undo'
1623
+ id: "UIKit.RichTextBody.undoButtonLabel",
1624
+ defaultMessage: [{
1625
+ "type": 0,
1626
+ "value": "Undo"
1627
+ }]
1563
1628
  },
1564
1629
  unorderedListButtonLabel: {
1565
- id: 'UIKit.RichTextBody.unorderedListButtonLabel',
1566
- description: 'Label for the bullet list button',
1567
- defaultMessage: 'Bullet list'
1630
+ id: "UIKit.RichTextBody.unorderedListButtonLabel",
1631
+ defaultMessage: [{
1632
+ "type": 0,
1633
+ "value": "Bullet list"
1634
+ }]
1568
1635
  }
1569
1636
  });
1570
1637
 
@@ -1930,7 +1997,7 @@ RichTextEditorBody.displayName = 'RichTextEditorBody';
1930
1997
  var RichTextEditorBody$1 = RichTextEditorBody;
1931
1998
 
1932
1999
  // NOTE: This string will be replaced on build time with the package version.
1933
- var version = "20.3.0";
2000
+ var version = "20.4.0";
1934
2001
 
1935
2002
  exports.Element = Element;
1936
2003
  exports.HiddenInput = HiddenInput$1;
@@ -26,6 +26,7 @@ var _Object$getOwnPropertyDescriptors = require('@babel/runtime-corejs3/core-js-
26
26
  var _Object$defineProperties = require('@babel/runtime-corejs3/core-js-stable/object/define-properties');
27
27
  var _Object$defineProperty = require('@babel/runtime-corejs3/core-js-stable/object/define-property');
28
28
  var escapeHtml = require('escape-html');
29
+ var DOMPurify = require('dompurify');
29
30
  var slate = require('slate');
30
31
  var slateHyperscript = require('slate-hyperscript');
31
32
  var parse = require('style-to-object');
@@ -72,6 +73,7 @@ var _Object$getOwnPropertyDescriptors__default = /*#__PURE__*/_interopDefault(_O
72
73
  var _Object$defineProperties__default = /*#__PURE__*/_interopDefault(_Object$defineProperties);
73
74
  var _Object$defineProperty__default = /*#__PURE__*/_interopDefault(_Object$defineProperty);
74
75
  var escapeHtml__default = /*#__PURE__*/_interopDefault(escapeHtml);
76
+ var DOMPurify__default = /*#__PURE__*/_interopDefault(DOMPurify);
75
77
  var parse__default = /*#__PURE__*/_interopDefault(parse);
76
78
  var isEmpty__default = /*#__PURE__*/_interopDefault(isEmpty$2);
77
79
  var _includesInstanceProperty__default = /*#__PURE__*/_interopDefault(_includesInstanceProperty);
@@ -449,10 +451,33 @@ function _objectSpread$f(e) { for (var r = 1; r < arguments.length; r++) { var _
449
451
  // more: https://docs.slatejs.org/concepts/12-typescript
450
452
  // example: https://github.com/ianstormtaylor/slate/blob/main/packages/slate-react/src/custom-types.ts
451
453
 
454
+ /**
455
+ * Escapes HTML but preserves anchor tags with sanitized attributes.
456
+ * This allows <a> tags to remain as clickable links while preventing XSS from other tags.
457
+ * Uses DOMPurify for robust sanitization against XSS attacks.
458
+ */
459
+ const escapeHtmlExceptAnchors = text => {
460
+ // Use DOMPurify to sanitize the text, allowing only anchor tags
461
+ // This is much more secure than regex-based parsing
462
+ const sanitized = DOMPurify__default["default"].sanitize(text, {
463
+ ALLOWED_TAGS: ['a'],
464
+ ALLOWED_ATTR: ['href', 'title', 'target', 'rel'],
465
+ // Block dangerous URL schemes
466
+ ALLOWED_URI_REGEXP: /^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i,
467
+ // Prevent DOM clobbering
468
+ SANITIZE_DOM: true,
469
+ // Keep relative URLs
470
+ ALLOW_DATA_ATTR: false,
471
+ // Return a string, not a DOM node
472
+ RETURN_DOM: false,
473
+ RETURN_DOM_FRAGMENT: false
474
+ });
475
+ return sanitized;
476
+ };
452
477
  const serializeNode = node => {
453
478
  var _context, _context5, _context6;
454
479
  if (slate.Text.isText(node)) {
455
- let string = escapeHtml__default["default"](node.text);
480
+ let string = escapeHtmlExceptAnchors(node.text);
456
481
  if (node.bold) {
457
482
  string = "<strong>".concat(string, "</strong>");
458
483
  }
@@ -1417,109 +1442,151 @@ var Dropdown$1 = Dropdown;
1417
1442
 
1418
1443
  var messages = reactIntl.defineMessages({
1419
1444
  boldButtonLabel: {
1420
- id: 'UIKit.RichTextBody.boldButtonLabel',
1421
- description: 'Label for the bold button',
1422
- defaultMessage: 'Bold'
1445
+ id: "UIKit.RichTextBody.boldButtonLabel",
1446
+ defaultMessage: [{
1447
+ "type": 0,
1448
+ "value": "Bold"
1449
+ }]
1423
1450
  },
1424
1451
  expandButtonLabel: {
1425
- id: 'UIKit.RichTextBody.expandButtonLabel',
1426
- description: 'Label for the expand button',
1427
- defaultMessage: 'Expand'
1452
+ id: "UIKit.RichTextBody.expandButtonLabel",
1453
+ defaultMessage: [{
1454
+ "type": 0,
1455
+ "value": "Expand"
1456
+ }]
1428
1457
  },
1429
1458
  italicButtonLabel: {
1430
- id: 'UIKit.RichTextBody.italicButtonLabel',
1431
- description: 'Label for the italic button',
1432
- defaultMessage: 'Italic'
1459
+ id: "UIKit.RichTextBody.italicButtonLabel",
1460
+ defaultMessage: [{
1461
+ "type": 0,
1462
+ "value": "Italic"
1463
+ }]
1433
1464
  },
1434
1465
  moreStylesDropdownLabel: {
1435
- id: 'UIKit.RichTextBody.moreStylesDropdownLabel',
1436
- description: 'Label for the more styles dropdown',
1437
- defaultMessage: 'More styles'
1466
+ id: "UIKit.RichTextBody.moreStylesDropdownLabel",
1467
+ defaultMessage: [{
1468
+ "type": 0,
1469
+ "value": "More styles"
1470
+ }]
1438
1471
  },
1439
1472
  moreStylesDropdownOptionStrikethrough: {
1440
- id: 'UIKit.RichTextBody.moreStylesDropdownOptionStrikethrough',
1441
- description: 'label for the more styles `strikethrough` option',
1442
- defaultMessage: 'Strikethrough'
1473
+ id: "UIKit.RichTextBody.moreStylesDropdownOptionStrikethrough",
1474
+ defaultMessage: [{
1475
+ "type": 0,
1476
+ "value": "Strikethrough"
1477
+ }]
1443
1478
  },
1444
1479
  moreStylesDropdownOptionSuperscript: {
1445
- id: 'UIKit.RichTextBody.moreStylesDropdownOptionSuperscript',
1446
- description: 'label for the more styles `superscript` option',
1447
- defaultMessage: 'Superscript'
1480
+ id: "UIKit.RichTextBody.moreStylesDropdownOptionSuperscript",
1481
+ defaultMessage: [{
1482
+ "type": 0,
1483
+ "value": "Superscript"
1484
+ }]
1448
1485
  },
1449
1486
  moreStylesDropdownOptionSubscript: {
1450
- id: 'UIKit.RichTextBody.moreStylesDropdownOptionSubscript',
1451
- description: 'label for the more styles `subscript` option',
1452
- defaultMessage: 'Subscript'
1487
+ id: "UIKit.RichTextBody.moreStylesDropdownOptionSubscript",
1488
+ defaultMessage: [{
1489
+ "type": 0,
1490
+ "value": "Subscript"
1491
+ }]
1453
1492
  },
1454
1493
  orderedListButtonLabel: {
1455
- id: 'UIKit.RichTextBody.orderedListButtonLabel',
1456
- description: 'Label for the numbered list button',
1457
- defaultMessage: 'Numbered list'
1494
+ id: "UIKit.RichTextBody.orderedListButtonLabel",
1495
+ defaultMessage: [{
1496
+ "type": 0,
1497
+ "value": "Numbered list"
1498
+ }]
1458
1499
  },
1459
1500
  redoButtonLabel: {
1460
- id: 'UIKit.RichTextBody.redoButtonLabel',
1461
- description: 'Label for the redo button',
1462
- defaultMessage: 'Redo'
1501
+ id: "UIKit.RichTextBody.redoButtonLabel",
1502
+ defaultMessage: [{
1503
+ "type": 0,
1504
+ "value": "Redo"
1505
+ }]
1463
1506
  },
1464
1507
  styleDropdownLabel: {
1465
- id: 'UIKit.RichTextBody.styleDropdownLabel',
1466
- description: 'Label for the style dropdown',
1467
- defaultMessage: 'Text styles'
1508
+ id: "UIKit.RichTextBody.styleDropdownLabel",
1509
+ defaultMessage: [{
1510
+ "type": 0,
1511
+ "value": "Text styles"
1512
+ }]
1468
1513
  },
1469
1514
  styleDropdownOptionParagraph: {
1470
- id: 'UIKit.RichTextBody.styleDropdownOptionParagraph',
1471
- description: 'Label for the `paragraph` option',
1472
- defaultMessage: 'Paragraph'
1515
+ id: "UIKit.RichTextBody.styleDropdownOptionParagraph",
1516
+ defaultMessage: [{
1517
+ "type": 0,
1518
+ "value": "Paragraph"
1519
+ }]
1473
1520
  },
1474
1521
  styleDropdownOptionH1: {
1475
- id: 'UIKit.RichTextBody.styleDropdownOptionH1',
1476
- description: 'Label for the `headline-one` option',
1477
- defaultMessage: 'Headline H1'
1522
+ id: "UIKit.RichTextBody.styleDropdownOptionH1",
1523
+ defaultMessage: [{
1524
+ "type": 0,
1525
+ "value": "Headline H1"
1526
+ }]
1478
1527
  },
1479
1528
  styleDropdownOptionH2: {
1480
- id: 'UIKit.RichTextBody.styleDropdownOptionH2',
1481
- description: 'Label for the `headline-two` option',
1482
- defaultMessage: 'Headline H2'
1529
+ id: "UIKit.RichTextBody.styleDropdownOptionH2",
1530
+ defaultMessage: [{
1531
+ "type": 0,
1532
+ "value": "Headline H2"
1533
+ }]
1483
1534
  },
1484
1535
  styleDropdownOptionH3: {
1485
- id: 'UIKit.RichTextBody.styleDropdownOptionH3',
1486
- description: 'Label for the `headline-three` option',
1487
- defaultMessage: 'Headline H3'
1536
+ id: "UIKit.RichTextBody.styleDropdownOptionH3",
1537
+ defaultMessage: [{
1538
+ "type": 0,
1539
+ "value": "Headline H3"
1540
+ }]
1488
1541
  },
1489
1542
  styleDropdownOptionH4: {
1490
- id: 'UIKit.RichTextBody.styleDropdownOptionH4',
1491
- description: 'Label for the `headline-four` option',
1492
- defaultMessage: 'Headline H4'
1543
+ id: "UIKit.RichTextBody.styleDropdownOptionH4",
1544
+ defaultMessage: [{
1545
+ "type": 0,
1546
+ "value": "Headline H4"
1547
+ }]
1493
1548
  },
1494
1549
  styleDropdownOptionH5: {
1495
- id: 'UIKit.RichTextBody.styleDropdownOptionH5',
1496
- description: 'Label for the `headline-five` option',
1497
- defaultMessage: 'Headline H5'
1550
+ id: "UIKit.RichTextBody.styleDropdownOptionH5",
1551
+ defaultMessage: [{
1552
+ "type": 0,
1553
+ "value": "Headline H5"
1554
+ }]
1498
1555
  },
1499
1556
  styleDropdownOptionQuote: {
1500
- id: 'UIKit.RichTextBody.styleDropdownOptionQuote',
1501
- description: 'Label for the `quote` option',
1502
- defaultMessage: 'Quote'
1557
+ id: "UIKit.RichTextBody.styleDropdownOptionQuote",
1558
+ defaultMessage: [{
1559
+ "type": 0,
1560
+ "value": "Quote"
1561
+ }]
1503
1562
  },
1504
1563
  styleDropdownOptionPreformatted: {
1505
- id: 'UIKit.RichTextBody.styleDropdownOptionPreformatted',
1506
- description: 'Label for the `code` option',
1507
- defaultMessage: 'Preformatted'
1564
+ id: "UIKit.RichTextBody.styleDropdownOptionPreformatted",
1565
+ defaultMessage: [{
1566
+ "type": 0,
1567
+ "value": "Preformatted"
1568
+ }]
1508
1569
  },
1509
1570
  underlinedButtonLabel: {
1510
- id: 'UIKit.RichTextBody.underlinedButtonLabel',
1511
- description: 'Label for the underline button',
1512
- defaultMessage: 'Underline'
1571
+ id: "UIKit.RichTextBody.underlinedButtonLabel",
1572
+ defaultMessage: [{
1573
+ "type": 0,
1574
+ "value": "Underline"
1575
+ }]
1513
1576
  },
1514
1577
  undoButtonLabel: {
1515
- id: 'UIKit.RichTextBody.undoButtonLabel',
1516
- description: 'Label for the undo button',
1517
- defaultMessage: 'Undo'
1578
+ id: "UIKit.RichTextBody.undoButtonLabel",
1579
+ defaultMessage: [{
1580
+ "type": 0,
1581
+ "value": "Undo"
1582
+ }]
1518
1583
  },
1519
1584
  unorderedListButtonLabel: {
1520
- id: 'UIKit.RichTextBody.unorderedListButtonLabel',
1521
- description: 'Label for the bullet list button',
1522
- defaultMessage: 'Bullet list'
1585
+ id: "UIKit.RichTextBody.unorderedListButtonLabel",
1586
+ defaultMessage: [{
1587
+ "type": 0,
1588
+ "value": "Bullet list"
1589
+ }]
1523
1590
  }
1524
1591
  });
1525
1592
 
@@ -1871,7 +1938,7 @@ RichTextEditorBody.displayName = 'RichTextEditorBody';
1871
1938
  var RichTextEditorBody$1 = RichTextEditorBody;
1872
1939
 
1873
1940
  // NOTE: This string will be replaced on build time with the package version.
1874
- var version = "20.3.0";
1941
+ var version = "20.4.0";
1875
1942
 
1876
1943
  exports.Element = Element;
1877
1944
  exports.HiddenInput = HiddenInput$1;
@@ -22,6 +22,7 @@ import _Object$getOwnPropertyDescriptors from '@babel/runtime-corejs3/core-js-st
22
22
  import _Object$defineProperties from '@babel/runtime-corejs3/core-js-stable/object/define-properties';
23
23
  import _Object$defineProperty from '@babel/runtime-corejs3/core-js-stable/object/define-property';
24
24
  import escapeHtml from 'escape-html';
25
+ import DOMPurify from 'dompurify';
25
26
  import { Editor, Element as Element$1, Transforms, Text, Range } from 'slate';
26
27
  import { jsx as jsx$1 } from 'slate-hyperscript';
27
28
  import parse from 'style-to-object';
@@ -410,10 +411,33 @@ function _objectSpread$f(e) { for (var r = 1; r < arguments.length; r++) { var _
410
411
  // more: https://docs.slatejs.org/concepts/12-typescript
411
412
  // example: https://github.com/ianstormtaylor/slate/blob/main/packages/slate-react/src/custom-types.ts
412
413
 
414
+ /**
415
+ * Escapes HTML but preserves anchor tags with sanitized attributes.
416
+ * This allows <a> tags to remain as clickable links while preventing XSS from other tags.
417
+ * Uses DOMPurify for robust sanitization against XSS attacks.
418
+ */
419
+ const escapeHtmlExceptAnchors = text => {
420
+ // Use DOMPurify to sanitize the text, allowing only anchor tags
421
+ // This is much more secure than regex-based parsing
422
+ const sanitized = DOMPurify.sanitize(text, {
423
+ ALLOWED_TAGS: ['a'],
424
+ ALLOWED_ATTR: ['href', 'title', 'target', 'rel'],
425
+ // Block dangerous URL schemes
426
+ ALLOWED_URI_REGEXP: /^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i,
427
+ // Prevent DOM clobbering
428
+ SANITIZE_DOM: true,
429
+ // Keep relative URLs
430
+ ALLOW_DATA_ATTR: false,
431
+ // Return a string, not a DOM node
432
+ RETURN_DOM: false,
433
+ RETURN_DOM_FRAGMENT: false
434
+ });
435
+ return sanitized;
436
+ };
413
437
  const serializeNode = node => {
414
438
  var _context, _context5, _context6;
415
439
  if (Text.isText(node)) {
416
- let string = escapeHtml(node.text);
440
+ let string = escapeHtmlExceptAnchors(node.text);
417
441
  if (node.bold) {
418
442
  string = "<strong>".concat(string, "</strong>");
419
443
  }
@@ -1423,109 +1447,151 @@ var Dropdown$1 = Dropdown;
1423
1447
 
1424
1448
  var messages = defineMessages({
1425
1449
  boldButtonLabel: {
1426
- id: 'UIKit.RichTextBody.boldButtonLabel',
1427
- description: 'Label for the bold button',
1428
- defaultMessage: 'Bold'
1450
+ id: "UIKit.RichTextBody.boldButtonLabel",
1451
+ defaultMessage: [{
1452
+ "type": 0,
1453
+ "value": "Bold"
1454
+ }]
1429
1455
  },
1430
1456
  expandButtonLabel: {
1431
- id: 'UIKit.RichTextBody.expandButtonLabel',
1432
- description: 'Label for the expand button',
1433
- defaultMessage: 'Expand'
1457
+ id: "UIKit.RichTextBody.expandButtonLabel",
1458
+ defaultMessage: [{
1459
+ "type": 0,
1460
+ "value": "Expand"
1461
+ }]
1434
1462
  },
1435
1463
  italicButtonLabel: {
1436
- id: 'UIKit.RichTextBody.italicButtonLabel',
1437
- description: 'Label for the italic button',
1438
- defaultMessage: 'Italic'
1464
+ id: "UIKit.RichTextBody.italicButtonLabel",
1465
+ defaultMessage: [{
1466
+ "type": 0,
1467
+ "value": "Italic"
1468
+ }]
1439
1469
  },
1440
1470
  moreStylesDropdownLabel: {
1441
- id: 'UIKit.RichTextBody.moreStylesDropdownLabel',
1442
- description: 'Label for the more styles dropdown',
1443
- defaultMessage: 'More styles'
1471
+ id: "UIKit.RichTextBody.moreStylesDropdownLabel",
1472
+ defaultMessage: [{
1473
+ "type": 0,
1474
+ "value": "More styles"
1475
+ }]
1444
1476
  },
1445
1477
  moreStylesDropdownOptionStrikethrough: {
1446
- id: 'UIKit.RichTextBody.moreStylesDropdownOptionStrikethrough',
1447
- description: 'label for the more styles `strikethrough` option',
1448
- defaultMessage: 'Strikethrough'
1478
+ id: "UIKit.RichTextBody.moreStylesDropdownOptionStrikethrough",
1479
+ defaultMessage: [{
1480
+ "type": 0,
1481
+ "value": "Strikethrough"
1482
+ }]
1449
1483
  },
1450
1484
  moreStylesDropdownOptionSuperscript: {
1451
- id: 'UIKit.RichTextBody.moreStylesDropdownOptionSuperscript',
1452
- description: 'label for the more styles `superscript` option',
1453
- defaultMessage: 'Superscript'
1485
+ id: "UIKit.RichTextBody.moreStylesDropdownOptionSuperscript",
1486
+ defaultMessage: [{
1487
+ "type": 0,
1488
+ "value": "Superscript"
1489
+ }]
1454
1490
  },
1455
1491
  moreStylesDropdownOptionSubscript: {
1456
- id: 'UIKit.RichTextBody.moreStylesDropdownOptionSubscript',
1457
- description: 'label for the more styles `subscript` option',
1458
- defaultMessage: 'Subscript'
1492
+ id: "UIKit.RichTextBody.moreStylesDropdownOptionSubscript",
1493
+ defaultMessage: [{
1494
+ "type": 0,
1495
+ "value": "Subscript"
1496
+ }]
1459
1497
  },
1460
1498
  orderedListButtonLabel: {
1461
- id: 'UIKit.RichTextBody.orderedListButtonLabel',
1462
- description: 'Label for the numbered list button',
1463
- defaultMessage: 'Numbered list'
1499
+ id: "UIKit.RichTextBody.orderedListButtonLabel",
1500
+ defaultMessage: [{
1501
+ "type": 0,
1502
+ "value": "Numbered list"
1503
+ }]
1464
1504
  },
1465
1505
  redoButtonLabel: {
1466
- id: 'UIKit.RichTextBody.redoButtonLabel',
1467
- description: 'Label for the redo button',
1468
- defaultMessage: 'Redo'
1506
+ id: "UIKit.RichTextBody.redoButtonLabel",
1507
+ defaultMessage: [{
1508
+ "type": 0,
1509
+ "value": "Redo"
1510
+ }]
1469
1511
  },
1470
1512
  styleDropdownLabel: {
1471
- id: 'UIKit.RichTextBody.styleDropdownLabel',
1472
- description: 'Label for the style dropdown',
1473
- defaultMessage: 'Text styles'
1513
+ id: "UIKit.RichTextBody.styleDropdownLabel",
1514
+ defaultMessage: [{
1515
+ "type": 0,
1516
+ "value": "Text styles"
1517
+ }]
1474
1518
  },
1475
1519
  styleDropdownOptionParagraph: {
1476
- id: 'UIKit.RichTextBody.styleDropdownOptionParagraph',
1477
- description: 'Label for the `paragraph` option',
1478
- defaultMessage: 'Paragraph'
1520
+ id: "UIKit.RichTextBody.styleDropdownOptionParagraph",
1521
+ defaultMessage: [{
1522
+ "type": 0,
1523
+ "value": "Paragraph"
1524
+ }]
1479
1525
  },
1480
1526
  styleDropdownOptionH1: {
1481
- id: 'UIKit.RichTextBody.styleDropdownOptionH1',
1482
- description: 'Label for the `headline-one` option',
1483
- defaultMessage: 'Headline H1'
1527
+ id: "UIKit.RichTextBody.styleDropdownOptionH1",
1528
+ defaultMessage: [{
1529
+ "type": 0,
1530
+ "value": "Headline H1"
1531
+ }]
1484
1532
  },
1485
1533
  styleDropdownOptionH2: {
1486
- id: 'UIKit.RichTextBody.styleDropdownOptionH2',
1487
- description: 'Label for the `headline-two` option',
1488
- defaultMessage: 'Headline H2'
1534
+ id: "UIKit.RichTextBody.styleDropdownOptionH2",
1535
+ defaultMessage: [{
1536
+ "type": 0,
1537
+ "value": "Headline H2"
1538
+ }]
1489
1539
  },
1490
1540
  styleDropdownOptionH3: {
1491
- id: 'UIKit.RichTextBody.styleDropdownOptionH3',
1492
- description: 'Label for the `headline-three` option',
1493
- defaultMessage: 'Headline H3'
1541
+ id: "UIKit.RichTextBody.styleDropdownOptionH3",
1542
+ defaultMessage: [{
1543
+ "type": 0,
1544
+ "value": "Headline H3"
1545
+ }]
1494
1546
  },
1495
1547
  styleDropdownOptionH4: {
1496
- id: 'UIKit.RichTextBody.styleDropdownOptionH4',
1497
- description: 'Label for the `headline-four` option',
1498
- defaultMessage: 'Headline H4'
1548
+ id: "UIKit.RichTextBody.styleDropdownOptionH4",
1549
+ defaultMessage: [{
1550
+ "type": 0,
1551
+ "value": "Headline H4"
1552
+ }]
1499
1553
  },
1500
1554
  styleDropdownOptionH5: {
1501
- id: 'UIKit.RichTextBody.styleDropdownOptionH5',
1502
- description: 'Label for the `headline-five` option',
1503
- defaultMessage: 'Headline H5'
1555
+ id: "UIKit.RichTextBody.styleDropdownOptionH5",
1556
+ defaultMessage: [{
1557
+ "type": 0,
1558
+ "value": "Headline H5"
1559
+ }]
1504
1560
  },
1505
1561
  styleDropdownOptionQuote: {
1506
- id: 'UIKit.RichTextBody.styleDropdownOptionQuote',
1507
- description: 'Label for the `quote` option',
1508
- defaultMessage: 'Quote'
1562
+ id: "UIKit.RichTextBody.styleDropdownOptionQuote",
1563
+ defaultMessage: [{
1564
+ "type": 0,
1565
+ "value": "Quote"
1566
+ }]
1509
1567
  },
1510
1568
  styleDropdownOptionPreformatted: {
1511
- id: 'UIKit.RichTextBody.styleDropdownOptionPreformatted',
1512
- description: 'Label for the `code` option',
1513
- defaultMessage: 'Preformatted'
1569
+ id: "UIKit.RichTextBody.styleDropdownOptionPreformatted",
1570
+ defaultMessage: [{
1571
+ "type": 0,
1572
+ "value": "Preformatted"
1573
+ }]
1514
1574
  },
1515
1575
  underlinedButtonLabel: {
1516
- id: 'UIKit.RichTextBody.underlinedButtonLabel',
1517
- description: 'Label for the underline button',
1518
- defaultMessage: 'Underline'
1576
+ id: "UIKit.RichTextBody.underlinedButtonLabel",
1577
+ defaultMessage: [{
1578
+ "type": 0,
1579
+ "value": "Underline"
1580
+ }]
1519
1581
  },
1520
1582
  undoButtonLabel: {
1521
- id: 'UIKit.RichTextBody.undoButtonLabel',
1522
- description: 'Label for the undo button',
1523
- defaultMessage: 'Undo'
1583
+ id: "UIKit.RichTextBody.undoButtonLabel",
1584
+ defaultMessage: [{
1585
+ "type": 0,
1586
+ "value": "Undo"
1587
+ }]
1524
1588
  },
1525
1589
  unorderedListButtonLabel: {
1526
- id: 'UIKit.RichTextBody.unorderedListButtonLabel',
1527
- description: 'Label for the bullet list button',
1528
- defaultMessage: 'Bullet list'
1590
+ id: "UIKit.RichTextBody.unorderedListButtonLabel",
1591
+ defaultMessage: [{
1592
+ "type": 0,
1593
+ "value": "Bullet list"
1594
+ }]
1529
1595
  }
1530
1596
  });
1531
1597
 
@@ -1891,6 +1957,6 @@ RichTextEditorBody.displayName = 'RichTextEditorBody';
1891
1957
  var RichTextEditorBody$1 = RichTextEditorBody;
1892
1958
 
1893
1959
  // NOTE: This string will be replaced on build time with the package version.
1894
- var version = "20.3.0";
1960
+ var version = "20.4.0";
1895
1961
 
1896
1962
  export { Element, HiddenInput$1 as HiddenInput, Leaf, RichTextEditorBody$1 as RichTextBody, Softbreaker, focusEditor, html$1 as html, isBlockActive, isRichTextEmpty as isEmpty, isMarkActive, index as localized, resetEditor, toggleBlock, toggleMark, validSlateStateAdapter, version, withLinks };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@commercetools-uikit/rich-text-utils",
3
3
  "description": "Utilities for working with rich-text components.",
4
- "version": "20.3.0",
4
+ "version": "20.4.0",
5
5
  "bugs": "https://github.com/commercetools/ui-kit/issues",
6
6
  "repository": {
7
7
  "type": "git",
@@ -24,20 +24,22 @@
24
24
  "dependencies": {
25
25
  "@babel/runtime": "^7.20.13",
26
26
  "@babel/runtime-corejs3": "^7.20.13",
27
- "@commercetools-uikit/design-system": "20.3.0",
28
- "@commercetools-uikit/icons": "20.3.0",
29
- "@commercetools-uikit/input-utils": "20.3.0",
30
- "@commercetools-uikit/spacings-inline": "20.3.0",
31
- "@commercetools-uikit/tooltip": "20.3.0",
32
- "@commercetools-uikit/utils": "20.3.0",
27
+ "@commercetools-uikit/design-system": "20.4.0",
28
+ "@commercetools-uikit/icons": "20.4.0",
29
+ "@commercetools-uikit/input-utils": "20.4.0",
30
+ "@commercetools-uikit/spacings-inline": "20.4.0",
31
+ "@commercetools-uikit/tooltip": "20.4.0",
32
+ "@commercetools-uikit/utils": "20.4.0",
33
33
  "@emotion/react": "^11.10.5",
34
34
  "@emotion/styled": "^11.10.5",
35
+ "@types/dompurify": "^2.4.0",
35
36
  "@types/escape-html": "1.0.4",
37
+ "dompurify": "3.2.7",
36
38
  "downshift": "9.0.10",
37
39
  "escape-html": "1.0.3",
38
40
  "is-hotkey": "0.2.0",
39
41
  "is-url": "^1.2.4",
40
- "lodash": "4.17.21",
42
+ "lodash": "4.17.23",
41
43
  "slate": "0.75.0",
42
44
  "slate-history": "0.113.1",
43
45
  "slate-hyperscript": "0.100.0",