UNPKG

evc

Version:

A simple javascript event calendar

613 lines (500 loc) 21.8 kB
(function webpackUniversalModuleDefinition(root, factory) { if(typeof exports === 'object' && typeof module === 'object') module.exports = factory(); else if(typeof define === 'function' && define.amd) define([], factory); else if(typeof exports === 'object') exports["EVC"] = factory(); else root["EVC"] = factory(); })(self, () => { return /******/ (() => { // webpackBootstrap /******/ "use strict"; /******/ // The require scope /******/ var __webpack_require__ = {}; /******/ /************************************************************************/ /******/ /* webpack/runtime/define property getters */ /******/ (() => { /******/ // define getter functions for harmony exports /******/ __webpack_require__.d = (exports, definition) => { /******/ for(var key in definition) { /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); /******/ } /******/ } /******/ }; /******/ })(); /******/ /******/ /* webpack/runtime/hasOwnProperty shorthand */ /******/ (() => { /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) /******/ })(); /******/ /******/ /* webpack/runtime/make namespace object */ /******/ (() => { /******/ // define __esModule on exports /******/ __webpack_require__.r = (exports) => { /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); /******/ } /******/ Object.defineProperty(exports, '__esModule', { value: true }); /******/ }; /******/ })(); /******/ /************************************************************************/ var __webpack_exports__ = {}; // ESM COMPAT FLAG __webpack_require__.r(__webpack_exports__); // EXPORTS __webpack_require__.d(__webpack_exports__, { "CalendarEvent": () => (/* reexport */ CalendarEvent), "EventCalendar": () => (/* reexport */ EventCalendar) }); ;// CONCATENATED MODULE: ./node_modules/uuid/dist/esm-browser/native.js const randomUUID = typeof crypto !== 'undefined' && crypto.randomUUID && crypto.randomUUID.bind(crypto); /* harmony default export */ const esm_browser_native = ({ randomUUID }); ;// CONCATENATED MODULE: ./node_modules/uuid/dist/esm-browser/rng.js // Unique ID creation requires a high quality random # generator. In the browser we therefore // require the crypto API and do not support built-in fallback to lower quality random number // generators (like Math.random()). let getRandomValues; const rnds8 = new Uint8Array(16); function rng() { // lazy load so that environments that need to polyfill have a chance to do so if (!getRandomValues) { // getRandomValues needs to be invoked in a context where "this" is a Crypto implementation. getRandomValues = typeof crypto !== 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto); if (!getRandomValues) { throw new Error('crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported'); } } return getRandomValues(rnds8); } ;// CONCATENATED MODULE: ./node_modules/uuid/dist/esm-browser/stringify.js /** * Convert array of 16 byte values to UUID string format of the form: * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX */ const byteToHex = []; for (let i = 0; i < 256; ++i) { byteToHex.push((i + 0x100).toString(16).slice(1)); } function unsafeStringify(arr, offset = 0) { // Note: Be careful editing this code! It's been tuned for performance // and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434 return byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + '-' + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + '-' + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + '-' + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + '-' + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]; } function stringify(arr, offset = 0) { const uuid = unsafeStringify(arr, offset); // Consistency check for valid UUID. If this throws, it's likely due to one // of the following: // - One or more input array values don't map to a hex octet (leading to // "undefined" in the uuid) // - Invalid input values for the RFC `version` or `variant` fields if (!validate(uuid)) { throw TypeError('Stringified UUID is invalid'); } return uuid; } /* harmony default export */ const esm_browser_stringify = ((/* unused pure expression or super */ null && (stringify))); ;// CONCATENATED MODULE: ./node_modules/uuid/dist/esm-browser/v4.js function v4(options, buf, offset) { if (esm_browser_native.randomUUID && !buf && !options) { return esm_browser_native.randomUUID(); } options = options || {}; const rnds = options.random || (options.rng || rng)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` rnds[6] = rnds[6] & 0x0f | 0x40; rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided if (buf) { offset = offset || 0; for (let i = 0; i < 16; ++i) { buf[offset + i] = rnds[i]; } return buf; } return unsafeStringify(rnds); } /* harmony default export */ const esm_browser_v4 = (v4); ;// CONCATENATED MODULE: ./src/CalendarEvent.js function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } var CalendarEvent = /*#__PURE__*/function () { function CalendarEvent(_ref) { var _ref$id = _ref.id, id = _ref$id === void 0 ? null : _ref$id, title = _ref.title, start = _ref.start, _ref$end = _ref.end, end = _ref$end === void 0 ? null : _ref$end, _ref$themeColor = _ref.themeColor, themeColor = _ref$themeColor === void 0 ? "#03a9f4" : _ref$themeColor, _ref$props = _ref.props, props = _ref$props === void 0 ? {} : _ref$props; _classCallCheck(this, CalendarEvent); this.id = id ? id : esm_browser_v4(); this.title = title; // if end day of weekly event is given but no start is given if (end && end.weekDay !== undefined && Number.isInteger(end.weekDay) && (start.weekDay === undefined || !Number.isInteger(start.weekDay))) { throw "End day of weekly event is given but no start day is given"; } this.start = start; this.end = end !== null && end !== void 0 ? end : {}; Object.assign(this.end, end !== null && end !== void 0 ? end : this.start); if (this.validateHexColor(themeColor)) { this.themeColor = themeColor; } this.props = props; } _createClass(CalendarEvent, [{ key: "validateHexColor", value: function validateHexColor(color) { if (color.match(/^#([0-9a-f]{3}){1,2}$/i) !== null) { return true; } else { throw "Invalid hex color " + color; } } }]); return CalendarEvent; }(); ;// CONCATENATED MODULE: ./src/EventCalendar.js function EventCalendar_classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function EventCalendar_defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function EventCalendar_createClass(Constructor, protoProps, staticProps) { if (protoProps) EventCalendar_defineProperties(Constructor.prototype, protoProps); if (staticProps) EventCalendar_defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } function _classPrivateFieldInitSpec(obj, privateMap, value) { _checkPrivateRedeclaration(obj, privateMap); privateMap.set(obj, value); } function _checkPrivateRedeclaration(obj, privateCollection) { if (privateCollection.has(obj)) { throw new TypeError("Cannot initialize the same private elements twice on an object"); } } function _classPrivateFieldSet(receiver, privateMap, value) { var descriptor = _classExtractFieldDescriptor(receiver, privateMap, "set"); _classApplyDescriptorSet(receiver, descriptor, value); return value; } function _classApplyDescriptorSet(receiver, descriptor, value) { if (descriptor.set) { descriptor.set.call(receiver, value); } else { if (!descriptor.writable) { throw new TypeError("attempted to set read only private field"); } descriptor.value = value; } } function _classPrivateFieldGet(receiver, privateMap) { var descriptor = _classExtractFieldDescriptor(receiver, privateMap, "get"); return _classApplyDescriptorGet(receiver, descriptor); } function _classExtractFieldDescriptor(receiver, privateMap, action) { if (!privateMap.has(receiver)) { throw new TypeError("attempted to " + action + " private field on non-instance"); } return privateMap.get(receiver); } function _classApplyDescriptorGet(receiver, descriptor) { if (descriptor.get) { return descriptor.get.call(receiver); } return descriptor.value; } var _today = /*#__PURE__*/new WeakMap(); var _days = /*#__PURE__*/new WeakMap(); var _month = /*#__PURE__*/new WeakMap(); var _year = /*#__PURE__*/new WeakMap(); var _events = /*#__PURE__*/new WeakMap(); var _defaultEvents = /*#__PURE__*/new WeakMap(); var _selectedDay = /*#__PURE__*/new WeakMap(); var _customEventStore = /*#__PURE__*/new WeakMap(); var _queuedCustomEvents = /*#__PURE__*/new WeakMap(); var EventCalendar = /*#__PURE__*/function () { function EventCalendar() { var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, _ref$events = _ref.events, events = _ref$events === void 0 ? [] : _ref$events; EventCalendar_classCallCheck(this, EventCalendar); _classPrivateFieldInitSpec(this, _today, { writable: true, value: new Date() }); _classPrivateFieldInitSpec(this, _days, { writable: true, value: void 0 }); _classPrivateFieldInitSpec(this, _month, { writable: true, value: void 0 }); _classPrivateFieldInitSpec(this, _year, { writable: true, value: void 0 }); _classPrivateFieldInitSpec(this, _events, { writable: true, value: [] }); _classPrivateFieldInitSpec(this, _defaultEvents, { writable: true, value: [new CalendarEvent({ title: "Today", start: { day: _classPrivateFieldGet(this, _today).getDate(), month: _classPrivateFieldGet(this, _today).getMonth() + 1, year: _classPrivateFieldGet(this, _today).getFullYear() }, themeColor: "#8a4af3" })] }); _classPrivateFieldInitSpec(this, _selectedDay, { writable: true, value: null }); _classPrivateFieldInitSpec(this, _customEventStore, { writable: true, value: [] }); _classPrivateFieldInitSpec(this, _queuedCustomEvents, { writable: true, value: [] }); // this.htmlElement = targetElement; if (this.validateNoDuplicateEvents(events)) { this.events = events; } else { throw "Duplicate Events Not Allowed"; } this.setup(); } EventCalendar_createClass(EventCalendar, [{ key: "month", get: function get() { return _classPrivateFieldGet(this, _month); }, set: function set(month) { _classPrivateFieldSet(this, _month, month); if (this.month > 11) { _classPrivateFieldSet(this, _month, 0); this.year++; } else if (this.month < 0) { _classPrivateFieldSet(this, _month, 11); this.year--; } //dispatch event this.dispatchCustomEvent("monthChanged", this.month); // update days this.updateDays(); } }, { key: "year", get: function get() { return _classPrivateFieldGet(this, _year); }, set: function set(year) { _classPrivateFieldSet(this, _year, year); this.dispatchCustomEvent("yearChanged", this.year); // update days this.updateDays(); } }, { key: "events", get: function get() { return _classPrivateFieldGet(this, _events); }, set: function set(events) { events.map(function (ev) { return new CalendarEvent(ev); }); // convert to calendar event if its not already _classPrivateFieldSet(this, _events, events.map(function (ev) { return ev instanceof CalendarEvent ? ev : new CalendarEvent(ev); })); this.updateDays(); this.dispatchCustomEvent("eventsChanged", this.events); } }, { key: "selectedDay", get: function get() { return _classPrivateFieldGet(this, _selectedDay); }, set: function set(day) { _classPrivateFieldSet(this, _selectedDay, day); this.dispatchCustomEvent("selectedDayChanged", { day: this.selectedDay, events: this.getEventsForDay(day) }); this.updateDays(); } }, { key: "days", get: function get() { var _this = this; var x = _classPrivateFieldGet(this, _days).map(function (day) { return { day: day, events: _this.getEventsForDay(day) }; }); return x; }, set: function set(days) { _classPrivateFieldSet(this, _days, days); this.dispatchCustomEvent("daysChanged", this.days); } }, { key: "customEventStore", get: function get() { return _classPrivateFieldGet(this, _customEventStore); }, set: function set(customEvents) { _classPrivateFieldSet(this, _customEventStore, []); } }, { key: "setup", value: function setup() { this.events = this.events.concat(_classPrivateFieldGet(this, _defaultEvents)); this.month = _classPrivateFieldGet(this, _today).getMonth(); this.year = _classPrivateFieldGet(this, _today).getFullYear(); this.days = this.getDaysInMonth(this.month, this.year); } }, { key: "on", value: function on(customEvent, callback) { var _this2 = this; _classPrivateFieldGet(this, _customEventStore).push({ customEventName: customEvent, callback: callback }); // check and even with this name is queued var queuedCallsForThisEvent = _classPrivateFieldGet(this, _queuedCustomEvents).filter(function (ev) { return ev.customEventName === customEvent; }); if (queuedCallsForThisEvent.length > 0) { queuedCallsForThisEvent.forEach(function (ev) { _this2.dispatchCustomEvent(ev.customEventName, ev.data); }); // clear queued calls _classPrivateFieldSet(this, _queuedCustomEvents, _classPrivateFieldGet(this, _queuedCustomEvents).filter(function (ev) { return ev.customEventName !== customEvent; })); } return this; } }, { key: "updateDays", value: function updateDays() { if (this.month !== undefined && Number.isInteger(this.month) && this.year !== undefined && Number.isInteger(this.year)) { this.days = this.getDaysInMonth(this.month, this.year); } } }, { key: "addEvent", value: function addEvent(event) { // make sure event is an instance of CalendarEvent if (!(event instanceof CalendarEvent)) { event = new CalendarEvent(event); } // make sure event is not already in events if (this.validateEventDoesntExistsAlready(event)) { this.events = this.events.concat(event); } else { throw "Duplicate Events Not Allowed"; } } }, { key: "removeEvent", value: function removeEvent(event) { // make sure event is an instance of CalendarEvent if (!(event instanceof CalendarEvent)) { event = new CalendarEvent(event); } this.events = this.events.filter(function (ev) { return ev.id !== event.id && JSON.stringify(ev) !== JSON.stringify(event); }); } }, { key: "dispatchCustomEvent", value: function dispatchCustomEvent(customEvent, data) { var _this3 = this; if (_classPrivateFieldGet(this, _customEventStore).length > 0) { _classPrivateFieldGet(this, _customEventStore).forEach(function (ev) { if (ev.customEventName === customEvent) { ev.callback(data, _this3); } }); } else { _classPrivateFieldGet(this, _queuedCustomEvents).push({ customEventName: customEvent, data: data }); } } }, { key: "getEventsForDay", value: function getEventsForDay(day) { var _this4 = this; var eventsFound = []; this.events.forEach(function (event) { if (_this4.checkDayHasEvent(day, event)) { eventsFound.push(event); } }); return eventsFound; } }, { key: "checkDayHasEvent", value: function checkDayHasEvent(day, event) { // check if all values is not undefined and is integer var validIntegers = function validIntegers() { for (var _len = arguments.length, value = new Array(_len), _key = 0; _key < _len; _key++) { value[_key] = arguments[_key]; } return value.every(function (v) { return v !== undefined && Number.isInteger(v); }); }; var checkSameObj = function checkSameObj(obj1, obj2) { return JSON.stringify(obj1) === JSON.stringify(obj2); }; var eventStartDay = validIntegers(event.start.day) === false ? 1 : event.start.day; var eventStartMonth = validIntegers(event.start.month) === false ? validIntegers(event.start.year) ? 1 : day.getMonth() + 1 : event.start.month; var eventStartYear = validIntegers(event.start.year) === false ? day.getFullYear() : event.start.year; var eventStartWeekDay = validIntegers(event.start.weekDay) === false ? null : event.start.weekDay; var eventEndDay = validIntegers(event.end.day) === false ? eventStartDay : event.end.day; var eventEndMonth = validIntegers(event.end.month) === false ? eventStartMonth : event.end.month; var eventEndYear = validIntegers(event.end.year) === false ? eventStartYear : event.end.year; var eventEndWeekDay = validIntegers(event.end.weekDay) === false ? eventStartWeekDay : event.end.weekDay; var eventStart = new Date(eventStartYear, eventStartMonth - 1, eventStartDay); var eventEnd = new Date(eventEndYear, eventEndMonth - 1, eventEndDay); //if its weekly event if (eventStartWeekDay !== null) { if (eventStartWeekDay !== null && day.getDay() === eventStartWeekDay && eventEndWeekDay === null) { return true; } else if (eventStartWeekDay !== null && eventEndWeekDay !== null && day.getDay() >= eventStartWeekDay && day.getDay() <= eventEndWeekDay) { return true; } } else { //for single day events if (this.matchSameDate(day, eventStart) && this.matchSameDate(day, eventEnd)) { return true; } //for multi day events else if (day.getTime() >= eventStart.getTime() && day.getTime() <= eventEnd.getTime()) { return true; } else { return false; } } } // makes sure event is not already in events }, { key: "validateEventDoesntExistsAlready", value: function validateEventDoesntExistsAlready(event) { var _this$events; var eventsAvailable = (_this$events = this.events) !== null && _this$events !== void 0 ? _this$events : []; return eventsAvailable.filter(function (ev) { return JSON.stringify(ev) === JSON.stringify(event); }).length === 0; } //make sure no duplicate events are }, { key: "validateNoDuplicateEvents", value: function validateNoDuplicateEvents(events) { var foundDuplicate = false; events.forEach(function (event) { if (foundDuplicate === true) { return; } if (events.filter(function (ev) { return JSON.stringify(ev) === JSON.stringify(event); }).length > 1) { foundDuplicate = true; } }); return !foundDuplicate; } }, { key: "getDaysInMonth", value: function getDaysInMonth(month, year) { var date = new Date(year, month, 1); var days = []; while (date.getMonth() === month) { days.push(new Date(date)); date.setDate(date.getDate() + 1); } return days; } }, { key: "matchSameDate", value: function matchSameDate(date1, date2) { return date1 && date2 && date1.getFullYear() === date2.getFullYear() && date1.getDate() === date2.getDate() && date1.getMonth() === date2.getMonth(); } }]); return EventCalendar; }(); ;// CONCATENATED MODULE: ./src/index.js /******/ return __webpack_exports__; /******/ })() ; });