diff options
Diffstat (limited to 'library/fullcalendar/packages/google-calendar')
-rw-r--r-- | library/fullcalendar/packages/google-calendar/index.global.js | 150 | ||||
-rw-r--r-- | library/fullcalendar/packages/google-calendar/index.global.min.js | 6 |
2 files changed, 156 insertions, 0 deletions
diff --git a/library/fullcalendar/packages/google-calendar/index.global.js b/library/fullcalendar/packages/google-calendar/index.global.js new file mode 100644 index 000000000..4e091c1d6 --- /dev/null +++ b/library/fullcalendar/packages/google-calendar/index.global.js @@ -0,0 +1,150 @@ +/*! +FullCalendar Google Calendar Plugin v6.0.3 +Docs & License: https://fullcalendar.io/docs/google-calendar +(c) 2022 Adam Shaw +*/ +FullCalendar.GoogleCalendar = (function (exports, core, internal) { + 'use strict'; + + // TODO: expose somehow + const API_BASE = 'https://www.googleapis.com/calendar/v3/calendars'; + const eventSourceDef = { + parseMeta(refined) { + let { googleCalendarId } = refined; + if (!googleCalendarId && refined.url) { + googleCalendarId = parseGoogleCalendarId(refined.url); + } + if (googleCalendarId) { + return { + googleCalendarId, + googleCalendarApiKey: refined.googleCalendarApiKey, + googleCalendarApiBase: refined.googleCalendarApiBase, + extraParams: refined.extraParams, + }; + } + return null; + }, + fetch(arg, successCallback, errorCallback) { + let { dateEnv, options } = arg.context; + let meta = arg.eventSource.meta; + let apiKey = meta.googleCalendarApiKey || options.googleCalendarApiKey; + if (!apiKey) { + errorCallback(new Error('Specify a googleCalendarApiKey. See https://fullcalendar.io/docs/google-calendar')); + } + else { + let url = buildUrl(meta); + // TODO: make DRY with json-feed-event-source + let { extraParams } = meta; + let extraParamsObj = typeof extraParams === 'function' ? extraParams() : extraParams; + let requestParams = buildRequestParams(arg.range, apiKey, extraParamsObj, dateEnv); + return internal.requestJson('GET', url, requestParams).then(([body, response]) => { + if (body.error) { + errorCallback(new core.JsonRequestError('Google Calendar API: ' + body.error.message, response)); + } + else { + successCallback({ + rawEvents: gcalItemsToRawEventDefs(body.items, requestParams.timeZone), + response, + }); + } + }, errorCallback); + } + }, + }; + function parseGoogleCalendarId(url) { + let match; + // detect if the ID was specified as a single string. + // will match calendars like "asdf1234@calendar.google.com" in addition to person email calendars. + if (/^[^/]+@([^/.]+\.)*(google|googlemail|gmail)\.com$/.test(url)) { + return url; + } + if ((match = /^https:\/\/www.googleapis.com\/calendar\/v3\/calendars\/([^/]*)/.exec(url)) || + (match = /^https?:\/\/www.google.com\/calendar\/feeds\/([^/]*)/.exec(url))) { + return decodeURIComponent(match[1]); + } + return null; + } + function buildUrl(meta) { + let apiBase = meta.googleCalendarApiBase; + if (!apiBase) { + apiBase = API_BASE; + } + return apiBase + '/' + encodeURIComponent(meta.googleCalendarId) + '/events'; + } + function buildRequestParams(range, apiKey, extraParams, dateEnv) { + let params; + let startStr; + let endStr; + if (dateEnv.canComputeOffset) { + // strings will naturally have offsets, which GCal needs + startStr = dateEnv.formatIso(range.start); + endStr = dateEnv.formatIso(range.end); + } + else { + // when timezone isn't known, we don't know what the UTC offset should be, so ask for +/- 1 day + // from the UTC day-start to guarantee we're getting all the events + // (start/end will be UTC-coerced dates, so toISOString is okay) + startStr = internal.addDays(range.start, -1).toISOString(); + endStr = internal.addDays(range.end, 1).toISOString(); + } + params = Object.assign(Object.assign({}, (extraParams || {})), { key: apiKey, timeMin: startStr, timeMax: endStr, singleEvents: true, maxResults: 9999 }); + if (dateEnv.timeZone !== 'local') { + params.timeZone = dateEnv.timeZone; + } + return params; + } + function gcalItemsToRawEventDefs(items, gcalTimezone) { + return items.map((item) => gcalItemToRawEventDef(item, gcalTimezone)); + } + function gcalItemToRawEventDef(item, gcalTimezone) { + let url = item.htmlLink || null; + // make the URLs for each event show times in the correct timezone + if (url && gcalTimezone) { + url = injectQsComponent(url, 'ctz=' + gcalTimezone); + } + return { + id: item.id, + title: item.summary, + start: item.start.dateTime || item.start.date, + end: item.end.dateTime || item.end.date, + url, + location: item.location, + description: item.description, + attachments: item.attachments || [], + extendedProps: (item.extendedProperties || {}).shared || {}, + }; + } + // Injects a string like "arg=value" into the querystring of a URL + // TODO: move to a general util file? + function injectQsComponent(url, component) { + // inject it after the querystring but before the fragment + return url.replace(/(\?.*?)?(#|$)/, (whole, qs, hash) => (qs ? qs + '&' : '?') + component + hash); + } + + const OPTION_REFINERS = { + googleCalendarApiKey: String, + }; + + const EVENT_SOURCE_REFINERS = { + googleCalendarApiKey: String, + googleCalendarId: String, + googleCalendarApiBase: String, + extraParams: internal.identity, + }; + + var plugin = core.createPlugin({ + name: '@fullcalendar/google-calendar', + eventSourceDefs: [eventSourceDef], + optionRefiners: OPTION_REFINERS, + eventSourceRefiners: EVENT_SOURCE_REFINERS, + }); + + core.globalPlugins.push(plugin); + + exports["default"] = plugin; + + Object.defineProperty(exports, '__esModule', { value: true }); + + return exports; + +})({}, FullCalendar, FullCalendar.Internal); diff --git a/library/fullcalendar/packages/google-calendar/index.global.min.js b/library/fullcalendar/packages/google-calendar/index.global.min.js new file mode 100644 index 000000000..7ed4c9ab0 --- /dev/null +++ b/library/fullcalendar/packages/google-calendar/index.global.min.js @@ -0,0 +1,6 @@ +/*! +FullCalendar Google Calendar Plugin v6.0.3 +Docs & License: https://fullcalendar.io/docs/google-calendar +(c) 2022 Adam Shaw +*/ +FullCalendar.GoogleCalendar=function(e,a,t){"use strict";const n={parseMeta(e){let{googleCalendarId:a}=e;return!a&&e.url&&(a=function(e){let a;if(/^[^/]+@([^/.]+\.)*(google|googlemail|gmail)\.com$/.test(e))return e;if((a=/^https:\/\/www.googleapis.com\/calendar\/v3\/calendars\/([^/]*)/.exec(e))||(a=/^https?:\/\/www.google.com\/calendar\/feeds\/([^/]*)/.exec(e)))return decodeURIComponent(a[1]);return null}(e.url)),a?{googleCalendarId:a,googleCalendarApiKey:e.googleCalendarApiKey,googleCalendarApiBase:e.googleCalendarApiBase,extraParams:e.extraParams}:null},fetch(e,n,r){let{dateEnv:o,options:l}=e.context,s=e.eventSource.meta,i=s.googleCalendarApiKey||l.googleCalendarApiKey;if(i){let l=function(e){let a=e.googleCalendarApiBase;a||(a="https://www.googleapis.com/calendar/v3/calendars");return a+"/"+encodeURIComponent(e.googleCalendarId)+"/events"}(s),{extraParams:d}=s,g="function"==typeof d?d():d,c=function(e,a,n,r){let o,l,s;r.canComputeOffset?(l=r.formatIso(e.start),s=r.formatIso(e.end)):(l=t.addDays(e.start,-1).toISOString(),s=t.addDays(e.end,1).toISOString());o=Object.assign(Object.assign({},n||{}),{key:a,timeMin:l,timeMax:s,singleEvents:!0,maxResults:9999}),"local"!==r.timeZone&&(o.timeZone=r.timeZone);return o}(e.range,i,g,o);return t.requestJson("GET",l,c).then(([e,t])=>{var o,l;e.error?r(new a.JsonRequestError("Google Calendar API: "+e.error.message,t)):n({rawEvents:(o=e.items,l=c.timeZone,o.map(e=>function(e,a){let t=e.htmlLink||null;t&&a&&(t=function(e,a){return e.replace(/(\?.*?)?(#|$)/,(e,t,n)=>(t?t+"&":"?")+a+n)}(t,"ctz="+a));return{id:e.id,title:e.summary,start:e.start.dateTime||e.start.date,end:e.end.dateTime||e.end.date,url:t,location:e.location,description:e.description,attachments:e.attachments||[],extendedProps:(e.extendedProperties||{}).shared||{}}}(e,l))),response:t})},r)}r(new Error("Specify a googleCalendarApiKey. See https://fullcalendar.io/docs/google-calendar"))}};const r={googleCalendarApiKey:String},o={googleCalendarApiKey:String,googleCalendarId:String,googleCalendarApiBase:String,extraParams:t.identity};var l=a.createPlugin({name:"@fullcalendar/google-calendar",eventSourceDefs:[n],optionRefiners:r,eventSourceRefiners:o});return a.globalPlugins.push(l),e.default=l,Object.defineProperty(e,"__esModule",{value:!0}),e}({},FullCalendar,FullCalendar.Internal);
\ No newline at end of file |