Path: blob/master/web-gui/buildyourownbotnet/assets/js/fullcalendar-2/gcal.js
1293 views
/*!1* FullCalendar v2.2.3 Google Calendar Plugin2* Docs & License: http://arshaw.com/fullcalendar/3* (c) 2013 Adam Shaw4*/56(function(factory) {7if (typeof define === 'function' && define.amd) {8define([ 'jquery' ], factory);9}10else {11factory(jQuery);12}13})(function($) {141516var API_BASE = 'https://www.googleapis.com/calendar/v3/calendars';17var fc = $.fullCalendar;18var applyAll = fc.applyAll;192021fc.sourceNormalizers.push(function(sourceOptions) {22var googleCalendarId = sourceOptions.googleCalendarId;23var url = sourceOptions.url;24var match;2526// if the Google Calendar ID hasn't been explicitly defined27if (!googleCalendarId && url) {2829// detect if the ID was specified as a single string.30// will match calendars like "[email protected]" in addition to person email calendars.31if ((match = /^[^\/]+@([^\/\.]+\.)*(google|googlemail|gmail)\.com$/.test(url))) {32googleCalendarId = url;33}34// try to scrape it out of a V1 or V3 API feed URL35else if (36(match = /^https:\/\/www.googleapis.com\/calendar\/v3\/calendars\/([^\/]*)/.exec(url)) ||37(match = /^https?:\/\/www.google.com\/calendar\/feeds\/([^\/]*)/.exec(url))38) {39googleCalendarId = decodeURIComponent(match[1]);40}4142if (googleCalendarId) {43sourceOptions.googleCalendarId = googleCalendarId;44}45}464748if (googleCalendarId) { // is this a Google Calendar?4950// make each Google Calendar source uneditable by default51if (sourceOptions.editable == null) {52sourceOptions.editable = false;53}5455// We want removeEventSource to work, but it won't know about the googleCalendarId primitive.56// Shoehorn it into the url, which will function as the unique primitive. Won't cause side effects.57// This hack is obsolete since 2.2.3, but keep it so this plugin file is compatible with old versions.58sourceOptions.url = googleCalendarId;59}60});616263fc.sourceFetchers.push(function(sourceOptions, start, end, timezone) {64if (sourceOptions.googleCalendarId) {65return transformOptions(sourceOptions, start, end, timezone, this); // `this` is the calendar66}67});686970function transformOptions(sourceOptions, start, end, timezone, calendar) {71var url = API_BASE + '/' + encodeURIComponent(sourceOptions.googleCalendarId) + '/events?callback=?'; // jsonp72var apiKey = sourceOptions.googleCalendarApiKey || calendar.options.googleCalendarApiKey;73var success = sourceOptions.success;74var data;75var timezoneArg; // populated when a specific timezone. escaped to Google's liking7677function reportError(message, apiErrorObjs) {78var errorObjs = apiErrorObjs || [ { message: message } ]; // to be passed into error handlers79var consoleObj = window.console;80var consoleWarnFunc = consoleObj ? (consoleObj.warn || consoleObj.log) : null;8182// call error handlers83(sourceOptions.googleCalendarError || $.noop).apply(calendar, errorObjs);84(calendar.options.googleCalendarError || $.noop).apply(calendar, errorObjs);8586// print error to debug console87if (consoleWarnFunc) {88consoleWarnFunc.apply(consoleObj, [ message ].concat(apiErrorObjs || []));89}90}9192if (!apiKey) {93reportError("Specify a googleCalendarApiKey. See http://fullcalendar.io/docs/google_calendar/");94return {}; // an empty source to use instead. won't fetch anything.95}9697// The API expects an ISO8601 datetime with a time and timezone part.98// Since the calendar's timezone offset isn't always known, request the date in UTC and pad it by a day on each99// side, guaranteeing we will receive all events in the desired range, albeit a superset.100// .utc() will set a zone and give it a 00:00:00 time.101if (!start.hasZone()) {102start = start.clone().utc().add(-1, 'day');103}104if (!end.hasZone()) {105end = end.clone().utc().add(1, 'day');106}107108// when sending timezone names to Google, only accepts underscores, not spaces109if (timezone && timezone != 'local') {110timezoneArg = timezone.replace(' ', '_');111}112113data = $.extend({}, sourceOptions.data || {}, {114key: apiKey,115timeMin: start.format(),116timeMax: end.format(),117timeZone: timezoneArg,118singleEvents: true,119maxResults: 9999120});121122return $.extend({}, sourceOptions, {123googleCalendarId: null, // prevents source-normalizing from happening again124url: url,125data: data,126startParam: false, // `false` omits this parameter. we already included it above127endParam: false, // same128timezoneParam: false, // same129success: function(data) {130var events = [];131var successArgs;132var successRes;133134if (data.error) {135reportError('Google Calendar API: ' + data.error.message, data.error.errors);136}137else if (data.items) {138$.each(data.items, function(i, entry) {139var url = entry.htmlLink;140141// make the URLs for each event show times in the correct timezone142if (timezoneArg) {143url = injectQsComponent(url, 'ctz=' + timezoneArg);144}145146events.push({147id: entry.id,148title: entry.summary,149start: entry.start.dateTime || entry.start.date, // try timed. will fall back to all-day150end: entry.end.dateTime || entry.end.date, // same151url: url,152location: entry.location,153description: entry.description154});155});156157// call the success handler(s) and allow it to return a new events array158successArgs = [ events ].concat(Array.prototype.slice.call(arguments, 1)); // forward other jq args159successRes = applyAll(success, this, successArgs);160if ($.isArray(successRes)) {161return successRes;162}163}164165return events;166}167});168}169170171// Injects a string like "arg=value" into the querystring of a URL172function injectQsComponent(url, component) {173// inject it after the querystring but before the fragment174return url.replace(/(\?.*?)?(#|$)/, function(whole, qs, hash) {175return (qs ? qs + '&' : '?') + component + hash;176});177}178179180});181182183