diff options
Diffstat (limited to 'library/fullcalendar/packages/rrule/index.global.js')
-rw-r--r-- | library/fullcalendar/packages/rrule/index.global.js | 145 |
1 files changed, 145 insertions, 0 deletions
diff --git a/library/fullcalendar/packages/rrule/index.global.js b/library/fullcalendar/packages/rrule/index.global.js new file mode 100644 index 000000000..795d352b5 --- /dev/null +++ b/library/fullcalendar/packages/rrule/index.global.js @@ -0,0 +1,145 @@ +/*! +FullCalendar RRule Plugin v6.0.3 +Docs & License: https://fullcalendar.io/docs/rrule-plugin +(c) 2022 Adam Shaw +*/ +FullCalendar.RRule = (function (exports, core, rrule, internal) { + 'use strict'; + + const recurringType = { + parse(eventProps, dateEnv) { + if (eventProps.rrule != null) { + let eventRRuleData = parseEventRRule(eventProps, dateEnv); + if (eventRRuleData) { + return { + typeData: { rruleSet: eventRRuleData.rruleSet, isTimeZoneSpecified: eventRRuleData.isTimeZoneSpecified }, + allDayGuess: !eventRRuleData.isTimeSpecified, + duration: eventProps.duration, + }; + } + } + return null; + }, + expand(eventRRuleData, framingRange, dateEnv) { + let dates; + if (eventRRuleData.isTimeZoneSpecified) { + dates = eventRRuleData.rruleSet.between(dateEnv.toDate(framingRange.start), // rrule lib will treat as UTC-zoned + dateEnv.toDate(framingRange.end), // (same) + true).map((date) => dateEnv.createMarker(date)); // convert UTC-zoned-date to locale datemarker + } + else { + // when no timezone in given start/end, the rrule lib will assume UTC, + // which is same as our DateMarkers. no need to manipulate + dates = eventRRuleData.rruleSet.between(framingRange.start, framingRange.end, true); + } + return dates; + }, + }; + function parseEventRRule(eventProps, dateEnv) { + let rruleSet; + let isTimeSpecified = false; + let isTimeZoneSpecified = false; + if (typeof eventProps.rrule === 'string') { + let res = parseRRuleString(eventProps.rrule); + rruleSet = res.rruleSet; + isTimeSpecified = res.isTimeSpecified; + isTimeZoneSpecified = res.isTimeZoneSpecified; + } + if (typeof eventProps.rrule === 'object' && eventProps.rrule) { // non-null object + let res = parseRRuleObject(eventProps.rrule, dateEnv); + rruleSet = new rrule.RRuleSet(); + rruleSet.rrule(res.rrule); + isTimeSpecified = res.isTimeSpecified; + isTimeZoneSpecified = res.isTimeZoneSpecified; + } + // convery to arrays. TODO: general util? + let exdateInputs = [].concat(eventProps.exdate || []); + let exruleInputs = [].concat(eventProps.exrule || []); + for (let exdateInput of exdateInputs) { + let res = internal.parseMarker(exdateInput); + isTimeSpecified = isTimeSpecified || !res.isTimeUnspecified; + isTimeZoneSpecified = isTimeZoneSpecified || res.timeZoneOffset !== null; + rruleSet.exdate(new Date(res.marker.valueOf() - (res.timeZoneOffset || 0) * 60 * 1000)); + } + // TODO: exrule is deprecated. what to do? (https://icalendar.org/iCalendar-RFC-5545/a-3-deprecated-features.html) + for (let exruleInput of exruleInputs) { + let res = parseRRuleObject(exruleInput, dateEnv); + isTimeSpecified = isTimeSpecified || res.isTimeSpecified; + isTimeZoneSpecified = isTimeZoneSpecified || res.isTimeZoneSpecified; + rruleSet.exrule(res.rrule); + } + return { rruleSet, isTimeSpecified, isTimeZoneSpecified }; + } + function parseRRuleObject(rruleInput, dateEnv) { + let isTimeSpecified = false; + let isTimeZoneSpecified = false; + function processDateInput(dateInput) { + if (typeof dateInput === 'string') { + let markerData = internal.parseMarker(dateInput); + if (markerData) { + isTimeSpecified = isTimeSpecified || !markerData.isTimeUnspecified; + isTimeZoneSpecified = isTimeZoneSpecified || markerData.timeZoneOffset !== null; + return new Date(markerData.marker.valueOf() - (markerData.timeZoneOffset || 0) * 60 * 1000); // NOT DRY + } + return null; + } + return dateInput; // TODO: what about number timestamps? + } + let rruleOptions = Object.assign(Object.assign({}, rruleInput), { dtstart: processDateInput(rruleInput.dtstart), until: processDateInput(rruleInput.until), freq: convertConstant(rruleInput.freq), wkst: rruleInput.wkst == null + ? (dateEnv.weekDow - 1 + 7) % 7 // convert Sunday-first to Monday-first + : convertConstant(rruleInput.wkst), byweekday: convertConstants(rruleInput.byweekday) }); + return { rrule: new rrule.RRule(rruleOptions), isTimeSpecified, isTimeZoneSpecified }; + } + function parseRRuleString(str) { + let rruleSet = rrule.rrulestr(str, { forceset: true }); + let analysis = analyzeRRuleString(str); + return Object.assign({ rruleSet }, analysis); + } + function analyzeRRuleString(str) { + let isTimeSpecified = false; + let isTimeZoneSpecified = false; + function processMatch(whole, introPart, datePart) { + let result = internal.parseMarker(datePart); + isTimeSpecified = isTimeSpecified || !result.isTimeUnspecified; + isTimeZoneSpecified = isTimeZoneSpecified || result.timeZoneOffset !== null; + } + str.replace(/\b(DTSTART:)([^\n]*)/, processMatch); + str.replace(/\b(EXDATE:)([^\n]*)/, processMatch); + str.replace(/\b(UNTIL=)([^;\n]*)/, processMatch); + return { isTimeSpecified, isTimeZoneSpecified }; + } + function convertConstants(input) { + if (Array.isArray(input)) { + return input.map(convertConstant); + } + return convertConstant(input); + } + function convertConstant(input) { + if (typeof input === 'string') { + return rrule.RRule[input.toUpperCase()]; + } + return input; + } + + const RRULE_EVENT_REFINERS = { + rrule: internal.identity, + exrule: internal.identity, + exdate: internal.identity, + duration: internal.createDuration, + }; + + var plugin = core.createPlugin({ + name: '@fullcalendar/rrule', + recurringTypes: [recurringType], + eventRefiners: RRULE_EVENT_REFINERS, + }); + + core.globalPlugins.push(plugin); + + exports["default"] = plugin; + + Object.defineProperty(exports, '__esModule', { value: true }); + + return exports; + +})({}, FullCalendar, rrule, FullCalendar.Internal); |