@fullcalendar/icalendar 5.7.2 → 5.10.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.
package/main.cjs.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- FullCalendar v5.7.2
2
+ FullCalendar v5.10.1
3
3
  Docs & License: https://fullcalendar.io/
4
4
  (c) 2021 Adam Shaw
5
5
  */
@@ -8,8 +8,8 @@ Docs & License: https://fullcalendar.io/
8
8
  Object.defineProperty(exports, '__esModule', { value: true });
9
9
 
10
10
  var tslib = require('tslib');
11
- var ICAL = require('ical.js');
12
11
  var common = require('@fullcalendar/common');
12
+ var ICAL = require('ical.js');
13
13
 
14
14
  function _interopNamespace(e) {
15
15
  if (e && e.__esModule) return e;
@@ -33,6 +33,113 @@ function _interopNamespace(e) {
33
33
 
34
34
  var ICAL__namespace = /*#__PURE__*/_interopNamespace(ICAL);
35
35
 
36
+ /* eslint-disable */
37
+ var IcalExpander = /** @class */ (function () {
38
+ function IcalExpander(opts) {
39
+ this.maxIterations = opts.maxIterations != null ? opts.maxIterations : 1000;
40
+ this.skipInvalidDates = opts.skipInvalidDates != null ? opts.skipInvalidDates : false;
41
+ this.jCalData = ICAL__namespace.parse(opts.ics);
42
+ this.component = new ICAL__namespace.Component(this.jCalData);
43
+ this.events = this.component.getAllSubcomponents('vevent').map(function (vevent) { return new ICAL__namespace.Event(vevent); });
44
+ if (this.skipInvalidDates) {
45
+ this.events = this.events.filter(function (evt) {
46
+ try {
47
+ evt.startDate.toJSDate();
48
+ evt.endDate.toJSDate();
49
+ return true;
50
+ }
51
+ catch (err) {
52
+ // skipping events with invalid time
53
+ return false;
54
+ }
55
+ });
56
+ }
57
+ }
58
+ IcalExpander.prototype.between = function (after, before) {
59
+ var _this = this;
60
+ function isEventWithinRange(startTime, endTime) {
61
+ return (!after || endTime >= after.getTime()) &&
62
+ (!before || startTime <= before.getTime());
63
+ }
64
+ function getTimes(eventOrOccurrence) {
65
+ var startTime = eventOrOccurrence.startDate.toJSDate().getTime();
66
+ var endTime = eventOrOccurrence.endDate.toJSDate().getTime();
67
+ // If it is an all day event, the end date is set to 00:00 of the next day
68
+ // So we need to make it be 23:59:59 to compare correctly with the given range
69
+ if (eventOrOccurrence.endDate.isDate && (endTime > startTime)) {
70
+ endTime -= 1;
71
+ }
72
+ return { startTime: startTime, endTime: endTime };
73
+ }
74
+ var exceptions = [];
75
+ this.events.forEach(function (event) {
76
+ if (event.isRecurrenceException())
77
+ exceptions.push(event);
78
+ });
79
+ var ret = {
80
+ events: [],
81
+ occurrences: [],
82
+ };
83
+ this.events.filter(function (e) { return !e.isRecurrenceException(); }).forEach(function (event) {
84
+ var exdates = [];
85
+ event.component.getAllProperties('exdate').forEach(function (exdateProp) {
86
+ var exdate = exdateProp.getFirstValue();
87
+ exdates.push(exdate.toJSDate().getTime());
88
+ });
89
+ // Recurring event is handled differently
90
+ if (event.isRecurring()) {
91
+ var iterator = event.iterator();
92
+ var next = void 0;
93
+ var i = 0;
94
+ var _loop_1 = function () {
95
+ i += 1;
96
+ next = iterator.next();
97
+ if (next) {
98
+ var occurrence_1 = event.getOccurrenceDetails(next);
99
+ var _b = getTimes(occurrence_1), startTime_1 = _b.startTime, endTime_1 = _b.endTime;
100
+ var isOccurrenceExcluded = exdates.indexOf(startTime_1) !== -1;
101
+ // TODO check that within same day?
102
+ var exception = exceptions.find(function (ex) { return ex.uid === event.uid && ex.recurrenceId.toJSDate().getTime() === occurrence_1.startDate.toJSDate().getTime(); });
103
+ // We have passed the max date, stop
104
+ if (before && startTime_1 > before.getTime())
105
+ return "break";
106
+ // Check that we are within our range
107
+ if (isEventWithinRange(startTime_1, endTime_1)) {
108
+ if (exception) {
109
+ ret.events.push(exception);
110
+ }
111
+ else if (!isOccurrenceExcluded) {
112
+ ret.occurrences.push(occurrence_1);
113
+ }
114
+ }
115
+ }
116
+ };
117
+ do {
118
+ var state_1 = _loop_1();
119
+ if (state_1 === "break")
120
+ break;
121
+ } while (next && (!_this.maxIterations || i < _this.maxIterations));
122
+ return;
123
+ }
124
+ // Non-recurring event:
125
+ var _a = getTimes(event), startTime = _a.startTime, endTime = _a.endTime;
126
+ if (isEventWithinRange(startTime, endTime))
127
+ ret.events.push(event);
128
+ });
129
+ return ret;
130
+ };
131
+ IcalExpander.prototype.before = function (before) {
132
+ return this.between(undefined, before);
133
+ };
134
+ IcalExpander.prototype.after = function (after) {
135
+ return this.between(after);
136
+ };
137
+ IcalExpander.prototype.all = function () {
138
+ return this.between();
139
+ };
140
+ return IcalExpander;
141
+ }());
142
+
36
143
  var eventSourceDef = {
37
144
  parseMeta: function (refined) {
38
145
  if (refined.url && refined.format === 'ics') {
@@ -46,12 +153,12 @@ var eventSourceDef = {
46
153
  fetch: function (arg, onSuccess, onFailure) {
47
154
  var meta = arg.eventSource.meta;
48
155
  var internalState = meta.internalState;
49
- function handleICalEvents(errorMessage, iCalEvents, xhr) {
156
+ function handleICalEvents(errorMessage, iCalExpander, xhr) {
50
157
  if (errorMessage) {
51
158
  onFailure({ message: errorMessage, xhr: xhr });
52
159
  }
53
160
  else {
54
- onSuccess({ rawEvents: expandICalEvents(iCalEvents, arg.range), xhr: xhr });
161
+ onSuccess({ rawEvents: expandICalEvents(iCalExpander, arg.range), xhr: xhr });
55
162
  }
56
163
  }
57
164
  /*
@@ -63,23 +170,26 @@ var eventSourceDef = {
63
170
  completed: false,
64
171
  callbacks: [handleICalEvents],
65
172
  errorMessage: '',
66
- iCalEvents: [],
173
+ iCalExpander: null,
67
174
  xhr: null,
68
175
  };
69
176
  requestICal(meta.url, function (rawFeed, xhr) {
70
- var iCalEvents = parseICalFeed(rawFeed);
177
+ var iCalExpander = new IcalExpander({
178
+ ics: rawFeed,
179
+ skipInvalidDates: true,
180
+ });
71
181
  for (var _i = 0, _a = internalState.callbacks; _i < _a.length; _i++) {
72
182
  var callback = _a[_i];
73
- callback('', iCalEvents, xhr);
183
+ callback('', iCalExpander, xhr);
74
184
  }
75
185
  internalState.completed = true;
76
186
  internalState.callbacks = [];
77
- internalState.iCalEvents = iCalEvents;
187
+ internalState.iCalExpander = iCalExpander;
78
188
  internalState.xhr = xhr;
79
189
  }, function (errorMessage, xhr) {
80
190
  for (var _i = 0, _a = internalState.callbacks; _i < _a.length; _i++) {
81
191
  var callback = _a[_i];
82
- callback(errorMessage, [], xhr);
192
+ callback(errorMessage, null, xhr);
83
193
  }
84
194
  internalState.completed = true;
85
195
  internalState.callbacks = [];
@@ -91,7 +201,7 @@ var eventSourceDef = {
91
201
  internalState.callbacks.push(handleICalEvents);
92
202
  }
93
203
  else {
94
- handleICalEvents(internalState.errorMessage, internalState.iCalEvents, internalState.xhr);
204
+ handleICalEvents(internalState.errorMessage, internalState.iCalExpander, internalState.xhr);
95
205
  }
96
206
  },
97
207
  };
@@ -109,80 +219,31 @@ function requestICal(url, successCallback, failureCallback) {
109
219
  xhr.onerror = function () { return failureCallback('Request failed', xhr); };
110
220
  xhr.send(null);
111
221
  }
112
- function parseICalFeed(feedStr) {
113
- var components = null;
114
- try {
115
- var feed = ICAL__namespace.parse(feedStr);
116
- var rootComponent = new ICAL__namespace.Component(feed);
117
- components = rootComponent.getAllSubcomponents('vevent');
118
- }
119
- catch (error) {
120
- console.warn("Error parsing feed: " + error);
121
- return [];
122
- }
123
- var iCalEvents = [];
124
- for (var _i = 0, components_1 = components; _i < components_1.length; _i++) {
125
- var component = components_1[_i];
126
- try {
127
- var iCalEvent = new ICAL__namespace.Event(component);
128
- if (iCalEvent.startDate) { // is an accessor method. if throws an error, is a bad event
129
- iCalEvents.push(iCalEvent);
130
- }
131
- }
132
- catch (error) {
133
- console.warn("Unable to process item in calendar: " + error);
134
- }
135
- }
136
- return iCalEvents;
137
- }
138
- function expandICalEvents(iCalEvents, range) {
139
- var eventInputs = [];
140
- for (var _i = 0, iCalEvents_1 = iCalEvents; _i < iCalEvents_1.length; _i++) {
141
- var iCalEvent = iCalEvents_1[_i];
142
- if (iCalEvent.isRecurring()) {
143
- eventInputs.push.apply(eventInputs, expandRecurringEvent(iCalEvent, range));
144
- }
145
- else {
146
- eventInputs.push(buildSingleEvent(iCalEvent));
147
- }
148
- }
149
- return eventInputs;
150
- }
151
- function buildSingleEvent(iCalEvent) {
152
- return tslib.__assign(tslib.__assign({}, buildNonDateProps(iCalEvent)), { start: iCalEvent.startDate.toString(), end: (specifiesEnd(iCalEvent) && iCalEvent.endDate)
153
- ? iCalEvent.endDate.toString()
154
- : null });
155
- }
156
- /*
157
- This is suprisingly involved and not built-in to ical.js:
158
- https://github.com/mozilla-comm/ical.js/issues/285
159
- https://github.com/mifi/ical-expander/blob/master/index.js
160
- TODO: handle VEVENTs that are *exceptions*
161
- */
162
- function expandRecurringEvent(iCalEvent, range) {
222
+ function expandICalEvents(iCalExpander, range) {
223
+ // expand the range. because our `range` is timeZone-agnostic UTC
224
+ // or maybe because ical.js always produces dates in local time? i forget
163
225
  var rangeStart = common.addDays(range.start, -1);
164
226
  var rangeEnd = common.addDays(range.end, 1);
165
- var expansion = iCalEvent.iterator();
166
- var hasDuration = specifiesEnd(iCalEvent);
167
- var eventInputs = [];
168
- var startDateTime;
169
- while ((startDateTime = expansion.next())) { // will start expanding ALL occurences
170
- var startDate = startDateTime.toJSDate();
171
- var endDate = null;
172
- var endDateTime = null;
173
- if (hasDuration) {
174
- endDateTime = startDateTime.clone();
175
- endDateTime.addDuration(iCalEvent.duration);
176
- endDate = endDateTime.toJSDate();
177
- }
178
- if (startDate >= rangeEnd.valueOf()) { // is event's start on-or-after the range's end?
179
- break;
180
- }
181
- else if ((endDate || startDate) > rangeStart.valueOf()) { // is event's end after the range's start?
182
- eventInputs.push(tslib.__assign(tslib.__assign({}, buildNonDateProps(iCalEvent)), { start: startDateTime.toString(), end: endDateTime ? endDateTime.toString() : null }));
183
- }
227
+ var iCalRes = iCalExpander.between(rangeStart, rangeEnd); // end inclusive. will give extra results
228
+ var expanded = [];
229
+ // TODO: instead of using startDate/endDate.toString to communicate allDay,
230
+ // we can query startDate/endDate.isDate. More efficient to avoid formatting/reparsing.
231
+ // single events
232
+ for (var _i = 0, _a = iCalRes.events; _i < _a.length; _i++) {
233
+ var iCalEvent = _a[_i];
234
+ expanded.push(tslib.__assign(tslib.__assign({}, buildNonDateProps(iCalEvent)), { start: iCalEvent.startDate.toString(), end: (specifiesEnd(iCalEvent) && iCalEvent.endDate)
235
+ ? iCalEvent.endDate.toString()
236
+ : null }));
237
+ }
238
+ // recurring event instances
239
+ for (var _b = 0, _c = iCalRes.occurrences; _b < _c.length; _b++) {
240
+ var iCalOccurence = _c[_b];
241
+ var iCalEvent = iCalOccurence.item;
242
+ expanded.push(tslib.__assign(tslib.__assign({}, buildNonDateProps(iCalEvent)), { start: iCalOccurence.startDate.toString(), end: (specifiesEnd(iCalEvent) && iCalOccurence.endDate)
243
+ ? iCalOccurence.endDate.toString()
244
+ : null }));
184
245
  }
185
- return eventInputs;
246
+ return expanded;
186
247
  }
187
248
  function buildNonDateProps(iCalEvent) {
188
249
  return {
package/main.global.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- FullCalendar v5.7.2
2
+ FullCalendar v5.10.1
3
3
  Docs & License: https://fullcalendar.io/
4
4
  (c) 2021 Adam Shaw
5
5
  */
@@ -54,6 +54,113 @@ var FullCalendarICalendar = (function (exports, common, ICAL) {
54
54
  return __assign.apply(this, arguments);
55
55
  };
56
56
 
57
+ /* eslint-disable */
58
+ var IcalExpander = /** @class */ (function () {
59
+ function IcalExpander(opts) {
60
+ this.maxIterations = opts.maxIterations != null ? opts.maxIterations : 1000;
61
+ this.skipInvalidDates = opts.skipInvalidDates != null ? opts.skipInvalidDates : false;
62
+ this.jCalData = ICAL__namespace.parse(opts.ics);
63
+ this.component = new ICAL__namespace.Component(this.jCalData);
64
+ this.events = this.component.getAllSubcomponents('vevent').map(function (vevent) { return new ICAL__namespace.Event(vevent); });
65
+ if (this.skipInvalidDates) {
66
+ this.events = this.events.filter(function (evt) {
67
+ try {
68
+ evt.startDate.toJSDate();
69
+ evt.endDate.toJSDate();
70
+ return true;
71
+ }
72
+ catch (err) {
73
+ // skipping events with invalid time
74
+ return false;
75
+ }
76
+ });
77
+ }
78
+ }
79
+ IcalExpander.prototype.between = function (after, before) {
80
+ var _this = this;
81
+ function isEventWithinRange(startTime, endTime) {
82
+ return (!after || endTime >= after.getTime()) &&
83
+ (!before || startTime <= before.getTime());
84
+ }
85
+ function getTimes(eventOrOccurrence) {
86
+ var startTime = eventOrOccurrence.startDate.toJSDate().getTime();
87
+ var endTime = eventOrOccurrence.endDate.toJSDate().getTime();
88
+ // If it is an all day event, the end date is set to 00:00 of the next day
89
+ // So we need to make it be 23:59:59 to compare correctly with the given range
90
+ if (eventOrOccurrence.endDate.isDate && (endTime > startTime)) {
91
+ endTime -= 1;
92
+ }
93
+ return { startTime: startTime, endTime: endTime };
94
+ }
95
+ var exceptions = [];
96
+ this.events.forEach(function (event) {
97
+ if (event.isRecurrenceException())
98
+ exceptions.push(event);
99
+ });
100
+ var ret = {
101
+ events: [],
102
+ occurrences: [],
103
+ };
104
+ this.events.filter(function (e) { return !e.isRecurrenceException(); }).forEach(function (event) {
105
+ var exdates = [];
106
+ event.component.getAllProperties('exdate').forEach(function (exdateProp) {
107
+ var exdate = exdateProp.getFirstValue();
108
+ exdates.push(exdate.toJSDate().getTime());
109
+ });
110
+ // Recurring event is handled differently
111
+ if (event.isRecurring()) {
112
+ var iterator = event.iterator();
113
+ var next = void 0;
114
+ var i = 0;
115
+ var _loop_1 = function () {
116
+ i += 1;
117
+ next = iterator.next();
118
+ if (next) {
119
+ var occurrence_1 = event.getOccurrenceDetails(next);
120
+ var _b = getTimes(occurrence_1), startTime_1 = _b.startTime, endTime_1 = _b.endTime;
121
+ var isOccurrenceExcluded = exdates.indexOf(startTime_1) !== -1;
122
+ // TODO check that within same day?
123
+ var exception = exceptions.find(function (ex) { return ex.uid === event.uid && ex.recurrenceId.toJSDate().getTime() === occurrence_1.startDate.toJSDate().getTime(); });
124
+ // We have passed the max date, stop
125
+ if (before && startTime_1 > before.getTime())
126
+ return "break";
127
+ // Check that we are within our range
128
+ if (isEventWithinRange(startTime_1, endTime_1)) {
129
+ if (exception) {
130
+ ret.events.push(exception);
131
+ }
132
+ else if (!isOccurrenceExcluded) {
133
+ ret.occurrences.push(occurrence_1);
134
+ }
135
+ }
136
+ }
137
+ };
138
+ do {
139
+ var state_1 = _loop_1();
140
+ if (state_1 === "break")
141
+ break;
142
+ } while (next && (!_this.maxIterations || i < _this.maxIterations));
143
+ return;
144
+ }
145
+ // Non-recurring event:
146
+ var _a = getTimes(event), startTime = _a.startTime, endTime = _a.endTime;
147
+ if (isEventWithinRange(startTime, endTime))
148
+ ret.events.push(event);
149
+ });
150
+ return ret;
151
+ };
152
+ IcalExpander.prototype.before = function (before) {
153
+ return this.between(undefined, before);
154
+ };
155
+ IcalExpander.prototype.after = function (after) {
156
+ return this.between(after);
157
+ };
158
+ IcalExpander.prototype.all = function () {
159
+ return this.between();
160
+ };
161
+ return IcalExpander;
162
+ }());
163
+
57
164
  var eventSourceDef = {
58
165
  parseMeta: function (refined) {
59
166
  if (refined.url && refined.format === 'ics') {
@@ -67,12 +174,12 @@ var FullCalendarICalendar = (function (exports, common, ICAL) {
67
174
  fetch: function (arg, onSuccess, onFailure) {
68
175
  var meta = arg.eventSource.meta;
69
176
  var internalState = meta.internalState;
70
- function handleICalEvents(errorMessage, iCalEvents, xhr) {
177
+ function handleICalEvents(errorMessage, iCalExpander, xhr) {
71
178
  if (errorMessage) {
72
179
  onFailure({ message: errorMessage, xhr: xhr });
73
180
  }
74
181
  else {
75
- onSuccess({ rawEvents: expandICalEvents(iCalEvents, arg.range), xhr: xhr });
182
+ onSuccess({ rawEvents: expandICalEvents(iCalExpander, arg.range), xhr: xhr });
76
183
  }
77
184
  }
78
185
  /*
@@ -84,23 +191,26 @@ var FullCalendarICalendar = (function (exports, common, ICAL) {
84
191
  completed: false,
85
192
  callbacks: [handleICalEvents],
86
193
  errorMessage: '',
87
- iCalEvents: [],
194
+ iCalExpander: null,
88
195
  xhr: null,
89
196
  };
90
197
  requestICal(meta.url, function (rawFeed, xhr) {
91
- var iCalEvents = parseICalFeed(rawFeed);
198
+ var iCalExpander = new IcalExpander({
199
+ ics: rawFeed,
200
+ skipInvalidDates: true,
201
+ });
92
202
  for (var _i = 0, _a = internalState.callbacks; _i < _a.length; _i++) {
93
203
  var callback = _a[_i];
94
- callback('', iCalEvents, xhr);
204
+ callback('', iCalExpander, xhr);
95
205
  }
96
206
  internalState.completed = true;
97
207
  internalState.callbacks = [];
98
- internalState.iCalEvents = iCalEvents;
208
+ internalState.iCalExpander = iCalExpander;
99
209
  internalState.xhr = xhr;
100
210
  }, function (errorMessage, xhr) {
101
211
  for (var _i = 0, _a = internalState.callbacks; _i < _a.length; _i++) {
102
212
  var callback = _a[_i];
103
- callback(errorMessage, [], xhr);
213
+ callback(errorMessage, null, xhr);
104
214
  }
105
215
  internalState.completed = true;
106
216
  internalState.callbacks = [];
@@ -112,7 +222,7 @@ var FullCalendarICalendar = (function (exports, common, ICAL) {
112
222
  internalState.callbacks.push(handleICalEvents);
113
223
  }
114
224
  else {
115
- handleICalEvents(internalState.errorMessage, internalState.iCalEvents, internalState.xhr);
225
+ handleICalEvents(internalState.errorMessage, internalState.iCalExpander, internalState.xhr);
116
226
  }
117
227
  },
118
228
  };
@@ -130,80 +240,31 @@ var FullCalendarICalendar = (function (exports, common, ICAL) {
130
240
  xhr.onerror = function () { return failureCallback('Request failed', xhr); };
131
241
  xhr.send(null);
132
242
  }
133
- function parseICalFeed(feedStr) {
134
- var components = null;
135
- try {
136
- var feed = ICAL__namespace.parse(feedStr);
137
- var rootComponent = new ICAL__namespace.Component(feed);
138
- components = rootComponent.getAllSubcomponents('vevent');
139
- }
140
- catch (error) {
141
- console.warn("Error parsing feed: " + error);
142
- return [];
143
- }
144
- var iCalEvents = [];
145
- for (var _i = 0, components_1 = components; _i < components_1.length; _i++) {
146
- var component = components_1[_i];
147
- try {
148
- var iCalEvent = new ICAL__namespace.Event(component);
149
- if (iCalEvent.startDate) { // is an accessor method. if throws an error, is a bad event
150
- iCalEvents.push(iCalEvent);
151
- }
152
- }
153
- catch (error) {
154
- console.warn("Unable to process item in calendar: " + error);
155
- }
156
- }
157
- return iCalEvents;
158
- }
159
- function expandICalEvents(iCalEvents, range) {
160
- var eventInputs = [];
161
- for (var _i = 0, iCalEvents_1 = iCalEvents; _i < iCalEvents_1.length; _i++) {
162
- var iCalEvent = iCalEvents_1[_i];
163
- if (iCalEvent.isRecurring()) {
164
- eventInputs.push.apply(eventInputs, expandRecurringEvent(iCalEvent, range));
165
- }
166
- else {
167
- eventInputs.push(buildSingleEvent(iCalEvent));
168
- }
169
- }
170
- return eventInputs;
171
- }
172
- function buildSingleEvent(iCalEvent) {
173
- return __assign(__assign({}, buildNonDateProps(iCalEvent)), { start: iCalEvent.startDate.toString(), end: (specifiesEnd(iCalEvent) && iCalEvent.endDate)
174
- ? iCalEvent.endDate.toString()
175
- : null });
176
- }
177
- /*
178
- This is suprisingly involved and not built-in to ical.js:
179
- https://github.com/mozilla-comm/ical.js/issues/285
180
- https://github.com/mifi/ical-expander/blob/master/index.js
181
- TODO: handle VEVENTs that are *exceptions*
182
- */
183
- function expandRecurringEvent(iCalEvent, range) {
243
+ function expandICalEvents(iCalExpander, range) {
244
+ // expand the range. because our `range` is timeZone-agnostic UTC
245
+ // or maybe because ical.js always produces dates in local time? i forget
184
246
  var rangeStart = common.addDays(range.start, -1);
185
247
  var rangeEnd = common.addDays(range.end, 1);
186
- var expansion = iCalEvent.iterator();
187
- var hasDuration = specifiesEnd(iCalEvent);
188
- var eventInputs = [];
189
- var startDateTime;
190
- while ((startDateTime = expansion.next())) { // will start expanding ALL occurences
191
- var startDate = startDateTime.toJSDate();
192
- var endDate = null;
193
- var endDateTime = null;
194
- if (hasDuration) {
195
- endDateTime = startDateTime.clone();
196
- endDateTime.addDuration(iCalEvent.duration);
197
- endDate = endDateTime.toJSDate();
198
- }
199
- if (startDate >= rangeEnd.valueOf()) { // is event's start on-or-after the range's end?
200
- break;
201
- }
202
- else if ((endDate || startDate) > rangeStart.valueOf()) { // is event's end after the range's start?
203
- eventInputs.push(__assign(__assign({}, buildNonDateProps(iCalEvent)), { start: startDateTime.toString(), end: endDateTime ? endDateTime.toString() : null }));
204
- }
248
+ var iCalRes = iCalExpander.between(rangeStart, rangeEnd); // end inclusive. will give extra results
249
+ var expanded = [];
250
+ // TODO: instead of using startDate/endDate.toString to communicate allDay,
251
+ // we can query startDate/endDate.isDate. More efficient to avoid formatting/reparsing.
252
+ // single events
253
+ for (var _i = 0, _a = iCalRes.events; _i < _a.length; _i++) {
254
+ var iCalEvent = _a[_i];
255
+ expanded.push(__assign(__assign({}, buildNonDateProps(iCalEvent)), { start: iCalEvent.startDate.toString(), end: (specifiesEnd(iCalEvent) && iCalEvent.endDate)
256
+ ? iCalEvent.endDate.toString()
257
+ : null }));
258
+ }
259
+ // recurring event instances
260
+ for (var _b = 0, _c = iCalRes.occurrences; _b < _c.length; _b++) {
261
+ var iCalOccurence = _c[_b];
262
+ var iCalEvent = iCalOccurence.item;
263
+ expanded.push(__assign(__assign({}, buildNonDateProps(iCalEvent)), { start: iCalOccurence.startDate.toString(), end: (specifiesEnd(iCalEvent) && iCalOccurence.endDate)
264
+ ? iCalOccurence.endDate.toString()
265
+ : null }));
205
266
  }
206
- return eventInputs;
267
+ return expanded;
207
268
  }
208
269
  function buildNonDateProps(iCalEvent) {
209
270
  return {
@@ -1,6 +1,6 @@
1
1
  /*!
2
- FullCalendar v5.7.2
2
+ FullCalendar v5.10.1
3
3
  Docs & License: https://fullcalendar.io/
4
4
  (c) 2021 Adam Shaw
5
5
  */
6
- var FullCalendarICalendar=function(e,t,r){"use strict";function n(e){if(e&&e.__esModule)return e;var t=Object.create(null);return e&&Object.keys(e).forEach((function(r){if("default"!==r){var n=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(t,r,n.get?n:{enumerable:!0,get:function(){return e[r]}})}})),t.default=e,Object.freeze(t)}var a=n(r),o=function(){return(o=Object.assign||function(e){for(var t,r=1,n=arguments.length;r<n;r++)for(var a in t=arguments[r])Object.prototype.hasOwnProperty.call(t,a)&&(e[a]=t[a]);return e}).apply(this,arguments)},l={parseMeta:function(e){return e.url&&"ics"===e.format?{url:e.url,format:"ics"}:null},fetch:function(e,t,r){var n,o,l,c,s=e.eventSource.meta,i=s.internalState;function f(n,a,o){n?r({message:n,xhr:o}):t({rawEvents:u(a,e.range),xhr:o})}!i||e.isRefetch?(i=s.internalState={completed:!1,callbacks:[f],errorMessage:"",iCalEvents:[],xhr:null},n=s.url,o=function(e,t){for(var r=function(e){var t=null;try{var r=a.parse(e);t=new a.Component(r).getAllSubcomponents("vevent")}catch(e){return console.warn("Error parsing feed: "+e),[]}for(var n=[],o=0,l=t;o<l.length;o++){var u=l[o];try{var c=new a.Event(u);c.startDate&&n.push(c)}catch(e){console.warn("Unable to process item in calendar: "+e)}}return n}(e),n=0,o=i.callbacks;n<o.length;n++)(0,o[n])("",r,t);i.completed=!0,i.callbacks=[],i.iCalEvents=r,i.xhr=t},l=function(e,t){for(var r=0,n=i.callbacks;r<n.length;r++)(0,n[r])(e,[],t);i.completed=!0,i.callbacks=[],i.errorMessage=e,i.xhr=t},(c=new XMLHttpRequest).open("GET",n,!0),c.onload=function(){c.status>=200&&c.status<400?o(c.responseText,c):l("Request failed",c)},c.onerror=function(){return l("Request failed",c)},c.send(null)):i.completed?f(i.errorMessage,i.iCalEvents,i.xhr):i.callbacks.push(f)}};function u(e,t){for(var r=[],n=0,a=e;n<a.length;n++){var o=a[n];o.isRecurring()?r.push.apply(r,s(o,t)):r.push(c(o))}return r}function c(e){return o(o({},i(e)),{start:e.startDate.toString(),end:d(e)&&e.endDate?e.endDate.toString():null})}function s(e,r){for(var n,a=t.addDays(r.start,-1),l=t.addDays(r.end,1),u=e.iterator(),c=d(e),s=[];n=u.next();){var f=n.toJSDate(),p=null,v=null;if(c&&((v=n.clone()).addDuration(e.duration),p=v.toJSDate()),f>=l.valueOf())break;(p||f)>a.valueOf()&&s.push(o(o({},i(e)),{start:n.toString(),end:v?v.toString():null}))}return s}function i(e){return{title:e.summary,url:f(e),extendedProps:{location:e.location,organizer:e.organizer,description:e.description}}}function f(e){var t=e.component.getFirstProperty("url");return t?t.getFirstValue():""}function d(e){return Boolean(e.component.getFirstProperty("dtend"))||Boolean(e.component.getFirstProperty("duration"))}var p=t.createPlugin({eventSourceDefs:[l]});return t.globalPlugins.push(p),e.default=p,Object.defineProperty(e,"__esModule",{value:!0}),e}({},FullCalendar,ICAL);
6
+ var FullCalendarICalendar=function(e,t,n){"use strict";function r(e){if(e&&e.__esModule)return e;var t=Object.create(null);return e&&Object.keys(e).forEach((function(n){if("default"!==n){var r=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(t,n,r.get?r:{enumerable:!0,get:function(){return e[n]}})}})),t.default=e,Object.freeze(t)}var a=r(n),i=function(){return(i=Object.assign||function(e){for(var t,n=1,r=arguments.length;n<r;n++)for(var a in t=arguments[n])Object.prototype.hasOwnProperty.call(t,a)&&(e[a]=t[a]);return e}).apply(this,arguments)},o=function(){function e(e){this.maxIterations=null!=e.maxIterations?e.maxIterations:1e3,this.skipInvalidDates=null!=e.skipInvalidDates&&e.skipInvalidDates,this.jCalData=a.parse(e.ics),this.component=new a.Component(this.jCalData),this.events=this.component.getAllSubcomponents("vevent").map((function(e){return new a.Event(e)})),this.skipInvalidDates&&(this.events=this.events.filter((function(e){try{return e.startDate.toJSDate(),e.endDate.toJSDate(),!0}catch(e){return!1}})))}return e.prototype.between=function(e,t){var n=this;function r(n,r){return(!e||r>=e.getTime())&&(!t||n<=t.getTime())}function a(e){var t=e.startDate.toJSDate().getTime(),n=e.endDate.toJSDate().getTime();return e.endDate.isDate&&n>t&&(n-=1),{startTime:t,endTime:n}}var i=[];this.events.forEach((function(e){e.isRecurrenceException()&&i.push(e)}));var o={events:[],occurrences:[]};return this.events.filter((function(e){return!e.isRecurrenceException()})).forEach((function(e){var s=[];if(e.component.getAllProperties("exdate").forEach((function(e){var t=e.getFirstValue();s.push(t.toJSDate().getTime())})),e.isRecurring()){var u=e.iterator(),c=void 0,l=0,f=function(){if(l+=1,c=u.next()){var n=e.getOccurrenceDetails(c),f=a(n),p=f.startTime,d=f.endTime,v=-1!==s.indexOf(p),h=i.find((function(t){return t.uid===e.uid&&t.recurrenceId.toJSDate().getTime()===n.startDate.toJSDate().getTime()}));if(t&&p>t.getTime())return"break";r(p,d)&&(h?o.events.push(h):v||o.occurrences.push(n))}};do{if("break"===f())break}while(c&&(!n.maxIterations||l<n.maxIterations))}else{var p=a(e);r(p.startTime,p.endTime)&&o.events.push(e)}})),o},e.prototype.before=function(e){return this.between(void 0,e)},e.prototype.after=function(e){return this.between(e)},e.prototype.all=function(){return this.between()},e}(),s={parseMeta:function(e){return e.url&&"ics"===e.format?{url:e.url,format:"ics"}:null},fetch:function(e,t,n){var r,a,i,s,c=e.eventSource.meta,l=c.internalState;function f(r,a,i){r?n({message:r,xhr:i}):t({rawEvents:u(a,e.range),xhr:i})}!l||e.isRefetch?(l=c.internalState={completed:!1,callbacks:[f],errorMessage:"",iCalExpander:null,xhr:null},r=c.url,a=function(e,t){for(var n=new o({ics:e,skipInvalidDates:!0}),r=0,a=l.callbacks;r<a.length;r++)(0,a[r])("",n,t);l.completed=!0,l.callbacks=[],l.iCalExpander=n,l.xhr=t},i=function(e,t){for(var n=0,r=l.callbacks;n<r.length;n++)(0,r[n])(e,null,t);l.completed=!0,l.callbacks=[],l.errorMessage=e,l.xhr=t},(s=new XMLHttpRequest).open("GET",r,!0),s.onload=function(){s.status>=200&&s.status<400?a(s.responseText,s):i("Request failed",s)},s.onerror=function(){return i("Request failed",s)},s.send(null)):l.completed?f(l.errorMessage,l.iCalExpander,l.xhr):l.callbacks.push(f)}};function u(e,n){for(var r=t.addDays(n.start,-1),a=t.addDays(n.end,1),o=e.between(r,a),s=[],u=0,l=o.events;u<l.length;u++){var p=l[u];s.push(i(i({},c(p)),{start:p.startDate.toString(),end:f(p)&&p.endDate?p.endDate.toString():null}))}for(var d=0,v=o.occurrences;d<v.length;d++){var h=v[d];p=h.item;s.push(i(i({},c(p)),{start:h.startDate.toString(),end:f(p)&&h.endDate?h.endDate.toString():null}))}return s}function c(e){return{title:e.summary,url:l(e),extendedProps:{location:e.location,organizer:e.organizer,description:e.description}}}function l(e){var t=e.component.getFirstProperty("url");return t?t.getFirstValue():""}function f(e){return Boolean(e.component.getFirstProperty("dtend"))||Boolean(e.component.getFirstProperty("duration"))}var p=t.createPlugin({eventSourceDefs:[s]});return t.globalPlugins.push(p),e.default=p,Object.defineProperty(e,"__esModule",{value:!0}),e}({},FullCalendar,ICAL);
package/main.js CHANGED
@@ -1,11 +1,118 @@
1
1
  /*!
2
- FullCalendar v5.7.2
2
+ FullCalendar v5.10.1
3
3
  Docs & License: https://fullcalendar.io/
4
4
  (c) 2021 Adam Shaw
5
5
  */
6
6
  import { __assign } from 'tslib';
7
- import * as ICAL from 'ical.js';
8
7
  import { createPlugin, addDays } from '@fullcalendar/common';
8
+ import * as ICAL from 'ical.js';
9
+
10
+ /* eslint-disable */
11
+ var IcalExpander = /** @class */ (function () {
12
+ function IcalExpander(opts) {
13
+ this.maxIterations = opts.maxIterations != null ? opts.maxIterations : 1000;
14
+ this.skipInvalidDates = opts.skipInvalidDates != null ? opts.skipInvalidDates : false;
15
+ this.jCalData = ICAL.parse(opts.ics);
16
+ this.component = new ICAL.Component(this.jCalData);
17
+ this.events = this.component.getAllSubcomponents('vevent').map(function (vevent) { return new ICAL.Event(vevent); });
18
+ if (this.skipInvalidDates) {
19
+ this.events = this.events.filter(function (evt) {
20
+ try {
21
+ evt.startDate.toJSDate();
22
+ evt.endDate.toJSDate();
23
+ return true;
24
+ }
25
+ catch (err) {
26
+ // skipping events with invalid time
27
+ return false;
28
+ }
29
+ });
30
+ }
31
+ }
32
+ IcalExpander.prototype.between = function (after, before) {
33
+ var _this = this;
34
+ function isEventWithinRange(startTime, endTime) {
35
+ return (!after || endTime >= after.getTime()) &&
36
+ (!before || startTime <= before.getTime());
37
+ }
38
+ function getTimes(eventOrOccurrence) {
39
+ var startTime = eventOrOccurrence.startDate.toJSDate().getTime();
40
+ var endTime = eventOrOccurrence.endDate.toJSDate().getTime();
41
+ // If it is an all day event, the end date is set to 00:00 of the next day
42
+ // So we need to make it be 23:59:59 to compare correctly with the given range
43
+ if (eventOrOccurrence.endDate.isDate && (endTime > startTime)) {
44
+ endTime -= 1;
45
+ }
46
+ return { startTime: startTime, endTime: endTime };
47
+ }
48
+ var exceptions = [];
49
+ this.events.forEach(function (event) {
50
+ if (event.isRecurrenceException())
51
+ exceptions.push(event);
52
+ });
53
+ var ret = {
54
+ events: [],
55
+ occurrences: [],
56
+ };
57
+ this.events.filter(function (e) { return !e.isRecurrenceException(); }).forEach(function (event) {
58
+ var exdates = [];
59
+ event.component.getAllProperties('exdate').forEach(function (exdateProp) {
60
+ var exdate = exdateProp.getFirstValue();
61
+ exdates.push(exdate.toJSDate().getTime());
62
+ });
63
+ // Recurring event is handled differently
64
+ if (event.isRecurring()) {
65
+ var iterator = event.iterator();
66
+ var next = void 0;
67
+ var i = 0;
68
+ var _loop_1 = function () {
69
+ i += 1;
70
+ next = iterator.next();
71
+ if (next) {
72
+ var occurrence_1 = event.getOccurrenceDetails(next);
73
+ var _b = getTimes(occurrence_1), startTime_1 = _b.startTime, endTime_1 = _b.endTime;
74
+ var isOccurrenceExcluded = exdates.indexOf(startTime_1) !== -1;
75
+ // TODO check that within same day?
76
+ var exception = exceptions.find(function (ex) { return ex.uid === event.uid && ex.recurrenceId.toJSDate().getTime() === occurrence_1.startDate.toJSDate().getTime(); });
77
+ // We have passed the max date, stop
78
+ if (before && startTime_1 > before.getTime())
79
+ return "break";
80
+ // Check that we are within our range
81
+ if (isEventWithinRange(startTime_1, endTime_1)) {
82
+ if (exception) {
83
+ ret.events.push(exception);
84
+ }
85
+ else if (!isOccurrenceExcluded) {
86
+ ret.occurrences.push(occurrence_1);
87
+ }
88
+ }
89
+ }
90
+ };
91
+ do {
92
+ var state_1 = _loop_1();
93
+ if (state_1 === "break")
94
+ break;
95
+ } while (next && (!_this.maxIterations || i < _this.maxIterations));
96
+ return;
97
+ }
98
+ // Non-recurring event:
99
+ var _a = getTimes(event), startTime = _a.startTime, endTime = _a.endTime;
100
+ if (isEventWithinRange(startTime, endTime))
101
+ ret.events.push(event);
102
+ });
103
+ return ret;
104
+ };
105
+ IcalExpander.prototype.before = function (before) {
106
+ return this.between(undefined, before);
107
+ };
108
+ IcalExpander.prototype.after = function (after) {
109
+ return this.between(after);
110
+ };
111
+ IcalExpander.prototype.all = function () {
112
+ return this.between();
113
+ };
114
+ return IcalExpander;
115
+ }());
9
116
 
10
117
  var eventSourceDef = {
11
118
  parseMeta: function (refined) {
@@ -20,12 +127,12 @@ var eventSourceDef = {
20
127
  fetch: function (arg, onSuccess, onFailure) {
21
128
  var meta = arg.eventSource.meta;
22
129
  var internalState = meta.internalState;
23
- function handleICalEvents(errorMessage, iCalEvents, xhr) {
130
+ function handleICalEvents(errorMessage, iCalExpander, xhr) {
24
131
  if (errorMessage) {
25
132
  onFailure({ message: errorMessage, xhr: xhr });
26
133
  }
27
134
  else {
28
- onSuccess({ rawEvents: expandICalEvents(iCalEvents, arg.range), xhr: xhr });
135
+ onSuccess({ rawEvents: expandICalEvents(iCalExpander, arg.range), xhr: xhr });
29
136
  }
30
137
  }
31
138
  /*
@@ -37,23 +144,26 @@ var eventSourceDef = {
37
144
  completed: false,
38
145
  callbacks: [handleICalEvents],
39
146
  errorMessage: '',
40
- iCalEvents: [],
147
+ iCalExpander: null,
41
148
  xhr: null,
42
149
  };
43
150
  requestICal(meta.url, function (rawFeed, xhr) {
44
- var iCalEvents = parseICalFeed(rawFeed);
151
+ var iCalExpander = new IcalExpander({
152
+ ics: rawFeed,
153
+ skipInvalidDates: true,
154
+ });
45
155
  for (var _i = 0, _a = internalState.callbacks; _i < _a.length; _i++) {
46
156
  var callback = _a[_i];
47
- callback('', iCalEvents, xhr);
157
+ callback('', iCalExpander, xhr);
48
158
  }
49
159
  internalState.completed = true;
50
160
  internalState.callbacks = [];
51
- internalState.iCalEvents = iCalEvents;
161
+ internalState.iCalExpander = iCalExpander;
52
162
  internalState.xhr = xhr;
53
163
  }, function (errorMessage, xhr) {
54
164
  for (var _i = 0, _a = internalState.callbacks; _i < _a.length; _i++) {
55
165
  var callback = _a[_i];
56
- callback(errorMessage, [], xhr);
166
+ callback(errorMessage, null, xhr);
57
167
  }
58
168
  internalState.completed = true;
59
169
  internalState.callbacks = [];
@@ -65,7 +175,7 @@ var eventSourceDef = {
65
175
  internalState.callbacks.push(handleICalEvents);
66
176
  }
67
177
  else {
68
- handleICalEvents(internalState.errorMessage, internalState.iCalEvents, internalState.xhr);
178
+ handleICalEvents(internalState.errorMessage, internalState.iCalExpander, internalState.xhr);
69
179
  }
70
180
  },
71
181
  };
@@ -83,80 +193,31 @@ function requestICal(url, successCallback, failureCallback) {
83
193
  xhr.onerror = function () { return failureCallback('Request failed', xhr); };
84
194
  xhr.send(null);
85
195
  }
86
- function parseICalFeed(feedStr) {
87
- var components = null;
88
- try {
89
- var feed = ICAL.parse(feedStr);
90
- var rootComponent = new ICAL.Component(feed);
91
- components = rootComponent.getAllSubcomponents('vevent');
92
- }
93
- catch (error) {
94
- console.warn("Error parsing feed: " + error);
95
- return [];
96
- }
97
- var iCalEvents = [];
98
- for (var _i = 0, components_1 = components; _i < components_1.length; _i++) {
99
- var component = components_1[_i];
100
- try {
101
- var iCalEvent = new ICAL.Event(component);
102
- if (iCalEvent.startDate) { // is an accessor method. if throws an error, is a bad event
103
- iCalEvents.push(iCalEvent);
104
- }
105
- }
106
- catch (error) {
107
- console.warn("Unable to process item in calendar: " + error);
108
- }
109
- }
110
- return iCalEvents;
111
- }
112
- function expandICalEvents(iCalEvents, range) {
113
- var eventInputs = [];
114
- for (var _i = 0, iCalEvents_1 = iCalEvents; _i < iCalEvents_1.length; _i++) {
115
- var iCalEvent = iCalEvents_1[_i];
116
- if (iCalEvent.isRecurring()) {
117
- eventInputs.push.apply(eventInputs, expandRecurringEvent(iCalEvent, range));
118
- }
119
- else {
120
- eventInputs.push(buildSingleEvent(iCalEvent));
121
- }
122
- }
123
- return eventInputs;
124
- }
125
- function buildSingleEvent(iCalEvent) {
126
- return __assign(__assign({}, buildNonDateProps(iCalEvent)), { start: iCalEvent.startDate.toString(), end: (specifiesEnd(iCalEvent) && iCalEvent.endDate)
127
- ? iCalEvent.endDate.toString()
128
- : null });
129
- }
130
- /*
131
- This is suprisingly involved and not built-in to ical.js:
132
- https://github.com/mozilla-comm/ical.js/issues/285
133
- https://github.com/mifi/ical-expander/blob/master/index.js
134
- TODO: handle VEVENTs that are *exceptions*
135
- */
136
- function expandRecurringEvent(iCalEvent, range) {
196
+ function expandICalEvents(iCalExpander, range) {
197
+ // expand the range. because our `range` is timeZone-agnostic UTC
198
+ // or maybe because ical.js always produces dates in local time? i forget
137
199
  var rangeStart = addDays(range.start, -1);
138
200
  var rangeEnd = addDays(range.end, 1);
139
- var expansion = iCalEvent.iterator();
140
- var hasDuration = specifiesEnd(iCalEvent);
141
- var eventInputs = [];
142
- var startDateTime;
143
- while ((startDateTime = expansion.next())) { // will start expanding ALL occurences
144
- var startDate = startDateTime.toJSDate();
145
- var endDate = null;
146
- var endDateTime = null;
147
- if (hasDuration) {
148
- endDateTime = startDateTime.clone();
149
- endDateTime.addDuration(iCalEvent.duration);
150
- endDate = endDateTime.toJSDate();
151
- }
152
- if (startDate >= rangeEnd.valueOf()) { // is event's start on-or-after the range's end?
153
- break;
154
- }
155
- else if ((endDate || startDate) > rangeStart.valueOf()) { // is event's end after the range's start?
156
- eventInputs.push(__assign(__assign({}, buildNonDateProps(iCalEvent)), { start: startDateTime.toString(), end: endDateTime ? endDateTime.toString() : null }));
157
- }
201
+ var iCalRes = iCalExpander.between(rangeStart, rangeEnd); // end inclusive. will give extra results
202
+ var expanded = [];
203
+ // TODO: instead of using startDate/endDate.toString to communicate allDay,
204
+ // we can query startDate/endDate.isDate. More efficient to avoid formatting/reparsing.
205
+ // single events
206
+ for (var _i = 0, _a = iCalRes.events; _i < _a.length; _i++) {
207
+ var iCalEvent = _a[_i];
208
+ expanded.push(__assign(__assign({}, buildNonDateProps(iCalEvent)), { start: iCalEvent.startDate.toString(), end: (specifiesEnd(iCalEvent) && iCalEvent.endDate)
209
+ ? iCalEvent.endDate.toString()
210
+ : null }));
211
+ }
212
+ // recurring event instances
213
+ for (var _b = 0, _c = iCalRes.occurrences; _b < _c.length; _b++) {
214
+ var iCalOccurence = _c[_b];
215
+ var iCalEvent = iCalOccurence.item;
216
+ expanded.push(__assign(__assign({}, buildNonDateProps(iCalEvent)), { start: iCalOccurence.startDate.toString(), end: (specifiesEnd(iCalEvent) && iCalOccurence.endDate)
217
+ ? iCalOccurence.endDate.toString()
218
+ : null }));
158
219
  }
159
- return eventInputs;
220
+ return expanded;
160
221
  }
161
222
  function buildNonDateProps(iCalEvent) {
162
223
  return {
package/main.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"main.js","sources":["src/main.ts"],"sourcesContent":["import * as ICAL from 'ical.js'\nimport { createPlugin, EventSourceDef, EventInput, addDays, DateRange, DateMarker } from '@fullcalendar/common'\n\ntype Success = (rawFeed: string, xhr: XMLHttpRequest) => void\ntype Failure = (error: string, xhr: XMLHttpRequest) => void\n\ninterface ICalFeedMeta {\n url: string\n format: 'ics', // for EventSourceApi\n internalState?: InternalState // HACK. TODO: use classes in future\n}\n\ninterface InternalState {\n completed: boolean\n callbacks: ((errorMessage: string, iCalEvents: ICAL.Event, xhr: XMLHttpRequest) => void)[]\n errorMessage: string\n iCalEvents: ICAL.Event\n xhr: XMLHttpRequest | null\n}\n\nlet eventSourceDef: EventSourceDef<ICalFeedMeta> = {\n\n parseMeta(refined) {\n if (refined.url && refined.format === 'ics') {\n return {\n url: refined.url,\n format: 'ics',\n }\n }\n return null\n },\n\n fetch(arg, onSuccess, onFailure) {\n let { meta } = arg.eventSource\n let { internalState } = meta\n\n function handleICalEvents(errorMessage, iCalEvents, xhr) {\n if (errorMessage) {\n onFailure({ message: errorMessage, xhr })\n } else {\n onSuccess({ rawEvents: expandICalEvents(iCalEvents, arg.range), xhr })\n }\n }\n\n /*\n NOTE: isRefetch is a HACK. we would do the recurring-expanding in a separate plugin hook,\n but we couldn't leverage built-in allDay-guessing, among other things.\n */\n if (!internalState || arg.isRefetch) {\n internalState = meta.internalState = { // our ghetto Promise\n completed: false,\n callbacks: [handleICalEvents],\n errorMessage: '',\n iCalEvents: [],\n xhr: null,\n }\n\n requestICal(\n meta.url,\n (rawFeed, xhr) => {\n const iCalEvents = parseICalFeed(rawFeed)\n\n for (let callback of internalState.callbacks) {\n callback('', iCalEvents, xhr)\n }\n\n internalState.completed = true\n internalState.callbacks = []\n internalState.iCalEvents = iCalEvents\n internalState.xhr = xhr\n },\n (errorMessage, xhr) => {\n for (let callback of internalState.callbacks) {\n callback(errorMessage, [], xhr)\n }\n\n internalState.completed = true\n internalState.callbacks = []\n internalState.errorMessage = errorMessage\n internalState.xhr = xhr\n },\n )\n } else if (!internalState.completed) {\n internalState.callbacks.push(handleICalEvents)\n } else {\n handleICalEvents(internalState.errorMessage, internalState.iCalEvents, internalState.xhr)\n }\n },\n}\n\nfunction requestICal(url: string, successCallback: Success, failureCallback: Failure) {\n const xhr = new XMLHttpRequest()\n xhr.open('GET', url, true)\n xhr.onload = () => {\n if (xhr.status >= 200 && xhr.status < 400) {\n successCallback(xhr.responseText, xhr)\n } else {\n failureCallback('Request failed', xhr)\n }\n }\n xhr.onerror = () => failureCallback('Request failed', xhr)\n xhr.send(null)\n}\n\nfunction parseICalFeed(feedStr: string): ICAL.Event[] {\n let components = null\n\n try {\n let feed = ICAL.parse(feedStr)\n let rootComponent = new ICAL.Component(feed)\n components = rootComponent.getAllSubcomponents('vevent')\n } catch (error) {\n console.warn(`Error parsing feed: ${error}`)\n return []\n }\n\n let iCalEvents: ICAL.Event[] = []\n\n for (let component of components) {\n try {\n let iCalEvent = new ICAL.Event(component)\n\n if (iCalEvent.startDate) { // is an accessor method. if throws an error, is a bad event\n iCalEvents.push(iCalEvent)\n }\n } catch (error) {\n console.warn(`Unable to process item in calendar: ${error}`)\n }\n }\n\n return iCalEvents\n}\n\nfunction expandICalEvents(iCalEvents: ICAL.Event[], range: DateRange): EventInput[] {\n let eventInputs: EventInput[] = []\n\n for (let iCalEvent of iCalEvents) {\n if (iCalEvent.isRecurring()) {\n eventInputs.push(\n ...expandRecurringEvent(iCalEvent, range),\n )\n } else {\n eventInputs.push(\n buildSingleEvent(iCalEvent),\n )\n }\n }\n\n return eventInputs\n}\n\nfunction buildSingleEvent(iCalEvent: ICAL.Event): EventInput {\n return {\n ...buildNonDateProps(iCalEvent),\n start: iCalEvent.startDate.toString(),\n end: (specifiesEnd(iCalEvent) && iCalEvent.endDate)\n ? iCalEvent.endDate.toString()\n : null,\n }\n}\n\n/*\nThis is suprisingly involved and not built-in to ical.js:\nhttps://github.com/mozilla-comm/ical.js/issues/285\nhttps://github.com/mifi/ical-expander/blob/master/index.js\nTODO: handle VEVENTs that are *exceptions*\n*/\nfunction expandRecurringEvent(iCalEvent: ICAL.Event, range: DateRange): EventInput[] {\n let rangeStart = addDays(range.start, -1)\n let rangeEnd = addDays(range.end, 1)\n let expansion = iCalEvent.iterator()\n let hasDuration = specifiesEnd(iCalEvent)\n let eventInputs: EventInput[] = []\n let startDateTime: ICAL.Time\n\n while ((startDateTime = expansion.next())) { // will start expanding ALL occurences\n let startDate = startDateTime.toJSDate()\n let endDate: DateMarker | null = null\n let endDateTime: ICAL.Time | null = null\n\n if (hasDuration) {\n endDateTime = startDateTime.clone()\n endDateTime.addDuration(iCalEvent.duration)\n endDate = endDateTime.toJSDate()\n }\n\n if (startDate >= rangeEnd.valueOf()) { // is event's start on-or-after the range's end?\n break\n } else if ((endDate || startDate) > rangeStart.valueOf()) { // is event's end after the range's start?\n eventInputs.push({\n ...buildNonDateProps(iCalEvent),\n start: startDateTime.toString(),\n end: endDateTime ? endDateTime.toString() : null,\n })\n }\n }\n\n return eventInputs\n}\n\nfunction buildNonDateProps(iCalEvent: ICAL.Event): EventInput {\n return {\n title: iCalEvent.summary,\n url: extractEventUrl(iCalEvent),\n extendedProps: {\n location: iCalEvent.location,\n organizer: iCalEvent.organizer,\n description: iCalEvent.description,\n },\n }\n}\n\nfunction extractEventUrl(iCalEvent: ICAL.Event): string {\n let urlProp = iCalEvent.component.getFirstProperty('url')\n return urlProp ? urlProp.getFirstValue() : ''\n}\n\nfunction specifiesEnd(iCalEvent: ICAL.Event) {\n return Boolean(iCalEvent.component.getFirstProperty('dtend')) ||\n Boolean(iCalEvent.component.getFirstProperty('duration'))\n}\n\nexport default createPlugin({\n eventSourceDefs: [eventSourceDef],\n})\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"main.js","sources":["src/ical-expander/IcalExpander.js","src/main.ts"],"sourcesContent":["/* eslint-disable */\n/*\nfrom https://github.com/mifi/ical-expander\nreleased under https://github.com/mifi/ical-expander/blob/master/LICENSE\noperates entirely in UTC\n*/\n\nimport * as ICAL from 'ical.js'\n\nexport class IcalExpander {\n constructor(opts) {\n this.maxIterations = opts.maxIterations != null ? opts.maxIterations : 1000;\n this.skipInvalidDates = opts.skipInvalidDates != null ? opts.skipInvalidDates : false;\n\n this.jCalData = ICAL.parse(opts.ics);\n this.component = new ICAL.Component(this.jCalData);\n this.events = this.component.getAllSubcomponents('vevent').map(vevent => new ICAL.Event(vevent));\n\n if (this.skipInvalidDates) {\n this.events = this.events.filter((evt) => {\n try {\n evt.startDate.toJSDate();\n evt.endDate.toJSDate();\n return true;\n } catch (err) {\n // skipping events with invalid time\n return false;\n }\n });\n }\n }\n\n between(after, before) {\n function isEventWithinRange(startTime, endTime) {\n return (!after || endTime >= after.getTime()) &&\n (!before || startTime <= before.getTime());\n }\n\n function getTimes(eventOrOccurrence) {\n const startTime = eventOrOccurrence.startDate.toJSDate().getTime();\n let endTime = eventOrOccurrence.endDate.toJSDate().getTime();\n\n // If it is an all day event, the end date is set to 00:00 of the next day\n // So we need to make it be 23:59:59 to compare correctly with the given range\n if (eventOrOccurrence.endDate.isDate && (endTime > startTime)) {\n endTime -= 1;\n }\n\n return { startTime, endTime };\n }\n\n const exceptions = [];\n\n this.events.forEach((event) => {\n if (event.isRecurrenceException()) exceptions.push(event);\n });\n\n const ret = {\n events: [],\n occurrences: [],\n };\n\n this.events.filter(e => !e.isRecurrenceException()).forEach((event) => {\n const exdates = [];\n\n event.component.getAllProperties('exdate').forEach((exdateProp) => {\n const exdate = exdateProp.getFirstValue();\n exdates.push(exdate.toJSDate().getTime());\n });\n\n // Recurring event is handled differently\n if (event.isRecurring()) {\n const iterator = event.iterator();\n\n let next;\n let i = 0;\n\n do {\n i += 1;\n next = iterator.next();\n if (next) {\n const occurrence = event.getOccurrenceDetails(next);\n\n const { startTime, endTime } = getTimes(occurrence);\n\n const isOccurrenceExcluded = exdates.indexOf(startTime) !== -1;\n\n // TODO check that within same day?\n const exception = exceptions.find(ex => ex.uid === event.uid && ex.recurrenceId.toJSDate().getTime() === occurrence.startDate.toJSDate().getTime());\n\n // We have passed the max date, stop\n if (before && startTime > before.getTime()) break;\n\n // Check that we are within our range\n if (isEventWithinRange(startTime, endTime)) {\n if (exception) {\n ret.events.push(exception);\n } else if (!isOccurrenceExcluded) {\n ret.occurrences.push(occurrence);\n }\n }\n }\n }\n while (next && (!this.maxIterations || i < this.maxIterations));\n\n return;\n }\n\n // Non-recurring event:\n const { startTime, endTime } = getTimes(event);\n\n if (isEventWithinRange(startTime, endTime)) ret.events.push(event);\n });\n\n return ret;\n }\n\n before(before) {\n return this.between(undefined, before);\n }\n\n after(after) {\n return this.between(after);\n }\n\n all() {\n return this.between();\n }\n}\n","import { createPlugin, EventSourceDef, EventInput, DateRange, addDays } from '@fullcalendar/common'\nimport * as ICAL from 'ical.js'\nimport { IcalExpander } from './ical-expander/IcalExpander'\n\ntype Success = (rawFeed: string, xhr: XMLHttpRequest) => void\ntype Failure = (error: string, xhr: XMLHttpRequest) => void\n\ninterface ICalFeedMeta {\n url: string\n format: 'ics', // for EventSourceApi\n internalState?: InternalState // HACK. TODO: use classes in future\n}\n\ninterface InternalState {\n completed: boolean\n callbacks: ((errorMessage: string, iCalExpander: IcalExpander, xhr: XMLHttpRequest) => void)[]\n errorMessage: string\n iCalExpander: IcalExpander\n xhr: XMLHttpRequest | null\n}\n\nlet eventSourceDef: EventSourceDef<ICalFeedMeta> = {\n\n parseMeta(refined) {\n if (refined.url && refined.format === 'ics') {\n return {\n url: refined.url,\n format: 'ics',\n }\n }\n return null\n },\n\n fetch(arg, onSuccess, onFailure) {\n let { meta } = arg.eventSource\n let { internalState } = meta\n\n function handleICalEvents(errorMessage, iCalExpander: IcalExpander, xhr) {\n if (errorMessage) {\n onFailure({ message: errorMessage, xhr })\n } else {\n onSuccess({ rawEvents: expandICalEvents(iCalExpander, arg.range), xhr })\n }\n }\n\n /*\n NOTE: isRefetch is a HACK. we would do the recurring-expanding in a separate plugin hook,\n but we couldn't leverage built-in allDay-guessing, among other things.\n */\n if (!internalState || arg.isRefetch) {\n internalState = meta.internalState = { // our ghetto Promise\n completed: false,\n callbacks: [handleICalEvents],\n errorMessage: '',\n iCalExpander: null,\n xhr: null,\n }\n\n requestICal(\n meta.url,\n (rawFeed, xhr) => {\n let iCalExpander = new IcalExpander({\n ics: rawFeed,\n skipInvalidDates: true,\n })\n\n for (let callback of internalState.callbacks) {\n callback('', iCalExpander, xhr)\n }\n\n internalState.completed = true\n internalState.callbacks = []\n internalState.iCalExpander = iCalExpander\n internalState.xhr = xhr\n },\n (errorMessage, xhr) => {\n for (let callback of internalState.callbacks) {\n callback(errorMessage, null, xhr)\n }\n\n internalState.completed = true\n internalState.callbacks = []\n internalState.errorMessage = errorMessage\n internalState.xhr = xhr\n },\n )\n } else if (!internalState.completed) {\n internalState.callbacks.push(handleICalEvents)\n } else {\n handleICalEvents(internalState.errorMessage, internalState.iCalExpander, internalState.xhr)\n }\n },\n}\n\nfunction requestICal(url: string, successCallback: Success, failureCallback: Failure) {\n const xhr = new XMLHttpRequest()\n xhr.open('GET', url, true)\n xhr.onload = () => {\n if (xhr.status >= 200 && xhr.status < 400) {\n successCallback(xhr.responseText, xhr)\n } else {\n failureCallback('Request failed', xhr)\n }\n }\n xhr.onerror = () => failureCallback('Request failed', xhr)\n xhr.send(null)\n}\n\nfunction expandICalEvents(iCalExpander: IcalExpander, range: DateRange): EventInput[] {\n // expand the range. because our `range` is timeZone-agnostic UTC\n // or maybe because ical.js always produces dates in local time? i forget\n let rangeStart = addDays(range.start, -1)\n let rangeEnd = addDays(range.end, 1)\n\n let iCalRes = iCalExpander.between(rangeStart, rangeEnd) // end inclusive. will give extra results\n let expanded: EventInput[] = []\n\n // TODO: instead of using startDate/endDate.toString to communicate allDay,\n // we can query startDate/endDate.isDate. More efficient to avoid formatting/reparsing.\n\n // single events\n for (let iCalEvent of iCalRes.events) {\n expanded.push({\n ...buildNonDateProps(iCalEvent),\n start: iCalEvent.startDate.toString(),\n end: (specifiesEnd(iCalEvent) && iCalEvent.endDate)\n ? iCalEvent.endDate.toString()\n : null,\n })\n }\n\n // recurring event instances\n for (let iCalOccurence of iCalRes.occurrences) {\n let iCalEvent = iCalOccurence.item\n expanded.push({\n ...buildNonDateProps(iCalEvent),\n start: iCalOccurence.startDate.toString(),\n end: (specifiesEnd(iCalEvent) && iCalOccurence.endDate)\n ? iCalOccurence.endDate.toString()\n : null,\n })\n }\n\n return expanded\n}\n\nfunction buildNonDateProps(iCalEvent: ICAL.Event): EventInput {\n return {\n title: iCalEvent.summary,\n url: extractEventUrl(iCalEvent),\n extendedProps: {\n location: iCalEvent.location,\n organizer: iCalEvent.organizer,\n description: iCalEvent.description,\n },\n }\n}\n\nfunction extractEventUrl(iCalEvent: ICAL.Event): string {\n let urlProp = iCalEvent.component.getFirstProperty('url')\n return urlProp ? urlProp.getFirstValue() : ''\n}\n\nfunction specifiesEnd(iCalEvent: ICAL.Event) {\n return Boolean(iCalEvent.component.getFirstProperty('dtend')) ||\n Boolean(iCalEvent.component.getFirstProperty('duration'))\n}\n\nexport default createPlugin({\n eventSourceDefs: [eventSourceDef],\n})\n"],"names":[],"mappings":";;;;;;;;;AAAA;AASA;IACE,sBAAY,IAAI;QACd,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,aAAa,IAAI,IAAI,GAAG,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;QAC5E,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,gBAAgB,IAAI,IAAI,GAAG,IAAI,CAAC,gBAAgB,GAAG,KAAK,CAAC;QAEtF,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACrC,IAAI,CAAC,SAAS,GAAG,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACnD,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,mBAAmB,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,UAAA,MAAM,IAAI,OAAA,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAA,CAAC,CAAC;QAEjG,IAAI,IAAI,CAAC,gBAAgB,EAAE;YACzB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,UAAC,GAAG;gBACnC,IAAI;oBACF,GAAG,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC;oBACzB,GAAG,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;oBACvB,OAAO,IAAI,CAAC;iBACb;gBAAC,OAAO,GAAG,EAAE;;oBAEZ,OAAO,KAAK,CAAC;iBACd;aACF,CAAC,CAAC;SACJ;KACF;IAED,8BAAO,GAAP,UAAQ,KAAK,EAAE,MAAM;QAArB,iBAmFC;QAlFC,SAAS,kBAAkB,CAAC,SAAS,EAAE,OAAO;YAC5C,OAAO,CAAC,CAAC,KAAK,IAAI,OAAO,IAAI,KAAK,CAAC,OAAO,EAAE;iBAC3C,CAAC,MAAM,IAAI,SAAS,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;SAC5C;QAED,SAAS,QAAQ,CAAC,iBAAiB;YACjC,IAAM,SAAS,GAAG,iBAAiB,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,CAAC;YACnE,IAAI,OAAO,GAAG,iBAAiB,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,CAAC;;;YAI7D,IAAI,iBAAiB,CAAC,OAAO,CAAC,MAAM,KAAK,OAAO,GAAG,SAAS,CAAC,EAAE;gBAC7D,OAAO,IAAI,CAAC,CAAC;aACd;YAED,OAAO,EAAE,SAAS,WAAA,EAAE,OAAO,SAAA,EAAE,CAAC;SAC/B;QAED,IAAM,UAAU,GAAG,EAAE,CAAC;QAEtB,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,UAAC,KAAK;YACxB,IAAI,KAAK,CAAC,qBAAqB,EAAE;gBAAE,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;SAC3D,CAAC,CAAC;QAEH,IAAM,GAAG,GAAG;YACV,MAAM,EAAE,EAAE;YACV,WAAW,EAAE,EAAE;SAChB,CAAC;QAEF,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,UAAA,CAAC,IAAI,OAAA,CAAC,CAAC,CAAC,qBAAqB,EAAE,GAAA,CAAC,CAAC,OAAO,CAAC,UAAC,KAAK;YAChE,IAAM,OAAO,GAAG,EAAE,CAAC;YAEnB,KAAK,CAAC,SAAS,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,UAAC,UAAU;gBAC5D,IAAM,MAAM,GAAG,UAAU,CAAC,aAAa,EAAE,CAAC;gBAC1C,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC;aAC3C,CAAC,CAAC;;YAGH,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE;gBACvB,IAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAC;gBAElC,IAAI,IAAI,SAAA,CAAC;gBACT,IAAI,CAAC,GAAG,CAAC,CAAC;;oBAGR,CAAC,IAAI,CAAC,CAAC;oBACP,IAAI,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC;oBACvB,IAAI,IAAI,EAAE;wBACR,IAAM,YAAU,GAAG,KAAK,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC;wBAE9C,IAAA,KAAyB,QAAQ,CAAC,YAAU,CAAC,EAA3C,WAAS,eAAA,EAAE,SAAO,aAAyB,CAAC;wBAEpD,IAAM,oBAAoB,GAAG,OAAO,CAAC,OAAO,CAAC,WAAS,CAAC,KAAK,CAAC,CAAC,CAAC;;wBAG/D,IAAM,SAAS,GAAG,UAAU,CAAC,IAAI,CAAC,UAAA,EAAE,IAAI,OAAA,EAAE,CAAC,GAAG,KAAK,KAAK,CAAC,GAAG,IAAI,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,KAAK,YAAU,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,GAAA,CAAC,CAAC;;wBAGpJ,IAAI,MAAM,IAAI,WAAS,GAAG,MAAM,CAAC,OAAO,EAAE;2CAAQ;;wBAGlD,IAAI,kBAAkB,CAAC,WAAS,EAAE,SAAO,CAAC,EAAE;4BAC1C,IAAI,SAAS,EAAE;gCACb,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;6BAC5B;iCAAM,IAAI,CAAC,oBAAoB,EAAE;gCAChC,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,YAAU,CAAC,CAAC;6BAClC;yBACF;qBACF;;gBAxBH;;;;yBA0BO,IAAI,KAAK,CAAC,KAAI,CAAC,aAAa,IAAI,CAAC,GAAG,KAAI,CAAC,aAAa,CAAC,EAAE;gBAEhE,OAAO;aACR;;YAGK,IAAA,KAAyB,QAAQ,CAAC,KAAK,CAAC,EAAtC,SAAS,eAAA,EAAE,OAAO,aAAoB,CAAC;YAE/C,IAAI,kBAAkB,CAAC,SAAS,EAAE,OAAO,CAAC;gBAAE,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;SACpE,CAAC,CAAC;QAEH,OAAO,GAAG,CAAC;KACZ;IAED,6BAAM,GAAN,UAAO,MAAM;QACX,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;KACxC;IAED,4BAAK,GAAL,UAAM,KAAK;QACT,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;KAC5B;IAED,0BAAG,GAAH;QACE,OAAO,IAAI,CAAC,OAAO,EAAE,CAAC;KACvB;IACH,mBAAC;AAAD,CAAC;;AC3GD,IAAI,cAAc,GAAiC;IAEjD,SAAS,YAAC,OAAO;QACf,IAAI,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,MAAM,KAAK,KAAK,EAAE;YAC3C,OAAO;gBACL,GAAG,EAAE,OAAO,CAAC,GAAG;gBAChB,MAAM,EAAE,KAAK;aACd,CAAA;SACF;QACD,OAAO,IAAI,CAAA;KACZ;IAED,KAAK,EAAL,UAAM,GAAG,EAAE,SAAS,EAAE,SAAS;QACvB,IAAA,IAAI,GAAK,GAAG,CAAC,WAAW,KAApB,CAAoB;QACxB,IAAA,aAAa,GAAK,IAAI,cAAT,CAAS;QAE5B,SAAS,gBAAgB,CAAC,YAAY,EAAE,YAA0B,EAAE,GAAG;YACrE,IAAI,YAAY,EAAE;gBAChB,SAAS,CAAC,EAAE,OAAO,EAAE,YAAY,EAAE,GAAG,KAAA,EAAE,CAAC,CAAA;aAC1C;iBAAM;gBACL,SAAS,CAAC,EAAE,SAAS,EAAE,gBAAgB,CAAC,YAAY,EAAE,GAAG,CAAC,KAAK,CAAC,EAAE,GAAG,KAAA,EAAE,CAAC,CAAA;aACzE;SACF;;;;;QAMD,IAAI,CAAC,aAAa,IAAI,GAAG,CAAC,SAAS,EAAE;YACnC,aAAa,GAAG,IAAI,CAAC,aAAa,GAAG;gBACnC,SAAS,EAAE,KAAK;gBAChB,SAAS,EAAE,CAAC,gBAAgB,CAAC;gBAC7B,YAAY,EAAE,EAAE;gBAChB,YAAY,EAAE,IAAI;gBAClB,GAAG,EAAE,IAAI;aACV,CAAA;YAED,WAAW,CACT,IAAI,CAAC,GAAG,EACR,UAAC,OAAO,EAAE,GAAG;gBACX,IAAI,YAAY,GAAG,IAAI,YAAY,CAAC;oBAClC,GAAG,EAAE,OAAO;oBACZ,gBAAgB,EAAE,IAAI;iBACvB,CAAC,CAAA;gBAEF,KAAqB,UAAuB,EAAvB,KAAA,aAAa,CAAC,SAAS,EAAvB,cAAuB,EAAvB,IAAuB,EAAE;oBAAzC,IAAI,QAAQ,SAAA;oBACf,QAAQ,CAAC,EAAE,EAAE,YAAY,EAAE,GAAG,CAAC,CAAA;iBAChC;gBAED,aAAa,CAAC,SAAS,GAAG,IAAI,CAAA;gBAC9B,aAAa,CAAC,SAAS,GAAG,EAAE,CAAA;gBAC5B,aAAa,CAAC,YAAY,GAAG,YAAY,CAAA;gBACzC,aAAa,CAAC,GAAG,GAAG,GAAG,CAAA;aACxB,EACD,UAAC,YAAY,EAAE,GAAG;gBAChB,KAAqB,UAAuB,EAAvB,KAAA,aAAa,CAAC,SAAS,EAAvB,cAAuB,EAAvB,IAAuB,EAAE;oBAAzC,IAAI,QAAQ,SAAA;oBACf,QAAQ,CAAC,YAAY,EAAE,IAAI,EAAE,GAAG,CAAC,CAAA;iBAClC;gBAED,aAAa,CAAC,SAAS,GAAG,IAAI,CAAA;gBAC9B,aAAa,CAAC,SAAS,GAAG,EAAE,CAAA;gBAC5B,aAAa,CAAC,YAAY,GAAG,YAAY,CAAA;gBACzC,aAAa,CAAC,GAAG,GAAG,GAAG,CAAA;aACxB,CACF,CAAA;SACF;aAAM,IAAI,CAAC,aAAa,CAAC,SAAS,EAAE;YACnC,aAAa,CAAC,SAAS,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAA;SAC/C;aAAM;YACL,gBAAgB,CAAC,aAAa,CAAC,YAAY,EAAE,aAAa,CAAC,YAAY,EAAE,aAAa,CAAC,GAAG,CAAC,CAAA;SAC5F;KACF;CACF,CAAA;AAED,SAAS,WAAW,CAAC,GAAW,EAAE,eAAwB,EAAE,eAAwB;IAClF,IAAM,GAAG,GAAG,IAAI,cAAc,EAAE,CAAA;IAChC,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE,IAAI,CAAC,CAAA;IAC1B,GAAG,CAAC,MAAM,GAAG;QACX,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,MAAM,GAAG,GAAG,EAAE;YACzC,eAAe,CAAC,GAAG,CAAC,YAAY,EAAE,GAAG,CAAC,CAAA;SACvC;aAAM;YACL,eAAe,CAAC,gBAAgB,EAAE,GAAG,CAAC,CAAA;SACvC;KACF,CAAA;IACD,GAAG,CAAC,OAAO,GAAG,cAAM,OAAA,eAAe,CAAC,gBAAgB,EAAE,GAAG,CAAC,GAAA,CAAA;IAC1D,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AAChB,CAAC;AAED,SAAS,gBAAgB,CAAC,YAA0B,EAAE,KAAgB;;;IAGpE,IAAI,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAA;IACzC,IAAI,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,CAAA;IAEpC,IAAI,OAAO,GAAG,YAAY,CAAC,OAAO,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAA;IACxD,IAAI,QAAQ,GAAiB,EAAE,CAAA;;;;IAM/B,KAAsB,UAAc,EAAd,KAAA,OAAO,CAAC,MAAM,EAAd,cAAc,EAAd,IAAc,EAAE;QAAjC,IAAI,SAAS,SAAA;QAChB,QAAQ,CAAC,IAAI,uBACR,iBAAiB,CAAC,SAAS,CAAC,KAC/B,KAAK,EAAE,SAAS,CAAC,SAAS,CAAC,QAAQ,EAAE,EACrC,GAAG,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,IAAI,SAAS,CAAC,OAAO;kBAC9C,SAAS,CAAC,OAAO,CAAC,QAAQ,EAAE;kBAC5B,IAAI,IACR,CAAA;KACH;;IAGD,KAA0B,UAAmB,EAAnB,KAAA,OAAO,CAAC,WAAW,EAAnB,cAAmB,EAAnB,IAAmB,EAAE;QAA1C,IAAI,aAAa,SAAA;QACpB,IAAI,SAAS,GAAG,aAAa,CAAC,IAAI,CAAA;QAClC,QAAQ,CAAC,IAAI,uBACR,iBAAiB,CAAC,SAAS,CAAC,KAC/B,KAAK,EAAE,aAAa,CAAC,SAAS,CAAC,QAAQ,EAAE,EACzC,GAAG,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,IAAI,aAAa,CAAC,OAAO;kBAClD,aAAa,CAAC,OAAO,CAAC,QAAQ,EAAE;kBAChC,IAAI,IACR,CAAA;KACH;IAED,OAAO,QAAQ,CAAA;AACjB,CAAC;AAED,SAAS,iBAAiB,CAAC,SAAqB;IAC9C,OAAO;QACL,KAAK,EAAE,SAAS,CAAC,OAAO;QACxB,GAAG,EAAE,eAAe,CAAC,SAAS,CAAC;QAC/B,aAAa,EAAE;YACb,QAAQ,EAAE,SAAS,CAAC,QAAQ;YAC5B,SAAS,EAAE,SAAS,CAAC,SAAS;YAC9B,WAAW,EAAE,SAAS,CAAC,WAAW;SACnC;KACF,CAAA;AACH,CAAC;AAED,SAAS,eAAe,CAAC,SAAqB;IAC5C,IAAI,OAAO,GAAG,SAAS,CAAC,SAAS,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAA;IACzD,OAAO,OAAO,GAAG,OAAO,CAAC,aAAa,EAAE,GAAG,EAAE,CAAA;AAC/C,CAAC;AAED,SAAS,YAAY,CAAC,SAAqB;IACzC,OAAO,OAAO,CAAC,SAAS,CAAC,SAAS,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;QAC3D,OAAO,CAAC,SAAS,CAAC,SAAS,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC,CAAA;AAC7D,CAAC;AAED,WAAe,YAAY,CAAC;IAC1B,eAAe,EAAE,CAAC,cAAc,CAAC;CAClC,CAAC;;;;"}
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@fullcalendar/icalendar",
3
- "version": "5.7.2",
3
+ "version": "5.10.1",
4
4
  "title": "FullCalendar iCalendar Plugin",
5
5
  "description": "Fetch events from a public iCalendar / .ics feed",
6
6
  "docs": "https://fullcalendar.io/docs/icalendar",
7
7
  "dependencies": {
8
- "@fullcalendar/common": "~5.7.2",
8
+ "@fullcalendar/common": "~5.10.1",
9
9
  "ical.js": "^1.4.0",
10
- "tslib": "^2.0.3"
10
+ "tslib": "^2.1.0"
11
11
  },
12
12
  "main": "main.cjs.js",
13
13
  "module": "main.js",