add-to-calendar-button 2.7.0 → 2.7.1

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.
@@ -5,7 +5,7 @@
5
5
  *
6
6
  * Style: 3D
7
7
  *
8
- * Version: 2.7.0
8
+ * Version: 2.7.1
9
9
  * Creator: Jens Kuerschner (https://jekuer.com)
10
10
  * Project: https://github.com/add2cal/add-to-calendar-button
11
11
  * License: Elastic License 2.0 (ELv2) (https://github.com/add2cal/add-to-calendar-button/blob/main/LICENSE.txt)
@@ -5,7 +5,7 @@
5
5
  *
6
6
  * Style: Date
7
7
  *
8
- * Version: 2.7.0
8
+ * Version: 2.7.1
9
9
  * Creator: Jens Kuerschner (https://jekuer.com)
10
10
  * Project: https://github.com/add2cal/add-to-calendar-button
11
11
  * License: Elastic License 2.0 (ELv2) (https://github.com/add2cal/add-to-calendar-button/blob/main/LICENSE.txt)
@@ -5,7 +5,7 @@
5
5
  *
6
6
  * Style: Flat
7
7
  *
8
- * Version: 2.7.0
8
+ * Version: 2.7.1
9
9
  * Creator: Jens Kuerschner (https://jekuer.com)
10
10
  * Project: https://github.com/add2cal/add-to-calendar-button
11
11
  * License: Elastic License 2.0 (ELv2) (https://github.com/add2cal/add-to-calendar-button/blob/main/LICENSE.txt)
@@ -5,7 +5,7 @@
5
5
  *
6
6
  * Style: Neumorphism
7
7
  *
8
- * Version: 2.7.0
8
+ * Version: 2.7.1
9
9
  * Creator: Jens Kuerschner (https://jekuer.com)
10
10
  * Project: https://github.com/add2cal/add-to-calendar-button
11
11
  * License: Elastic License 2.0 (ELv2) (https://github.com/add2cal/add-to-calendar-button/blob/main/LICENSE.txt)
@@ -5,7 +5,7 @@
5
5
  *
6
6
  * Style: Round
7
7
  *
8
- * Version: 2.7.0
8
+ * Version: 2.7.1
9
9
  * Creator: Jens Kuerschner (https://jekuer.com)
10
10
  * Project: https://github.com/add2cal/add-to-calendar-button
11
11
  * License: Elastic License 2.0 (ELv2) (https://github.com/add2cal/add-to-calendar-button/blob/main/LICENSE.txt)
@@ -5,7 +5,7 @@
5
5
  *
6
6
  * Style: Text
7
7
  *
8
- * Version: 2.7.0
8
+ * Version: 2.7.1
9
9
  * Creator: Jens Kuerschner (https://jekuer.com)
10
10
  * Project: https://github.com/add2cal/add-to-calendar-button
11
11
  * License: Elastic License 2.0 (ELv2) (https://github.com/add2cal/add-to-calendar-button/blob/main/LICENSE.txt)
@@ -5,7 +5,7 @@
5
5
  *
6
6
  * Style: Default
7
7
  *
8
- * Version: 2.7.0
8
+ * Version: 2.7.1
9
9
  * Creator: Jens Kuerschner (https://jekuer.com)
10
10
  * Project: https://github.com/add2cal/add-to-calendar-button
11
11
  * License: Elastic License 2.0 (ELv2) (https://github.com/add2cal/add-to-calendar-button/blob/main/LICENSE.txt)
@@ -974,14 +974,14 @@ function tzlib_get_timezones(jsonType = false) {
974
974
  * Add to Calendar Button
975
975
  * ++++++++++++++++++++++
976
976
  *
977
- * Version: 2.7.0
977
+ * Version: 2.7.1
978
978
  * Creator: Jens Kuerschner (https://jekuer.com)
979
979
  * Project: https://github.com/add2cal/add-to-calendar-button
980
980
  * License: Elastic License 2.0 (ELv2) (https://github.com/add2cal/add-to-calendar-button/blob/main/LICENSE.txt)
981
981
  * Note: DO NOT REMOVE THE COPYRIGHT NOTICE ABOVE!
982
982
  *
983
983
  */
984
- const atcbVersion = '2.7.0';
984
+ const atcbVersion = '2.7.1';
985
985
  const atcbCssTemplate = {};
986
986
  const atcbIsBrowser = () => {
987
987
  if (typeof window === 'undefined') {
@@ -1516,8 +1516,9 @@ function atcb_decorate_data_description(data, i) {
1516
1516
  description = cleanDescription(description);
1517
1517
  if (data.customVar) {
1518
1518
  for (const key in data.customVar) {
1519
- const sanitizedKey = key.replace(/[^\w\-.]/g, '');
1520
- description = description.replace(new RegExp(`%%${sanitizedKey}%%`, 'g'), data.customVar[`${key}`]);
1519
+ const sanitizedKey = '%%' + key.replace(/[^\w\-.]/g, '') + '%%';
1520
+ // eslint-disable-next-line security/detect-non-literal-regexp
1521
+ description = description.replace(new RegExp(sanitizedKey, 'gi'), data.customVar[`${key}`]);
1521
1522
  }
1522
1523
  }
1523
1524
  const descriptionHtmlFree = atcb_rewrite_html_elements(description, true);
@@ -1575,9 +1576,11 @@ function atcb_decorate_data_extend(data) {
1575
1576
  }
1576
1577
  if (data.customVar) {
1577
1578
  for (const key in data.customVar) {
1578
- const sanitizedKey = key.replace(/[^\w\-.]/g, '');
1579
- data.dates[`${i}`].name = data.dates[`${i}`].name.replace(new RegExp(`%%${sanitizedKey}%%`, 'g'), data.customVar[`${key}`]);
1580
- data.dates[`${i}`].location = data.dates[`${i}`].location.replace(new RegExp(`%%${sanitizedKey}%%`, 'g'), data.customVar[`${key}`]);
1579
+ const sanitizedKey = '%%' + key.replace(/[^\w\-.]/g, '') + '%%';
1580
+ // eslint-disable-next-line security/detect-non-literal-regexp
1581
+ data.dates[`${i}`].name = data.dates[`${i}`].name.replace(new RegExp(sanitizedKey, 'gi'), data.customVar[`${key}`]);
1582
+ // eslint-disable-next-line security/detect-non-literal-regexp
1583
+ data.dates[`${i}`].location = data.dates[`${i}`].location.replace(new RegExp(sanitizedKey, 'gi'), data.customVar[`${key}`]);
1581
1584
  }
1582
1585
  }
1583
1586
  }
@@ -1590,26 +1593,31 @@ function atcb_decorate_data_extend(data) {
1590
1593
  return data;
1591
1594
  }
1592
1595
  function atcb_date_cleanup(dateTimeData) {
1596
+ function isValidDateFormat(dateStr) {
1597
+ return /^\d\d\d\d-\d\d-\d\d(?:T\d\d:\d\d)?(?::\d\d)?(?:.\d\d\d)?Z?$/i.test(dateStr);
1598
+ }
1599
+ function isValidTodayFormat(dateStr) {
1600
+ return /^today(?:\+(?:\d|\d\d|\d\d\d|\d\d\d\d))?$/i.test(dateStr);
1601
+ }
1593
1602
  if (!dateTimeData.endDate || dateTimeData.endDate === '') {
1594
1603
  dateTimeData.endDate = dateTimeData.startDate;
1595
1604
  }
1596
1605
  const endpoints = ['start', 'end'];
1597
1606
  endpoints.forEach(function (point) {
1598
- if (!/^(?:\d{4}-\d{2}-\d{2}T?(?:\d{2}:\d{2})?Z?|today(?:\+\d{1,4})?)$/i.test(dateTimeData[point + 'Date'])) {
1607
+ const dateStr = dateTimeData[point + 'Date'];
1608
+ if (!isValidDateFormat(dateStr) && !isValidTodayFormat(dateStr)) {
1599
1609
  dateTimeData[point + 'Date'] = 'badly-formed';
1600
1610
  } else {
1601
- dateTimeData[point + 'Date'] = atcb_date_calculation(dateTimeData[point + 'Date']);
1611
+ if (isValidTodayFormat(dateStr)) dateTimeData[point + 'Date'] = atcb_date_calculation(dateStr);
1602
1612
  if (dateTimeData[point + 'Date']) {
1603
- dateTimeData[point + 'Date'] = dateTimeData[point + 'Date'].replace(/\.\d{3}/, '').replace('Z', '');
1604
1613
  const tmpSplitStartDate = dateTimeData[point + 'Date'].split('T');
1605
1614
  if (tmpSplitStartDate[1]) {
1606
1615
  dateTimeData[point + 'Date'] = tmpSplitStartDate[0];
1607
1616
  dateTimeData[point + 'Time'] = tmpSplitStartDate[1];
1608
1617
  }
1609
1618
  }
1610
- if (dateTimeData[point + 'Time'] && dateTimeData[point + 'Time'].length === 8) {
1611
- const timeStr = dateTimeData[point + 'Time'];
1612
- dateTimeData[point + 'Time'] = timeStr.substring(0, timeStr.length - 3);
1619
+ if (dateTimeData[point + 'Time'] && dateTimeData[point + 'Time'].length > 5) {
1620
+ dateTimeData[point + 'Time'] = dateTimeData[point + 'Time'].substring(0, 5);
1613
1621
  }
1614
1622
  }
1615
1623
  });
@@ -1654,12 +1662,7 @@ function atcb_date_calculation(dateString) {
1654
1662
  dateString = dateString.replace(/today/gi, todayString);
1655
1663
  const dateStringParts = dateString.split('+');
1656
1664
  const dateParts = dateStringParts[0].split('-');
1657
- let newDate = (function () {
1658
- if (dateParts[0].length < 4) {
1659
- return new Date(Date.UTC(dateParts[2], dateParts[0] - 1, dateParts[1]));
1660
- }
1661
- return new Date(Date.UTC(dateParts[0], dateParts[1] - 1, dateParts[2]));
1662
- })();
1665
+ const newDate = new Date(Date.UTC(dateParts[0], dateParts[1] - 1, dateParts[2].substring(0, 2)));
1663
1666
  if (dateStringParts[1] && dateStringParts[1] > 0) {
1664
1667
  newDate.setDate(newDate.getDate() + parseInt(dateStringParts[1]));
1665
1668
  }
@@ -974,14 +974,14 @@ function tzlib_get_timezones(jsonType = false) {
974
974
  * Add to Calendar Button
975
975
  * ++++++++++++++++++++++
976
976
  *
977
- * Version: 2.7.0
977
+ * Version: 2.7.1
978
978
  * Creator: Jens Kuerschner (https://jekuer.com)
979
979
  * Project: https://github.com/add2cal/add-to-calendar-button
980
980
  * License: Elastic License 2.0 (ELv2) (https://github.com/add2cal/add-to-calendar-button/blob/main/LICENSE.txt)
981
981
  * Note: DO NOT REMOVE THE COPYRIGHT NOTICE ABOVE!
982
982
  *
983
983
  */
984
- const atcbVersion = '2.7.0';
984
+ const atcbVersion = '2.7.1';
985
985
  const atcbCssTemplate = {
986
986
  if (typeof window === 'undefined') {
987
987
  return false;
@@ -1515,8 +1515,9 @@ function atcb_decorate_data_description(data, i) {
1515
1515
  description = cleanDescription(description);
1516
1516
  if (data.customVar) {
1517
1517
  for (const key in data.customVar) {
1518
- const sanitizedKey = key.replace(/[^\w\-.]/g, '');
1519
- description = description.replace(new RegExp(`%%${sanitizedKey}%%`, 'g'), data.customVar[`${key}`]);
1518
+ const sanitizedKey = '%%' + key.replace(/[^\w\-.]/g, '') + '%%';
1519
+ // eslint-disable-next-line security/detect-non-literal-regexp
1520
+ description = description.replace(new RegExp(sanitizedKey, 'gi'), data.customVar[`${key}`]);
1520
1521
  }
1521
1522
  }
1522
1523
  const descriptionHtmlFree = atcb_rewrite_html_elements(description, true);
@@ -1574,9 +1575,11 @@ function atcb_decorate_data_extend(data) {
1574
1575
  }
1575
1576
  if (data.customVar) {
1576
1577
  for (const key in data.customVar) {
1577
- const sanitizedKey = key.replace(/[^\w\-.]/g, '');
1578
- data.dates[`${i}`].name = data.dates[`${i}`].name.replace(new RegExp(`%%${sanitizedKey}%%`, 'g'), data.customVar[`${key}`]);
1579
- data.dates[`${i}`].location = data.dates[`${i}`].location.replace(new RegExp(`%%${sanitizedKey}%%`, 'g'), data.customVar[`${key}`]);
1578
+ const sanitizedKey = '%%' + key.replace(/[^\w\-.]/g, '') + '%%';
1579
+ // eslint-disable-next-line security/detect-non-literal-regexp
1580
+ data.dates[`${i}`].name = data.dates[`${i}`].name.replace(new RegExp(sanitizedKey, 'gi'), data.customVar[`${key}`]);
1581
+ // eslint-disable-next-line security/detect-non-literal-regexp
1582
+ data.dates[`${i}`].location = data.dates[`${i}`].location.replace(new RegExp(sanitizedKey, 'gi'), data.customVar[`${key}`]);
1580
1583
  }
1581
1584
  }
1582
1585
  }
@@ -1589,26 +1592,31 @@ function atcb_decorate_data_extend(data) {
1589
1592
  return data;
1590
1593
  }
1591
1594
  function atcb_date_cleanup(dateTimeData) {
1595
+ function isValidDateFormat(dateStr) {
1596
+ return /^\d\d\d\d-\d\d-\d\d(?:T\d\d:\d\d)?(?::\d\d)?(?:.\d\d\d)?Z?$/i.test(dateStr);
1597
+ }
1598
+ function isValidTodayFormat(dateStr) {
1599
+ return /^today(?:\+(?:\d|\d\d|\d\d\d|\d\d\d\d))?$/i.test(dateStr);
1600
+ }
1592
1601
  if (!dateTimeData.endDate || dateTimeData.endDate === '') {
1593
1602
  dateTimeData.endDate = dateTimeData.startDate;
1594
1603
  }
1595
1604
  const endpoints = ['start', 'end'];
1596
1605
  endpoints.forEach(function (point) {
1597
- if (!/^(?:\d{4}-\d{2}-\d{2}T?(?:\d{2}:\d{2})?Z?|today(?:\+\d{1,4})?)$/i.test(dateTimeData[point + 'Date'])) {
1606
+ const dateStr = dateTimeData[point + 'Date'];
1607
+ if (!isValidDateFormat(dateStr) && !isValidTodayFormat(dateStr)) {
1598
1608
  dateTimeData[point + 'Date'] = 'badly-formed';
1599
1609
  } else {
1600
- dateTimeData[point + 'Date'] = atcb_date_calculation(dateTimeData[point + 'Date']);
1610
+ if (isValidTodayFormat(dateStr)) dateTimeData[point + 'Date'] = atcb_date_calculation(dateStr);
1601
1611
  if (dateTimeData[point + 'Date']) {
1602
- dateTimeData[point + 'Date'] = dateTimeData[point + 'Date'].replace(/\.\d{3}/, '').replace('Z', '');
1603
1612
  const tmpSplitStartDate = dateTimeData[point + 'Date'].split('T');
1604
1613
  if (tmpSplitStartDate[1]) {
1605
1614
  dateTimeData[point + 'Date'] = tmpSplitStartDate[0];
1606
1615
  dateTimeData[point + 'Time'] = tmpSplitStartDate[1];
1607
1616
  }
1608
1617
  }
1609
- if (dateTimeData[point + 'Time'] && dateTimeData[point + 'Time'].length === 8) {
1610
- const timeStr = dateTimeData[point + 'Time'];
1611
- dateTimeData[point + 'Time'] = timeStr.substring(0, timeStr.length - 3);
1618
+ if (dateTimeData[point + 'Time'] && dateTimeData[point + 'Time'].length > 5) {
1619
+ dateTimeData[point + 'Time'] = dateTimeData[point + 'Time'].substring(0, 5);
1612
1620
  }
1613
1621
  }
1614
1622
  });
@@ -1653,12 +1661,7 @@ function atcb_date_calculation(dateString) {
1653
1661
  dateString = dateString.replace(/today/gi, todayString);
1654
1662
  const dateStringParts = dateString.split('+');
1655
1663
  const dateParts = dateStringParts[0].split('-');
1656
- let newDate = (function () {
1657
- if (dateParts[0].length < 4) {
1658
- return new Date(Date.UTC(dateParts[2], dateParts[0] - 1, dateParts[1]));
1659
- }
1660
- return new Date(Date.UTC(dateParts[0], dateParts[1] - 1, dateParts[2]));
1661
- })();
1664
+ const newDate = new Date(Date.UTC(dateParts[0], dateParts[1] - 1, dateParts[2].substring(0, 2)));
1662
1665
  if (dateStringParts[1] && dateStringParts[1] > 0) {
1663
1666
  newDate.setDate(newDate.getDate() + parseInt(dateStringParts[1]));
1664
1667
  }
@@ -974,14 +974,14 @@ function tzlib_get_timezones(jsonType = false) {
974
974
  * Add to Calendar Button
975
975
  * ++++++++++++++++++++++
976
976
  *
977
- * Version: 2.7.0
977
+ * Version: 2.7.1
978
978
  * Creator: Jens Kuerschner (https://jekuer.com)
979
979
  * Project: https://github.com/add2cal/add-to-calendar-button
980
980
  * License: Elastic License 2.0 (ELv2) (https://github.com/add2cal/add-to-calendar-button/blob/main/LICENSE.txt)
981
981
  * Note: DO NOT REMOVE THE COPYRIGHT NOTICE ABOVE!
982
982
  *
983
983
  */
984
- const atcbVersion = '2.7.0';
984
+ const atcbVersion = '2.7.1';
985
985
  const atcbCssTemplate = {};
986
986
  const atcbIsBrowser = () => {
987
987
  if (typeof window === 'undefined') {
@@ -1516,8 +1516,9 @@ function atcb_decorate_data_description(data, i) {
1516
1516
  description = cleanDescription(description);
1517
1517
  if (data.customVar) {
1518
1518
  for (const key in data.customVar) {
1519
- const sanitizedKey = key.replace(/[^\w\-.]/g, '');
1520
- description = description.replace(new RegExp(`%%${sanitizedKey}%%`, 'g'), data.customVar[`${key}`]);
1519
+ const sanitizedKey = '%%' + key.replace(/[^\w\-.]/g, '') + '%%';
1520
+ // eslint-disable-next-line security/detect-non-literal-regexp
1521
+ description = description.replace(new RegExp(sanitizedKey, 'gi'), data.customVar[`${key}`]);
1521
1522
  }
1522
1523
  }
1523
1524
  const descriptionHtmlFree = atcb_rewrite_html_elements(description, true);
@@ -1575,9 +1576,11 @@ function atcb_decorate_data_extend(data) {
1575
1576
  }
1576
1577
  if (data.customVar) {
1577
1578
  for (const key in data.customVar) {
1578
- const sanitizedKey = key.replace(/[^\w\-.]/g, '');
1579
- data.dates[`${i}`].name = data.dates[`${i}`].name.replace(new RegExp(`%%${sanitizedKey}%%`, 'g'), data.customVar[`${key}`]);
1580
- data.dates[`${i}`].location = data.dates[`${i}`].location.replace(new RegExp(`%%${sanitizedKey}%%`, 'g'), data.customVar[`${key}`]);
1579
+ const sanitizedKey = '%%' + key.replace(/[^\w\-.]/g, '') + '%%';
1580
+ // eslint-disable-next-line security/detect-non-literal-regexp
1581
+ data.dates[`${i}`].name = data.dates[`${i}`].name.replace(new RegExp(sanitizedKey, 'gi'), data.customVar[`${key}`]);
1582
+ // eslint-disable-next-line security/detect-non-literal-regexp
1583
+ data.dates[`${i}`].location = data.dates[`${i}`].location.replace(new RegExp(sanitizedKey, 'gi'), data.customVar[`${key}`]);
1581
1584
  }
1582
1585
  }
1583
1586
  }
@@ -1590,26 +1593,31 @@ function atcb_decorate_data_extend(data) {
1590
1593
  return data;
1591
1594
  }
1592
1595
  function atcb_date_cleanup(dateTimeData) {
1596
+ function isValidDateFormat(dateStr) {
1597
+ return /^\d\d\d\d-\d\d-\d\d(?:T\d\d:\d\d)?(?::\d\d)?(?:.\d\d\d)?Z?$/i.test(dateStr);
1598
+ }
1599
+ function isValidTodayFormat(dateStr) {
1600
+ return /^today(?:\+(?:\d|\d\d|\d\d\d|\d\d\d\d))?$/i.test(dateStr);
1601
+ }
1593
1602
  if (!dateTimeData.endDate || dateTimeData.endDate === '') {
1594
1603
  dateTimeData.endDate = dateTimeData.startDate;
1595
1604
  }
1596
1605
  const endpoints = ['start', 'end'];
1597
1606
  endpoints.forEach(function (point) {
1598
- if (!/^(?:\d{4}-\d{2}-\d{2}T?(?:\d{2}:\d{2})?Z?|today(?:\+\d{1,4})?)$/i.test(dateTimeData[point + 'Date'])) {
1607
+ const dateStr = dateTimeData[point + 'Date'];
1608
+ if (!isValidDateFormat(dateStr) && !isValidTodayFormat(dateStr)) {
1599
1609
  dateTimeData[point + 'Date'] = 'badly-formed';
1600
1610
  } else {
1601
- dateTimeData[point + 'Date'] = atcb_date_calculation(dateTimeData[point + 'Date']);
1611
+ if (isValidTodayFormat(dateStr)) dateTimeData[point + 'Date'] = atcb_date_calculation(dateStr);
1602
1612
  if (dateTimeData[point + 'Date']) {
1603
- dateTimeData[point + 'Date'] = dateTimeData[point + 'Date'].replace(/\.\d{3}/, '').replace('Z', '');
1604
1613
  const tmpSplitStartDate = dateTimeData[point + 'Date'].split('T');
1605
1614
  if (tmpSplitStartDate[1]) {
1606
1615
  dateTimeData[point + 'Date'] = tmpSplitStartDate[0];
1607
1616
  dateTimeData[point + 'Time'] = tmpSplitStartDate[1];
1608
1617
  }
1609
1618
  }
1610
- if (dateTimeData[point + 'Time'] && dateTimeData[point + 'Time'].length === 8) {
1611
- const timeStr = dateTimeData[point + 'Time'];
1612
- dateTimeData[point + 'Time'] = timeStr.substring(0, timeStr.length - 3);
1619
+ if (dateTimeData[point + 'Time'] && dateTimeData[point + 'Time'].length > 5) {
1620
+ dateTimeData[point + 'Time'] = dateTimeData[point + 'Time'].substring(0, 5);
1613
1621
  }
1614
1622
  }
1615
1623
  });
@@ -1654,12 +1662,7 @@ function atcb_date_calculation(dateString) {
1654
1662
  dateString = dateString.replace(/today/gi, todayString);
1655
1663
  const dateStringParts = dateString.split('+');
1656
1664
  const dateParts = dateStringParts[0].split('-');
1657
- let newDate = (function () {
1658
- if (dateParts[0].length < 4) {
1659
- return new Date(Date.UTC(dateParts[2], dateParts[0] - 1, dateParts[1]));
1660
- }
1661
- return new Date(Date.UTC(dateParts[0], dateParts[1] - 1, dateParts[2]));
1662
- })();
1665
+ const newDate = new Date(Date.UTC(dateParts[0], dateParts[1] - 1, dateParts[2].substring(0, 2)));
1663
1666
  if (dateStringParts[1] && dateStringParts[1] > 0) {
1664
1667
  newDate.setDate(newDate.getDate() + parseInt(dateStringParts[1]));
1665
1668
  }
package/dist/atcb.js CHANGED
@@ -974,14 +974,14 @@ function tzlib_get_timezones(jsonType = false) {
974
974
  * Add to Calendar Button
975
975
  * ++++++++++++++++++++++
976
976
  *
977
- * Version: 2.7.0
977
+ * Version: 2.7.1
978
978
  * Creator: Jens Kuerschner (https://jekuer.com)
979
979
  * Project: https://github.com/add2cal/add-to-calendar-button
980
980
  * License: Elastic License 2.0 (ELv2) (https://github.com/add2cal/add-to-calendar-button/blob/main/LICENSE.txt)
981
981
  * Note: DO NOT REMOVE THE COPYRIGHT NOTICE ABOVE!
982
982
  *
983
983
  */
984
- const atcbVersion = '2.7.0';
984
+ const atcbVersion = '2.7.1';
985
985
  const atcbCssTemplate = {
986
986
  if (typeof window === 'undefined') {
987
987
  return false;
@@ -1515,8 +1515,9 @@ function atcb_decorate_data_description(data, i) {
1515
1515
  description = cleanDescription(description);
1516
1516
  if (data.customVar) {
1517
1517
  for (const key in data.customVar) {
1518
- const sanitizedKey = key.replace(/[^\w\-.]/g, '');
1519
- description = description.replace(new RegExp(`%%${sanitizedKey}%%`, 'g'), data.customVar[`${key}`]);
1518
+ const sanitizedKey = '%%' + key.replace(/[^\w\-.]/g, '') + '%%';
1519
+ // eslint-disable-next-line security/detect-non-literal-regexp
1520
+ description = description.replace(new RegExp(sanitizedKey, 'gi'), data.customVar[`${key}`]);
1520
1521
  }
1521
1522
  }
1522
1523
  const descriptionHtmlFree = atcb_rewrite_html_elements(description, true);
@@ -1574,9 +1575,11 @@ function atcb_decorate_data_extend(data) {
1574
1575
  }
1575
1576
  if (data.customVar) {
1576
1577
  for (const key in data.customVar) {
1577
- const sanitizedKey = key.replace(/[^\w\-.]/g, '');
1578
- data.dates[`${i}`].name = data.dates[`${i}`].name.replace(new RegExp(`%%${sanitizedKey}%%`, 'g'), data.customVar[`${key}`]);
1579
- data.dates[`${i}`].location = data.dates[`${i}`].location.replace(new RegExp(`%%${sanitizedKey}%%`, 'g'), data.customVar[`${key}`]);
1578
+ const sanitizedKey = '%%' + key.replace(/[^\w\-.]/g, '') + '%%';
1579
+ // eslint-disable-next-line security/detect-non-literal-regexp
1580
+ data.dates[`${i}`].name = data.dates[`${i}`].name.replace(new RegExp(sanitizedKey, 'gi'), data.customVar[`${key}`]);
1581
+ // eslint-disable-next-line security/detect-non-literal-regexp
1582
+ data.dates[`${i}`].location = data.dates[`${i}`].location.replace(new RegExp(sanitizedKey, 'gi'), data.customVar[`${key}`]);
1580
1583
  }
1581
1584
  }
1582
1585
  }
@@ -1589,26 +1592,31 @@ function atcb_decorate_data_extend(data) {
1589
1592
  return data;
1590
1593
  }
1591
1594
  function atcb_date_cleanup(dateTimeData) {
1595
+ function isValidDateFormat(dateStr) {
1596
+ return /^\d\d\d\d-\d\d-\d\d(?:T\d\d:\d\d)?(?::\d\d)?(?:.\d\d\d)?Z?$/i.test(dateStr);
1597
+ }
1598
+ function isValidTodayFormat(dateStr) {
1599
+ return /^today(?:\+(?:\d|\d\d|\d\d\d|\d\d\d\d))?$/i.test(dateStr);
1600
+ }
1592
1601
  if (!dateTimeData.endDate || dateTimeData.endDate === '') {
1593
1602
  dateTimeData.endDate = dateTimeData.startDate;
1594
1603
  }
1595
1604
  const endpoints = ['start', 'end'];
1596
1605
  endpoints.forEach(function (point) {
1597
- if (!/^(?:\d{4}-\d{2}-\d{2}T?(?:\d{2}:\d{2})?Z?|today(?:\+\d{1,4})?)$/i.test(dateTimeData[point + 'Date'])) {
1606
+ const dateStr = dateTimeData[point + 'Date'];
1607
+ if (!isValidDateFormat(dateStr) && !isValidTodayFormat(dateStr)) {
1598
1608
  dateTimeData[point + 'Date'] = 'badly-formed';
1599
1609
  } else {
1600
- dateTimeData[point + 'Date'] = atcb_date_calculation(dateTimeData[point + 'Date']);
1610
+ if (isValidTodayFormat(dateStr)) dateTimeData[point + 'Date'] = atcb_date_calculation(dateStr);
1601
1611
  if (dateTimeData[point + 'Date']) {
1602
- dateTimeData[point + 'Date'] = dateTimeData[point + 'Date'].replace(/\.\d{3}/, '').replace('Z', '');
1603
1612
  const tmpSplitStartDate = dateTimeData[point + 'Date'].split('T');
1604
1613
  if (tmpSplitStartDate[1]) {
1605
1614
  dateTimeData[point + 'Date'] = tmpSplitStartDate[0];
1606
1615
  dateTimeData[point + 'Time'] = tmpSplitStartDate[1];
1607
1616
  }
1608
1617
  }
1609
- if (dateTimeData[point + 'Time'] && dateTimeData[point + 'Time'].length === 8) {
1610
- const timeStr = dateTimeData[point + 'Time'];
1611
- dateTimeData[point + 'Time'] = timeStr.substring(0, timeStr.length - 3);
1618
+ if (dateTimeData[point + 'Time'] && dateTimeData[point + 'Time'].length > 5) {
1619
+ dateTimeData[point + 'Time'] = dateTimeData[point + 'Time'].substring(0, 5);
1612
1620
  }
1613
1621
  }
1614
1622
  });
@@ -1653,12 +1661,7 @@ function atcb_date_calculation(dateString) {
1653
1661
  dateString = dateString.replace(/today/gi, todayString);
1654
1662
  const dateStringParts = dateString.split('+');
1655
1663
  const dateParts = dateStringParts[0].split('-');
1656
- let newDate = (function () {
1657
- if (dateParts[0].length < 4) {
1658
- return new Date(Date.UTC(dateParts[2], dateParts[0] - 1, dateParts[1]));
1659
- }
1660
- return new Date(Date.UTC(dateParts[0], dateParts[1] - 1, dateParts[2]));
1661
- })();
1664
+ const newDate = new Date(Date.UTC(dateParts[0], dateParts[1] - 1, dateParts[2].substring(0, 2)));
1662
1665
  if (dateStringParts[1] && dateStringParts[1] > 0) {
1663
1666
  newDate.setDate(newDate.getDate() + parseInt(dateStringParts[1]));
1664
1667
  }
@@ -6,14 +6,14 @@ const tzlibActions = require('timezones-ical-library');
6
6
  * Add to Calendar Button
7
7
  * ++++++++++++++++++++++
8
8
  *
9
- * Version: 2.7.0
9
+ * Version: 2.7.1
10
10
  * Creator: Jens Kuerschner (https://jekuer.com)
11
11
  * Project: https://github.com/add2cal/add-to-calendar-button
12
12
  * License: Elastic License 2.0 (ELv2) (https://github.com/add2cal/add-to-calendar-button/blob/main/LICENSE.txt)
13
13
  * Note: DO NOT REMOVE THE COPYRIGHT NOTICE ABOVE!
14
14
  *
15
15
  */
16
- const atcbVersion = '2.7.0';
16
+ const atcbVersion = '2.7.1';
17
17
  const atcbCssTemplate = {
18
18
  if (typeof window === 'undefined') {
19
19
  return false;
@@ -547,8 +547,9 @@ function atcb_decorate_data_description(data, i) {
547
547
  description = cleanDescription(description);
548
548
  if (data.customVar) {
549
549
  for (const key in data.customVar) {
550
- const sanitizedKey = key.replace(/[^\w\-.]/g, '');
551
- description = description.replace(new RegExp(`%%${sanitizedKey}%%`, 'g'), data.customVar[`${key}`]);
550
+ const sanitizedKey = '%%' + key.replace(/[^\w\-.]/g, '') + '%%';
551
+ // eslint-disable-next-line security/detect-non-literal-regexp
552
+ description = description.replace(new RegExp(sanitizedKey, 'gi'), data.customVar[`${key}`]);
552
553
  }
553
554
  }
554
555
  const descriptionHtmlFree = atcb_rewrite_html_elements(description, true);
@@ -606,9 +607,11 @@ function atcb_decorate_data_extend(data) {
606
607
  }
607
608
  if (data.customVar) {
608
609
  for (const key in data.customVar) {
609
- const sanitizedKey = key.replace(/[^\w\-.]/g, '');
610
- data.dates[`${i}`].name = data.dates[`${i}`].name.replace(new RegExp(`%%${sanitizedKey}%%`, 'g'), data.customVar[`${key}`]);
611
- data.dates[`${i}`].location = data.dates[`${i}`].location.replace(new RegExp(`%%${sanitizedKey}%%`, 'g'), data.customVar[`${key}`]);
610
+ const sanitizedKey = '%%' + key.replace(/[^\w\-.]/g, '') + '%%';
611
+ // eslint-disable-next-line security/detect-non-literal-regexp
612
+ data.dates[`${i}`].name = data.dates[`${i}`].name.replace(new RegExp(sanitizedKey, 'gi'), data.customVar[`${key}`]);
613
+ // eslint-disable-next-line security/detect-non-literal-regexp
614
+ data.dates[`${i}`].location = data.dates[`${i}`].location.replace(new RegExp(sanitizedKey, 'gi'), data.customVar[`${key}`]);
612
615
  }
613
616
  }
614
617
  }
@@ -621,26 +624,31 @@ function atcb_decorate_data_extend(data) {
621
624
  return data;
622
625
  }
623
626
  function atcb_date_cleanup(dateTimeData) {
627
+ function isValidDateFormat(dateStr) {
628
+ return /^\d\d\d\d-\d\d-\d\d(?:T\d\d:\d\d)?(?::\d\d)?(?:.\d\d\d)?Z?$/i.test(dateStr);
629
+ }
630
+ function isValidTodayFormat(dateStr) {
631
+ return /^today(?:\+(?:\d|\d\d|\d\d\d|\d\d\d\d))?$/i.test(dateStr);
632
+ }
624
633
  if (!dateTimeData.endDate || dateTimeData.endDate === '') {
625
634
  dateTimeData.endDate = dateTimeData.startDate;
626
635
  }
627
636
  const endpoints = ['start', 'end'];
628
637
  endpoints.forEach(function (point) {
629
- if (!/^(?:\d{4}-\d{2}-\d{2}T?(?:\d{2}:\d{2})?Z?|today(?:\+\d{1,4})?)$/i.test(dateTimeData[point + 'Date'])) {
638
+ const dateStr = dateTimeData[point + 'Date'];
639
+ if (!isValidDateFormat(dateStr) && !isValidTodayFormat(dateStr)) {
630
640
  dateTimeData[point + 'Date'] = 'badly-formed';
631
641
  } else {
632
- dateTimeData[point + 'Date'] = atcb_date_calculation(dateTimeData[point + 'Date']);
642
+ if (isValidTodayFormat(dateStr)) dateTimeData[point + 'Date'] = atcb_date_calculation(dateStr);
633
643
  if (dateTimeData[point + 'Date']) {
634
- dateTimeData[point + 'Date'] = dateTimeData[point + 'Date'].replace(/\.\d{3}/, '').replace('Z', '');
635
644
  const tmpSplitStartDate = dateTimeData[point + 'Date'].split('T');
636
645
  if (tmpSplitStartDate[1]) {
637
646
  dateTimeData[point + 'Date'] = tmpSplitStartDate[0];
638
647
  dateTimeData[point + 'Time'] = tmpSplitStartDate[1];
639
648
  }
640
649
  }
641
- if (dateTimeData[point + 'Time'] && dateTimeData[point + 'Time'].length === 8) {
642
- const timeStr = dateTimeData[point + 'Time'];
643
- dateTimeData[point + 'Time'] = timeStr.substring(0, timeStr.length - 3);
650
+ if (dateTimeData[point + 'Time'] && dateTimeData[point + 'Time'].length > 5) {
651
+ dateTimeData[point + 'Time'] = dateTimeData[point + 'Time'].substring(0, 5);
644
652
  }
645
653
  }
646
654
  });
@@ -685,12 +693,7 @@ function atcb_date_calculation(dateString) {
685
693
  dateString = dateString.replace(/today/gi, todayString);
686
694
  const dateStringParts = dateString.split('+');
687
695
  const dateParts = dateStringParts[0].split('-');
688
- let newDate = (function () {
689
- if (dateParts[0].length < 4) {
690
- return new Date(Date.UTC(dateParts[2], dateParts[0] - 1, dateParts[1]));
691
- }
692
- return new Date(Date.UTC(dateParts[0], dateParts[1] - 1, dateParts[2]));
693
- })();
696
+ const newDate = new Date(Date.UTC(dateParts[0], dateParts[1] - 1, dateParts[2].substring(0, 2)));
694
697
  if (dateStringParts[1] && dateStringParts[1] > 0) {
695
698
  newDate.setDate(newDate.getDate() + parseInt(dateStringParts[1]));
696
699
  }
@@ -6,14 +6,14 @@ const tzlibActions = require('timezones-ical-library');
6
6
  * Add to Calendar Button
7
7
  * ++++++++++++++++++++++
8
8
  *
9
- * Version: 2.7.0
9
+ * Version: 2.7.1
10
10
  * Creator: Jens Kuerschner (https://jekuer.com)
11
11
  * Project: https://github.com/add2cal/add-to-calendar-button
12
12
  * License: Elastic License 2.0 (ELv2) (https://github.com/add2cal/add-to-calendar-button/blob/main/LICENSE.txt)
13
13
  * Note: DO NOT REMOVE THE COPYRIGHT NOTICE ABOVE!
14
14
  *
15
15
  */
16
- const atcbVersion = '2.7.0';
16
+ const atcbVersion = '2.7.1';
17
17
  const atcbCssTemplate = {
18
18
  if (typeof window === 'undefined') {
19
19
  return false;
@@ -547,8 +547,9 @@ function atcb_decorate_data_description(data, i) {
547
547
  description = cleanDescription(description);
548
548
  if (data.customVar) {
549
549
  for (const key in data.customVar) {
550
- const sanitizedKey = key.replace(/[^\w\-.]/g, '');
551
- description = description.replace(new RegExp(`%%${sanitizedKey}%%`, 'g'), data.customVar[`${key}`]);
550
+ const sanitizedKey = '%%' + key.replace(/[^\w\-.]/g, '') + '%%';
551
+ // eslint-disable-next-line security/detect-non-literal-regexp
552
+ description = description.replace(new RegExp(sanitizedKey, 'gi'), data.customVar[`${key}`]);
552
553
  }
553
554
  }
554
555
  const descriptionHtmlFree = atcb_rewrite_html_elements(description, true);
@@ -606,9 +607,11 @@ function atcb_decorate_data_extend(data) {
606
607
  }
607
608
  if (data.customVar) {
608
609
  for (const key in data.customVar) {
609
- const sanitizedKey = key.replace(/[^\w\-.]/g, '');
610
- data.dates[`${i}`].name = data.dates[`${i}`].name.replace(new RegExp(`%%${sanitizedKey}%%`, 'g'), data.customVar[`${key}`]);
611
- data.dates[`${i}`].location = data.dates[`${i}`].location.replace(new RegExp(`%%${sanitizedKey}%%`, 'g'), data.customVar[`${key}`]);
610
+ const sanitizedKey = '%%' + key.replace(/[^\w\-.]/g, '') + '%%';
611
+ // eslint-disable-next-line security/detect-non-literal-regexp
612
+ data.dates[`${i}`].name = data.dates[`${i}`].name.replace(new RegExp(sanitizedKey, 'gi'), data.customVar[`${key}`]);
613
+ // eslint-disable-next-line security/detect-non-literal-regexp
614
+ data.dates[`${i}`].location = data.dates[`${i}`].location.replace(new RegExp(sanitizedKey, 'gi'), data.customVar[`${key}`]);
612
615
  }
613
616
  }
614
617
  }
@@ -621,26 +624,31 @@ function atcb_decorate_data_extend(data) {
621
624
  return data;
622
625
  }
623
626
  function atcb_date_cleanup(dateTimeData) {
627
+ function isValidDateFormat(dateStr) {
628
+ return /^\d\d\d\d-\d\d-\d\d(?:T\d\d:\d\d)?(?::\d\d)?(?:.\d\d\d)?Z?$/i.test(dateStr);
629
+ }
630
+ function isValidTodayFormat(dateStr) {
631
+ return /^today(?:\+(?:\d|\d\d|\d\d\d|\d\d\d\d))?$/i.test(dateStr);
632
+ }
624
633
  if (!dateTimeData.endDate || dateTimeData.endDate === '') {
625
634
  dateTimeData.endDate = dateTimeData.startDate;
626
635
  }
627
636
  const endpoints = ['start', 'end'];
628
637
  endpoints.forEach(function (point) {
629
- if (!/^(?:\d{4}-\d{2}-\d{2}T?(?:\d{2}:\d{2})?Z?|today(?:\+\d{1,4})?)$/i.test(dateTimeData[point + 'Date'])) {
638
+ const dateStr = dateTimeData[point + 'Date'];
639
+ if (!isValidDateFormat(dateStr) && !isValidTodayFormat(dateStr)) {
630
640
  dateTimeData[point + 'Date'] = 'badly-formed';
631
641
  } else {
632
- dateTimeData[point + 'Date'] = atcb_date_calculation(dateTimeData[point + 'Date']);
642
+ if (isValidTodayFormat(dateStr)) dateTimeData[point + 'Date'] = atcb_date_calculation(dateStr);
633
643
  if (dateTimeData[point + 'Date']) {
634
- dateTimeData[point + 'Date'] = dateTimeData[point + 'Date'].replace(/\.\d{3}/, '').replace('Z', '');
635
644
  const tmpSplitStartDate = dateTimeData[point + 'Date'].split('T');
636
645
  if (tmpSplitStartDate[1]) {
637
646
  dateTimeData[point + 'Date'] = tmpSplitStartDate[0];
638
647
  dateTimeData[point + 'Time'] = tmpSplitStartDate[1];
639
648
  }
640
649
  }
641
- if (dateTimeData[point + 'Time'] && dateTimeData[point + 'Time'].length === 8) {
642
- const timeStr = dateTimeData[point + 'Time'];
643
- dateTimeData[point + 'Time'] = timeStr.substring(0, timeStr.length - 3);
650
+ if (dateTimeData[point + 'Time'] && dateTimeData[point + 'Time'].length > 5) {
651
+ dateTimeData[point + 'Time'] = dateTimeData[point + 'Time'].substring(0, 5);
644
652
  }
645
653
  }
646
654
  });
@@ -685,12 +693,7 @@ function atcb_date_calculation(dateString) {
685
693
  dateString = dateString.replace(/today/gi, todayString);
686
694
  const dateStringParts = dateString.split('+');
687
695
  const dateParts = dateStringParts[0].split('-');
688
- let newDate = (function () {
689
- if (dateParts[0].length < 4) {
690
- return new Date(Date.UTC(dateParts[2], dateParts[0] - 1, dateParts[1]));
691
- }
692
- return new Date(Date.UTC(dateParts[0], dateParts[1] - 1, dateParts[2]));
693
- })();
696
+ const newDate = new Date(Date.UTC(dateParts[0], dateParts[1] - 1, dateParts[2].substring(0, 2)));
694
697
  if (dateStringParts[1] && dateStringParts[1] > 0) {
695
698
  newDate.setDate(newDate.getDate() + parseInt(dateStringParts[1]));
696
699
  }
@@ -6,14 +6,14 @@ const tzlibActions = require('timezones-ical-library');
6
6
  * Add to Calendar Button
7
7
  * ++++++++++++++++++++++
8
8
  *
9
- * Version: 2.7.0
9
+ * Version: 2.7.1
10
10
  * Creator: Jens Kuerschner (https://jekuer.com)
11
11
  * Project: https://github.com/add2cal/add-to-calendar-button
12
12
  * License: Elastic License 2.0 (ELv2) (https://github.com/add2cal/add-to-calendar-button/blob/main/LICENSE.txt)
13
13
  * Note: DO NOT REMOVE THE COPYRIGHT NOTICE ABOVE!
14
14
  *
15
15
  */
16
- const atcbVersion = '2.7.0';
16
+ const atcbVersion = '2.7.1';
17
17
  const atcbCssTemplate = {};
18
18
  const atcbIsBrowser = () => {
19
19
  if (typeof window === 'undefined') {
@@ -548,8 +548,9 @@ function atcb_decorate_data_description(data, i) {
548
548
  description = cleanDescription(description);
549
549
  if (data.customVar) {
550
550
  for (const key in data.customVar) {
551
- const sanitizedKey = key.replace(/[^\w\-.]/g, '');
552
- description = description.replace(new RegExp(`%%${sanitizedKey}%%`, 'g'), data.customVar[`${key}`]);
551
+ const sanitizedKey = '%%' + key.replace(/[^\w\-.]/g, '') + '%%';
552
+ // eslint-disable-next-line security/detect-non-literal-regexp
553
+ description = description.replace(new RegExp(sanitizedKey, 'gi'), data.customVar[`${key}`]);
553
554
  }
554
555
  }
555
556
  const descriptionHtmlFree = atcb_rewrite_html_elements(description, true);
@@ -607,9 +608,11 @@ function atcb_decorate_data_extend(data) {
607
608
  }
608
609
  if (data.customVar) {
609
610
  for (const key in data.customVar) {
610
- const sanitizedKey = key.replace(/[^\w\-.]/g, '');
611
- data.dates[`${i}`].name = data.dates[`${i}`].name.replace(new RegExp(`%%${sanitizedKey}%%`, 'g'), data.customVar[`${key}`]);
612
- data.dates[`${i}`].location = data.dates[`${i}`].location.replace(new RegExp(`%%${sanitizedKey}%%`, 'g'), data.customVar[`${key}`]);
611
+ const sanitizedKey = '%%' + key.replace(/[^\w\-.]/g, '') + '%%';
612
+ // eslint-disable-next-line security/detect-non-literal-regexp
613
+ data.dates[`${i}`].name = data.dates[`${i}`].name.replace(new RegExp(sanitizedKey, 'gi'), data.customVar[`${key}`]);
614
+ // eslint-disable-next-line security/detect-non-literal-regexp
615
+ data.dates[`${i}`].location = data.dates[`${i}`].location.replace(new RegExp(sanitizedKey, 'gi'), data.customVar[`${key}`]);
613
616
  }
614
617
  }
615
618
  }
@@ -622,26 +625,31 @@ function atcb_decorate_data_extend(data) {
622
625
  return data;
623
626
  }
624
627
  function atcb_date_cleanup(dateTimeData) {
628
+ function isValidDateFormat(dateStr) {
629
+ return /^\d\d\d\d-\d\d-\d\d(?:T\d\d:\d\d)?(?::\d\d)?(?:.\d\d\d)?Z?$/i.test(dateStr);
630
+ }
631
+ function isValidTodayFormat(dateStr) {
632
+ return /^today(?:\+(?:\d|\d\d|\d\d\d|\d\d\d\d))?$/i.test(dateStr);
633
+ }
625
634
  if (!dateTimeData.endDate || dateTimeData.endDate === '') {
626
635
  dateTimeData.endDate = dateTimeData.startDate;
627
636
  }
628
637
  const endpoints = ['start', 'end'];
629
638
  endpoints.forEach(function (point) {
630
- if (!/^(?:\d{4}-\d{2}-\d{2}T?(?:\d{2}:\d{2})?Z?|today(?:\+\d{1,4})?)$/i.test(dateTimeData[point + 'Date'])) {
639
+ const dateStr = dateTimeData[point + 'Date'];
640
+ if (!isValidDateFormat(dateStr) && !isValidTodayFormat(dateStr)) {
631
641
  dateTimeData[point + 'Date'] = 'badly-formed';
632
642
  } else {
633
- dateTimeData[point + 'Date'] = atcb_date_calculation(dateTimeData[point + 'Date']);
643
+ if (isValidTodayFormat(dateStr)) dateTimeData[point + 'Date'] = atcb_date_calculation(dateStr);
634
644
  if (dateTimeData[point + 'Date']) {
635
- dateTimeData[point + 'Date'] = dateTimeData[point + 'Date'].replace(/\.\d{3}/, '').replace('Z', '');
636
645
  const tmpSplitStartDate = dateTimeData[point + 'Date'].split('T');
637
646
  if (tmpSplitStartDate[1]) {
638
647
  dateTimeData[point + 'Date'] = tmpSplitStartDate[0];
639
648
  dateTimeData[point + 'Time'] = tmpSplitStartDate[1];
640
649
  }
641
650
  }
642
- if (dateTimeData[point + 'Time'] && dateTimeData[point + 'Time'].length === 8) {
643
- const timeStr = dateTimeData[point + 'Time'];
644
- dateTimeData[point + 'Time'] = timeStr.substring(0, timeStr.length - 3);
651
+ if (dateTimeData[point + 'Time'] && dateTimeData[point + 'Time'].length > 5) {
652
+ dateTimeData[point + 'Time'] = dateTimeData[point + 'Time'].substring(0, 5);
645
653
  }
646
654
  }
647
655
  });
@@ -686,12 +694,7 @@ function atcb_date_calculation(dateString) {
686
694
  dateString = dateString.replace(/today/gi, todayString);
687
695
  const dateStringParts = dateString.split('+');
688
696
  const dateParts = dateStringParts[0].split('-');
689
- let newDate = (function () {
690
- if (dateParts[0].length < 4) {
691
- return new Date(Date.UTC(dateParts[2], dateParts[0] - 1, dateParts[1]));
692
- }
693
- return new Date(Date.UTC(dateParts[0], dateParts[1] - 1, dateParts[2]));
694
- })();
697
+ const newDate = new Date(Date.UTC(dateParts[0], dateParts[1] - 1, dateParts[2].substring(0, 2)));
695
698
  if (dateStringParts[1] && dateStringParts[1] > 0) {
696
699
  newDate.setDate(newDate.getDate() + parseInt(dateStringParts[1]));
697
700
  }
@@ -6,14 +6,14 @@ const tzlibActions = require('timezones-ical-library');
6
6
  * Add to Calendar Button
7
7
  * ++++++++++++++++++++++
8
8
  *
9
- * Version: 2.7.0
9
+ * Version: 2.7.1
10
10
  * Creator: Jens Kuerschner (https://jekuer.com)
11
11
  * Project: https://github.com/add2cal/add-to-calendar-button
12
12
  * License: Elastic License 2.0 (ELv2) (https://github.com/add2cal/add-to-calendar-button/blob/main/LICENSE.txt)
13
13
  * Note: DO NOT REMOVE THE COPYRIGHT NOTICE ABOVE!
14
14
  *
15
15
  */
16
- const atcbVersion = '2.7.0';
16
+ const atcbVersion = '2.7.1';
17
17
  const atcbCssTemplate = {};
18
18
  const atcbIsBrowser = () => {
19
19
  if (typeof window === 'undefined') {
@@ -548,8 +548,9 @@ function atcb_decorate_data_description(data, i) {
548
548
  description = cleanDescription(description);
549
549
  if (data.customVar) {
550
550
  for (const key in data.customVar) {
551
- const sanitizedKey = key.replace(/[^\w\-.]/g, '');
552
- description = description.replace(new RegExp(`%%${sanitizedKey}%%`, 'g'), data.customVar[`${key}`]);
551
+ const sanitizedKey = '%%' + key.replace(/[^\w\-.]/g, '') + '%%';
552
+ // eslint-disable-next-line security/detect-non-literal-regexp
553
+ description = description.replace(new RegExp(sanitizedKey, 'gi'), data.customVar[`${key}`]);
553
554
  }
554
555
  }
555
556
  const descriptionHtmlFree = atcb_rewrite_html_elements(description, true);
@@ -607,9 +608,11 @@ function atcb_decorate_data_extend(data) {
607
608
  }
608
609
  if (data.customVar) {
609
610
  for (const key in data.customVar) {
610
- const sanitizedKey = key.replace(/[^\w\-.]/g, '');
611
- data.dates[`${i}`].name = data.dates[`${i}`].name.replace(new RegExp(`%%${sanitizedKey}%%`, 'g'), data.customVar[`${key}`]);
612
- data.dates[`${i}`].location = data.dates[`${i}`].location.replace(new RegExp(`%%${sanitizedKey}%%`, 'g'), data.customVar[`${key}`]);
611
+ const sanitizedKey = '%%' + key.replace(/[^\w\-.]/g, '') + '%%';
612
+ // eslint-disable-next-line security/detect-non-literal-regexp
613
+ data.dates[`${i}`].name = data.dates[`${i}`].name.replace(new RegExp(sanitizedKey, 'gi'), data.customVar[`${key}`]);
614
+ // eslint-disable-next-line security/detect-non-literal-regexp
615
+ data.dates[`${i}`].location = data.dates[`${i}`].location.replace(new RegExp(sanitizedKey, 'gi'), data.customVar[`${key}`]);
613
616
  }
614
617
  }
615
618
  }
@@ -622,26 +625,31 @@ function atcb_decorate_data_extend(data) {
622
625
  return data;
623
626
  }
624
627
  function atcb_date_cleanup(dateTimeData) {
628
+ function isValidDateFormat(dateStr) {
629
+ return /^\d\d\d\d-\d\d-\d\d(?:T\d\d:\d\d)?(?::\d\d)?(?:.\d\d\d)?Z?$/i.test(dateStr);
630
+ }
631
+ function isValidTodayFormat(dateStr) {
632
+ return /^today(?:\+(?:\d|\d\d|\d\d\d|\d\d\d\d))?$/i.test(dateStr);
633
+ }
625
634
  if (!dateTimeData.endDate || dateTimeData.endDate === '') {
626
635
  dateTimeData.endDate = dateTimeData.startDate;
627
636
  }
628
637
  const endpoints = ['start', 'end'];
629
638
  endpoints.forEach(function (point) {
630
- if (!/^(?:\d{4}-\d{2}-\d{2}T?(?:\d{2}:\d{2})?Z?|today(?:\+\d{1,4})?)$/i.test(dateTimeData[point + 'Date'])) {
639
+ const dateStr = dateTimeData[point + 'Date'];
640
+ if (!isValidDateFormat(dateStr) && !isValidTodayFormat(dateStr)) {
631
641
  dateTimeData[point + 'Date'] = 'badly-formed';
632
642
  } else {
633
- dateTimeData[point + 'Date'] = atcb_date_calculation(dateTimeData[point + 'Date']);
643
+ if (isValidTodayFormat(dateStr)) dateTimeData[point + 'Date'] = atcb_date_calculation(dateStr);
634
644
  if (dateTimeData[point + 'Date']) {
635
- dateTimeData[point + 'Date'] = dateTimeData[point + 'Date'].replace(/\.\d{3}/, '').replace('Z', '');
636
645
  const tmpSplitStartDate = dateTimeData[point + 'Date'].split('T');
637
646
  if (tmpSplitStartDate[1]) {
638
647
  dateTimeData[point + 'Date'] = tmpSplitStartDate[0];
639
648
  dateTimeData[point + 'Time'] = tmpSplitStartDate[1];
640
649
  }
641
650
  }
642
- if (dateTimeData[point + 'Time'] && dateTimeData[point + 'Time'].length === 8) {
643
- const timeStr = dateTimeData[point + 'Time'];
644
- dateTimeData[point + 'Time'] = timeStr.substring(0, timeStr.length - 3);
651
+ if (dateTimeData[point + 'Time'] && dateTimeData[point + 'Time'].length > 5) {
652
+ dateTimeData[point + 'Time'] = dateTimeData[point + 'Time'].substring(0, 5);
645
653
  }
646
654
  }
647
655
  });
@@ -686,12 +694,7 @@ function atcb_date_calculation(dateString) {
686
694
  dateString = dateString.replace(/today/gi, todayString);
687
695
  const dateStringParts = dateString.split('+');
688
696
  const dateParts = dateStringParts[0].split('-');
689
- let newDate = (function () {
690
- if (dateParts[0].length < 4) {
691
- return new Date(Date.UTC(dateParts[2], dateParts[0] - 1, dateParts[1]));
692
- }
693
- return new Date(Date.UTC(dateParts[0], dateParts[1] - 1, dateParts[2]));
694
- })();
697
+ const newDate = new Date(Date.UTC(dateParts[0], dateParts[1] - 1, dateParts[2].substring(0, 2)));
695
698
  if (dateStringParts[1] && dateStringParts[1] > 0) {
696
699
  newDate.setDate(newDate.getDate() + parseInt(dateStringParts[1]));
697
700
  }
@@ -6,14 +6,14 @@ import { tzlib_get_ical_block, tzlib_get_offset, tzlib_get_timezones } from 'tim
6
6
  * Add to Calendar Button
7
7
  * ++++++++++++++++++++++
8
8
  *
9
- * Version: 2.7.0
9
+ * Version: 2.7.1
10
10
  * Creator: Jens Kuerschner (https://jekuer.com)
11
11
  * Project: https://github.com/add2cal/add-to-calendar-button
12
12
  * License: Elastic License 2.0 (ELv2) (https://github.com/add2cal/add-to-calendar-button/blob/main/LICENSE.txt)
13
13
  * Note: DO NOT REMOVE THE COPYRIGHT NOTICE ABOVE!
14
14
  *
15
15
  */
16
- const atcbVersion = '2.7.0';
16
+ const atcbVersion = '2.7.1';
17
17
  const atcbCssTemplate = {
18
18
  if (typeof window === 'undefined') {
19
19
  return false;
@@ -547,8 +547,9 @@ function atcb_decorate_data_description(data, i) {
547
547
  description = cleanDescription(description);
548
548
  if (data.customVar) {
549
549
  for (const key in data.customVar) {
550
- const sanitizedKey = key.replace(/[^\w\-.]/g, '');
551
- description = description.replace(new RegExp(`%%${sanitizedKey}%%`, 'g'), data.customVar[`${key}`]);
550
+ const sanitizedKey = '%%' + key.replace(/[^\w\-.]/g, '') + '%%';
551
+ // eslint-disable-next-line security/detect-non-literal-regexp
552
+ description = description.replace(new RegExp(sanitizedKey, 'gi'), data.customVar[`${key}`]);
552
553
  }
553
554
  }
554
555
  const descriptionHtmlFree = atcb_rewrite_html_elements(description, true);
@@ -606,9 +607,11 @@ function atcb_decorate_data_extend(data) {
606
607
  }
607
608
  if (data.customVar) {
608
609
  for (const key in data.customVar) {
609
- const sanitizedKey = key.replace(/[^\w\-.]/g, '');
610
- data.dates[`${i}`].name = data.dates[`${i}`].name.replace(new RegExp(`%%${sanitizedKey}%%`, 'g'), data.customVar[`${key}`]);
611
- data.dates[`${i}`].location = data.dates[`${i}`].location.replace(new RegExp(`%%${sanitizedKey}%%`, 'g'), data.customVar[`${key}`]);
610
+ const sanitizedKey = '%%' + key.replace(/[^\w\-.]/g, '') + '%%';
611
+ // eslint-disable-next-line security/detect-non-literal-regexp
612
+ data.dates[`${i}`].name = data.dates[`${i}`].name.replace(new RegExp(sanitizedKey, 'gi'), data.customVar[`${key}`]);
613
+ // eslint-disable-next-line security/detect-non-literal-regexp
614
+ data.dates[`${i}`].location = data.dates[`${i}`].location.replace(new RegExp(sanitizedKey, 'gi'), data.customVar[`${key}`]);
612
615
  }
613
616
  }
614
617
  }
@@ -621,26 +624,31 @@ function atcb_decorate_data_extend(data) {
621
624
  return data;
622
625
  }
623
626
  function atcb_date_cleanup(dateTimeData) {
627
+ function isValidDateFormat(dateStr) {
628
+ return /^\d\d\d\d-\d\d-\d\d(?:T\d\d:\d\d)?(?::\d\d)?(?:.\d\d\d)?Z?$/i.test(dateStr);
629
+ }
630
+ function isValidTodayFormat(dateStr) {
631
+ return /^today(?:\+(?:\d|\d\d|\d\d\d|\d\d\d\d))?$/i.test(dateStr);
632
+ }
624
633
  if (!dateTimeData.endDate || dateTimeData.endDate === '') {
625
634
  dateTimeData.endDate = dateTimeData.startDate;
626
635
  }
627
636
  const endpoints = ['start', 'end'];
628
637
  endpoints.forEach(function (point) {
629
- if (!/^(?:\d{4}-\d{2}-\d{2}T?(?:\d{2}:\d{2})?Z?|today(?:\+\d{1,4})?)$/i.test(dateTimeData[point + 'Date'])) {
638
+ const dateStr = dateTimeData[point + 'Date'];
639
+ if (!isValidDateFormat(dateStr) && !isValidTodayFormat(dateStr)) {
630
640
  dateTimeData[point + 'Date'] = 'badly-formed';
631
641
  } else {
632
- dateTimeData[point + 'Date'] = atcb_date_calculation(dateTimeData[point + 'Date']);
642
+ if (isValidTodayFormat(dateStr)) dateTimeData[point + 'Date'] = atcb_date_calculation(dateStr);
633
643
  if (dateTimeData[point + 'Date']) {
634
- dateTimeData[point + 'Date'] = dateTimeData[point + 'Date'].replace(/\.\d{3}/, '').replace('Z', '');
635
644
  const tmpSplitStartDate = dateTimeData[point + 'Date'].split('T');
636
645
  if (tmpSplitStartDate[1]) {
637
646
  dateTimeData[point + 'Date'] = tmpSplitStartDate[0];
638
647
  dateTimeData[point + 'Time'] = tmpSplitStartDate[1];
639
648
  }
640
649
  }
641
- if (dateTimeData[point + 'Time'] && dateTimeData[point + 'Time'].length === 8) {
642
- const timeStr = dateTimeData[point + 'Time'];
643
- dateTimeData[point + 'Time'] = timeStr.substring(0, timeStr.length - 3);
650
+ if (dateTimeData[point + 'Time'] && dateTimeData[point + 'Time'].length > 5) {
651
+ dateTimeData[point + 'Time'] = dateTimeData[point + 'Time'].substring(0, 5);
644
652
  }
645
653
  }
646
654
  });
@@ -685,12 +693,7 @@ function atcb_date_calculation(dateString) {
685
693
  dateString = dateString.replace(/today/gi, todayString);
686
694
  const dateStringParts = dateString.split('+');
687
695
  const dateParts = dateStringParts[0].split('-');
688
- let newDate = (function () {
689
- if (dateParts[0].length < 4) {
690
- return new Date(Date.UTC(dateParts[2], dateParts[0] - 1, dateParts[1]));
691
- }
692
- return new Date(Date.UTC(dateParts[0], dateParts[1] - 1, dateParts[2]));
693
- })();
696
+ const newDate = new Date(Date.UTC(dateParts[0], dateParts[1] - 1, dateParts[2].substring(0, 2)));
694
697
  if (dateStringParts[1] && dateStringParts[1] > 0) {
695
698
  newDate.setDate(newDate.getDate() + parseInt(dateStringParts[1]));
696
699
  }
@@ -6,14 +6,14 @@ import { tzlib_get_ical_block, tzlib_get_offset, tzlib_get_timezones } from 'tim
6
6
  * Add to Calendar Button
7
7
  * ++++++++++++++++++++++
8
8
  *
9
- * Version: 2.7.0
9
+ * Version: 2.7.1
10
10
  * Creator: Jens Kuerschner (https://jekuer.com)
11
11
  * Project: https://github.com/add2cal/add-to-calendar-button
12
12
  * License: Elastic License 2.0 (ELv2) (https://github.com/add2cal/add-to-calendar-button/blob/main/LICENSE.txt)
13
13
  * Note: DO NOT REMOVE THE COPYRIGHT NOTICE ABOVE!
14
14
  *
15
15
  */
16
- const atcbVersion = '2.7.0';
16
+ const atcbVersion = '2.7.1';
17
17
  const atcbCssTemplate = {
18
18
  if (typeof window === 'undefined') {
19
19
  return false;
@@ -547,8 +547,9 @@ function atcb_decorate_data_description(data, i) {
547
547
  description = cleanDescription(description);
548
548
  if (data.customVar) {
549
549
  for (const key in data.customVar) {
550
- const sanitizedKey = key.replace(/[^\w\-.]/g, '');
551
- description = description.replace(new RegExp(`%%${sanitizedKey}%%`, 'g'), data.customVar[`${key}`]);
550
+ const sanitizedKey = '%%' + key.replace(/[^\w\-.]/g, '') + '%%';
551
+ // eslint-disable-next-line security/detect-non-literal-regexp
552
+ description = description.replace(new RegExp(sanitizedKey, 'gi'), data.customVar[`${key}`]);
552
553
  }
553
554
  }
554
555
  const descriptionHtmlFree = atcb_rewrite_html_elements(description, true);
@@ -606,9 +607,11 @@ function atcb_decorate_data_extend(data) {
606
607
  }
607
608
  if (data.customVar) {
608
609
  for (const key in data.customVar) {
609
- const sanitizedKey = key.replace(/[^\w\-.]/g, '');
610
- data.dates[`${i}`].name = data.dates[`${i}`].name.replace(new RegExp(`%%${sanitizedKey}%%`, 'g'), data.customVar[`${key}`]);
611
- data.dates[`${i}`].location = data.dates[`${i}`].location.replace(new RegExp(`%%${sanitizedKey}%%`, 'g'), data.customVar[`${key}`]);
610
+ const sanitizedKey = '%%' + key.replace(/[^\w\-.]/g, '') + '%%';
611
+ // eslint-disable-next-line security/detect-non-literal-regexp
612
+ data.dates[`${i}`].name = data.dates[`${i}`].name.replace(new RegExp(sanitizedKey, 'gi'), data.customVar[`${key}`]);
613
+ // eslint-disable-next-line security/detect-non-literal-regexp
614
+ data.dates[`${i}`].location = data.dates[`${i}`].location.replace(new RegExp(sanitizedKey, 'gi'), data.customVar[`${key}`]);
612
615
  }
613
616
  }
614
617
  }
@@ -621,26 +624,31 @@ function atcb_decorate_data_extend(data) {
621
624
  return data;
622
625
  }
623
626
  function atcb_date_cleanup(dateTimeData) {
627
+ function isValidDateFormat(dateStr) {
628
+ return /^\d\d\d\d-\d\d-\d\d(?:T\d\d:\d\d)?(?::\d\d)?(?:.\d\d\d)?Z?$/i.test(dateStr);
629
+ }
630
+ function isValidTodayFormat(dateStr) {
631
+ return /^today(?:\+(?:\d|\d\d|\d\d\d|\d\d\d\d))?$/i.test(dateStr);
632
+ }
624
633
  if (!dateTimeData.endDate || dateTimeData.endDate === '') {
625
634
  dateTimeData.endDate = dateTimeData.startDate;
626
635
  }
627
636
  const endpoints = ['start', 'end'];
628
637
  endpoints.forEach(function (point) {
629
- if (!/^(?:\d{4}-\d{2}-\d{2}T?(?:\d{2}:\d{2})?Z?|today(?:\+\d{1,4})?)$/i.test(dateTimeData[point + 'Date'])) {
638
+ const dateStr = dateTimeData[point + 'Date'];
639
+ if (!isValidDateFormat(dateStr) && !isValidTodayFormat(dateStr)) {
630
640
  dateTimeData[point + 'Date'] = 'badly-formed';
631
641
  } else {
632
- dateTimeData[point + 'Date'] = atcb_date_calculation(dateTimeData[point + 'Date']);
642
+ if (isValidTodayFormat(dateStr)) dateTimeData[point + 'Date'] = atcb_date_calculation(dateStr);
633
643
  if (dateTimeData[point + 'Date']) {
634
- dateTimeData[point + 'Date'] = dateTimeData[point + 'Date'].replace(/\.\d{3}/, '').replace('Z', '');
635
644
  const tmpSplitStartDate = dateTimeData[point + 'Date'].split('T');
636
645
  if (tmpSplitStartDate[1]) {
637
646
  dateTimeData[point + 'Date'] = tmpSplitStartDate[0];
638
647
  dateTimeData[point + 'Time'] = tmpSplitStartDate[1];
639
648
  }
640
649
  }
641
- if (dateTimeData[point + 'Time'] && dateTimeData[point + 'Time'].length === 8) {
642
- const timeStr = dateTimeData[point + 'Time'];
643
- dateTimeData[point + 'Time'] = timeStr.substring(0, timeStr.length - 3);
650
+ if (dateTimeData[point + 'Time'] && dateTimeData[point + 'Time'].length > 5) {
651
+ dateTimeData[point + 'Time'] = dateTimeData[point + 'Time'].substring(0, 5);
644
652
  }
645
653
  }
646
654
  });
@@ -685,12 +693,7 @@ function atcb_date_calculation(dateString) {
685
693
  dateString = dateString.replace(/today/gi, todayString);
686
694
  const dateStringParts = dateString.split('+');
687
695
  const dateParts = dateStringParts[0].split('-');
688
- let newDate = (function () {
689
- if (dateParts[0].length < 4) {
690
- return new Date(Date.UTC(dateParts[2], dateParts[0] - 1, dateParts[1]));
691
- }
692
- return new Date(Date.UTC(dateParts[0], dateParts[1] - 1, dateParts[2]));
693
- })();
696
+ const newDate = new Date(Date.UTC(dateParts[0], dateParts[1] - 1, dateParts[2].substring(0, 2)));
694
697
  if (dateStringParts[1] && dateStringParts[1] > 0) {
695
698
  newDate.setDate(newDate.getDate() + parseInt(dateStringParts[1]));
696
699
  }
@@ -6,14 +6,14 @@ import { tzlib_get_ical_block, tzlib_get_offset, tzlib_get_timezones } from 'tim
6
6
  * Add to Calendar Button
7
7
  * ++++++++++++++++++++++
8
8
  *
9
- * Version: 2.7.0
9
+ * Version: 2.7.1
10
10
  * Creator: Jens Kuerschner (https://jekuer.com)
11
11
  * Project: https://github.com/add2cal/add-to-calendar-button
12
12
  * License: Elastic License 2.0 (ELv2) (https://github.com/add2cal/add-to-calendar-button/blob/main/LICENSE.txt)
13
13
  * Note: DO NOT REMOVE THE COPYRIGHT NOTICE ABOVE!
14
14
  *
15
15
  */
16
- const atcbVersion = '2.7.0';
16
+ const atcbVersion = '2.7.1';
17
17
  const atcbCssTemplate = {};
18
18
  const atcbIsBrowser = () => {
19
19
  if (typeof window === 'undefined') {
@@ -548,8 +548,9 @@ function atcb_decorate_data_description(data, i) {
548
548
  description = cleanDescription(description);
549
549
  if (data.customVar) {
550
550
  for (const key in data.customVar) {
551
- const sanitizedKey = key.replace(/[^\w\-.]/g, '');
552
- description = description.replace(new RegExp(`%%${sanitizedKey}%%`, 'g'), data.customVar[`${key}`]);
551
+ const sanitizedKey = '%%' + key.replace(/[^\w\-.]/g, '') + '%%';
552
+ // eslint-disable-next-line security/detect-non-literal-regexp
553
+ description = description.replace(new RegExp(sanitizedKey, 'gi'), data.customVar[`${key}`]);
553
554
  }
554
555
  }
555
556
  const descriptionHtmlFree = atcb_rewrite_html_elements(description, true);
@@ -607,9 +608,11 @@ function atcb_decorate_data_extend(data) {
607
608
  }
608
609
  if (data.customVar) {
609
610
  for (const key in data.customVar) {
610
- const sanitizedKey = key.replace(/[^\w\-.]/g, '');
611
- data.dates[`${i}`].name = data.dates[`${i}`].name.replace(new RegExp(`%%${sanitizedKey}%%`, 'g'), data.customVar[`${key}`]);
612
- data.dates[`${i}`].location = data.dates[`${i}`].location.replace(new RegExp(`%%${sanitizedKey}%%`, 'g'), data.customVar[`${key}`]);
611
+ const sanitizedKey = '%%' + key.replace(/[^\w\-.]/g, '') + '%%';
612
+ // eslint-disable-next-line security/detect-non-literal-regexp
613
+ data.dates[`${i}`].name = data.dates[`${i}`].name.replace(new RegExp(sanitizedKey, 'gi'), data.customVar[`${key}`]);
614
+ // eslint-disable-next-line security/detect-non-literal-regexp
615
+ data.dates[`${i}`].location = data.dates[`${i}`].location.replace(new RegExp(sanitizedKey, 'gi'), data.customVar[`${key}`]);
613
616
  }
614
617
  }
615
618
  }
@@ -622,26 +625,31 @@ function atcb_decorate_data_extend(data) {
622
625
  return data;
623
626
  }
624
627
  function atcb_date_cleanup(dateTimeData) {
628
+ function isValidDateFormat(dateStr) {
629
+ return /^\d\d\d\d-\d\d-\d\d(?:T\d\d:\d\d)?(?::\d\d)?(?:.\d\d\d)?Z?$/i.test(dateStr);
630
+ }
631
+ function isValidTodayFormat(dateStr) {
632
+ return /^today(?:\+(?:\d|\d\d|\d\d\d|\d\d\d\d))?$/i.test(dateStr);
633
+ }
625
634
  if (!dateTimeData.endDate || dateTimeData.endDate === '') {
626
635
  dateTimeData.endDate = dateTimeData.startDate;
627
636
  }
628
637
  const endpoints = ['start', 'end'];
629
638
  endpoints.forEach(function (point) {
630
- if (!/^(?:\d{4}-\d{2}-\d{2}T?(?:\d{2}:\d{2})?Z?|today(?:\+\d{1,4})?)$/i.test(dateTimeData[point + 'Date'])) {
639
+ const dateStr = dateTimeData[point + 'Date'];
640
+ if (!isValidDateFormat(dateStr) && !isValidTodayFormat(dateStr)) {
631
641
  dateTimeData[point + 'Date'] = 'badly-formed';
632
642
  } else {
633
- dateTimeData[point + 'Date'] = atcb_date_calculation(dateTimeData[point + 'Date']);
643
+ if (isValidTodayFormat(dateStr)) dateTimeData[point + 'Date'] = atcb_date_calculation(dateStr);
634
644
  if (dateTimeData[point + 'Date']) {
635
- dateTimeData[point + 'Date'] = dateTimeData[point + 'Date'].replace(/\.\d{3}/, '').replace('Z', '');
636
645
  const tmpSplitStartDate = dateTimeData[point + 'Date'].split('T');
637
646
  if (tmpSplitStartDate[1]) {
638
647
  dateTimeData[point + 'Date'] = tmpSplitStartDate[0];
639
648
  dateTimeData[point + 'Time'] = tmpSplitStartDate[1];
640
649
  }
641
650
  }
642
- if (dateTimeData[point + 'Time'] && dateTimeData[point + 'Time'].length === 8) {
643
- const timeStr = dateTimeData[point + 'Time'];
644
- dateTimeData[point + 'Time'] = timeStr.substring(0, timeStr.length - 3);
651
+ if (dateTimeData[point + 'Time'] && dateTimeData[point + 'Time'].length > 5) {
652
+ dateTimeData[point + 'Time'] = dateTimeData[point + 'Time'].substring(0, 5);
645
653
  }
646
654
  }
647
655
  });
@@ -686,12 +694,7 @@ function atcb_date_calculation(dateString) {
686
694
  dateString = dateString.replace(/today/gi, todayString);
687
695
  const dateStringParts = dateString.split('+');
688
696
  const dateParts = dateStringParts[0].split('-');
689
- let newDate = (function () {
690
- if (dateParts[0].length < 4) {
691
- return new Date(Date.UTC(dateParts[2], dateParts[0] - 1, dateParts[1]));
692
- }
693
- return new Date(Date.UTC(dateParts[0], dateParts[1] - 1, dateParts[2]));
694
- })();
697
+ const newDate = new Date(Date.UTC(dateParts[0], dateParts[1] - 1, dateParts[2].substring(0, 2)));
695
698
  if (dateStringParts[1] && dateStringParts[1] > 0) {
696
699
  newDate.setDate(newDate.getDate() + parseInt(dateStringParts[1]));
697
700
  }
@@ -6,14 +6,14 @@ import { tzlib_get_ical_block, tzlib_get_offset, tzlib_get_timezones } from 'tim
6
6
  * Add to Calendar Button
7
7
  * ++++++++++++++++++++++
8
8
  *
9
- * Version: 2.7.0
9
+ * Version: 2.7.1
10
10
  * Creator: Jens Kuerschner (https://jekuer.com)
11
11
  * Project: https://github.com/add2cal/add-to-calendar-button
12
12
  * License: Elastic License 2.0 (ELv2) (https://github.com/add2cal/add-to-calendar-button/blob/main/LICENSE.txt)
13
13
  * Note: DO NOT REMOVE THE COPYRIGHT NOTICE ABOVE!
14
14
  *
15
15
  */
16
- const atcbVersion = '2.7.0';
16
+ const atcbVersion = '2.7.1';
17
17
  const atcbCssTemplate = {};
18
18
  const atcbIsBrowser = () => {
19
19
  if (typeof window === 'undefined') {
@@ -548,8 +548,9 @@ function atcb_decorate_data_description(data, i) {
548
548
  description = cleanDescription(description);
549
549
  if (data.customVar) {
550
550
  for (const key in data.customVar) {
551
- const sanitizedKey = key.replace(/[^\w\-.]/g, '');
552
- description = description.replace(new RegExp(`%%${sanitizedKey}%%`, 'g'), data.customVar[`${key}`]);
551
+ const sanitizedKey = '%%' + key.replace(/[^\w\-.]/g, '') + '%%';
552
+ // eslint-disable-next-line security/detect-non-literal-regexp
553
+ description = description.replace(new RegExp(sanitizedKey, 'gi'), data.customVar[`${key}`]);
553
554
  }
554
555
  }
555
556
  const descriptionHtmlFree = atcb_rewrite_html_elements(description, true);
@@ -607,9 +608,11 @@ function atcb_decorate_data_extend(data) {
607
608
  }
608
609
  if (data.customVar) {
609
610
  for (const key in data.customVar) {
610
- const sanitizedKey = key.replace(/[^\w\-.]/g, '');
611
- data.dates[`${i}`].name = data.dates[`${i}`].name.replace(new RegExp(`%%${sanitizedKey}%%`, 'g'), data.customVar[`${key}`]);
612
- data.dates[`${i}`].location = data.dates[`${i}`].location.replace(new RegExp(`%%${sanitizedKey}%%`, 'g'), data.customVar[`${key}`]);
611
+ const sanitizedKey = '%%' + key.replace(/[^\w\-.]/g, '') + '%%';
612
+ // eslint-disable-next-line security/detect-non-literal-regexp
613
+ data.dates[`${i}`].name = data.dates[`${i}`].name.replace(new RegExp(sanitizedKey, 'gi'), data.customVar[`${key}`]);
614
+ // eslint-disable-next-line security/detect-non-literal-regexp
615
+ data.dates[`${i}`].location = data.dates[`${i}`].location.replace(new RegExp(sanitizedKey, 'gi'), data.customVar[`${key}`]);
613
616
  }
614
617
  }
615
618
  }
@@ -622,26 +625,31 @@ function atcb_decorate_data_extend(data) {
622
625
  return data;
623
626
  }
624
627
  function atcb_date_cleanup(dateTimeData) {
628
+ function isValidDateFormat(dateStr) {
629
+ return /^\d\d\d\d-\d\d-\d\d(?:T\d\d:\d\d)?(?::\d\d)?(?:.\d\d\d)?Z?$/i.test(dateStr);
630
+ }
631
+ function isValidTodayFormat(dateStr) {
632
+ return /^today(?:\+(?:\d|\d\d|\d\d\d|\d\d\d\d))?$/i.test(dateStr);
633
+ }
625
634
  if (!dateTimeData.endDate || dateTimeData.endDate === '') {
626
635
  dateTimeData.endDate = dateTimeData.startDate;
627
636
  }
628
637
  const endpoints = ['start', 'end'];
629
638
  endpoints.forEach(function (point) {
630
- if (!/^(?:\d{4}-\d{2}-\d{2}T?(?:\d{2}:\d{2})?Z?|today(?:\+\d{1,4})?)$/i.test(dateTimeData[point + 'Date'])) {
639
+ const dateStr = dateTimeData[point + 'Date'];
640
+ if (!isValidDateFormat(dateStr) && !isValidTodayFormat(dateStr)) {
631
641
  dateTimeData[point + 'Date'] = 'badly-formed';
632
642
  } else {
633
- dateTimeData[point + 'Date'] = atcb_date_calculation(dateTimeData[point + 'Date']);
643
+ if (isValidTodayFormat(dateStr)) dateTimeData[point + 'Date'] = atcb_date_calculation(dateStr);
634
644
  if (dateTimeData[point + 'Date']) {
635
- dateTimeData[point + 'Date'] = dateTimeData[point + 'Date'].replace(/\.\d{3}/, '').replace('Z', '');
636
645
  const tmpSplitStartDate = dateTimeData[point + 'Date'].split('T');
637
646
  if (tmpSplitStartDate[1]) {
638
647
  dateTimeData[point + 'Date'] = tmpSplitStartDate[0];
639
648
  dateTimeData[point + 'Time'] = tmpSplitStartDate[1];
640
649
  }
641
650
  }
642
- if (dateTimeData[point + 'Time'] && dateTimeData[point + 'Time'].length === 8) {
643
- const timeStr = dateTimeData[point + 'Time'];
644
- dateTimeData[point + 'Time'] = timeStr.substring(0, timeStr.length - 3);
651
+ if (dateTimeData[point + 'Time'] && dateTimeData[point + 'Time'].length > 5) {
652
+ dateTimeData[point + 'Time'] = dateTimeData[point + 'Time'].substring(0, 5);
645
653
  }
646
654
  }
647
655
  });
@@ -686,12 +694,7 @@ function atcb_date_calculation(dateString) {
686
694
  dateString = dateString.replace(/today/gi, todayString);
687
695
  const dateStringParts = dateString.split('+');
688
696
  const dateParts = dateStringParts[0].split('-');
689
- let newDate = (function () {
690
- if (dateParts[0].length < 4) {
691
- return new Date(Date.UTC(dateParts[2], dateParts[0] - 1, dateParts[1]));
692
- }
693
- return new Date(Date.UTC(dateParts[0], dateParts[1] - 1, dateParts[2]));
694
- })();
697
+ const newDate = new Date(Date.UTC(dateParts[0], dateParts[1] - 1, dateParts[2].substring(0, 2)));
695
698
  if (dateStringParts[1] && dateStringParts[1] > 0) {
696
699
  newDate.setDate(newDate.getDate() + parseInt(dateStringParts[1]));
697
700
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "add-to-calendar-button",
3
- "version": "2.7.0",
3
+ "version": "2.7.1",
4
4
  "engines": {
5
5
  "node": ">=18.17.0",
6
6
  "npm": ">=9.6.7"