From a9ae17036d30a676c833a6ddb98409f19cbbd963 Mon Sep 17 00:00:00 2001 From: Mario Date: Wed, 25 Jan 2023 13:09:00 +0000 Subject: update fullcalendar --- .../packages/icalendar/index.global.js | 225 +++++++++++++++++++++ .../packages/icalendar/index.global.min.js | 6 + 2 files changed, 231 insertions(+) create mode 100644 library/fullcalendar/packages/icalendar/index.global.js create mode 100644 library/fullcalendar/packages/icalendar/index.global.min.js (limited to 'library/fullcalendar/packages/icalendar') diff --git a/library/fullcalendar/packages/icalendar/index.global.js b/library/fullcalendar/packages/icalendar/index.global.js new file mode 100644 index 000000000..c92e09e54 --- /dev/null +++ b/library/fullcalendar/packages/icalendar/index.global.js @@ -0,0 +1,225 @@ +/*! +FullCalendar iCalendar Plugin v6.0.3 +Docs & License: https://fullcalendar.io/docs/icalendar +(c) 2022 Adam Shaw +*/ +FullCalendar.ICalendar = (function (exports, core, internal, ICAL) { + 'use strict'; + + function _interopNamespace(e) { + if (e && e.__esModule) return e; + var n = Object.create(null); + if (e) { + Object.keys(e).forEach(function (k) { + if (k !== 'default') { + var d = Object.getOwnPropertyDescriptor(e, k); + Object.defineProperty(n, k, d.get ? d : { + enumerable: true, + get: function () { return e[k]; } + }); + } + }); + } + n["default"] = e; + return n; + } + + var ICAL__namespace = /*#__PURE__*/_interopNamespace(ICAL); + + /* eslint-disable */ + class IcalExpander { + constructor(opts) { + this.maxIterations = opts.maxIterations != null ? opts.maxIterations : 1000; + this.skipInvalidDates = opts.skipInvalidDates != null ? opts.skipInvalidDates : false; + this.jCalData = ICAL__namespace.parse(opts.ics); + this.component = new ICAL__namespace.Component(this.jCalData); + this.events = this.component.getAllSubcomponents('vevent').map(vevent => new ICAL__namespace.Event(vevent)); + if (this.skipInvalidDates) { + this.events = this.events.filter((evt) => { + try { + evt.startDate.toJSDate(); + evt.endDate.toJSDate(); + return true; + } + catch (err) { + // skipping events with invalid time + return false; + } + }); + } + } + between(after, before) { + function isEventWithinRange(startTime, endTime) { + return (!after || endTime >= after.getTime()) && + (!before || startTime <= before.getTime()); + } + function getTimes(eventOrOccurrence) { + const startTime = eventOrOccurrence.startDate.toJSDate().getTime(); + let endTime = eventOrOccurrence.endDate.toJSDate().getTime(); + // If it is an all day event, the end date is set to 00:00 of the next day + // So we need to make it be 23:59:59 to compare correctly with the given range + if (eventOrOccurrence.endDate.isDate && (endTime > startTime)) { + endTime -= 1; + } + return { startTime, endTime }; + } + const exceptions = []; + this.events.forEach((event) => { + if (event.isRecurrenceException()) + exceptions.push(event); + }); + const ret = { + events: [], + occurrences: [], + }; + this.events.filter(e => !e.isRecurrenceException()).forEach((event) => { + const exdates = []; + event.component.getAllProperties('exdate').forEach((exdateProp) => { + const exdate = exdateProp.getFirstValue(); + exdates.push(exdate.toJSDate().getTime()); + }); + // Recurring event is handled differently + if (event.isRecurring()) { + const iterator = event.iterator(); + let next; + let i = 0; + do { + i += 1; + next = iterator.next(); + if (next) { + const occurrence = event.getOccurrenceDetails(next); + const { startTime, endTime } = getTimes(occurrence); + const isOccurrenceExcluded = exdates.indexOf(startTime) !== -1; + // TODO check that within same day? + const exception = exceptions.find(ex => ex.uid === event.uid && ex.recurrenceId.toJSDate().getTime() === occurrence.startDate.toJSDate().getTime()); + // We have passed the max date, stop + if (before && startTime > before.getTime()) + break; + // Check that we are within our range + if (isEventWithinRange(startTime, endTime)) { + if (exception) { + ret.events.push(exception); + } + else if (!isOccurrenceExcluded) { + ret.occurrences.push(occurrence); + } + } + } + } while (next && (!this.maxIterations || i < this.maxIterations)); + return; + } + // Non-recurring event: + const { startTime, endTime } = getTimes(event); + if (isEventWithinRange(startTime, endTime)) + ret.events.push(event); + }); + return ret; + } + before(before) { + return this.between(undefined, before); + } + after(after) { + return this.between(after); + } + all() { + return this.between(); + } + } + + const eventSourceDef = { + parseMeta(refined) { + if (refined.url && refined.format === 'ics') { + return { + url: refined.url, + format: 'ics', + }; + } + return null; + }, + fetch(arg, successCallback, errorCallback) { + let meta = arg.eventSource.meta; + let { internalState } = meta; + /* + NOTE: isRefetch is a HACK. we would do the recurring-expanding in a separate plugin hook, + but we couldn't leverage built-in allDay-guessing, among other things. + */ + if (!internalState || arg.isRefetch) { + internalState = meta.internalState = { + response: null, + iCalExpanderPromise: fetch(meta.url, { method: 'GET' }).then((response) => { + return response.text().then((icsText) => { + internalState.response = response; + return new IcalExpander({ + ics: icsText, + skipInvalidDates: true, + }); + }); + }), + }; + } + internalState.iCalExpanderPromise.then((iCalExpander) => { + successCallback({ + rawEvents: expandICalEvents(iCalExpander, arg.range), + response: internalState.response, + }); + }, errorCallback); + }, + }; + function expandICalEvents(iCalExpander, range) { + // expand the range. because our `range` is timeZone-agnostic UTC + // or maybe because ical.js always produces dates in local time? i forget + let rangeStart = internal.addDays(range.start, -1); + let rangeEnd = internal.addDays(range.end, 1); + let iCalRes = iCalExpander.between(rangeStart, rangeEnd); // end inclusive. will give extra results + let expanded = []; + // TODO: instead of using startDate/endDate.toString to communicate allDay, + // we can query startDate/endDate.isDate. More efficient to avoid formatting/reparsing. + // single events + for (let iCalEvent of iCalRes.events) { + expanded.push(Object.assign(Object.assign({}, buildNonDateProps(iCalEvent)), { start: iCalEvent.startDate.toString(), end: (specifiesEnd(iCalEvent) && iCalEvent.endDate) + ? iCalEvent.endDate.toString() + : null })); + } + // recurring event instances + for (let iCalOccurence of iCalRes.occurrences) { + let iCalEvent = iCalOccurence.item; + expanded.push(Object.assign(Object.assign({}, buildNonDateProps(iCalEvent)), { start: iCalOccurence.startDate.toString(), end: (specifiesEnd(iCalEvent) && iCalOccurence.endDate) + ? iCalOccurence.endDate.toString() + : null })); + } + return expanded; + } + function buildNonDateProps(iCalEvent) { + return { + title: iCalEvent.summary, + url: extractEventUrl(iCalEvent), + extendedProps: { + location: iCalEvent.location, + organizer: iCalEvent.organizer, + description: iCalEvent.description, + }, + }; + } + function extractEventUrl(iCalEvent) { + let urlProp = iCalEvent.component.getFirstProperty('url'); + return urlProp ? urlProp.getFirstValue() : ''; + } + function specifiesEnd(iCalEvent) { + return Boolean(iCalEvent.component.getFirstProperty('dtend')) || + Boolean(iCalEvent.component.getFirstProperty('duration')); + } + + var plugin = core.createPlugin({ + name: '@fullcalendar/icalendar', + eventSourceDefs: [eventSourceDef], + }); + + core.globalPlugins.push(plugin); + + exports["default"] = plugin; + + Object.defineProperty(exports, '__esModule', { value: true }); + + return exports; + +})({}, FullCalendar, FullCalendar.Internal, ICAL); diff --git a/library/fullcalendar/packages/icalendar/index.global.min.js b/library/fullcalendar/packages/icalendar/index.global.min.js new file mode 100644 index 000000000..01d7e81ec --- /dev/null +++ b/library/fullcalendar/packages/icalendar/index.global.min.js @@ -0,0 +1,6 @@ +/*! +FullCalendar iCalendar Plugin v6.0.3 +Docs & License: https://fullcalendar.io/docs/icalendar +(c) 2022 Adam Shaw +*/ +FullCalendar.ICalendar=function(e,t,n,r){"use strict";function a(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,t}var s=a(r);class i{constructor(e){this.maxIterations=null!=e.maxIterations?e.maxIterations:1e3,this.skipInvalidDates=null!=e.skipInvalidDates&&e.skipInvalidDates,this.jCalData=s.parse(e.ics),this.component=new s.Component(this.jCalData),this.events=this.component.getAllSubcomponents("vevent").map(e=>new s.Event(e)),this.skipInvalidDates&&(this.events=this.events.filter(e=>{try{return e.startDate.toJSDate(),e.endDate.toJSDate(),!0}catch(e){return!1}}))}between(e,t){function n(n,r){return(!e||r>=e.getTime())&&(!t||n<=t.getTime())}function r(e){const t=e.startDate.toJSDate().getTime();let n=e.endDate.toJSDate().getTime();return e.endDate.isDate&&n>t&&(n-=1),{startTime:t,endTime:n}}const a=[];this.events.forEach(e=>{e.isRecurrenceException()&&a.push(e)});const s={events:[],occurrences:[]};return this.events.filter(e=>!e.isRecurrenceException()).forEach(e=>{const i=[];if(e.component.getAllProperties("exdate").forEach(e=>{const t=e.getFirstValue();i.push(t.toJSDate().getTime())}),e.isRecurring()){const o=e.iterator();let c,l=0;do{if(l+=1,c=o.next(),c){const o=e.getOccurrenceDetails(c),{startTime:l,endTime:u}=r(o),d=-1!==i.indexOf(l),p=a.find(t=>t.uid===e.uid&&t.recurrenceId.toJSDate().getTime()===o.startDate.toJSDate().getTime());if(t&&l>t.getTime())break;n(l,u)&&(p?s.events.push(p):d||s.occurrences.push(o))}}while(c&&(!this.maxIterations||le.url&&"ics"===e.format?{url:e.url,format:"ics"}:null,fetch(e,t,n){let r=e.eventSource.meta,{internalState:a}=r;a&&!e.isRefetch||(a=r.internalState={response:null,iCalExpanderPromise:fetch(r.url,{method:"GET"}).then(e=>e.text().then(t=>(a.response=e,new i({ics:t,skipInvalidDates:!0}))))}),a.iCalExpanderPromise.then(n=>{t({rawEvents:c(n,e.range),response:a.response})},n)}};function c(e,t){let r=n.addDays(t.start,-1),a=n.addDays(t.end,1),s=e.between(r,a),i=[];for(let e of s.events)i.push(Object.assign(Object.assign({},l(e)),{start:e.startDate.toString(),end:d(e)&&e.endDate?e.endDate.toString():null}));for(let e of s.occurrences){let t=e.item;i.push(Object.assign(Object.assign({},l(t)),{start:e.startDate.toString(),end:d(t)&&e.endDate?e.endDate.toString():null}))}return i}function l(e){return{title:e.summary,url:u(e),extendedProps:{location:e.location,organizer:e.organizer,description:e.description}}}function u(e){let 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({name:"@fullcalendar/icalendar",eventSourceDefs:[o]});return t.globalPlugins.push(p),e.default=p,Object.defineProperty(e,"__esModule",{value:!0}),e}({},FullCalendar,FullCalendar.Internal,ICAL); \ No newline at end of file -- cgit v1.2.3