PageSourceSearch

https://localbranding.de/files/theme_lb_de/js/ics.js

js localbranding.de collected 2026-10-07 04:52:27 UTC 8,474 bytes, 240 lines download raw bytes

vendor: 8,474 bytes, lines 1-240
1/* global saveAs, Blob, BlobBuilder, console */
2/* exported ics */
3
4var ics = function(uidDomain, prodId) {
5  'use strict';
6
7  if (navigator.userAgent.indexOf('MSIE') > -1 && navigator.userAgent.indexOf('MSIE 10') == -1) {
8    console.log('Unsupported Browser');
9    return;
10  }
11
12  if (typeof uidDomain === 'undefined') { uidDomain = 'default'; }
13  if (typeof prodId === 'undefined') { prodId = 'Calendar'; }
14
15  var SEPARATOR = (navigator.appVersion.indexOf('Win') !== -1) ? '\r\n' : '\n';
16  var calendarEvents = [];
17  var calendarStart = [
18    'BEGIN:VCALENDAR',
19    'PRODID:' + prodId,
20    'VERSION:2.0'
21  ].join(SEPARATOR);
22  var calendarEnd = SEPARATOR + 'END:VCALENDAR';
23  var BYDAY_VALUES = ['SU', 'MO', 'TU', 'WE', 'TH', 'FR', 'SA'];
24
25  return {
26    /**
27     * Returns events array
28     * @return {array} Events
29     */
30    'events': function() {
31      return calendarEvents;
32    },
33
34    /**
35     * Returns calendar
36     * @return {string} Calendar in iCalendar format
37     */
38    'calendar': function() {
39      return calendarStart + SEPARATOR + calendarEvents.join(SEPARATOR) + calendarEnd;
40    },
41
42    /**
43     * Add event to the calendar
44     * @param  {string} subject     Subject/Title of event
45     * @param  {string} description Description of event
46     * @param  {string} location    Location of event
47     * @param  {string} begin       Beginning date of event
48     * @param  {string} stop        Ending date of event
49     */
50    'addEvent': function(subject, description, location, begin, stop, rrule) {
51      // I'm not in the mood to make these optional... So they are all required
52      if (typeof subject === 'undefined' ||
53        typeof description === 'undefined' ||
54        typeof location === 'undefined' ||
55        typeof begin === 'undefined' ||
56        typeof stop === 'undefined'
57      ) {
58        return false;
59      }
60
61      // validate rrule
62      if (rrule) {
63        if (!rrule.rrule) {
64          if (rrule.freq !== 'YEARLY' && rrule.freq !== 'MONTHLY' && rrule.freq !== 'WEEKLY' && rrule.freq !== 'DAILY') {
65            throw "Recurrence rrule frequency must be provided and be one of the following: 'YEARLY', 'MONTHLY', 'WEEKLY', or 'DAILY'";
66          }
67
68          if (rrule.until) {
69            if (isNaN(Date.parse(rrule.until))) {
70              throw "Recurrence rrule 'until' must be a valid date string";
71            }
72          }
73
74          if (rrule.interval) {
75            if (isNaN(parseInt(rrule.interval))) {
76              throw "Recurrence rrule 'interval' must be an integer";
77            }
78          }
79
80          if (rrule.count) {
81            if (isNaN(parseInt(rrule.count))) {
82              throw "Recurrence rrule 'count' must be an integer";
83            }
84          }
85
86          if (typeof rrule.byday !== 'undefined') {
87            if ((Object.prototype.toString.call(rrule.byday) !== '[object Array]')) {
88              throw "Recurrence rrule 'byday' must be an array";
89            }
90
91            if (rrule.byday.length > 7) {
92              throw "Recurrence rrule 'byday' array must not be longer than the 7 days in a week";
93            }
94
95            // Filter any possible repeats
96            rrule.byday = rrule.byday.filter(function(elem, pos) {
97              return rrule.byday.indexOf(elem) == pos;
98            });
99
100            for (var d in rrule.byday) {
101              if (BYDAY_VALUES.indexOf(rrule.byday[d]) < 0) {
102                throw "Recurrence rrule 'byday' values must include only the following: 'SU', 'MO', 'TU', 'WE', 'TH', 'FR', 'SA'";
103              }
104            }
105          }
106        }
107      }
108
109      //TODO add time and time zone? use moment to format?
110      var start_date = new Date(begin);
111      var end_date = new Date(stop);
112      var now_date = new Date();
113
114      var start_year = ("0000" + (start_date.getFullYear().toString())).slice(-4);
115      var start_month = ("00" + ((start_date.getMonth() + 1).toString())).slice(-2);
116      var start_day = ("00" + ((start_date.getDate()).toString())).slice(-2);
117      var start_hours = ("00" + (start_date.getHours().toString())).slice(-2);
118      var start_minutes = ("00" + (start_date.getMinutes().toString())).slice(-2);
119      var start_seconds = ("00" + (start_date.getSeconds().toString())).slice(-2);
120
121      var end_year = ("0000" + (end_date.getFullYear().toString())).slice(-4);
122      var end_month = ("00" + ((end_date.getMonth() + 1).toString())).slice(-2);
123      var end_day = ("00" + ((end_date.getDate()).toString())).slice(-2);
124      var end_hours = ("00" + (end_date.getHours().toString())).slice(-2);
125      var end_minutes = ("00" + (end_date.getMinutes().toString())).slice(-2);
126      var end_seconds = ("00" + (end_date.getSeconds().toString())).slice(-2);
127
128      var now_year = ("0000" + (now_date.getFullYear().toString())).slice(-4);
129      var now_month = ("00" + ((now_date.getMonth() + 1).toString())).slice(-2);
130      var now_day = ("00" + ((now_date.getDate()).toString())).slice(-2);
131      var now_hours = ("00" + (now_date.getHours().toString())).slice(-2);
132      var now_minutes = ("00" + (now_date.getMinutes().toString())).slice(-2);
133      var now_seconds = ("00" + (now_date.getSeconds().toString())).slice(-2);
134
135      // Since some calendars don't add 0 second events, we need to remove time if there is none...
136      var start_time = '';
137      var end_time = '';
138      if (start_hours + start_minutes + start_seconds + end_hours + end_minutes + end_seconds != 0) {
139        start_time = 'T' + start_hours + start_minutes + start_seconds;
140        end_time = 'T' + end_hours + end_minutes + end_seconds;
141      }
142      var now_time = 'T' + now_hours + now_minutes + now_seconds;
143
144      var start = start_year + start_month + start_day + start_time;
145      var end = end_year + end_month + end_day + end_time;
146      var now = now_year + now_month + now_day + now_time;
147
148      // recurrence rrule vars
149      var rruleString;
150      if (rrule) {
151        if (rrule.rrule) {
152          rruleString = rrule.rrule;
153        } else {
154          rruleString = 'rrule:FREQ=' + rrule.freq;
155
156          if (rrule.until) {
157            var uDate = new Date(Date.parse(rrule.until)).toISOString();
158            rruleString += ';UNTIL=' + uDate.substring(0, uDate.length - 13).replace(/[-]/g, '') + '000000Z';
159          }
160
161          if (rrule.interval) {
162            rruleString += ';INTERVAL=' + rrule.interval;
163          }
164
165          if (rrule.count) {
166            rruleString += ';COUNT=' + rrule.count;
167          }
168
169          if (rrule.byday && rrule.byday.length > 0) {
170            rruleString += ';BYDAY=' + rrule.byday.join(',');
171          }
172        }
173      }
174
175      var stamp = new Date().toISOString();
176
177      var calendarEvent = [
178        'BEGIN:VEVENT',
179        'UID:' + calendarEvents.length + "@" + uidDomain,
180        'CLASS:PUBLIC',
181        'DESCRIPTION:' + description,
182        'DTSTAMP;VALUE=DATE-TIME:' + now,
183        'DTSTART;VALUE=DATE-TIME:' + start,
184        'DTEND;VALUE=DATE-TIME:' + end,
185        'LOCATION:' + location,
186        'SUMMARY;LANGUAGE=en-us:' + subject,
187        'TRANSP:TRANSPARENT',
188        'END:VEVENT'
189      ];
190
191      if (rruleString) {
192        calendarEvent.splice(4, 0, rruleString);
193      }
194
195      calendarEvent = calendarEvent.join(SEPARATOR);
196
197      calendarEvents.push(calendarEvent);
198      return calendarEvent;
199    },
200
201    /**
202     * Download calendar using the saveAs function from filesave.js
203     * @param  {string} filename Filename
204     * @param  {string} ext      Extention
205     */
206    'download': function(filename, ext) {
207      if (calendarEvents.length < 1) {
208        return false;
209      }
210
211      ext = (typeof ext !== 'undefined') ? ext : '.ics';
212      filename = (typeof filename !== 'undefined') ? filename : 'calendar';
213      var calendar = calendarStart + SEPARATOR + calendarEvents.join(SEPARATOR) + calendarEnd;
214
215      var blob;
216      if (navigator.userAgent.indexOf('MSIE 10') === -1) { // chrome or firefox
217        blob = new Blob([calendar]);
218      } else { // ie
219        var bb = new BlobBuilder();
220        bb.append(calendar);
221        blob = bb.getBlob('text/x-vCalendar;charset=' + document.characterSet);
222      }
223      saveAs(blob, filename + ext);
224      return calendar;
225    },
226
227    /**
228     * Build and return the ical contents
229     */
230    'build': function() {
231      if (calendarEvents.length < 1) {
232        return false;
233      }
234
235      var calendar = calendarStart + SEPARATOR + calendarEvents.join(SEPARATOR) + calendarEnd;
236
237      return calendar;
238    }
239  };
240};

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.