add-to-calendar-button 2.6.20 → 2.6.21

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.
@@ -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.6.20
9
+ * Version: 2.6.21
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.6.20';
16
+ const atcbVersion = '2.6.21';
17
17
  const atcbCssTemplate = {
18
18
  if (typeof window === 'undefined') {
19
19
  return false;
@@ -56,7 +56,7 @@ const atcbIsAndroid = atcbIsBrowser()
56
56
  };*/
57
57
  const atcbIsSafari = atcbIsBrowser()
58
58
  ? () => {
59
- if (/^((?!chrome|android|crios|fxios).)*safari/i.test(navigator.userAgent)) {
59
+ if (/^(?:(?!chrome|android|crios|fxios).)*safari/i.test(navigator.userAgent)) {
60
60
  return true;
61
61
  } else {
62
62
  return false;
@@ -74,7 +74,7 @@ const atcbIsMobile = () => {
74
74
  };
75
75
  const atcbIsWebView = atcbIsBrowser()
76
76
  ? () => {
77
- if (/(; ?wv|(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari))/i.test(navigator.userAgent)) {
77
+ if (/; ?wv|(?:iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/i.test(navigator.userAgent)) {
78
78
  return true;
79
79
  } else {
80
80
  return false;
@@ -85,7 +85,7 @@ const atcbIsWebView = atcbIsBrowser()
85
85
  };
86
86
  const atcbIsProblematicWebView = atcbIsBrowser()
87
87
  ? () => {
88
- if (/(Instagram)/i.test(navigator.userAgent)) {
88
+ if (/Instagram/i.test(navigator.userAgent)) {
89
89
  return true;
90
90
  } else {
91
91
  return false;
@@ -304,7 +304,7 @@ function atcb_decorate_data_timezone(tz = null) {
304
304
  function atcb_decorate_data_rrule(data) {
305
305
  if (data.recurrence && data.recurrence !== '') {
306
306
  data.recurrence = data.recurrence.replace(/\s+/g, '').toUpperCase();
307
- if (!/^(RRULE:[\w=;,:+-/\\]+|daily|weekly|monthly|yearly)$/im.test(data.recurrence)) {
307
+ if (!/^(?:RRULE:[\w=;,:+\-/\\]+|daily|weekly|monthly|yearly)$/im.test(data.recurrence)) {
308
308
  data.recurrence = '!wrong rrule format!';
309
309
  } else {
310
310
  if (/^RRULE:/i.test(data.recurrence)) {
@@ -547,8 +547,7 @@ 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(/[^a-zA-Z0-9\-_.]/g, '');
551
- // eslint-disable-next-line security/detect-non-literal-regexp
550
+ const sanitizedKey = key.replace(/[^\w\-.]/g, '');
552
551
  description = description.replace(new RegExp(`%%${sanitizedKey}%%`, 'g'), data.customVar[`${key}`]);
553
552
  }
554
553
  }
@@ -607,10 +606,8 @@ function atcb_decorate_data_extend(data) {
607
606
  }
608
607
  if (data.customVar) {
609
608
  for (const key in data.customVar) {
610
- const sanitizedKey = key.replace(/[^a-zA-Z0-9\-_.]/g, '');
611
- // eslint-disable-next-line security/detect-non-literal-regexp
609
+ const sanitizedKey = key.replace(/[^\w\-.]/g, '');
612
610
  data.dates[`${i}`].name = data.dates[`${i}`].name.replace(new RegExp(`%%${sanitizedKey}%%`, 'g'), data.customVar[`${key}`]);
613
- // eslint-disable-next-line security/detect-non-literal-regexp
614
611
  data.dates[`${i}`].location = data.dates[`${i}`].location.replace(new RegExp(`%%${sanitizedKey}%%`, 'g'), data.customVar[`${key}`]);
615
612
  }
616
613
  }
@@ -629,7 +626,7 @@ function atcb_date_cleanup(dateTimeData) {
629
626
  }
630
627
  const endpoints = ['start', 'end'];
631
628
  endpoints.forEach(function (point) {
632
- if (!/^(\d{4}-\d{2}-\d{2}T?(?:\d{2}:\d{2}|)Z?|today(?:\+\d{1,4}|))$/i.test(dateTimeData[point + 'Date'])) {
629
+ if (!/^(?:\d{4}-\d{2}-\d{2}T?(?:\d{2}:\d{2})?Z?|today(?:\+\d{1,4})?)$/i.test(dateTimeData[point + 'Date'])) {
633
630
  dateTimeData[point + 'Date'] = 'badly-formed';
634
631
  } else {
635
632
  dateTimeData[point + 'Date'] = atcb_date_calculation(dateTimeData[point + 'Date']);
@@ -834,7 +831,7 @@ async function atcb_validate_buttonStyle(data, msgPrefix) {
834
831
  if (!availableStyles.includes(data.buttonStyle)) {
835
832
  throw new Error(msgPrefix + ' failed: provided buttonStyle invalid');
836
833
  }
837
- if (data.customCss && data.customCss !== '' && (!atcb_secure_url(data.customCss, false) || !/\.css($|\?)/.test(data.customCss))) {
834
+ if (data.customCss && data.customCss !== '' && (!atcb_secure_url(data.customCss, false) || !/\.css(?:$|\?)/.test(data.customCss))) {
838
835
  throw new Error(msgPrefix + ' failed: customCss provided, but no valid url');
839
836
  }
840
837
  if ((!data.customCss || data.customCss === '') && data.buttonStyle === 'custom') {
@@ -935,7 +932,7 @@ async function atcb_validate_attendee(data, msgPrefix, i, msgSuffix) {
935
932
  return true;
936
933
  }
937
934
  async function atcb_validate_uid(data, msgPrefix, i, msgSuffix) {
938
- if (!/^(\w|-){1,254}$/.test(data.dates[`${i}`].uid)) {
935
+ if (!/^(?:\w|-){1,254}$/.test(data.dates[`${i}`].uid)) {
939
936
  if (data.debug) {
940
937
  console.warn(msgPrefix + ': UID not valid. May only contain alpha, digits, and dashes; and be less than 255 characters. Falling back to an automated value!' + msgSuffix);
941
938
  }
@@ -1004,7 +1001,7 @@ async function atcb_validate_rrule(data, msgPrefix) {
1004
1001
  if (data.recurrence && data.recurrence !== '' && data.dates.length > 1) {
1005
1002
  throw new Error(msgPrefix + ' failed: RRULE and multi-date set at the same time');
1006
1003
  }
1007
- if (data.recurrence && data.recurrence !== '' && !/^RRULE:[\w=;,:+-/\\]+$/i.test(data.recurrence)) {
1004
+ if (data.recurrence && data.recurrence !== '' && !/^RRULE:[\w=;,:+\-/\\]+$/i.test(data.recurrence)) {
1008
1005
  throw new Error(msgPrefix + ' failed: RRULE data misspelled');
1009
1006
  }
1010
1007
  return true;
@@ -1013,22 +1010,22 @@ async function atcb_validate_rrule_simplyfied(data, msgPrefix) {
1013
1010
  if (data.recurrence_interval && (data.recurrence_interval < 1 || data.recurrence_interval % 1 !== 0)) {
1014
1011
  throw new Error(msgPrefix + ' failed: recurrence data (interval) misspelled');
1015
1012
  }
1016
- if (data.recurrence_until && data.recurrence_until !== '' && !/^(\d|-|:)+$/i.test(data.recurrence_until)) {
1013
+ if (data.recurrence_until && data.recurrence_until !== '' && !/^[\d\-:]+$/.test(data.recurrence_until)) {
1017
1014
  throw new Error(msgPrefix + ' failed: recurrence data (until) misspelled');
1018
1015
  }
1019
1016
  if (data.recurrence_count && (data.recurrence_count < 1 || data.recurrence_count % 1 !== 0)) {
1020
1017
  throw new Error(msgPrefix + ' failed: recurrence data (interval) misspelled');
1021
1018
  }
1022
- if (data.recurrence_byMonth && data.recurrence_byMonth !== '' && !/^(\d|,)+$/.test(data.recurrence_byMonth)) {
1019
+ if (data.recurrence_byMonth && data.recurrence_byMonth !== '' && !/^[\d,]+$/.test(data.recurrence_byMonth)) {
1023
1020
  throw new Error(msgPrefix + ' failed: recurrence data (byMonth) misspelled');
1024
1021
  }
1025
- if (data.recurrence_byMonthDay && data.recurrence_byMonthDay !== '' && !/^(\d|,)+$/.test(data.recurrence_byMonthDay)) {
1022
+ if (data.recurrence_byMonthDay && data.recurrence_byMonthDay !== '' && !/^[\d,]+$/.test(data.recurrence_byMonthDay)) {
1026
1023
  throw new Error(msgPrefix + ' failed: recurrence data (byMonthDay) misspelled');
1027
1024
  }
1028
- if (data.recurrence_byDay && data.recurrence_byDay !== '' && !/^(\d|-|MO|TU|WE|TH|FR|SA|SU|,)+$/im.test(data.recurrence_byDay)) {
1025
+ if (data.recurrence_byDay && data.recurrence_byDay !== '' && !/^(?:[\d,-]|MO|TU|WE|TH|FR|SA|SU)+$/im.test(data.recurrence_byDay)) {
1029
1026
  throw new Error(msgPrefix + ' failed: recurrence data (byDay) misspelled');
1030
1027
  }
1031
- if (data.recurrence_weekstart && data.recurrence_weekstart !== '' && !/^(MO|TU|WE|TH|FR|SA|SU)$/im.test(data.recurrence_weekstart)) {
1028
+ if (data.recurrence_weekstart && data.recurrence_weekstart !== '' && !/^(?:MO|TU|WE|TH|FR|SA|SU)$/im.test(data.recurrence_weekstart)) {
1032
1029
  throw new Error(msgPrefix + ' failed: recurrence data (weekstart) misspelled');
1033
1030
  }
1034
1031
  return true;
@@ -2260,7 +2257,8 @@ function atcb_create_atcbl(host, atList = true, returnEl = false, licenseNoteOnl
2260
2257
  }
2261
2258
  } else {
2262
2259
  atcbL.innerHTML = 'Using the <a href="https://add-to-calendar-pro.com" target="_blank" rel="noopener referrer">Add to Calendar Button</a>, licensed under the Elastic License 2.0 (ELv2).';
2263
- atcbL.setAttribute('style', 'none !important');
2260
+ atcbL.setAttribute('style', 'display:none !important');
2261
+ atcbL.classList.add('atcb-attribution');
2264
2262
  host.append(atcbL);
2265
2263
  }
2266
2264
  if (returnEl) return null;
@@ -2937,7 +2935,7 @@ function atcb_subscribe_ical(data, fileUrl) {
2937
2935
  function atcb_subscribe_google(data, fileUrl) {
2938
2936
  const baseUrl = 'https://calendar.google.com/calendar/r?cid=';
2939
2937
  const baseUrlApp = 'calendar.google.com/calendar?cid=';
2940
- const fileUrlRegex = /^(https?:\/\/|webcal:\/\/|\/\/)calendar\.google\.com\//;
2938
+ const fileUrlRegex = /^(?:https?:\/\/|webcal:\/\/|\/\/)calendar\.google\.com\//;
2941
2939
  const newFileUrl = (function () {
2942
2940
  if (fileUrlRegex.test(fileUrl)) {
2943
2941
  return fileUrl.replace(/^(.)*\?cid=/, '');
@@ -2972,7 +2970,7 @@ function atcb_generate_google(data, date, subEvent = 'all') {
2972
2970
  urlParts.push('https://calendar.google.com/calendar/render?action=TEMPLATE');
2973
2971
  const formattedDate = atcb_generate_time(date, 'clean', 'google');
2974
2972
  urlParts.push('dates=' + encodeURIComponent(formattedDate.start) + '%2F' + encodeURIComponent(formattedDate.end));
2975
- if (date.timeZone && date.timeZone !== '' && !/(GMT[+|-]\d{1,2}|Etc\/U|Etc\/Zulu|CET|CST6CDT|EET|EST|EST5EDT|MET|MST|MST7MDT|PST8PDT|WET)/i.test(date.timeZone) && !formattedDate.allday) {
2973
+ if (date.timeZone && date.timeZone !== '' && !/GMT[+|-]\d{1,2}|Etc\/U|Etc\/Zulu|CET|CST6CDT|EET|EST|MET|MST|PST8PDT|WET/i.test(date.timeZone) && !formattedDate.allday) {
2976
2974
  urlParts.push('ctz=' + date.timeZone);
2977
2975
  }
2978
2976
  if (date.name && date.name !== '') {
@@ -3123,7 +3121,6 @@ function atcb_open_cal_url(data, type, url, subscribe = false, subEvent = null,
3123
3121
  return;
3124
3122
  }
3125
3123
  }
3126
- // eslint-disable-next-line security/detect-non-literal-fs-filename
3127
3124
  const newTab = window.open(url, target);
3128
3125
  if (newTab) {
3129
3126
  newTab.focus();
@@ -3345,7 +3342,7 @@ function atcb_generate_time(data, style = 'delimiters', targetCal = 'general', a
3345
3342
  }
3346
3343
  return durationHours + ':' + ('0' + durationMinutes).slice(-2);
3347
3344
  })();
3348
- if (targetCal == 'ical' || (targetCal == 'google' && !/(GMT[+|-]\d{1,2}|Etc\/U|Etc\/Zulu|CET|CST6CDT|EET|EST|EST5EDT|MET|MST|MST7MDT|PST8PDT|WET)/i.test(data.timeZone))) {
3345
+ if (targetCal == 'ical' || (targetCal == 'google' && !/GMT[+|-]\d{1,2}|Etc\/U|Etc\/Zulu|CET|CST6CDT|EET|EST|MET|MST|PST8PDT|WET/i.test(data.timeZone))) {
3349
3346
  return {
3350
3347
  start: atcb_format_datetime(newStartDate, 'clean', true, true),
3351
3348
  end: atcb_format_datetime(newEndDate, 'clean', true, true),
@@ -3667,7 +3664,7 @@ function atcb_secure_url(url, throwError = true) {
3667
3664
  }
3668
3665
  }
3669
3666
  function atcb_validEmail(email) {
3670
- if (!/^.{0,70}@.{1,30}\.[a-zA-Z]{2,9}$/.test(email)) {
3667
+ if (!/^.{0,70}@.{1,30}\.[a-z]{2,9}$/i.test(email)) {
3671
3668
  return false;
3672
3669
  }
3673
3670
  return true;
@@ -3685,9 +3682,9 @@ function atcb_rewrite_html_elements(content, clear = false, iCalBreaks = false)
3685
3682
  content = content.replace(/\{url\}(.+?)\{\/url\}/gi, (match, p1) => {
3686
3683
  return p1.split('|')[0];
3687
3684
  });
3688
- content = content.replace(/\[(|\/)(hr|p|b|strong|u|i|em|li|ul|ol|h\d)\]/gi, '');
3689
- content = content.replace(/\{(|\/)(hr|p|b|strong|u|i|em|li|ul|ol|h\d)\}/gi, '');
3690
- content = content.replace(/&[#a-zA-Z0-9]{1,9};/gi, '');
3685
+ content = content.replace(/\[\/?(hr|[pbui]|strong|em|li|ul|ol|h\d)\]/gi, '');
3686
+ content = content.replace(/\{\/?(hr|[pbui]|strong|em|li|ul|ol|h\d)\}/gi, '');
3687
+ content = content.replace(/&[#a-z0-9]{1,9};/gi, '');
3691
3688
  } else {
3692
3689
  content = content.replace(/\[url\]((?:(?!\[\/url\]).)*)\[\/url\]/gi, function (match, p1) {
3693
3690
  return atcb_parse_url_code(p1);
@@ -3695,8 +3692,8 @@ function atcb_rewrite_html_elements(content, clear = false, iCalBreaks = false)
3695
3692
  content = content.replace(/\{url\}((?:(?!\[\/url\]).)*)\{\/url\}/gi, function (match, p1) {
3696
3693
  return atcb_parse_url_code(p1);
3697
3694
  });
3698
- content = content.replace(/\[(\/|)(br|hr|p|b|strong|u|i|em|li|ul|ol|h\d)(\s?\/?)\]/gi, '<$1$2$3>');
3699
- content = content.replace(/\{(\/|)(br|hr|p|b|strong|u|i|em|li|ul|ol|h\d)(\s?\/?)\}/gi, '<$1$2$3>');
3695
+ content = content.replace(/\[(\/)?(br|hr|[pbui]|strong|em|li|ul|ol|h\d)(\s?\/?)\]/gi, '<$1$2$3>');
3696
+ content = content.replace(/\{(\/)?(br|hr|[pbui]|strong|em|li|ul|ol|h\d)(\s?\/?)\}/gi, '<$1$2$3>');
3700
3697
  }
3701
3698
  return content;
3702
3699
  }
@@ -4906,7 +4903,7 @@ if (atcbIsBrowser()) {
4906
4903
  this.data.identifier = this.identifier;
4907
4904
  } else {
4908
4905
  if (this.data.identifier && this.data.identifier !== '') {
4909
- if (!/^[\w\-_]+$/.test(this.data.identifier)) {
4906
+ if (!/^[\w-]+$/.test(this.data.identifier)) {
4910
4907
  this.data.identifier = '';
4911
4908
  if (this.debug) {
4912
4909
  let prefix = 'Add to Calendar Button';
@@ -5104,7 +5101,7 @@ async function atcb_load_css(host, rootObj = null, data) {
5104
5101
  const cssGlobalContent = document.createElement('style');
5105
5102
  cssGlobalContent.id = 'atcb-global-style';
5106
5103
  const scrollBarWidth = window.innerWidth - document.documentElement.clientWidth;
5107
- cssGlobalContent.innerText = '.atcb-modal-no-scroll{overflow-y:hidden !important;-webkit-overflow-scrolling:touch;} body.atcb-modal-no-scroll{padding-right:' + scrollBarWidth + 'px;}';
5104
+ cssGlobalContent.innerText = '.atcb-modal-no-scroll{overflow-y:hidden !important;-webkit-overflow-scrolling:touch;} body.atcb-modal-no-scroll{padding-right:' + scrollBarWidth + 'px;}.atcb-attribution{display:none;}';
5108
5105
  if (nonceVal) {
5109
5106
  cssGlobalContent.setAttribute('nonce', nonceVal);
5110
5107
  }
@@ -5253,7 +5250,7 @@ async function atcb_action(inputData, triggerElement, keyboardTrigger = false) {
5253
5250
  if (triggerElement.id && triggerElement.id !== '') {
5254
5251
  data.identifier = triggerElement.id;
5255
5252
  } else {
5256
- if (data.identifier && data.identifier != '' && /^[\w\-_]+$/.test(data.identifier)) {
5253
+ if (data.identifier && data.identifier != '' && /^[\w-]+$/.test(data.identifier)) {
5257
5254
  data.identifier = 'atcb-btn-' + data.identifier;
5258
5255
  } else {
5259
5256
  data.identifier = 'atcb-btn-custom';
@@ -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.6.20
9
+ * Version: 2.6.21
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.6.20';
16
+ const atcbVersion = '2.6.21';
17
17
  const atcbCssTemplate = {
18
18
  if (typeof window === 'undefined') {
19
19
  return false;
@@ -56,7 +56,7 @@ const atcbIsAndroid = atcbIsBrowser()
56
56
  };*/
57
57
  const atcbIsSafari = atcbIsBrowser()
58
58
  ? () => {
59
- if (/^((?!chrome|android|crios|fxios).)*safari/i.test(navigator.userAgent)) {
59
+ if (/^(?:(?!chrome|android|crios|fxios).)*safari/i.test(navigator.userAgent)) {
60
60
  return true;
61
61
  } else {
62
62
  return false;
@@ -74,7 +74,7 @@ const atcbIsMobile = () => {
74
74
  };
75
75
  const atcbIsWebView = atcbIsBrowser()
76
76
  ? () => {
77
- if (/(; ?wv|(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari))/i.test(navigator.userAgent)) {
77
+ if (/; ?wv|(?:iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/i.test(navigator.userAgent)) {
78
78
  return true;
79
79
  } else {
80
80
  return false;
@@ -85,7 +85,7 @@ const atcbIsWebView = atcbIsBrowser()
85
85
  };
86
86
  const atcbIsProblematicWebView = atcbIsBrowser()
87
87
  ? () => {
88
- if (/(Instagram)/i.test(navigator.userAgent)) {
88
+ if (/Instagram/i.test(navigator.userAgent)) {
89
89
  return true;
90
90
  } else {
91
91
  return false;
@@ -304,7 +304,7 @@ function atcb_decorate_data_timezone(tz = null) {
304
304
  function atcb_decorate_data_rrule(data) {
305
305
  if (data.recurrence && data.recurrence !== '') {
306
306
  data.recurrence = data.recurrence.replace(/\s+/g, '').toUpperCase();
307
- if (!/^(RRULE:[\w=;,:+-/\\]+|daily|weekly|monthly|yearly)$/im.test(data.recurrence)) {
307
+ if (!/^(?:RRULE:[\w=;,:+\-/\\]+|daily|weekly|monthly|yearly)$/im.test(data.recurrence)) {
308
308
  data.recurrence = '!wrong rrule format!';
309
309
  } else {
310
310
  if (/^RRULE:/i.test(data.recurrence)) {
@@ -547,8 +547,7 @@ 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(/[^a-zA-Z0-9\-_.]/g, '');
551
- // eslint-disable-next-line security/detect-non-literal-regexp
550
+ const sanitizedKey = key.replace(/[^\w\-.]/g, '');
552
551
  description = description.replace(new RegExp(`%%${sanitizedKey}%%`, 'g'), data.customVar[`${key}`]);
553
552
  }
554
553
  }
@@ -607,10 +606,8 @@ function atcb_decorate_data_extend(data) {
607
606
  }
608
607
  if (data.customVar) {
609
608
  for (const key in data.customVar) {
610
- const sanitizedKey = key.replace(/[^a-zA-Z0-9\-_.]/g, '');
611
- // eslint-disable-next-line security/detect-non-literal-regexp
609
+ const sanitizedKey = key.replace(/[^\w\-.]/g, '');
612
610
  data.dates[`${i}`].name = data.dates[`${i}`].name.replace(new RegExp(`%%${sanitizedKey}%%`, 'g'), data.customVar[`${key}`]);
613
- // eslint-disable-next-line security/detect-non-literal-regexp
614
611
  data.dates[`${i}`].location = data.dates[`${i}`].location.replace(new RegExp(`%%${sanitizedKey}%%`, 'g'), data.customVar[`${key}`]);
615
612
  }
616
613
  }
@@ -629,7 +626,7 @@ function atcb_date_cleanup(dateTimeData) {
629
626
  }
630
627
  const endpoints = ['start', 'end'];
631
628
  endpoints.forEach(function (point) {
632
- if (!/^(\d{4}-\d{2}-\d{2}T?(?:\d{2}:\d{2}|)Z?|today(?:\+\d{1,4}|))$/i.test(dateTimeData[point + 'Date'])) {
629
+ if (!/^(?:\d{4}-\d{2}-\d{2}T?(?:\d{2}:\d{2})?Z?|today(?:\+\d{1,4})?)$/i.test(dateTimeData[point + 'Date'])) {
633
630
  dateTimeData[point + 'Date'] = 'badly-formed';
634
631
  } else {
635
632
  dateTimeData[point + 'Date'] = atcb_date_calculation(dateTimeData[point + 'Date']);
@@ -834,7 +831,7 @@ async function atcb_validate_buttonStyle(data, msgPrefix) {
834
831
  if (!availableStyles.includes(data.buttonStyle)) {
835
832
  throw new Error(msgPrefix + ' failed: provided buttonStyle invalid');
836
833
  }
837
- if (data.customCss && data.customCss !== '' && (!atcb_secure_url(data.customCss, false) || !/\.css($|\?)/.test(data.customCss))) {
834
+ if (data.customCss && data.customCss !== '' && (!atcb_secure_url(data.customCss, false) || !/\.css(?:$|\?)/.test(data.customCss))) {
838
835
  throw new Error(msgPrefix + ' failed: customCss provided, but no valid url');
839
836
  }
840
837
  if ((!data.customCss || data.customCss === '') && data.buttonStyle === 'custom') {
@@ -935,7 +932,7 @@ async function atcb_validate_attendee(data, msgPrefix, i, msgSuffix) {
935
932
  return true;
936
933
  }
937
934
  async function atcb_validate_uid(data, msgPrefix, i, msgSuffix) {
938
- if (!/^(\w|-){1,254}$/.test(data.dates[`${i}`].uid)) {
935
+ if (!/^(?:\w|-){1,254}$/.test(data.dates[`${i}`].uid)) {
939
936
  if (data.debug) {
940
937
  console.warn(msgPrefix + ': UID not valid. May only contain alpha, digits, and dashes; and be less than 255 characters. Falling back to an automated value!' + msgSuffix);
941
938
  }
@@ -1004,7 +1001,7 @@ async function atcb_validate_rrule(data, msgPrefix) {
1004
1001
  if (data.recurrence && data.recurrence !== '' && data.dates.length > 1) {
1005
1002
  throw new Error(msgPrefix + ' failed: RRULE and multi-date set at the same time');
1006
1003
  }
1007
- if (data.recurrence && data.recurrence !== '' && !/^RRULE:[\w=;,:+-/\\]+$/i.test(data.recurrence)) {
1004
+ if (data.recurrence && data.recurrence !== '' && !/^RRULE:[\w=;,:+\-/\\]+$/i.test(data.recurrence)) {
1008
1005
  throw new Error(msgPrefix + ' failed: RRULE data misspelled');
1009
1006
  }
1010
1007
  return true;
@@ -1013,22 +1010,22 @@ async function atcb_validate_rrule_simplyfied(data, msgPrefix) {
1013
1010
  if (data.recurrence_interval && (data.recurrence_interval < 1 || data.recurrence_interval % 1 !== 0)) {
1014
1011
  throw new Error(msgPrefix + ' failed: recurrence data (interval) misspelled');
1015
1012
  }
1016
- if (data.recurrence_until && data.recurrence_until !== '' && !/^(\d|-|:)+$/i.test(data.recurrence_until)) {
1013
+ if (data.recurrence_until && data.recurrence_until !== '' && !/^[\d\-:]+$/.test(data.recurrence_until)) {
1017
1014
  throw new Error(msgPrefix + ' failed: recurrence data (until) misspelled');
1018
1015
  }
1019
1016
  if (data.recurrence_count && (data.recurrence_count < 1 || data.recurrence_count % 1 !== 0)) {
1020
1017
  throw new Error(msgPrefix + ' failed: recurrence data (interval) misspelled');
1021
1018
  }
1022
- if (data.recurrence_byMonth && data.recurrence_byMonth !== '' && !/^(\d|,)+$/.test(data.recurrence_byMonth)) {
1019
+ if (data.recurrence_byMonth && data.recurrence_byMonth !== '' && !/^[\d,]+$/.test(data.recurrence_byMonth)) {
1023
1020
  throw new Error(msgPrefix + ' failed: recurrence data (byMonth) misspelled');
1024
1021
  }
1025
- if (data.recurrence_byMonthDay && data.recurrence_byMonthDay !== '' && !/^(\d|,)+$/.test(data.recurrence_byMonthDay)) {
1022
+ if (data.recurrence_byMonthDay && data.recurrence_byMonthDay !== '' && !/^[\d,]+$/.test(data.recurrence_byMonthDay)) {
1026
1023
  throw new Error(msgPrefix + ' failed: recurrence data (byMonthDay) misspelled');
1027
1024
  }
1028
- if (data.recurrence_byDay && data.recurrence_byDay !== '' && !/^(\d|-|MO|TU|WE|TH|FR|SA|SU|,)+$/im.test(data.recurrence_byDay)) {
1025
+ if (data.recurrence_byDay && data.recurrence_byDay !== '' && !/^(?:[\d,-]|MO|TU|WE|TH|FR|SA|SU)+$/im.test(data.recurrence_byDay)) {
1029
1026
  throw new Error(msgPrefix + ' failed: recurrence data (byDay) misspelled');
1030
1027
  }
1031
- if (data.recurrence_weekstart && data.recurrence_weekstart !== '' && !/^(MO|TU|WE|TH|FR|SA|SU)$/im.test(data.recurrence_weekstart)) {
1028
+ if (data.recurrence_weekstart && data.recurrence_weekstart !== '' && !/^(?:MO|TU|WE|TH|FR|SA|SU)$/im.test(data.recurrence_weekstart)) {
1032
1029
  throw new Error(msgPrefix + ' failed: recurrence data (weekstart) misspelled');
1033
1030
  }
1034
1031
  return true;
@@ -1539,7 +1536,8 @@ function atcb_create_atcbl(host, atList = true, returnEl = false, licenseNoteOnl
1539
1536
  }
1540
1537
  } else {
1541
1538
  atcbL.innerHTML = 'Using the <a href="https://add-to-calendar-pro.com" target="_blank" rel="noopener referrer">Add to Calendar Button</a>, licensed under the Elastic License 2.0 (ELv2).';
1542
- atcbL.setAttribute('style', 'none !important');
1539
+ atcbL.setAttribute('style', 'display:none !important');
1540
+ atcbL.classList.add('atcb-attribution');
1543
1541
  host.append(atcbL);
1544
1542
  }
1545
1543
  if (returnEl) return null;
@@ -2216,7 +2214,7 @@ function atcb_subscribe_ical(data, fileUrl) {
2216
2214
  function atcb_subscribe_google(data, fileUrl) {
2217
2215
  const baseUrl = 'https://calendar.google.com/calendar/r?cid=';
2218
2216
  const baseUrlApp = 'calendar.google.com/calendar?cid=';
2219
- const fileUrlRegex = /^(https?:\/\/|webcal:\/\/|\/\/)calendar\.google\.com\//;
2217
+ const fileUrlRegex = /^(?:https?:\/\/|webcal:\/\/|\/\/)calendar\.google\.com\//;
2220
2218
  const newFileUrl = (function () {
2221
2219
  if (fileUrlRegex.test(fileUrl)) {
2222
2220
  return fileUrl.replace(/^(.)*\?cid=/, '');
@@ -2251,7 +2249,7 @@ function atcb_generate_google(data, date, subEvent = 'all') {
2251
2249
  urlParts.push('https://calendar.google.com/calendar/render?action=TEMPLATE');
2252
2250
  const formattedDate = atcb_generate_time(date, 'clean', 'google');
2253
2251
  urlParts.push('dates=' + encodeURIComponent(formattedDate.start) + '%2F' + encodeURIComponent(formattedDate.end));
2254
- if (date.timeZone && date.timeZone !== '' && !/(GMT[+|-]\d{1,2}|Etc\/U|Etc\/Zulu|CET|CST6CDT|EET|EST|EST5EDT|MET|MST|MST7MDT|PST8PDT|WET)/i.test(date.timeZone) && !formattedDate.allday) {
2252
+ if (date.timeZone && date.timeZone !== '' && !/GMT[+|-]\d{1,2}|Etc\/U|Etc\/Zulu|CET|CST6CDT|EET|EST|MET|MST|PST8PDT|WET/i.test(date.timeZone) && !formattedDate.allday) {
2255
2253
  urlParts.push('ctz=' + date.timeZone);
2256
2254
  }
2257
2255
  if (date.name && date.name !== '') {
@@ -2402,7 +2400,6 @@ function atcb_open_cal_url(data, type, url, subscribe = false, subEvent = null,
2402
2400
  return;
2403
2401
  }
2404
2402
  }
2405
- // eslint-disable-next-line security/detect-non-literal-fs-filename
2406
2403
  const newTab = window.open(url, target);
2407
2404
  if (newTab) {
2408
2405
  newTab.focus();
@@ -2624,7 +2621,7 @@ function atcb_generate_time(data, style = 'delimiters', targetCal = 'general', a
2624
2621
  }
2625
2622
  return durationHours + ':' + ('0' + durationMinutes).slice(-2);
2626
2623
  })();
2627
- if (targetCal == 'ical' || (targetCal == 'google' && !/(GMT[+|-]\d{1,2}|Etc\/U|Etc\/Zulu|CET|CST6CDT|EET|EST|EST5EDT|MET|MST|MST7MDT|PST8PDT|WET)/i.test(data.timeZone))) {
2624
+ if (targetCal == 'ical' || (targetCal == 'google' && !/GMT[+|-]\d{1,2}|Etc\/U|Etc\/Zulu|CET|CST6CDT|EET|EST|MET|MST|PST8PDT|WET/i.test(data.timeZone))) {
2628
2625
  return {
2629
2626
  start: atcb_format_datetime(newStartDate, 'clean', true, true),
2630
2627
  end: atcb_format_datetime(newEndDate, 'clean', true, true),
@@ -2946,7 +2943,7 @@ function atcb_secure_url(url, throwError = true) {
2946
2943
  }
2947
2944
  }
2948
2945
  function atcb_validEmail(email) {
2949
- if (!/^.{0,70}@.{1,30}\.[a-zA-Z]{2,9}$/.test(email)) {
2946
+ if (!/^.{0,70}@.{1,30}\.[a-z]{2,9}$/i.test(email)) {
2950
2947
  return false;
2951
2948
  }
2952
2949
  return true;
@@ -2964,9 +2961,9 @@ function atcb_rewrite_html_elements(content, clear = false, iCalBreaks = false)
2964
2961
  content = content.replace(/\{url\}(.+?)\{\/url\}/gi, (match, p1) => {
2965
2962
  return p1.split('|')[0];
2966
2963
  });
2967
- content = content.replace(/\[(|\/)(hr|p|b|strong|u|i|em|li|ul|ol|h\d)\]/gi, '');
2968
- content = content.replace(/\{(|\/)(hr|p|b|strong|u|i|em|li|ul|ol|h\d)\}/gi, '');
2969
- content = content.replace(/&[#a-zA-Z0-9]{1,9};/gi, '');
2964
+ content = content.replace(/\[\/?(hr|[pbui]|strong|em|li|ul|ol|h\d)\]/gi, '');
2965
+ content = content.replace(/\{\/?(hr|[pbui]|strong|em|li|ul|ol|h\d)\}/gi, '');
2966
+ content = content.replace(/&[#a-z0-9]{1,9};/gi, '');
2970
2967
  } else {
2971
2968
  content = content.replace(/\[url\]((?:(?!\[\/url\]).)*)\[\/url\]/gi, function (match, p1) {
2972
2969
  return atcb_parse_url_code(p1);
@@ -2974,8 +2971,8 @@ function atcb_rewrite_html_elements(content, clear = false, iCalBreaks = false)
2974
2971
  content = content.replace(/\{url\}((?:(?!\[\/url\]).)*)\{\/url\}/gi, function (match, p1) {
2975
2972
  return atcb_parse_url_code(p1);
2976
2973
  });
2977
- content = content.replace(/\[(\/|)(br|hr|p|b|strong|u|i|em|li|ul|ol|h\d)(\s?\/?)\]/gi, '<$1$2$3>');
2978
- content = content.replace(/\{(\/|)(br|hr|p|b|strong|u|i|em|li|ul|ol|h\d)(\s?\/?)\}/gi, '<$1$2$3>');
2974
+ content = content.replace(/\[(\/)?(br|hr|[pbui]|strong|em|li|ul|ol|h\d)(\s?\/?)\]/gi, '<$1$2$3>');
2975
+ content = content.replace(/\{(\/)?(br|hr|[pbui]|strong|em|li|ul|ol|h\d)(\s?\/?)\}/gi, '<$1$2$3>');
2979
2976
  }
2980
2977
  return content;
2981
2978
  }
@@ -4185,7 +4182,7 @@ if (atcbIsBrowser()) {
4185
4182
  this.data.identifier = this.identifier;
4186
4183
  } else {
4187
4184
  if (this.data.identifier && this.data.identifier !== '') {
4188
- if (!/^[\w\-_]+$/.test(this.data.identifier)) {
4185
+ if (!/^[\w-]+$/.test(this.data.identifier)) {
4189
4186
  this.data.identifier = '';
4190
4187
  if (this.debug) {
4191
4188
  let prefix = 'Add to Calendar Button';
@@ -4383,7 +4380,7 @@ async function atcb_load_css(host, rootObj = null, data) {
4383
4380
  const cssGlobalContent = document.createElement('style');
4384
4381
  cssGlobalContent.id = 'atcb-global-style';
4385
4382
  const scrollBarWidth = window.innerWidth - document.documentElement.clientWidth;
4386
- cssGlobalContent.innerText = '.atcb-modal-no-scroll{overflow-y:hidden !important;-webkit-overflow-scrolling:touch;} body.atcb-modal-no-scroll{padding-right:' + scrollBarWidth + 'px;}';
4383
+ cssGlobalContent.innerText = '.atcb-modal-no-scroll{overflow-y:hidden !important;-webkit-overflow-scrolling:touch;} body.atcb-modal-no-scroll{padding-right:' + scrollBarWidth + 'px;}.atcb-attribution{display:none;}';
4387
4384
  if (nonceVal) {
4388
4385
  cssGlobalContent.setAttribute('nonce', nonceVal);
4389
4386
  }
@@ -4532,7 +4529,7 @@ async function atcb_action(inputData, triggerElement, keyboardTrigger = false) {
4532
4529
  if (triggerElement.id && triggerElement.id !== '') {
4533
4530
  data.identifier = triggerElement.id;
4534
4531
  } else {
4535
- if (data.identifier && data.identifier != '' && /^[\w\-_]+$/.test(data.identifier)) {
4532
+ if (data.identifier && data.identifier != '' && /^[\w-]+$/.test(data.identifier)) {
4536
4533
  data.identifier = 'atcb-btn-' + data.identifier;
4537
4534
  } else {
4538
4535
  data.identifier = 'atcb-btn-custom';