1/*! 2FullCalendar Google Calendar Plugin v4.3.0 3Docs & License: https://fullcalendar.io/ 4(c) 2019 Adam Shaw 5*/ 6 7(function (global, factory) { 8 typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@fullcalendar/core')) : 9 typeof define === 'function' && define.amd ? define(['exports', '@fullcalendar/core'], factory) : 10 (global = global || self, factory(global.FullCalendarGoogleCalendar = {}, global.FullCalendar)); 11}(this, function (exports, core) { 'use strict'; 12 13 /*! ***************************************************************************** 14 Copyright (c) Microsoft Corporation. All rights reserved. 15 Licensed under the Apache License, Version 2.0 (the "License"); you may not use 16 this file except in compliance with the License. You may obtain a copy of the 17 License at http://www.apache.org/licenses/LICENSE-2.0 18 19 THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 20 KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED 21 WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, 22 MERCHANTABLITY OR NON-INFRINGEMENT. 23 24 See the Apache Version 2.0 License for specific language governing permissions 25 and limitations under the License. 26 ***************************************************************************** */ 27 28 var __assign = function() { 29 __assign = Object.assign || function __assign(t) { 30 for (var s, i = 1, n = arguments.length; i < n; i++) { 31 s = arguments[i]; 32 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 33 } 34 return t; 35 }; 36 return __assign.apply(this, arguments); 37 }; 38 39 // TODO: expose somehow 40 var API_BASE = 'https://www.googleapis.com/calendar/v3/calendars'; 41 var STANDARD_PROPS = { 42 url: String, 43 googleCalendarApiKey: String, 44 googleCalendarId: String, 45 data: null 46 }; 47 var eventSourceDef = { 48 parseMeta: function (raw) { 49 if (typeof raw === 'string') { 50 raw = { url: raw }; 51 } 52 if (typeof raw === 'object') { 53 var standardProps = core.refineProps(raw, STANDARD_PROPS); 54 if (!standardProps.googleCalendarId && standardProps.url) { 55 standardProps.googleCalendarId = parseGoogleCalendarId(standardProps.url); 56 } 57 delete standardProps.url; 58 if (standardProps.googleCalendarId) { 59 return standardProps; 60 } 61 } 62 return null; 63 }, 64 fetch: function (arg, onSuccess, onFailure) { 65 var calendar = arg.calendar; 66 var meta = arg.eventSource.meta; 67 var apiKey = meta.googleCalendarApiKey || calendar.opt('googleCalendarApiKey'); 68 if (!apiKey) { 69 onFailure({ 70 message: 'Specify a googleCalendarApiKey. See http://fullcalendar.io/docs/google_calendar/' 71 }); 72 } 73 else { 74 var url = buildUrl(meta); 75 var requestParams_1 = buildRequestParams(arg.range, apiKey, meta.data, calendar.dateEnv); 76 core.requestJson('GET', url, requestParams_1, function (body, xhr) { 77 if (body.error) { 78 onFailure({ 79 message: 'Google Calendar API: ' + body.error.message, 80 errors: body.error.errors, 81 xhr: xhr 82 }); 83 } 84 else { 85 onSuccess({ 86 rawEvents: gcalItemsToRawEventDefs(body.items, requestParams_1.timeZone), 87 xhr: xhr 88 }); 89 } 90 }, function (message, xhr) { 91 onFailure({ message: message, xhr: xhr }); 92 }); 93 } 94 } 95 }; 96 function parseGoogleCalendarId(url) { 97 var match;
98 // detect if the ID was specified as a single string. 99 // will match calendars like "[email protected]" in addition to person email calendars. 100 if (/^[^\/]+@([^\/\.]+\.)*(google|googlemail|gmail)\.com$/.test(url)) { 101 return url; 102 } 103 else if ((match = /^https:\/\/www.googleapis.com\/calendar\/v3\/calendars\/([^\/]*)/.exec(url)) || 104 (match = /^https?:\/\/www.google.com\/calendar\/feeds\/([^\/]*)/.exec(url))) { 105 return decodeURIComponent(match[1]); 106 } 107 } 108 function buildUrl(meta) { 109 return API_BASE + '/' + encodeURIComponent(meta.googleCalendarId) + '/events'; 110 } 111 function buildRequestParams(range, apiKey, extraParams, dateEnv) { 112 var params; 113 var startStr; 114 var endStr; 115 if (dateEnv.canComputeOffset) { 116 // strings will naturally have offsets, which GCal needs 117 startStr = dateEnv.formatIso(range.start); 118 endStr = dateEnv.formatIso(range.end); 119 } 120 else { 121 // when timezone isn't known, we don't know what the UTC offset should be, so ask for +/- 1 day 122 // from the UTC day-start to guarantee we're getting all the events 123 // (start/end will be UTC-coerced dates, so toISOString is okay) 124 startStr = core.addDays(range.start, -1).toISOString(); 125 endStr = core.addDays(range.end, 1).toISOString(); 126 } 127 params = __assign({}, (extraParams || {}), { key: apiKey, timeMin: startStr, timeMax: endStr, singleEvents: true, maxResults: 9999 }); 128 if (dateEnv.timeZone !== 'local') { 129 params.timeZone = dateEnv.timeZone; 130 } 131 return params; 132 } 133 function gcalItemsToRawEventDefs(items, gcalTimezone) { 134 return items.map(function (item) { 135 return gcalItemToRawEventDef(item, gcalTimezone); 136 }); 137 } 138 function gcalItemToRawEventDef(item, gcalTimezone) { 139 var url = item.htmlLink || null; 140 // make the URLs for each event show times in the correct timezone 141 if (url && gcalTimezone) { 142 url = injectQsComponent(url, 'ctz=' + gcalTimezone); 143 } 144 return { 145 id: item.id, 146 title: item.summary, 147 start: item.start.dateTime || item.start.date, 148 end: item.end.dateTime || item.end.date, 149 url: url, 150 location: item.location, 151 description: item.description 152 }; 153 } 154 // Injects a string like "arg=value" into the querystring of a URL 155 // TODO: move to a general util file? 156 function injectQsComponent(url, component) { 157 // inject it after the querystring but before the fragment 158 return url.replace(/(\?.*?)?(#|$)/, function (whole, qs, hash) { 159 return (qs ? qs + '&' : '?') + component + hash; 160 }); 161 } 162 var main = core.createPlugin({ 163 eventSourceDefs: [eventSourceDef] 164 }); 165 166 exports.default = main; 167 168 Object.defineProperty(exports, '__esModule', { value: true }); 169 170}));
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.