var VCAL_DATETIME_FORMAT = "YMMDD[T]HHmmss"; //20160216T130500 var UID_FORMAT = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'; var NEW_LINE = "\r\n"; var productID = window.title; function VMeta() { this.properties = new Map(); this.children = []; this.tag = "VMETA"; } VMeta.formatDate = function (aMoment) { 'use strict'; return aMoment.format(VCAL_DATETIME_FORMAT); }; VMeta.generateUID = function () { 'use strict'; return UID_FORMAT.replace(/[xy]/g, function (c) { var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8); return v.toString(16); }); }; VMeta.prototype.set = function (key, value) { 'use strict'; this.properties.set(key, value); }; VMeta.prototype.get = function (key) { 'use strict'; this.properties.get(key); }; VMeta.prototype.add = function (child) { 'use strict'; this.children.push(child); }; VMeta.prototype.mapToString = function () { 'use strict'; var output = ""; this.properties.forEach(function (value, key, map) { output += (NEW_LINE + key + ":" + value); }); return output; }; VMeta.prototype.childrenToString = function () { 'use strict'; var output = ""; this.children.forEach(function (child) { output += (NEW_LINE + child.toString()); }); return output; }; VMeta.prototype.toString = function () { 'use strict'; var output = "BEGIN:" + this.tag; output += this.mapToString(); output += this.childrenToString(); output += (NEW_LINE + "END:" + this.tag); return output; }; function VCalendar(calendarName) { 'use strict'; VMeta.call(this); this.add(VTimeZone.Berlin()); this.tag = "VCALENDAR"; this.set('X-WR-CALNAME', calendarName); this.set('VERSION', '2.0'); this.set('PRODID', productID); this.set('METHOD', "PUBLISH"); this.set('X-WR-TIMEZONE', "Europe/Berlin"); this.set('CALSCALE', "GREGORIAN"); }; VCalendar.prototype = Object.create(VMeta.prototype); VCalendar.prototype.constructor = VCalendar; function VEvent(timezoneName, startMoment, endMoment, title, description) { VMeta.call(this); this.tag = "VEVENT"; this.set('DTSTART;TZID=' + timezoneName, VMeta.formatDate(startMoment)); this.set('DTEND;TZID=' + timezoneName, VMeta.formatDate(endMoment)); this.set('DTSTAMP', VMeta.formatDate(moment()) + "Z"); this.set('UID', VMeta.generateUID()); this.set('SUMMARY', title); this.set('DESCRIPTION', description); this.set('CLASS', "PUBLIC"); this.set('TRANSP', "OPAQUE"); this.set('STATUS', "CONFIRMED"); this.set('ORGANIZER', ""); } VEvent.prototype = Object.create(VMeta.prototype); VEvent.prototype.constructor = VEvent; function VTimeZone() { VMeta.call(this); this.tag = "VTIMEZONE"; } VTimeZone.prototype = Object.create(VMeta.prototype); VTimeZone.prototype.constructor = VTimeZone; VTimeZone.Berlin = function () { var tz = new VTimeZone(); tz.children = [VTimeDef.MESZ(), VTimeDef.MEZ()]; tz.set("TZID", "Europe/Berlin"); return tz; } function VTimeDef(name) { VMeta.call(this); this.tag = name; } VTimeDef.prototype = Object.create(VMeta.prototype); VTimeDef.prototype.constructor = VTimeDef; VTimeDef.MESZ = function () { var timedef = new VTimeDef("DAYLIGHT"); timedef.set("TZOFFSETFROM", "+0100"); timedef.set("RRULE", "FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU"); timedef.set("DTSTART", "19819329T020000"); timedef.set("TZNAME", "MESZ"); timedef.set("TZOFFSETTO", "+0200"); return timedef; } VTimeDef.MEZ = function () { var timedef = new VTimeDef("STANDARD"); timedef.set("TZOFFSETFROM", "+0200"); timedef.set("RRULE", "FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU"); timedef.set("DTSTART", "19961027T030000"); timedef.set("TZNAME", "MEZ"); timedef.set("TZOFFSETTO", "+0100"); return timedef; }