UNPKG

@progress/kendo-ui

Version:

This package is part of the [Kendo UI for jQuery](http://www.telerik.com/kendo-ui) suite.

1,509 lines (1,204 loc) 109 kB
module.exports = /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) /******/ return installedModules[moduleId].exports; /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ exports: {}, /******/ id: moduleId, /******/ loaded: false /******/ }; /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ // Flag the module as loaded /******/ module.loaded = true; /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ // __webpack_public_path__ /******/ __webpack_require__.p = ""; /******/ // Load entry module and return exports /******/ return __webpack_require__(0); /******/ }) /************************************************************************/ /******/ ({ /***/ 0: /***/ (function(module, exports, __webpack_require__) { module.exports = __webpack_require__(1303); /***/ }), /***/ 3: /***/ (function(module, exports) { module.exports = function() { throw new Error("define cannot be used indirect"); }; /***/ }), /***/ 1010: /***/ (function(module, exports) { module.exports = require("./kendo.dropdownlist"); /***/ }), /***/ 1122: /***/ (function(module, exports) { module.exports = require("./kendo.datepicker"); /***/ }), /***/ 1139: /***/ (function(module, exports) { module.exports = require("./kendo.numerictextbox"); /***/ }), /***/ 1303: /***/ (function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define){ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(1010), __webpack_require__(1122), __webpack_require__(1139) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); })(function(){ var __meta__ = { // jshint ignore:line id: "scheduler.recurrence", name: "Recurrence", category: "web", depends: [ "dropdownlist", "datepicker", "numerictextbox" ], hidden: true }; (function($, undefined) { var kendo = window.kendo, timezone = kendo.timezone, Class = kendo.Class, ui = kendo.ui, Widget = ui.Widget, DropDownList = ui.DropDownList, kendoDate = kendo.date, setTime = kendoDate.setTime, setDayOfWeek = kendoDate.setDayOfWeek, adjustDST = kendoDate.adjustDST, firstDayOfMonth = kendoDate.firstDayOfMonth, getMilliseconds = kendoDate.getMilliseconds, DAYS_IN_LEAPYEAR = [0,31,60,91,121,152,182,213,244,274,305,335,366], DAYS_IN_YEAR = [0,31,59,90,120,151,181,212,243,273,304,334,365], MONTHS = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31], WEEK_DAYS = { 0: "SU", 1: "MO", 2: "TU", 3: "WE", 4: "TH", 5: "FR", 6: "SA" }, WEEK_DAYS_IDX = { "SU": 0, "MO": 1, "TU": 2, "WE": 3, "TH": 4, "FR": 5, "SA": 6 }, DATE_FORMATS = [ "yyyy-MM-ddTHH:mm:ss.fffzzz", "yyyy-MM-ddTHH:mm:sszzz", "yyyy-MM-ddTHH:mm:ss", "yyyy-MM-ddTHH:mm", "yyyy-MM-ddTHH", "yyyy-MM-dd", "yyyyMMddTHHmmssfffzzz", "yyyyMMddTHHmmsszzz", "yyyyMMddTHHmmss", "yyyyMMddTHHmm", "yyyyMMddTHH", "yyyyMMdd" ], RULE_NAMES = ["months", "weeks", "yearDays", "monthDays", "weekDays", "hours", "minutes", "seconds"], RULE_NAMES_LENGTH = RULE_NAMES.length, RECURRENCE_DATE_FORMAT = "yyyyMMddTHHmmssZ", limitation = { months: function(date, end, rule) { var monthRules = rule.months, months = ruleValues(monthRules, date.getMonth() + 1), changed = false; if (months !== null) { if (months.length) { date.setMonth(months[0] - 1, 1); } else { date.setFullYear(date.getFullYear() + 1, monthRules[0] - 1, 1); } changed = true; } return changed; }, monthDays: function(date, end, rule) { var monthLength, month, days, changed = false, hours = date.getHours(), normalize = function(monthDay) { if (monthDay < 0) { monthDay = monthLength + monthDay + 1; } return monthDay; }; while (date <= end) { month = date.getMonth(); monthLength = getMonthLength(date); days = ruleValues(rule.monthDays, date.getDate(), normalize); if (days === null) { return changed; } changed = true; if (days.length) { date.setMonth(month, days.sort(numberSortPredicate)[0]); adjustDST(date, hours); if (month === date.getMonth()) { break; } } else { date.setMonth(month + 1, 1); } } return changed; }, yearDays: function(date, end, rule) { var year, yearDays, changed = false, hours = date.getHours(), normalize = function(yearDay) { if (yearDay < 0) { yearDay = year + yearDay; } return yearDay; }; while (date < end) { year = leapYear(date) ? 366 : 365; yearDays = ruleValues(rule.yearDays, dayInYear(date), normalize); if (yearDays === null) { return changed; } changed = true; year = date.getFullYear(); if (yearDays.length) { date.setFullYear(year, 0, yearDays.sort(numberSortPredicate)[0]); adjustDST(date, hours); break; } else { date.setFullYear(year + 1, 0, 1); } } return changed; }, weeks: function(date, end, rule) { var weekStart = rule.weekStart, year, weeks, day, changed = false, hours = date.getHours(), normalize = function(week) { if (week < 0) { week = 53 + week; } return week; }; while (date < end) { weeks = ruleValues(rule.weeks, weekInYear(date, weekStart), normalize); if (weeks === null) { return changed; } changed = true; year = date.getFullYear(); if (weeks.length) { day = (weeks.sort(numberSortPredicate)[0] * 7) - 1; date.setFullYear(year, 0, day); setDayOfWeek(date, weekStart, -1); adjustDST(date, hours); break; } else { date.setFullYear(year + 1, 0, 1); } } return changed; }, weekDays: function(date, end, rule) { var weekDays = rule.weekDays; var weekStart = rule.weekStart; var weekDayRules = ruleWeekValues(weekDays, date, weekStart); var hours = date.getHours(); var weekDayRule, day; if (weekDayRules === null) { return false; } weekDayRule = weekDayRules[0]; if (!weekDayRule) { weekDayRule = weekDays[0]; setDayOfWeek(date, weekStart); } day = weekDayRule.day; if (weekDayRule.offset) { while (date <= end && !isInWeek(date, weekDayRule, weekStart)) { if (weekInMonth(date, weekStart) === numberOfWeeks(date, weekStart)) { date.setMonth(date.getMonth() + 1, 1); adjustDST(date, hours); } else { date.setDate(date.getDate() + 7); adjustDST(date, hours); setDayOfWeek(date, weekStart, -1); } } } if (date.getDay() !== day) { setDayOfWeek(date, day); } return true; }, hours: function(date, end, rule) { var hourRules = rule.hours, startTime = rule._startTime, startHours = startTime.getHours(), hours = ruleValues(hourRules, startHours), changed = false; if (hours !== null) { changed = true; date.setHours(startHours); adjustDST(date, startHours); if (hours.length) { hours = hours[0]; date.setHours(hours); } else { hours = date.getHours(); date.setDate(date.getDate() + 1); adjustDST(date, hours); hours = hourRules[0]; date.setHours(hours); adjustDST(date, hours); } if (rule.minutes) { date.setMinutes(0); } startTime.setHours(hours, date.getMinutes()); } return changed; }, minutes: function(date, end, rule) { var minuteRules = rule.minutes, currentMinutes = date.getMinutes(), minutes = ruleValues(minuteRules, currentMinutes), hours = rule._startTime.getHours(), changed = false; if (minutes !== null) { changed = true; if (minutes.length) { minutes = minutes[0]; } else { hours += 1; minutes = minuteRules[0]; } if (rule.seconds) { date.setSeconds(0); } date.setHours(hours, minutes); hours = hours % 24; adjustDST(date, hours); rule._startTime.setHours(hours, minutes, date.getSeconds()); } return changed; }, seconds: function(date, end, rule) { var secondRules = rule.seconds, hours = rule._startTime.getHours(), seconds = ruleValues(secondRules, date.getSeconds()), minutes = date.getMinutes(), changed = false; if (seconds !== null) { changed = true; if (seconds.length) { date.setSeconds(seconds[0]); } else { minutes += 1; date.setMinutes(minutes, secondRules[0]); if (minutes > 59) { minutes = minutes % 60; hours = (hours + 1) % 24; } } rule._startTime.setHours(hours, minutes, date.getSeconds()); } return changed; } }, BaseFrequency = Class.extend({ next: function(date, rule) { var startTime = rule._startTime, day = startTime.getDate(), minutes, seconds; if (rule.seconds) { seconds = date.getSeconds() + 1; date.setSeconds(seconds); startTime.setSeconds(seconds); startTime.setDate(day); } else if (rule.minutes) { minutes = date.getMinutes() + 1; date.setMinutes(minutes); startTime.setMinutes(minutes); startTime.setDate(day); } else { return false; } return true; }, normalize: function(options) { var rule = options.rule; if (options.idx === 4 && rule.hours) { rule._startTime.setHours(0); this._hour(options.date, rule); } }, limit: function(date, end, rule) { var interval = rule.interval, ruleName, firstRule, modified, idx, day; while (date <= end) { modified = firstRule = undefined; day = date.getDate(); for (idx = 0; idx < RULE_NAMES_LENGTH; idx++) { ruleName = RULE_NAMES[idx]; if (rule[ruleName]) { modified = limitation[ruleName](date, end, rule); if (firstRule !== undefined && modified) { break; } else { firstRule = modified; } } if (modified) { this.normalize({ date: date, rule: rule, day: day, idx: idx }); } } if ((interval === 1 || !this.interval(rule, date)) && idx === RULE_NAMES_LENGTH) { break; } } }, interval: function (rule, current) { var start = new Date(rule._startPeriod); var date = new Date(current); var hours = current.getHours(); var weekStart = rule.weekStart; var interval = rule.interval; var frequency = rule.freq; var modified = false; var excess = 0; var month = 0; var day = 1; var diff; var startTimeHours; if (frequency === "hourly") { diff = date.getTimezoneOffset() - start.getTimezoneOffset(); startTimeHours = rule._startTime.getHours(); date = date.getTime(); if (hours !== startTimeHours) { date += (startTimeHours - hours) * kendoDate.MS_PER_HOUR; } date -= start; if (diff) { date -= diff * kendoDate.MS_PER_MINUTE; } diff = Math.floor(date / kendoDate.MS_PER_HOUR); excess = intervalExcess(diff, interval); if (excess !== 0) { this._hour(current, rule, excess); modified = true; } } else if (frequency === "daily") { kendoDate.setTime(date, -start, true); diff = Math.round(date / kendoDate.MS_PER_DAY); excess = intervalExcess(diff, interval); if (excess !== 0) { this._date(current, rule, excess); modified = true; } } else if (frequency === "weekly") { excess = this._getNumberOfWeeksBetweenDates(start, current); var normalizedCurrentIndex = normalizeDayIndex(current.getDay(), weekStart); var normalizedStartIndex = normalizeDayIndex(start.getDay(), weekStart); if (normalizedCurrentIndex < normalizedStartIndex) { excess += 1; } excess = intervalExcess(excess, interval); if (excess !== 0) { kendoDate.setDayOfWeek(current, rule.weekStart, -1); current.setDate(current.getDate() + (excess * 7)); adjustDST(current, hours); modified = true; } } else if (frequency === "monthly") { diff = current.getFullYear() - start.getFullYear(); diff = current.getMonth() - start.getMonth() + (diff * 12); excess = intervalExcess(diff, interval); if (excess !== 0) { day = rule._hasRuleValue ? 1 : current.getDate(); current.setFullYear(current.getFullYear(), current.getMonth() + excess, day); adjustDST(current, hours); modified = true; } } else if (frequency === "yearly") { diff = current.getFullYear() - start.getFullYear(); excess = intervalExcess(diff, interval); if (!rule.months) { month = current.getMonth(); } if (!rule.yearDays && !rule.monthDays && !rule.weekDays) { day = current.getDate(); } if (excess !== 0) { current.setFullYear(current.getFullYear() + excess, month, day); adjustDST(current, hours); modified = true; } } return modified; }, _getNumberOfWeeksBetweenDates: function(first, second){ var weeks = (second - first) / 604800000; var exactWeeks = Math.floor(weeks); //this is happening when weeks pass DST change if (weeks - exactWeeks > 0.99) { exactWeeks = Math.round(weeks); } return exactWeeks; }, _hour: function(date, rule, interval) { var startTime = rule._startTime, hours = startTime.getHours(); if (interval) { hours += interval; } date.setHours(hours); hours = hours % 24; startTime.setHours(hours); adjustDST(date, hours); }, _date: function(date, rule, interval) { var hours = date.getHours(); date.setDate(date.getDate() + interval); if (!adjustDST(date, hours)) { this._hour(date, rule); } } }), HourlyFrequency = BaseFrequency.extend({ next: function(date, rule) { if (!BaseFrequency.fn.next(date, rule)) { this._hour(date, rule, 1); } }, normalize: function(options) { var rule = options.rule; if (options.idx === 4) { rule._startTime.setHours(0); this._hour(options.date, rule); } } }), DailyFrequency = BaseFrequency.extend({ next: function(date, rule) { if (!BaseFrequency.fn.next(date, rule)) { this[rule.hours ? "_hour" : "_date"](date, rule, 1); } } }), WeeklyFrequency = DailyFrequency.extend({ setup: function(rule, eventStartDate) { if (!rule.weekDays) { rule.weekDays = [{ day: eventStartDate.getDay(), offset: 0 }]; } } }), MonthlyFrequency = BaseFrequency.extend({ next: function(date, rule) { var day, hours; if (!BaseFrequency.fn.next(date, rule)) { if (rule.hours) { this._hour(date, rule, 1); } else if (rule.monthDays || rule.weekDays || rule.yearDays || rule.weeks) { this._date(date, rule, 1); } else { day = date.getDate(); hours = date.getHours(); date.setMonth(date.getMonth() + 1); adjustDST(date, hours); while(date.getDate() !== day) { date.setDate(day); adjustDST(date, hours); } this._hour(date, rule); } } }, normalize: function(options) { var rule = options.rule, date = options.date, hours = date.getHours(); if (options.idx === 0 && !rule.monthDays && !rule.weekDays) { date.setDate(options.day); adjustDST(date, hours); } else { BaseFrequency.fn.normalize(options); } }, setup: function(rule, eventStartDate, date) { if (!rule.monthDays && !rule.weekDays) { date.setDate(eventStartDate.getDate()); } } }), YearlyFrequency = MonthlyFrequency.extend({ next: function(date, rule) { var day, hours = date.getHours(); if (!BaseFrequency.fn.next(date, rule)) { if (rule.hours) { this._hour(date, rule, 1); } else if (rule.monthDays || rule.weekDays || rule.yearDays || rule.weeks) { this._date(date, rule, 1); } else if (rule.months) { day = date.getDate(); date.setMonth(date.getMonth() + 1); adjustDST(date, hours); while(date.getDate() !== day) { date.setDate(day); adjustDST(date, hours); } this._hour(date, rule); } else { date.setFullYear(date.getFullYear() + 1); adjustDST(date, hours); this._hour(date, rule); } } }, setup: function() {} }), frequencies = { "hourly" : new HourlyFrequency(), "daily" : new DailyFrequency(), "weekly" : new WeeklyFrequency(), "monthly" : new MonthlyFrequency(), "yearly" : new YearlyFrequency() }, CLICK = "click", CHANGE = "change"; function intervalExcess(diff, interval) { var excess; if (diff !== 0 && diff < interval) { excess = interval - diff; } else { excess = diff % interval; if (excess) { excess = interval - excess; } } return excess; } function dayInYear(date) { var month = date.getMonth(); var days = leapYear(date) ? DAYS_IN_LEAPYEAR[month] : DAYS_IN_YEAR[month]; return days + date.getDate(); } function weekInYear(date, weekStart){ var year, days; date = new Date(date.getFullYear(), date.getMonth(), date.getDate()); adjustDST(date, 0); year = date.getFullYear(); if (weekStart !== undefined) { setDayOfWeek(date, weekStart, -1); date.setDate(date.getDate() + 4); } else { date.setDate(date.getDate() + (4 - (date.getDay() || 7))); } adjustDST(date, 0); days = Math.floor((date.getTime() - new Date(year, 0, 1, -6)) / 86400000); return 1 + Math.floor(days / 7); } function weekInMonth(date, weekStart) { var firstWeekDay = firstDayOfMonth(date).getDay(); var firstWeekLength = 7 - (firstWeekDay + 7 - (weekStart || 7)) || 7; if (firstWeekLength < 0) { firstWeekLength += 7; } return Math.ceil((date.getDate() - firstWeekLength) / 7) + 1; } function normalizeDayIndex(weekDay, weekStart) { return weekDay + (weekDay < weekStart ? 7 : 0); } function normalizeOffset(date, rule, weekStart) { var offset = rule.offset; if (!offset) { return weekInMonth(date, weekStart); } var lastDate = new Date(date.getFullYear(), date.getMonth() + 1, 0); var weeksInMonth = weekInMonth(lastDate, weekStart); var day = normalizeDayIndex(rule.day, weekStart); var skipFirst = day < normalizeDayIndex(new Date(date.getFullYear(), date.getMonth(), 1).getDay(), weekStart); var skipLast = day > normalizeDayIndex(lastDate.getDay(), weekStart); if (offset < 0) { offset = weeksInMonth + (offset + 1 - (skipLast ? 1 : 0)); } else if (skipFirst) { offset += 1; } weeksInMonth -= (skipLast ? 1 : 0); if (offset < (skipFirst ? 1 : 0) || offset > weeksInMonth) { return null; } return offset; } function numberOfWeeks(date, weekStart) { return weekInMonth(new Date(date.getFullYear(), date.getMonth() + 1, 0), weekStart); } function isInWeek(date, rule, weekStart) { return weekInMonth(date, weekStart) === normalizeOffset(date, rule, weekStart); } function ruleWeekValues(weekDays, date, weekStart) { var currentDay = normalizeDayIndex(date.getDay(), weekStart); var length = weekDays.length; var ruleWeekOffset; var weekDay, day; var weekNumber; var result = []; var idx = 0; for (;idx < length; idx++) { weekDay = weekDays[idx]; weekNumber = weekInMonth(date, weekStart); ruleWeekOffset = normalizeOffset(date, weekDay, weekStart); if (ruleWeekOffset === null) { continue; } if (weekNumber < ruleWeekOffset) { result.push(weekDay); } else if (weekNumber === ruleWeekOffset) { day = normalizeDayIndex(weekDay.day, weekStart); if (currentDay < day) { result.push(weekDay); } else if (currentDay === day) { return null; } } } return result; } function ruleValues(rules, value, normalize) { var idx = 0, length = rules.length, availableRules = [], ruleValue; for (; idx < length; idx++) { ruleValue = rules[idx]; if (normalize) { ruleValue = normalize(ruleValue); } if (value === ruleValue) { return null; } else if (value < ruleValue) { availableRules.push(ruleValue); } } return availableRules; } function parseArray(list, range) { var idx = 0, length = list.length, value; for (; idx < length; idx++) { value = parseInt(list[idx], 10); if (isNaN(value) || value < range.start || value > range.end || (value === 0 && range.start < 0)) { return null; } list[idx] = value; } return list.sort(numberSortPredicate); } function parseWeekDayList(list) { var idx = 0, length = list.length, value, valueLength, day; for (; idx < length; idx++) { value = list[idx]; valueLength = value.length; day = value.substring(valueLength - 2).toUpperCase(); day = WEEK_DAYS_IDX[day]; if (day === undefined) { return null; } list[idx] = { offset: parseInt(value.substring(0, valueLength - 2), 10) || 0, day: day }; } return list; } function serializeWeekDayList(list) { var idx = 0, length = list.length, value, valueString, result = []; for (; idx < length; idx++) { value = list[idx]; if (typeof value === "string") { valueString = value; } else { valueString = "" + WEEK_DAYS[value.day]; if (value.offset) { valueString = value.offset + valueString; } } result.push(valueString); } return result.toString(); } function getMonthLength(date) { var month = date.getMonth(); if (month === 1) { if (new Date(date.getFullYear(), 1, 29).getMonth() === 1) { return 29; } return 28; } return MONTHS[month]; } function leapYear(year) { year = year.getFullYear(); return ((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0); } function numberSortPredicate(a, b) { return a - b; } function parseExceptions(exceptions, zone) { var idx = 0, length, date, dates = []; if (exceptions) { exceptions = exceptions.split(exceptions.indexOf(";") !== -1 ? ";" : ","); length = exceptions.length; for (; idx < length; idx++) { date = parseUTCDate(exceptions[idx], zone); if (date) { dates.push(date); } } } return dates; } function isException(exceptions, date, zone) { var dates = $.isArray(exceptions) ? exceptions : parseExceptions(exceptions, zone), dateTime = date.getTime() - date.getMilliseconds(), idx = 0, length = dates.length; for (; idx < length; idx++) { if (dates[idx].getTime() === dateTime) { return true; } } return false; } function toExceptionString(dates, zone) { var idx = 0; var length; var date; var result = [].concat(dates); for (length = result.length; idx < length; idx++) { date = result[idx]; date = kendo.timezone.convert(date, zone || date.getTimezoneOffset(), "Etc/UTC"); result[idx] = kendo.toString(date, RECURRENCE_DATE_FORMAT); } return result.join(","); } function startPeriodByFreq(start, rule) { var date = new Date(start); switch (rule.freq) { case "yearly": date.setFullYear(date.getFullYear(), 0, 1); break; case "monthly": date.setFullYear(date.getFullYear(), date.getMonth(), 1); break; case "weekly": setDayOfWeek(date, rule.weekStart, -1); break; default: break; } if (rule.hours) { date.setHours(0); } if (rule.minutes) { date.setMinutes(0); } if (rule.seconds) { date.setSeconds(0); } return date; } function endPeriodByFreq(start, rule) { var date = new Date(start); switch (rule.freq) { case "yearly": date.setFullYear(date.getFullYear(), 11, 31); break; case "monthly": date.setFullYear(date.getFullYear(), date.getMonth() + 1, 0); break; case "weekly": setDayOfWeek(date, rule.weekStart, -1); date.setDate(date.getDate() + 6); break; default: break; } if (rule.hours) { date.setHours(23); } if (rule.minutes) { date.setMinutes(59); } if (rule.seconds) { date.setSeconds(59); } return date; } function eventsByPosition(periodEvents, start, positions) { var periodEventsLength = periodEvents.length; var events = []; var position; var event; for (var idx = 0, length = positions.length; idx < length; idx++) { position = positions[idx]; if (position < 0) { position = periodEventsLength + position; } else { position -= 1; //convert to zero based index } event = periodEvents[position]; if (event && event.start >= start) { events.push(event); } } return events; } function removeExceptionDates(periodEvents, exceptionDates, zone) { var events = []; var event; for (var idx = 0; idx < periodEvents.length; idx++) { event = periodEvents[idx]; if (!isException(exceptionDates, event.start, zone)) { events.push(event); } } return events; } function expand(event, start, end, zone) { var rule = parseRule(event.recurrenceRule, zone), startTime, endTime, endDate, hours, minutes, seconds, durationMS, startPeriod, inPeriod, ruleStart, ruleEnd, useEventStart, freqName, exceptionDates, eventStartTime, eventStartMS, eventStart, count, freq, positions, currentIdx, periodEvents, events = [], shiftedStart, shiftedEnd, shiftedStartTime, shifterEndTime; if (!rule) { return [event]; } positions = rule.positions; currentIdx = positions ? 0 : 1; ruleStart = rule.start; ruleEnd = rule.end; if (ruleStart || ruleEnd) { event = event.clone({ start: ruleStart ? new Date(ruleStart.value[0]) : undefined, end: ruleEnd ? new Date(ruleEnd.value[0]) : undefined }); } eventStart = event.start; eventStartMS = eventStart.getTime(); eventStartTime = getMilliseconds(eventStart); exceptionDates = parseExceptions(event.recurrenceException, zone); if (!exceptionDates[0] && rule.exdates) { exceptionDates = rule.exdates.value; event.set("recurrenceException", toExceptionString(exceptionDates, zone)); } startPeriod = start = new Date(start); end = new Date(end); freqName = rule.freq; freq = frequencies[freqName]; count = rule.count; if (rule.until && rule.until < end) { end = new Date(rule.until); } useEventStart = freqName === "yearly" || freqName === "monthly" || freqName === "weekly"; if (start < eventStartMS || count || rule.interval > 1 || useEventStart || ((freqName === "daily" || freqName === "hourly") && !rule.seconds)) { start = new Date(eventStartMS); } else { hours = start.getHours(); minutes = start.getMinutes(); seconds = start.getSeconds(); if (!rule.hours) { hours = eventStart.getHours(); } if (!rule.minutes) { minutes = eventStart.getMinutes(); } if (!rule.seconds) { seconds = eventStart.getSeconds(); } start.setHours(hours, minutes, seconds, eventStart.getMilliseconds()); } rule._startPeriod = new Date(start); if (positions) { start = startPeriodByFreq(start, rule); end = endPeriodByFreq(end, rule); var diff = getMilliseconds(end) - getMilliseconds(start); if (diff < 0) { hours = start.getHours(); end.setHours(hours, start.getMinutes(), start.getSeconds(), start.getMilliseconds()); kendoDate.adjustDST(end, hours); } rule._startPeriod = new Date(start); rule._endPeriod = endPeriodByFreq(start, rule); } durationMS = event.duration(); rule._startTime = startTime = kendoDate.toInvariantTime(start); if (freq.setup) { freq.setup(rule, eventStart, start); } freq.limit(start, end, rule); while (start <= end) { endDate = new Date(start); setTime(endDate, durationMS); inPeriod = start >= startPeriod || endDate > startPeriod; if (inPeriod && !isException(exceptionDates, start, zone) || positions) { startTime = kendoDate.toUtcTime(kendoDate.getDate(start)) + getMilliseconds(rule._startTime); endTime = startTime + durationMS; if (eventStartMS !== start.getTime() || eventStartTime !== getMilliseconds(rule._startTime)) { if(!event.isAllDay){ var startZone = event.startTimezone || event.endTimezone; var endZone = event.endTimezone || event.startTimezone; if((zone && startZone) || (!zone && !startZone)){ var startOffsetDiff = getZoneOffset(start, zone) - getZoneOffset(event.start, zone); var endOffsetDiff = getZoneOffset(endDate, zone) - getZoneOffset(event.end, zone); var startTZOffsetDiff = getZoneOffset(start, startZone) - getZoneOffset(event.start, startZone); var endTZOffsetDiff = getZoneOffset(endDate, endZone) - getZoneOffset(event.end, endZone); if(startOffsetDiff !== startTZOffsetDiff){ var offsetTicksStart = (startOffsetDiff - startTZOffsetDiff) * 60000; shiftedStart = new Date(start.getTime() - offsetTicksStart); shiftedStartTime = startTime - offsetTicksStart; } if(endOffsetDiff !== endTZOffsetDiff){ var offsetTicksEnd = (endOffsetDiff - endTZOffsetDiff) * 60000; shiftedEnd = new Date(endDate.getTime() - offsetTicksEnd); shifterEndTime = endTime - offsetTicksEnd; } } } events.push(event.toOccurrence({ start: shiftedStart || new Date(start), end: shiftedEnd || endDate, _startTime: shiftedStartTime || startTime, _endTime: shifterEndTime || endTime })); shiftedStart = shiftedEnd = shiftedStartTime = shifterEndTime = null; } else { event._startTime = startTime; event._endTime = endTime; events.push(event); } } if (positions) { freq.next(start, rule); freq.limit(start, end, rule); if (start > rule._endPeriod) { periodEvents = eventsByPosition(events.slice(currentIdx), eventStart, positions); periodEvents = removeExceptionDates(periodEvents, exceptionDates, zone); events = events.slice(0, currentIdx).concat(periodEvents); rule._endPeriod = endPeriodByFreq(start, rule); currentIdx = events.length; } if (count && count === currentIdx) { break; } } else { if (count && count === currentIdx) { break; } currentIdx += 1; var isMissingDSTHour = isDSTMissingHour(start); freq.next(start, rule); if(isMissingDSTHour && rule.freq!=="hourly" && kendoDate.toInvariantTime(event.start).getTime() !== kendoDate.toInvariantTime(start).getTime()){ rule._startTime = startTime = new Date(start.getTime() - 3600000); } freq.limit(start, end, rule); } } return events; } function isDSTMissingHour(date){ var dateOffset = date.getTimezoneOffset(); var dateMinusHour = new Date(date.getTime() - 3600000); var dateMinusHourOffset = dateMinusHour.getTimezoneOffset(); return dateOffset < dateMinusHourOffset; } function getZoneOffset(date, zone) { return zone ? kendo.timezone.offset(date, zone): date.getTimezoneOffset(); } function parseUTCDate(value, zone) { value = kendo.parseDate(value, DATE_FORMATS); //Parse UTC to local time if (value && zone) { value = timezone.apply(value, zone); } return value; } function parseDateRule(dateRule, zone) { var pairs = dateRule.split(";"); var pair; var property; var value; var tzid; var valueIdx, valueLength; for (var idx = 0, length = pairs.length; idx < length; idx++) { pair = pairs[idx].split(":"); property = pair[0]; value = pair[1]; if (property.indexOf("TZID") !== -1) { tzid = property.substring(property.indexOf("TZID")).split("=")[1]; } if (value) { value = value.split(","); for (valueIdx = 0, valueLength = value.length; valueIdx < valueLength; valueIdx++) { value[valueIdx] = parseUTCDate(value[valueIdx], tzid || zone); } } } if (value) { return { value: value, tzid: tzid }; } } function parseRule(recur, zone) { var instance = {}; var splits, value; var idx = 0, length; var ruleValue = false; var rule, part, parts; var property, weekStart, weekDays; var predicate = function(a, b) { var day1 = a.day, day2 = b.day; if (day1 < weekStart) { day1 += 7; } if (day2 < weekStart) { day2 += 7; } return day1 - day2; }; if (!recur) { return null; } parts = recur.split("\n"); if (!parts[1] && (recur.indexOf("DTSTART") !== -1 || recur.indexOf("DTEND") !== -1 || recur.indexOf("EXDATE") !== -1)) { parts = recur.split(" "); } for (idx = 0, length = parts.length; idx < length; idx++) { part = $.trim(parts[idx]); if (part.indexOf("DTSTART") !== -1) { instance.start = parseDateRule(part, zone); } else if (part.indexOf("DTEND") !== -1) { instance.end = parseDateRule(part, zone); } else if (part.indexOf("EXDATE") !== -1) { instance.exdates = parseDateRule(part, zone); } else if (part.indexOf("RRULE") !== -1) { rule = part.substring(6); } else if ($.trim(part)) { rule = part; } } rule = rule.split(";"); for (idx = 0, length = rule.length; idx < length; idx++) { property = rule[idx]; splits = property.split("="); value = $.trim(splits[1]).split(","); switch ($.trim(splits[0]).toUpperCase()) { case "FREQ": instance.freq = value[0].toLowerCase(); break; case "UNTIL": instance.until = parseUTCDate(value[0], zone); break; case "COUNT": instance.count = parseInt(value[0], 10); break; case "INTERVAL": instance.interval = parseInt(value[0], 10); break; case "BYSECOND": instance.seconds = parseArray(value, { start: 0, end: 60 }); ruleValue = true; break; case "BYMINUTE": instance.minutes = parseArray(value, { start: 0, end: 59 }); ruleValue = true; break; case "BYHOUR": instance.hours = parseArray(value, { start: 0, end: 23 }); ruleValue = true; break; case "BYMONTHDAY": instance.monthDays = parseArray(value, { start: -31, end: 31 }); ruleValue = true; break; case "BYYEARDAY": instance.yearDays = parseArray(value, { start: -366, end: 366 }); ruleValue = true; break; case "BYMONTH": instance.months = parseArray(value, { start: 1, end: 12 }); ruleValue = true; break; case "BYDAY": instance.weekDays = weekDays = parseWeekDayList(value); ruleValue = true; break; case "BYWEEKNO": instance.weeks = parseArray(value, { start: -53, end: 53 }); ruleValue = true; break; case "BYSETPOS": instance.positions = parseArray(value, { start: -366, end: 366 }); break; case "WKST": instance.weekStart = weekStart = WEEK_DAYS_IDX[value[0]]; break; } } if (instance.freq === undefined || (instance.count !== undefined && instance.until)) { return null; } if (!instance.interval) { instance.interval = 1; } if (weekStart === undefined) { instance.weekStart = weekStart = kendo.culture().calendar.firstDay; } if (weekDays) { instance.weekDays = weekDays.sort(predicate); } if (instance.positions && !ruleValue) {