fullcalendar-google.js 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. /*!
  2. FullCalendar Google Calendar Plugin v4.4.2
  3. Docs & License: https://fullcalendar.io/
  4. (c) 2019 Adam Shaw
  5. */
  6. (function (global, factory) {
  7. typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@fullcalendar/core')) :
  8. typeof define === 'function' && define.amd ? define(['exports', '@fullcalendar/core'], factory) :
  9. (global = global || self, factory(global.FullCalendarGoogleCalendar = {}, global.FullCalendar));
  10. }(this, function (exports, core) { 'use strict';
  11. /*! *****************************************************************************
  12. Copyright (c) Microsoft Corporation.
  13. Permission to use, copy, modify, and/or distribute this software for any
  14. purpose with or without fee is hereby granted.
  15. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
  16. REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  17. AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
  18. INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  19. LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
  20. OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  21. PERFORMANCE OF THIS SOFTWARE.
  22. ***************************************************************************** */
  23. var __assign = function() {
  24. __assign = Object.assign || function __assign(t) {
  25. for (var s, i = 1, n = arguments.length; i < n; i++) {
  26. s = arguments[i];
  27. for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
  28. }
  29. return t;
  30. };
  31. return __assign.apply(this, arguments);
  32. };
  33. // TODO: expose somehow
  34. var API_BASE = 'https://www.googleapis.com/calendar/v3/calendars';
  35. var STANDARD_PROPS = {
  36. url: String,
  37. googleCalendarApiKey: String,
  38. googleCalendarId: String,
  39. googleCalendarApiBase: String,
  40. data: null
  41. };
  42. var eventSourceDef = {
  43. parseMeta: function (raw) {
  44. if (typeof raw === 'string') {
  45. raw = { url: raw };
  46. }
  47. if (typeof raw === 'object') {
  48. var standardProps = core.refineProps(raw, STANDARD_PROPS);
  49. if (!standardProps.googleCalendarId && standardProps.url) {
  50. standardProps.googleCalendarId = parseGoogleCalendarId(standardProps.url);
  51. }
  52. delete standardProps.url;
  53. if (standardProps.googleCalendarId) {
  54. return standardProps;
  55. }
  56. }
  57. return null;
  58. },
  59. fetch: function (arg, onSuccess, onFailure) {
  60. var calendar = arg.calendar;
  61. var meta = arg.eventSource.meta;
  62. var apiKey = meta.googleCalendarApiKey || calendar.opt('googleCalendarApiKey');
  63. if (!apiKey) {
  64. onFailure({
  65. message: 'Specify a googleCalendarApiKey. See http://fullcalendar.io/docs/google_calendar/'
  66. });
  67. }
  68. else {
  69. var url = buildUrl(meta);
  70. var requestParams_1 = buildRequestParams(arg.range, apiKey, meta.data, calendar.dateEnv);
  71. core.requestJson('GET', url, requestParams_1, function (body, xhr) {
  72. if (body.error) {
  73. onFailure({
  74. message: 'Google Calendar API: ' + body.error.message,
  75. errors: body.error.errors,
  76. xhr: xhr
  77. });
  78. }
  79. else {
  80. onSuccess({
  81. rawEvents: gcalItemsToRawEventDefs(body.items, requestParams_1.timeZone),
  82. xhr: xhr
  83. });
  84. }
  85. }, function (message, xhr) {
  86. onFailure({ message: message, xhr: xhr });
  87. });
  88. }
  89. }
  90. };
  91. function parseGoogleCalendarId(url) {
  92. var match;
  93. // detect if the ID was specified as a single string.
  94. // will match calendars like "asdf1234@calendar.google.com" in addition to person email calendars.
  95. if (/^[^\/]+@([^\/\.]+\.)*(google|googlemail|gmail)\.com$/.test(url)) {
  96. return url;
  97. }
  98. else if ((match = /^https:\/\/www.googleapis.com\/calendar\/v3\/calendars\/([^\/]*)/.exec(url)) ||
  99. (match = /^https?:\/\/www.google.com\/calendar\/feeds\/([^\/]*)/.exec(url))) {
  100. return decodeURIComponent(match[1]);
  101. }
  102. }
  103. function buildUrl(meta) {
  104. var apiBase = meta.googleCalendarApiBase;
  105. if (!apiBase) {
  106. apiBase = API_BASE;
  107. }
  108. return apiBase + '/' + encodeURIComponent(meta.googleCalendarId) + '/events';
  109. }
  110. function buildRequestParams(range, apiKey, extraParams, dateEnv) {
  111. var params;
  112. var startStr;
  113. var endStr;
  114. if (dateEnv.canComputeOffset) {
  115. // strings will naturally have offsets, which GCal needs
  116. startStr = dateEnv.formatIso(range.start);
  117. endStr = dateEnv.formatIso(range.end);
  118. }
  119. else {
  120. // when timezone isn't known, we don't know what the UTC offset should be, so ask for +/- 1 day
  121. // from the UTC day-start to guarantee we're getting all the events
  122. // (start/end will be UTC-coerced dates, so toISOString is okay)
  123. startStr = core.addDays(range.start, -1).toISOString();
  124. endStr = core.addDays(range.end, 1).toISOString();
  125. }
  126. params = __assign({}, (extraParams || {}), { key: apiKey, timeMin: startStr, timeMax: endStr, singleEvents: true, maxResults: 9999 });
  127. if (dateEnv.timeZone !== 'local') {
  128. params.timeZone = dateEnv.timeZone;
  129. }
  130. return params;
  131. }
  132. function gcalItemsToRawEventDefs(items, gcalTimezone) {
  133. return items.map(function (item) {
  134. return gcalItemToRawEventDef(item, gcalTimezone);
  135. });
  136. }
  137. function gcalItemToRawEventDef(item, gcalTimezone) {
  138. var url = item.htmlLink || null;
  139. // make the URLs for each event show times in the correct timezone
  140. if (url && gcalTimezone) {
  141. url = injectQsComponent(url, 'ctz=' + gcalTimezone);
  142. }
  143. return {
  144. id: item.id,
  145. title: item.summary,
  146. start: item.start.dateTime || item.start.date,
  147. end: item.end.dateTime || item.end.date,
  148. url: url,
  149. location: item.location,
  150. description: item.description
  151. };
  152. }
  153. // Injects a string like "arg=value" into the querystring of a URL
  154. // TODO: move to a general util file?
  155. function injectQsComponent(url, component) {
  156. // inject it after the querystring but before the fragment
  157. return url.replace(/(\?.*?)?(#|$)/, function (whole, qs, hash) {
  158. return (qs ? qs + '&' : '?') + component + hash;
  159. });
  160. }
  161. var main = core.createPlugin({
  162. eventSourceDefs: [eventSourceDef]
  163. });
  164. exports.default = main;
  165. Object.defineProperty(exports, '__esModule', { value: true });
  166. }));