From 326b57e0651a6a03e57cf910285bcce1e082e42a Mon Sep 17 00:00:00 2001 From: Borisov Dmitry Date: Mon, 12 Nov 2012 23:41:08 +0600 Subject: [PATCH 01/13] 1st steps to dz 4 --- collection.js | 36 +++++++++++++ event-collection.js | 21 ++++++++ event-model.js | 118 ++++++++++++++++++++++++++++++++++++++++++ event-random.js | 113 ++++++++++++++++++++++++++++++++++++++++ event-utils.js | 122 ++++++++++++++++++++++++++++++++++++++++++++ model.js | 39 ++++++++++++++ 6 files changed, 449 insertions(+) create mode 100644 collection.js create mode 100644 event-collection.js create mode 100644 event-model.js create mode 100644 event-random.js create mode 100644 event-utils.js create mode 100644 model.js diff --git a/collection.js b/collection.js new file mode 100644 index 0000000..83e3d0b --- /dev/null +++ b/collection.js @@ -0,0 +1,36 @@ +var Collection = function () { + 'use strict'; + this.items = []; +}; + +/** + * @return {Collection} + */ +Collection.prototype.add = function (model) { + 'use strict'; + this.items.push(model); +}; +/** + * @param {Function} selector + * + * @see https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/filter + * + * @example + * new Collection().filter(function (item) { + * return item.get('attendee').indexOf("me") !== -1; + * }); + * @return {Collection} + */ +Collection.prototype.filter = function (selector) { + 'use strict'; + this.items.filter(selector); + return this; +}; +/** + * @return {Collection} + */ +Collection.prototype.sortBy = function (selector) { + 'use strict'; + this.items.sort(selector); + return this; +}; \ No newline at end of file diff --git a/event-collection.js b/event-collection.js new file mode 100644 index 0000000..55210ba --- /dev/null +++ b/event-collection.js @@ -0,0 +1,21 @@ +var Events = function (items) { + Collection.apply(this, arguments); +}; +inherits(Events, Collection); + +/** + * @return {Events} + */ +Events.prototype.findOnlyMyEvents = function () {}; +/** + * @return {Events} + */ +Events.prototype.findFutureEvents = function () {}; +/** + * @return {Events} + */ +Events.prototype.findPastEvents = function () {}; +/** + * @return {Events} + */ +Events.prototype.sortByName = function () {}; \ No newline at end of file diff --git a/event-model.js b/event-model.js new file mode 100644 index 0000000..fe34abd --- /dev/null +++ b/event-model.js @@ -0,0 +1,118 @@ +function checkStartDate(date) { + 'use strict'; + if (date === null) { + date = new Date(); + } else if (!(date instanceof Date && isFinite(date))) { + console.log("Start date is invalid, check syntax"); + date = null; + } + return date; +} + +function checkEndDate(endDate, startDate) { + 'use strict'; + var date; + if (endDate === null) { + date = startDate; + date.setHours(startDate.getHours() + 1); + } else if (endDate instanceof Date && isFinite(endDate)) { + if (endDate < startDate) { + console.log("End date should be after start date"); + date = null; + } else { + date = endDate; + } + } else { + console.log("End date is invalid, check syntax"); + date = null; + } + return date; +} + +var REPEAT = { + NEVER: {title: "None", value: "+ 0.0.0 0:0"}, + DAY: {title: "Every Day", value: "+ 1.0.0 0:0"}, + WEEK: {title: "Every Week", value: "+ 7.0.0 0:0"}, + TWOWEEK: {title: "Every 2 weeks", value: "+ 14.0.0 0:0"}, + MONTH: {title: "Every month", value: "+ 0.1.0 0:0"}, + YEAR: {title: "Every year", value: "+ 0.0.1 0:0"} +}; + +var ALERT = { + NONE: {title: "None", value: "+ 0.0.0 0:0"}, + B5MIN: {title: "5 minutes before", value: "- 0.0.0 0:5"}, + B15MIN: {title: "15 minutes before", value: "- 0.0.0 0:15"}, + B30MIN: {title: "30 minutes before", value: "- 0.0.0 0:30"}, + B1HOUR: {title: "1 hour before", value: "- 0.0.0 1:0"}, + B1DAY: {title: "1 day before", value: "- 0.0.0 24:0"} +}; + +function checkAddTime(addTime) { + 'use strict'; + var re, splitted; + re = "([+-]) (\\d?\\d.\\d?\\d.\\d?\\d) (\\d?\\d:\\d?\\d)"; + splitted = addTime.match(re); + if (splitted === null || splitted.length !== 4) { + splitted = null; + } + return splitted; +} + +function checkRepeat(repeat) { + 'use strict'; + if (repeat === null) { + repeat = REPEAT.NEVER; + } else if (!(repeat.title && repeat.value)) { + console.log("Unknown type of 'repeat' variable"); + repeat = null; + } else if (!checkAddTime(repeat.value)) { + console.log("Add time in 'repeat' variable must have format '+ dd.MM.YY hh:mm'"); + repeat = null; + } + return repeat; +} + +function checkAlert(alert) { + 'use strict'; + if (alert === null) { + alert = ALERT.NONE; + } else if (!(alert.title && alert.value)) { + console.log("Unknown type of 'alert' variable"); + alert = null; + } else if (!checkAddTime(alert.value)) { + console.log("Add time in 'alert' variable must have format '+ dd.MM.YY hh:mm'"); + alert = null; + } + return alert; +} + +var Event = function (data) { + Model.apply(this, arguments); +}; +inherits(Event, Model); + +/** + * Функция, валидирующая объект Event + * + * @return {Event} + */ +Event.prototype.validate = function () { + 'use strict'; + this.starts = checkStartDate(this.starts); + if (this.starts === null) { + return; + } + this.ends = checkEndDate(this.ends, this.starts); + if (this.ends === null) { + return; + } + this.repeat = checkRepeat(this.repeat); + if (this.repeat === null) { + return; + } + this.alert = checkAlert(this.alert); + if (this.alert === null) { + return; + } + return this; +}; \ No newline at end of file diff --git a/event-random.js b/event-random.js new file mode 100644 index 0000000..58787a6 --- /dev/null +++ b/event-random.js @@ -0,0 +1,113 @@ +/*jslint plusplus: true*/ +var activities = ["Studying", "Drunken feast", "Karaoke singing", "Hanging around"]; +var locations = ["My home", "My work", "My friend's house", "1905 Sq.", "UrFU", "Unknown"]; + +/** + * Возвращает случайное число в интервале [min, max] + * + * @param {Number} min нижний предел + * @param {Number} max верхний предел + * + * @return {Number} + */ +function getRandomInt(min, max) { + 'use strict'; + return Math.floor(Math.random() * (max - min + 1)) + min; +} + +/** + * Возвращает случайный элемент массива + * + * @param {Array} arr массив + * + * @return {Object} + */ +function getRandomElement(arr) { + 'use strict'; + return arr[getRandomInt(0, arr.length - 1)]; +} + +/** + * Возвращает сгенерированную строку из случайных символов + * + * @return {String} + */ +function getRandomString() { + 'use strict'; + var chars, length, str, i; + chars = "01234 56789 ABCDE FGHIJ KLMNO PQRST UVWXT Zabcd efghi klmno pqrst uvwxy z"; + chars = chars.split(''); + length = getRandomInt(4, chars.length); + str = ''; + for (i = 0; i < length; i++) { + str += getRandomElement(chars); + } + return str; +} + +/** + * Возвращает случайное собственное свойство объекта + * + * @param {Object} obj объект + * + * @return {Object} + */ +function getRandomPropertyVal(obj) { + 'use strict'; + var keys, prop; + keys = []; + for (prop in obj) { + if (obj.hasOwnProperty(prop)) { + keys.push(prop); + } + } + return obj[getRandomElement(keys)]; +} + +/** + * Возвращает сгенерированную дату начала события + * Вычисляется как текущая дата начала события + случайное число дней от -28 до 28 + * + * @return {Date} + */ +function getRandomStartDate() { + 'use strict'; + var startDate = new Date(); + startDate.setDate(startDate.getDate() + getRandomInt(-28, 28)); + startDate.setHours(getRandomInt(0, 23)); + startDate.setMinutes(getRandomInt(0, 59)); + return startDate; +} + +/** + * Возвращает сгенерированную дату окончания события + * Вычисляется как дата начала события + случайное число часов от 1 до 23 + * @param {Number|Date} startDate Начало события + * + * @return {Date} + */ +function getRandomEndDate(startDate) { + 'use strict'; + var endDate = new Date(startDate.getTime()); + endDate.setHours(startDate.getHours() + getRandomInt(1, 23)); + endDate.setMinutes(getRandomInt(0, 59)); + return endDate; +} + +/** + * Возвращает сгенерированный случайным образом объект Event + * + * @return {Object} + */ +function getRandomEvent() { + 'use strict'; + var title, location, starts, ends, repeat, alert, notes; + title = getRandomElement(activities); + location = getRandomElement(locations); + starts = getRandomStartDate(); + ends = getRandomEndDate(starts); + repeat = getRandomPropertyVal(REPEAT); + alert = getRandomPropertyVal(ALERT); + notes = getRandomString(); + return Event(title, location, starts, ends, repeat, alert, notes); +} \ No newline at end of file diff --git a/event-utils.js b/event-utils.js new file mode 100644 index 0000000..bd1c19b --- /dev/null +++ b/event-utils.js @@ -0,0 +1,122 @@ +function inherits(Constructor, SuperConstructor) { + var F = function () {}; // Временный, чистый конструктор + // Сохраняем ссылку + F.prototype = SuperConstructor.prototype; + // Применяем __proto__ = prototype + Constructor.prototype = new F(); +} + +/** + * Добавляет к дате кол-во лет, месяцев, дней и т.д определенных в параметре + * Параметр добавления даты должен иметь формат + dd.MM.YY hh:mm + * @param {Number|Date} date Дата + * @param {String} dateTimeStr Строка в формате '+ dd.MM.YY hh:mm' + * + * @return {Date} + */ +function addDateTime(date, dateTimeStr) { + 'use strict'; + var result, splitted, sign, addDate, dd, mm, yy, addTime, hh, min; + splitted = checkAddTime(dateTimeStr); + result = new Date(date.getTime()); + if (splitted) { + if (splitted[1] === '-') { + sign = -1; + } else { + sign = 1; + } + addDate = splitted[2].split('.'); + addTime = splitted[3].split(':'); + result.setDate(result.getDate() + sign * addDate[0]); + result.setMonth(result.getMonth() + sign * addDate[1]); + result.setYear(result.getYear() + sign * addDate[2]); + result.setHours(result.getHours() + sign * addTime[0]); + result.setMinutes(result.getMinutes() + sign * addTime[1]); + } else { + console.log("Add time in 'addDateTime' function must have format '+ dd.MM.YY hh:mm'"); + } + return result; +} + +/** + * Вычисляет когда в следующий раз случится периодическое событие + * + * @param {Event} event Событие + * + * @return {Date} + */ +function getNextHappenDate(event) { + 'use strict'; + var nhd, today; + if (!event.nextHappenDate) { + today = new Date(); + nhd = event.startDate; + while (nhd < today) { + nhd = addDateTime(nhd, event.repeat.value); + } + event.nextHappenDate = nhd; + } + return event.nextHappenDate; +} + +/** + * Вычисляет следующее время напоминания для периодических событий + * + * @param {Event} event Событие + * + * @return {Date} + */ +function getNextAlarmTime(event) { + 'use strict'; + var nhd = getNextHappenDate(event); + return addDateTime(nhd, event.alert.value); +} + +/** + * Функция проверяет, нужно ли напомнить о событии + * + * @param {Event} event Событие + * + * @return {Boolean} + */ +function isAlertTime(event) { + 'use strict'; + var today, diff; + today = new Date(); + diff = today - getNextAlarmTime(event); + return diff > -500 && diff < 500; +} + +/** + * Вычисляет дату начала недели + * + * @param {Date} [date="new Date()"] Дата + * + * @return {Date} + */ +function getWeekStartDate(date) { + 'use strict'; + var startOfWeek; + date = date || new Date(); + startOfWeek = new Date(date.getTime()); + startOfWeek.setDate(date.getDate() - date.getDay() + 1); + startOfWeek.setHours(0); + startOfWeek.setMinutes(0); + return startOfWeek; +} + +/** + * Вычисляет дату конца недели + * + * @param {Date} [date="new Date()"] Дата + * + * @return {Date} + */ +function getWeekEndDate(date) { + 'use strict'; + var startOfWeek, endOfWeek; + startOfWeek = getWeekStartDate(date); + endOfWeek = new Date(startOfWeek.getTime()); + endOfWeek.setDate(startOfWeek.getDate() + 7); + return endOfWeek; +} \ No newline at end of file diff --git a/model.js b/model.js new file mode 100644 index 0000000..353e9c6 --- /dev/null +++ b/model.js @@ -0,0 +1,39 @@ +var Model = function (data) { + "use strict"; + var propName; + for (propName in data) { + if (this.hasOwnProperty(propName)) { + this[propName] = data[propName]; + } + } + +}; + +/** + * @param {Object} attributes + * + * @example + * item.set({title: "March 20", content: "In his eyes she eclipses..."}); + */ +Model.prototype.set = function (attributes) { + "use strict"; + var attribute; + for (attribute in attributes) { + if (this.hasOwnProperty(attribute)) { + this[attribute] = attributes[attribute]; + } + } +}; +/** + * @param {String} attribute + */ +Model.prototype.get = function (attribute) { + if (this.hasOwnProperty(attribute)) { + return this[attribute]; + } +}; +/** + * @param {Object} attributes + */ +Model.prototype.validate = function (attributes) {throw new Error('this is Abstract method')}; +// Другие необходимые вам поля \ No newline at end of file From 4a992c55d8ad707c09c190116ce5f9b433a03681 Mon Sep 17 00:00:00 2001 From: Dmitry Borisov Date: Tue, 13 Nov 2012 19:17:36 +0600 Subject: [PATCH 02/13] all but everything works --- collection.js | 81 +++++++++++++++++++++----------------- event-collection.html | 28 ++++++++++++++ event-collection.js | 90 +++++++++++++++++++++++++++++++++---------- event-model.js | 23 ++++++++++- event-random.js | 26 +++++++++++-- model.js | 8 +--- 6 files changed, 190 insertions(+), 66 deletions(-) create mode 100644 event-collection.html diff --git a/collection.js b/collection.js index 83e3d0b..3df0bce 100644 --- a/collection.js +++ b/collection.js @@ -1,36 +1,47 @@ -var Collection = function () { - 'use strict'; - this.items = []; -}; - -/** - * @return {Collection} - */ -Collection.prototype.add = function (model) { - 'use strict'; - this.items.push(model); -}; -/** - * @param {Function} selector - * - * @see https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/filter - * - * @example - * new Collection().filter(function (item) { - * return item.get('attendee').indexOf("me") !== -1; - * }); - * @return {Collection} - */ -Collection.prototype.filter = function (selector) { - 'use strict'; - this.items.filter(selector); - return this; -}; -/** - * @return {Collection} - */ -Collection.prototype.sortBy = function (selector) { - 'use strict'; - this.items.sort(selector); - return this; +var Collection = function (items) { + 'use strict'; + this.items = []; + for (item in items) { + if (item.validate()) { + this.items.push(item); + } + } +}; + +/** + * @return {Collection} + */ +Collection.prototype.add = function (model) { + 'use strict'; + this.items.push(model); +}; +/** + * , selector + * + * @param {Function} selector + * + * @see https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/filter + * + * @return {Collection} + */ +Collection.prototype.filter = function (selector) { + 'use strict'; + this.items.filter(selector); + return this; +}; +/** + * , selector + * + * @param {Function} selector + * @param {Boolean} asc + * + * @return {Collection} + */ +Collection.prototype.sortBy = function (selector, asc) { + 'use strict'; + this.items.sort(selector); + if (asc) { + this.items.reverse(); + } + return this; }; \ No newline at end of file diff --git a/event-collection.html b/event-collection.html new file mode 100644 index 0000000..1e4e616 --- /dev/null +++ b/event-collection.html @@ -0,0 +1,28 @@ + + + + + + EVents test + + + + + +
+ + + + + +
+ + + + + + + + + + diff --git a/event-collection.js b/event-collection.js index 55210ba..5af68ac 100644 --- a/event-collection.js +++ b/event-collection.js @@ -1,21 +1,69 @@ -var Events = function (items) { - Collection.apply(this, arguments); -}; -inherits(Events, Collection); - -/** - * @return {Events} - */ -Events.prototype.findOnlyMyEvents = function () {}; -/** - * @return {Events} - */ -Events.prototype.findFutureEvents = function () {}; -/** - * @return {Events} - */ -Events.prototype.findPastEvents = function () {}; -/** - * @return {Events} - */ -Events.prototype.sortByName = function () {}; \ No newline at end of file +var Events = function (items) { + Collection.apply(this, arguments); +}; +inherits(Events, Collection); + +/** + * @return {Events} + */ +Events.prototype.findPastEvents = function () { + 'use strict'; + return this.filter(function (event) { + return event.endDate < new Date(); + }); +}; +/** + * @return {Events} + */ +Events.prototype.findFutureEvents = function () { + 'use strict'; + return this.filter(function (event) { + return event.startDate > new Date(); + }); +}; +/** + * @return {Events} + */ +Events.prototype.findThisWeekEvents = function () { + 'use strict'; + return this.filter(function (event) { + return event.startDate > getWeekStartDate() && event.startDate < getWeekEndDate(); + }); +}; +/** + * @return {Events} + */ +Events.prototype.findPartyEvents = function () { + 'use strict'; + return this.filter(function (event) { + return event.title === 'Drunken feast'; + }); +}; +/** + * @return {Events} + */ +Events.prototype.findNightAlarms = function () { + 'use strict'; + return this.filter(function (event) { + var alarm = getNextAlarmTime(event); + return alarm.getHours() > 0 && alarm.getHours() < 8; + }); +}; +/** + * @return {Events} + */ +Events.prototype.sortByStartDate = function (asc) { + 'use strict'; + return this.sortBy(function (a, b) { + return b.startDate - a.startDate; + }, asc); +}; +/** + * @return {Events} + */ +Events.prototype.sortByNextHappenDate = function (asc) { + 'use strict'; + return this.sortBy(function (a, b) { + return getNextHappenDate(b) - getNextHappenDate(a); + }, asc); +}; \ No newline at end of file diff --git a/event-model.js b/event-model.js index fe34abd..804444b 100644 --- a/event-model.js +++ b/event-model.js @@ -85,7 +85,28 @@ function checkAlert(alert) { } return alert; } - +/** + * Создает объект Event + * + * @param {String} [title="New Event"] Имя события + * @param {String} [location] Место события + * @param {Number|Date} [starts="new Date()"] Начало события + * @param {Number|Date} [ends="starts + 1"] Конец события + * @param {Object} [repeat="REPEAT.NEVER"] Периодичность события + * @param {Object} [alert="ALERT.NONE"] Предупреждение + * @param {String} [notes] Заметки + * + * @example + * new Event({title: "Лекция JavaScript", + * location: "УРГУ", + * starts: new Date('2011-10-10T14:48:00'), + * ends: new Date('2011-10-10T15:48:00'), + * repeat: REPEAT.WEEK, + * alert: ALERT.B30MIN, + * notes: "Вспомнить, что проходили на прошлом занятии"}) + * + * @return {Event} + */ var Event = function (data) { Model.apply(this, arguments); }; diff --git a/event-random.js b/event-random.js index 58787a6..bca6c3a 100644 --- a/event-random.js +++ b/event-random.js @@ -97,7 +97,7 @@ function getRandomEndDate(startDate) { /** * Возвращает сгенерированный случайным образом объект Event * - * @return {Object} + * @return {Event} */ function getRandomEvent() { 'use strict'; @@ -109,5 +109,25 @@ function getRandomEvent() { repeat = getRandomPropertyVal(REPEAT); alert = getRandomPropertyVal(ALERT); notes = getRandomString(); - return Event(title, location, starts, ends, repeat, alert, notes); -} \ No newline at end of file + return new Event({ + title: title, + location: location, + starts: starts, + ends: ends, + repeat: repeat, + alert: alert, + notes: notes + }); +} + +function getRandomEventCollection(size) { + 'use strict'; + var i, events; + events = new Events(); + for (i = 0; i < size; i++) { + events.add(getRandomEvent()); + } + return events; +} + +var events = getRandomEventCollection(20); \ No newline at end of file diff --git a/model.js b/model.js index 353e9c6..16bf6d4 100644 --- a/model.js +++ b/model.js @@ -2,9 +2,7 @@ var Model = function (data) { "use strict"; var propName; for (propName in data) { - if (this.hasOwnProperty(propName)) { - this[propName] = data[propName]; - } + this[propName] = data[propName]; } }; @@ -19,9 +17,7 @@ Model.prototype.set = function (attributes) { "use strict"; var attribute; for (attribute in attributes) { - if (this.hasOwnProperty(attribute)) { - this[attribute] = attributes[attribute]; - } + this[attribute] = attributes[attribute]; } }; /** From 2c2505984dcf2296dfadcb704825a1ce73b88333 Mon Sep 17 00:00:00 2001 From: Dmitry Borisov Date: Wed, 14 Nov 2012 18:38:32 +0600 Subject: [PATCH 03/13] almost everything works --- collection.js | 4 +++- event-model.js | 4 ++-- event-random.js | 4 ++-- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/collection.js b/collection.js index 3df0bce..ba6a9e1 100644 --- a/collection.js +++ b/collection.js @@ -26,7 +26,9 @@ Collection.prototype.add = function (model) { */ Collection.prototype.filter = function (selector) { 'use strict'; - this.items.filter(selector); + var tmp; + tmp = this.items.filter(selector); + this.items = tmp; return this; }; /** diff --git a/event-model.js b/event-model.js index 804444b..200bbe7 100644 --- a/event-model.js +++ b/event-model.js @@ -99,8 +99,8 @@ function checkAlert(alert) { * @example * new Event({title: "Лекция JavaScript", * location: "УРГУ", - * starts: new Date('2011-10-10T14:48:00'), - * ends: new Date('2011-10-10T15:48:00'), + * startDate: new Date('2011-10-10T14:48:00'), + * endDate: new Date('2011-10-10T15:48:00'), * repeat: REPEAT.WEEK, * alert: ALERT.B30MIN, * notes: "Вспомнить, что проходили на прошлом занятии"}) diff --git a/event-random.js b/event-random.js index bca6c3a..a8298f8 100644 --- a/event-random.js +++ b/event-random.js @@ -112,8 +112,8 @@ function getRandomEvent() { return new Event({ title: title, location: location, - starts: starts, - ends: ends, + startDate: starts, + endDate: ends, repeat: repeat, alert: alert, notes: notes From c7b3c287ed738f9a817f28844c7947848ccc3355 Mon Sep 17 00:00:00 2001 From: Borisov Dmitry Date: Fri, 16 Nov 2012 00:30:26 +0600 Subject: [PATCH 04/13] decided to make it my way --- collection.js | 94 ++++++++++++------------ event-collection.html | 1 + event-collection.js | 140 ++++++++++++++++++------------------ event-model.js | 4 +- model.js | 3 +- new 2.js | 52 ++++++++++++++ utils.js | 161 ++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 335 insertions(+), 120 deletions(-) create mode 100644 new 2.js create mode 100644 utils.js diff --git a/collection.js b/collection.js index ba6a9e1..e39dbac 100644 --- a/collection.js +++ b/collection.js @@ -1,49 +1,47 @@ -var Collection = function (items) { - 'use strict'; - this.items = []; - for (item in items) { - if (item.validate()) { - this.items.push(item); - } - } -}; - -/** - * @return {Collection} - */ -Collection.prototype.add = function (model) { - 'use strict'; - this.items.push(model); -}; -/** - * , selector - * - * @param {Function} selector - * - * @see https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/filter - * - * @return {Collection} - */ -Collection.prototype.filter = function (selector) { - 'use strict'; - var tmp; - tmp = this.items.filter(selector); - this.items = tmp; - return this; -}; -/** - * , selector - * - * @param {Function} selector - * @param {Boolean} asc - * - * @return {Collection} - */ -Collection.prototype.sortBy = function (selector, asc) { - 'use strict'; - this.items.sort(selector); - if (asc) { - this.items.reverse(); - } - return this; +var Collection = function (items) { + 'use strict'; + this.items = []; + for (var item in items) { + if (items[item].validate()) { + this.items.push(item); + } + } +}; + +/** + * @return {Collection} + */ +Collection.prototype.add = function (model) { + 'use strict'; + this.items.push(model); +}; +/** + * , selector + * + * @param {Function} selector + * + * @see https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/filter + * + * @return {Collection} + */ +Collection.prototype.filter = function (selector) { + 'use strict'; + var tmp = this.items.filter(selector); + return new this.constructor(tmp); +}; +/** + * , selector + * + * @param {Function} selector + * @param {Boolean} asc + * + * @return {Collection} + */ +Collection.prototype.sortBy = function (selector, asc) { + 'use strict'; + this.items.sort(selector); + if (asc) { + this.items.reverse(); + } + return this; }; \ No newline at end of file diff --git a/event-collection.html b/event-collection.html index 1e4e616..557f53f 100644 --- a/event-collection.html +++ b/event-collection.html @@ -23,6 +23,7 @@ + diff --git a/event-collection.js b/event-collection.js index 5af68ac..d0f299e 100644 --- a/event-collection.js +++ b/event-collection.js @@ -1,69 +1,71 @@ -var Events = function (items) { - Collection.apply(this, arguments); -}; -inherits(Events, Collection); - -/** - * @return {Events} - */ -Events.prototype.findPastEvents = function () { - 'use strict'; - return this.filter(function (event) { - return event.endDate < new Date(); - }); -}; -/** - * @return {Events} - */ -Events.prototype.findFutureEvents = function () { - 'use strict'; - return this.filter(function (event) { - return event.startDate > new Date(); - }); -}; -/** - * @return {Events} - */ -Events.prototype.findThisWeekEvents = function () { - 'use strict'; - return this.filter(function (event) { - return event.startDate > getWeekStartDate() && event.startDate < getWeekEndDate(); - }); -}; -/** - * @return {Events} - */ -Events.prototype.findPartyEvents = function () { - 'use strict'; - return this.filter(function (event) { - return event.title === 'Drunken feast'; - }); -}; -/** - * @return {Events} - */ -Events.prototype.findNightAlarms = function () { - 'use strict'; - return this.filter(function (event) { - var alarm = getNextAlarmTime(event); - return alarm.getHours() > 0 && alarm.getHours() < 8; - }); -}; -/** - * @return {Events} - */ -Events.prototype.sortByStartDate = function (asc) { - 'use strict'; - return this.sortBy(function (a, b) { - return b.startDate - a.startDate; - }, asc); -}; -/** - * @return {Events} - */ -Events.prototype.sortByNextHappenDate = function (asc) { - 'use strict'; - return this.sortBy(function (a, b) { - return getNextHappenDate(b) - getNextHappenDate(a); - }, asc); -}; \ No newline at end of file +var Events = function (items) { + Collection.apply(this, arguments); +}; +inherits(Events, Collection); + +/** + * @return {Events} + */ +Events.prototype.findPastEvents = function () { + 'use strict'; + return this.filter(function (event) { + return event.endDate < new Date(); + }); +}; +/** + * @return {Events} + */ +Events.prototype.findFutureEvents = function () { + 'use strict'; + return this.filter(function (event) { + return event.startDate > new Date(); + }); +}; +/** + * @return {Events} + */ +Events.prototype.findThisWeekEvents = function () { + 'use strict'; + return this.filter(function (event) { + return event.startDate > getWeekStartDate() && event.startDate < getWeekEndDate(); + }); +}; +/** + * @return {Events} + */ +Events.prototype.findPartyEvents = function () { + 'use strict'; + return this.filter(function (event) { + return event.title === 'Drunken feast'; + }); +}; +/** + * @return {Events} + */ +Events.prototype.findNightAlarms = function () { + 'use strict'; + return this.filter(function (event) { + var alarm = getNextAlarmTime(event); + return alarm.getHours() > 0 && alarm.getHours() < 8; + }); +}; +/** + * @return {Events} + */ +Events.prototype.sortByStartDate = function (asc) { + 'use strict'; + return this.sortBy(function (a, b) { + return b.startDate - a.startDate; + }, asc); +}; +/** + * @return {Events} + */ +Events.prototype.sortByNextHappenDate = function (asc) { + 'use strict'; + return this.sortBy(function (a, b) { + return getNextHappenDate(b) - getNextHappenDate(a); + }, asc); +}; + +Events.prototype.constructor = Events; \ No newline at end of file diff --git a/event-model.js b/event-model.js index 200bbe7..033108c 100644 --- a/event-model.js +++ b/event-model.js @@ -136,4 +136,6 @@ Event.prototype.validate = function () { return; } return this; -}; \ No newline at end of file +}; + +Event.prototype.constructor = Event; \ No newline at end of file diff --git a/model.js b/model.js index 16bf6d4..1303e32 100644 --- a/model.js +++ b/model.js @@ -31,5 +31,4 @@ Model.prototype.get = function (attribute) { /** * @param {Object} attributes */ -Model.prototype.validate = function (attributes) {throw new Error('this is Abstract method')}; -// Другие необходимые вам поля \ No newline at end of file +Model.prototype.validate = function (attributes) {throw new Error('this is Abstract method')}; \ No newline at end of file diff --git a/new 2.js b/new 2.js new file mode 100644 index 0000000..24a04ea --- /dev/null +++ b/new 2.js @@ -0,0 +1,52 @@ +var Collection = function (items) { + 'use strict'; + var item; + this.items = []; + for (item in items) { + if (items.hasOwnProperty(item)) { + this.add(item); + } + } +}; + +/** + * @return {Collection} + */ +Collection.prototype = + { + add : function (model) { + if (model.validate()) { + this.items.push(model); + } + }, + /** + * Фильтрация коллекции по правилам, определенным в функции selector + * + * @param {Function} selector + * + * @see https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/filter + * + * @return {Collection} + */ + filter : function (selector) { + var tmp; + tmp = this.items.filter(selector); + this.items = tmp; + return this; + }, + /** + * Сортировка коллекции по правилам, определенным в функции selector + * + * @param {Function} selector + * @param {Boolean} asc + * + * @return {Collection} + */ + sortBy : function (selector, asc) { + this.items.sort(selector); + if (asc) { + this.items.reverse(); + } + return this; + } + }; \ No newline at end of file diff --git a/utils.js b/utils.js new file mode 100644 index 0000000..43c0ec2 --- /dev/null +++ b/utils.js @@ -0,0 +1,161 @@ +/*jslint plusplus: true*/ +var Const = { + ACTIVITIES : ["Studying", "Drunken feast", "Karaoke singing", "Hanging around"], + LOCATIONS : ["My home", "My work", "My friend's house", "1905 Sq.", "UrFU", "Unknown"], + REPEAT : { + NEVER: {title: "None", value: "+ 0.0.0 0:0"}, + DAY: {title: "Every Day", value: "+ 1.0.0 0:0"}, + WEEK: {title: "Every Week", value: "+ 7.0.0 0:0"}, + TWOWEEK: {title: "Every 2 weeks", value: "+ 14.0.0 0:0"}, + MONTH: {title: "Every month", value: "+ 0.1.0 0:0"}, + YEAR: {title: "Every year", value: "+ 0.0.1 0:0"} + }, + ALERT : { + NONE: {title: "None", value: "+ 0.0.0 0:0"}, + B5MIN: {title: "5 minutes before", value: "- 0.0.0 0:5"}, + B15MIN: {title: "15 minutes before", value: "- 0.0.0 0:15"}, + B30MIN: {title: "30 minutes before", value: "- 0.0.0 0:30"}, + B1HOUR: {title: "1 hour before", value: "- 0.0.0 1:0"}, + B1DAY: {title: "1 day before", value: "- 0.0.0 24:0"} + } +}; +var Utils = (function () { + 'use strict'; + var Random = function (e) { + this.activities = e.ACTIVITIES; + this.locations = e.LOCATIONS; + this.repeat = e.REPEAT; + this.alert = e.ALERT; + }; + + Random.prototype = + { + /** + * Возвращает случайное число в интервале [min, max] + * + * @param {Number} min нижний предел + * @param {Number} max верхний предел + * + * @return {Number} + */ + getRandomInt : function (min, max) { + return Math.floor(Math.random() * (max - min + 1)) + min; + }, + + /** + * Возвращает случайный элемент массива + * + * @param {Array} arr массив + * + * @return {Object} + */ + getRandomElement : function (arr) { + return arr[this.getRandomInt(0, arr.length - 1)]; + }, + + /** + * Возвращает сгенерированную строку из случайных символов + * + * @return {String} + */ + getRandomString : function () { + var chars, length, str, i; + chars = "01234 56789 ABCDE FGHIJ KLMNO PQRST UVWXT Zabcd efghi klmno pqrst uvwxy z"; + chars = chars.split(''); + length = this.getRandomInt(4, chars.length); + str = ''; + for (i = 0; i < length; i++) { + str += this.getRandomElement(chars); + } + return str; + }, + + /** + * Возвращает случайное собственное свойство объекта + * + * @param {Object} obj объект + * + * @return {Object} + */ + getRandomPropertyVal : function (obj) { + var keys, prop; + keys = []; + for (prop in obj) { + if (obj.hasOwnProperty(prop)) { + keys.push(prop); + } + } + return obj[this.getRandomElement(keys)]; + }, + + /** + * Возвращает сгенерированную дату начала события + * Вычисляется как текущая дата начала события + случайное число дней от -28 до 28 + * + * @return {Date} + */ + getRandomStartDate : function () { + var startDate = new Date(); + startDate.setDate(startDate.getDate() + this.getRandomInt(-28, 28)); + startDate.setHours(this.getRandomInt(0, 23)); + startDate.setMinutes(this.getRandomInt(0, 59)); + return startDate; + }, + + /** + * Возвращает сгенерированную дату окончания события + * Вычисляется как дата начала события + случайное число часов от 1 до 23 + * @param {Number|Date} startDate Начало события + * + * @return {Date} + */ + getRandomEndDate : function (startDate) { + var endDate = new Date(startDate.getTime()); + endDate.setHours(startDate.getHours() + this.getRandomInt(1, 23)); + endDate.setMinutes(this.getRandomInt(0, 59)); + return endDate; + }, + + /** + * Возвращает сгенерированный случайным образом объект Event + * + * @return {Event} + */ + getRandomEvent : function () { + var title, location, starts, ends, repeat, alert, notes; + title = this.getRandomElement(this.activities); + location = this.getRandomElement(this.locations); + starts = this.getRandomStartDate(); + ends = this.getRandomEndDate(starts); + repeat = this.getRandomPropertyVal(this.repeat); + alert = this.getRandomPropertyVal(this.alert); + notes = this.getRandomString(); + return new Event({ + title: title, + location: location, + startDate: starts, + endDate: ends, + repeat: repeat, + alert: alert, + notes: notes + }); + }, + + getRandomEventCollection : function (size) { + var i, events; + events = new Events(); + for (i = 0; i < size; i++) { + events.add(this.getRandomEvent()); + } + return events; + } + }; + + return { + randomEventCollection: function (size) { + return new Random(Const).getRandomEventCollection(size); + } + }; +}()); + +var events = Utils.randomEventCollection(20); \ No newline at end of file From 9ff6566e05f973dba3bfdd1f752b3a84dc995d5b Mon Sep 17 00:00:00 2001 From: Borisov Dmitry Date: Fri, 16 Nov 2012 00:41:00 +0600 Subject: [PATCH 05/13] updated wrong field names --- collection.js | 2 +- event-model.js | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/collection.js b/collection.js index e39dbac..8f61651 100644 --- a/collection.js +++ b/collection.js @@ -3,7 +3,7 @@ var Collection = function (items) { this.items = []; for (var item in items) { if (items[item].validate()) { - this.items.push(item); + this.items.push(items[item]); } } }; diff --git a/event-model.js b/event-model.js index 033108c..19c97b0 100644 --- a/event-model.js +++ b/event-model.js @@ -119,12 +119,12 @@ inherits(Event, Model); */ Event.prototype.validate = function () { 'use strict'; - this.starts = checkStartDate(this.starts); - if (this.starts === null) { + this.startDate = checkStartDate(this.startDate); + if (this.startDate === null) { return; } - this.ends = checkEndDate(this.ends, this.starts); - if (this.ends === null) { + this.endDate = checkEndDate(this.endDate, this.startDate); + if (this.endDate === null) { return; } this.repeat = checkRepeat(this.repeat); From e20528f03d87d0a506115733830a73d99fb63110 Mon Sep 17 00:00:00 2001 From: Dmitry Borisov Date: Fri, 16 Nov 2012 18:13:49 +0600 Subject: [PATCH 06/13] yet another commit --- collection.js | 93 +++++++++++++++-------------- new 2.js => collection2.js | 13 ++-- event-collection.html | 6 +- event-model.js | 116 ++++++++++++++++++++++-------------- model.js | 76 ++++++++++++----------- utils.js | 71 ++++++++++++++++++++++ 6 files changed, 242 insertions(+), 133 deletions(-) rename new 2.js => collection2.js (79%) diff --git a/collection.js b/collection.js index 8f61651..7ab7251 100644 --- a/collection.js +++ b/collection.js @@ -1,47 +1,48 @@ -var Collection = function (items) { - 'use strict'; - this.items = []; - for (var item in items) { - if (items[item].validate()) { - this.items.push(items[item]); - } - } -}; - -/** - * @return {Collection} - */ -Collection.prototype.add = function (model) { - 'use strict'; - this.items.push(model); -}; -/** - * , selector - * - * @param {Function} selector - * - * @see https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/filter - * - * @return {Collection} - */ -Collection.prototype.filter = function (selector) { - 'use strict'; - var tmp = this.items.filter(selector); - return new this.constructor(tmp); -}; -/** - * , selector - * - * @param {Function} selector - * @param {Boolean} asc - * - * @return {Collection} - */ -Collection.prototype.sortBy = function (selector, asc) { - 'use strict'; - this.items.sort(selector); - if (asc) { - this.items.reverse(); - } - return this; +var Collection = function (items) { + 'use strict'; + var item; + this.items = []; + for (item in items) { + if (items[item].validate()) { + this.items.push(items[item]); + } + } +}; + +/** + * @return {Collection} + */ +Collection.prototype.add = function (model) { + 'use strict'; + this.items.push(model); +}; +/** + * , selector + * + * @param {Function} selector + * + * @see https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/filter + * + * @return {Collection} + */ +Collection.prototype.filter = function (selector) { + 'use strict'; + var tmp = this.items.filter(selector); + return new this.constructor(tmp); +}; +/** + * , selector + * + * @param {Function} selector + * @param {Boolean} asc + * + * @return {Collection} + */ +Collection.prototype.sortBy = function (selector, asc) { + 'use strict'; + this.items.sort(selector); + if (asc) { + this.items.reverse(); + } + return this; }; \ No newline at end of file diff --git a/new 2.js b/collection2.js similarity index 79% rename from new 2.js rename to collection2.js index 24a04ea..ef12f6b 100644 --- a/new 2.js +++ b/collection2.js @@ -4,7 +4,9 @@ var Collection = function (items) { this.items = []; for (item in items) { if (items.hasOwnProperty(item)) { - this.add(item); + if (items[item].validate()) { + this.items.push(items[item]); + } } } }; @@ -15,6 +17,7 @@ var Collection = function (items) { Collection.prototype = { add : function (model) { + 'use strict'; if (model.validate()) { this.items.push(model); } @@ -29,10 +32,9 @@ Collection.prototype = * @return {Collection} */ filter : function (selector) { - var tmp; - tmp = this.items.filter(selector); - this.items = tmp; - return this; + 'use strict'; + var tmp = this.items.filter(selector); + return new this.constructor(tmp); }, /** * Сортировка коллекции по правилам, определенным в функции selector @@ -43,6 +45,7 @@ Collection.prototype = * @return {Collection} */ sortBy : function (selector, asc) { + 'use strict'; this.items.sort(selector); if (asc) { this.items.reverse(); diff --git a/event-collection.html b/event-collection.html index 557f53f..38b6993 100644 --- a/event-collection.html +++ b/event-collection.html @@ -17,13 +17,11 @@ - - + - - + diff --git a/event-model.js b/event-model.js index 19c97b0..d01f725 100644 --- a/event-model.js +++ b/event-model.js @@ -29,24 +29,6 @@ function checkEndDate(endDate, startDate) { return date; } -var REPEAT = { - NEVER: {title: "None", value: "+ 0.0.0 0:0"}, - DAY: {title: "Every Day", value: "+ 1.0.0 0:0"}, - WEEK: {title: "Every Week", value: "+ 7.0.0 0:0"}, - TWOWEEK: {title: "Every 2 weeks", value: "+ 14.0.0 0:0"}, - MONTH: {title: "Every month", value: "+ 0.1.0 0:0"}, - YEAR: {title: "Every year", value: "+ 0.0.1 0:0"} -}; - -var ALERT = { - NONE: {title: "None", value: "+ 0.0.0 0:0"}, - B5MIN: {title: "5 minutes before", value: "- 0.0.0 0:5"}, - B15MIN: {title: "15 minutes before", value: "- 0.0.0 0:15"}, - B30MIN: {title: "30 minutes before", value: "- 0.0.0 0:30"}, - B1HOUR: {title: "1 hour before", value: "- 0.0.0 1:0"}, - B1DAY: {title: "1 day before", value: "- 0.0.0 24:0"} -}; - function checkAddTime(addTime) { 'use strict'; var re, splitted; @@ -61,7 +43,7 @@ function checkAddTime(addTime) { function checkRepeat(repeat) { 'use strict'; if (repeat === null) { - repeat = REPEAT.NEVER; + repeat = Const.REPEAT.NEVER; } else if (!(repeat.title && repeat.value)) { console.log("Unknown type of 'repeat' variable"); repeat = null; @@ -75,7 +57,7 @@ function checkRepeat(repeat) { function checkAlert(alert) { 'use strict'; if (alert === null) { - alert = ALERT.NONE; + alert = Const.ALERT.NONE; } else if (!(alert.title && alert.value)) { console.log("Unknown type of 'alert' variable"); alert = null; @@ -92,8 +74,8 @@ function checkAlert(alert) { * @param {String} [location] Место события * @param {Number|Date} [starts="new Date()"] Начало события * @param {Number|Date} [ends="starts + 1"] Конец события - * @param {Object} [repeat="REPEAT.NEVER"] Периодичность события - * @param {Object} [alert="ALERT.NONE"] Предупреждение + * @param {Object} [repeat="Const.REPEAT.NEVER"] Периодичность события + * @param {Object} [alert="Const.ALERT.NONE"] Предупреждение * @param {String} [notes] Заметки * * @example @@ -117,25 +99,71 @@ inherits(Event, Model); * * @return {Event} */ -Event.prototype.validate = function () { - 'use strict'; - this.startDate = checkStartDate(this.startDate); - if (this.startDate === null) { - return; - } - this.endDate = checkEndDate(this.endDate, this.startDate); - if (this.endDate === null) { - return; - } - this.repeat = checkRepeat(this.repeat); - if (this.repeat === null) { - return; - } - this.alert = checkAlert(this.alert); - if (this.alert === null) { - return; - } - return this; -}; - -Event.prototype.constructor = Event; \ No newline at end of file +Event.prototype = + { + constructor : Event, + validate : function () { + 'use strict'; + this.startDate = checkStartDate(this.startDate); + if (this.startDate === null) { + return; + } + this.endDate = checkEndDate(this.endDate, this.startDate); + if (this.endDate === null) { + return; + } + this.repeat = checkRepeat(this.repeat); + if (this.repeat === null) { + return; + } + this.alert = checkAlert(this.alert); + if (this.alert === null) { + return; + } + return this; + }, + /** + * Вычисляет когда в следующий раз случится периодическое событие + * + * @return {Date} + */ + getNextHappenDate : function() { + 'use strict'; + var nhd, today; + if (!this.nextHappenDate) { + today = new Date(); + nhd = this.startDate; + while (nhd < today) { + nhd = Utils.addDateTime(nhd, this.repeat.value); + } + this.nextHappenDate = nhd; + } + return this.nextHappenDate; + }, + /** + * Вычисляет следующее время напоминания для периодических событий + * + * @param {Event} event Событие + * + * @return {Date} + */ + getNextAlarmTime : function() { + 'use strict'; + var nhd = this.getNextHappenDate(); + return Utils.addDateTime(nhd, event.alert.value); + }, + /** + * Функция проверяет, нужно ли напомнить о событии + * + * @param {Event} event Событие + * + * @return {Boolean} + */ + isAlertTime : function() { + 'use strict'; + var today, diff; + today = new Date(); + diff = today - this.getNextAlarmTime(); + return diff > -500 && diff < 500; + } + }; \ No newline at end of file diff --git a/model.js b/model.js index 1303e32..addca58 100644 --- a/model.js +++ b/model.js @@ -1,34 +1,42 @@ -var Model = function (data) { - "use strict"; - var propName; - for (propName in data) { - this[propName] = data[propName]; - } - -}; - -/** - * @param {Object} attributes - * - * @example - * item.set({title: "March 20", content: "In his eyes she eclipses..."}); - */ -Model.prototype.set = function (attributes) { - "use strict"; - var attribute; - for (attribute in attributes) { - this[attribute] = attributes[attribute]; - } -}; -/** - * @param {String} attribute - */ -Model.prototype.get = function (attribute) { - if (this.hasOwnProperty(attribute)) { - return this[attribute]; - } -}; -/** - * @param {Object} attributes - */ -Model.prototype.validate = function (attributes) {throw new Error('this is Abstract method')}; \ No newline at end of file +var Model = function (data) { + "use strict"; + var propName; + for (propName in data) { + this[propName] = data[propName]; + } + +}; + +/** + * @param {Object} attributes + * + * @example + * item.set({title: "March 20", content: "In his eyes she eclipses..."}); + */ +Model.prototype.set = function (attributes) { + "use strict"; + var attribute; + for (attribute in attributes) { + this[attribute] = attributes[attribute]; + } +}; +/** + * @param {String} attribute + */ +Model.prototype.get = function (attribute) { + if (this.hasOwnProperty(attribute)) { + return this[attribute]; + } +}; +/** + * @param {Object} attributes + */ +Model.prototype.validate = function (attributes) {throw new Error('this is Abstract method')}; + +function inherits(Constructor, SuperConstructor) { + var F = function () {}; // , + // + F.prototype = SuperConstructor.prototype; + // __proto__ = prototype + Constructor.prototype = new F(); +} \ No newline at end of file diff --git a/utils.js b/utils.js index 43c0ec2..130ba67 100644 --- a/utils.js +++ b/utils.js @@ -151,9 +151,80 @@ var Utils = (function () { } }; + /** + * Добавляет к дате кол-во лет, месяцев, дней и т.д определенных в параметре + * Параметр добавления даты должен иметь формат + dd.MM.YY hh:mm + * @param {Number|Date} date Дата + * @param {String} dateTimeStr Строка в формате '+ dd.MM.YY hh:mm' + * + * @return {Date} + */ + function addDateTime(date, dateTimeStr) { + var result, splitted, sign, addDate, dd, mm, yy, addTime, hh, min; + splitted = checkAddTime(dateTimeStr); + result = new Date(date.getTime()); + if (splitted) { + if (splitted[1] === '-') { + sign = -1; + } else { + sign = 1; + } + addDate = splitted[2].split('.'); + addTime = splitted[3].split(':'); + result.setDate(result.getDate() + sign * addDate[0]); + result.setMonth(result.getMonth() + sign * addDate[1]); + result.setYear(result.getYear() + sign * addDate[2]); + result.setHours(result.getHours() + sign * addTime[0]); + result.setMinutes(result.getMinutes() + sign * addTime[1]); + } else { + console.log("Add time in 'addDateTime' function must have format '+ dd.MM.YY hh:mm'"); + } + return result; + } + + /** + * Вычисляет дату начала недели + * + * @param {Date} [date="new Date()"] Дата + * + * @return {Date} + */ + function getWeekStartDate(date) { + var startOfWeek; + date = date || new Date(); + startOfWeek = new Date(date.getTime()); + startOfWeek.setDate(date.getDate() - date.getDay() + 1); + startOfWeek.setHours(0); + startOfWeek.setMinutes(0); + return startOfWeek; + } + /** + * Вычисляет дату конца недели + * + * @param {Date} [date="new Date()"] Дата + * + * @return {Date} + */ + function getWeekEndDate(date) { + var startOfWeek, endOfWeek; + startOfWeek = getWeekStartDate(date); + endOfWeek = new Date(startOfWeek.getTime()); + endOfWeek.setDate(startOfWeek.getDate() + 7); + return endOfWeek; + } + return { randomEventCollection: function (size) { return new Random(Const).getRandomEventCollection(size); + }, + addDateTime: function (date, dateTimeStr) { + return addDateTime(date, dateTimeStr); + }, + getWeekStartDate: function (date) { + return getWeekStartDate(date); + }, + getWeekEndDate: function (date) { + return getWeekEndDate(date); } }; }()); From 484b43c8f80cd84bdbaa0d234ffc8c0116bf8b4a Mon Sep 17 00:00:00 2001 From: Borisov Dmitry Date: Sat, 17 Nov 2012 01:35:55 +0600 Subject: [PATCH 07/13] Voila --- collection.js | 103 +++++++++++++++++--------------- collection2.js | 55 ----------------- event-collection.html | 2 +- event-collection.js | 19 ++++-- event-model.js | 134 +++++++++++++++++++++--------------------- model.js | 92 ++++++++++++++++------------- 6 files changed, 187 insertions(+), 218 deletions(-) delete mode 100644 collection2.js diff --git a/collection.js b/collection.js index 7ab7251..ef12f6b 100644 --- a/collection.js +++ b/collection.js @@ -1,48 +1,55 @@ -var Collection = function (items) { - 'use strict'; - var item; - this.items = []; - for (item in items) { - if (items[item].validate()) { - this.items.push(items[item]); - } - } -}; - -/** - * @return {Collection} - */ -Collection.prototype.add = function (model) { - 'use strict'; - this.items.push(model); -}; -/** - * , selector - * - * @param {Function} selector - * - * @see https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/filter - * - * @return {Collection} - */ -Collection.prototype.filter = function (selector) { - 'use strict'; - var tmp = this.items.filter(selector); - return new this.constructor(tmp); -}; -/** - * , selector - * - * @param {Function} selector - * @param {Boolean} asc - * - * @return {Collection} - */ -Collection.prototype.sortBy = function (selector, asc) { - 'use strict'; - this.items.sort(selector); - if (asc) { - this.items.reverse(); - } - return this; -}; \ No newline at end of file +var Collection = function (items) { + 'use strict'; + var item; + this.items = []; + for (item in items) { + if (items.hasOwnProperty(item)) { + if (items[item].validate()) { + this.items.push(items[item]); + } + } + } +}; + +/** + * @return {Collection} + */ +Collection.prototype = + { + add : function (model) { + 'use strict'; + if (model.validate()) { + this.items.push(model); + } + }, + /** + * Фильтрация коллекции по правилам, определенным в функции selector + * + * @param {Function} selector + * + * @see https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/filter + * + * @return {Collection} + */ + filter : function (selector) { + 'use strict'; + var tmp = this.items.filter(selector); + return new this.constructor(tmp); + }, + /** + * Сортировка коллекции по правилам, определенным в функции selector + * + * @param {Function} selector + * @param {Boolean} asc + * + * @return {Collection} + */ + sortBy : function (selector, asc) { + 'use strict'; + this.items.sort(selector); + if (asc) { + this.items.reverse(); + } + return this; + } + }; \ No newline at end of file diff --git a/collection2.js b/collection2.js deleted file mode 100644 index ef12f6b..0000000 --- a/collection2.js +++ /dev/null @@ -1,55 +0,0 @@ -var Collection = function (items) { - 'use strict'; - var item; - this.items = []; - for (item in items) { - if (items.hasOwnProperty(item)) { - if (items[item].validate()) { - this.items.push(items[item]); - } - } - } -}; - -/** - * @return {Collection} - */ -Collection.prototype = - { - add : function (model) { - 'use strict'; - if (model.validate()) { - this.items.push(model); - } - }, - /** - * Фильтрация коллекции по правилам, определенным в функции selector - * - * @param {Function} selector - * - * @see https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/filter - * - * @return {Collection} - */ - filter : function (selector) { - 'use strict'; - var tmp = this.items.filter(selector); - return new this.constructor(tmp); - }, - /** - * Сортировка коллекции по правилам, определенным в функции selector - * - * @param {Function} selector - * @param {Boolean} asc - * - * @return {Collection} - */ - sortBy : function (selector, asc) { - 'use strict'; - this.items.sort(selector); - if (asc) { - this.items.reverse(); - } - return this; - } - }; \ No newline at end of file diff --git a/event-collection.html b/event-collection.html index 38b6993..46fa1f9 100644 --- a/event-collection.html +++ b/event-collection.html @@ -18,7 +18,7 @@ - + diff --git a/event-collection.js b/event-collection.js index d0f299e..af7bd44 100644 --- a/event-collection.js +++ b/event-collection.js @@ -1,9 +1,12 @@ var Events = function (items) { + 'use strict'; Collection.apply(this, arguments); }; inherits(Events, Collection); +Events.prototype.constructor = Events; /** + * Возвращает новую коллекцию, содержащую только прошедшие события * @return {Events} */ Events.prototype.findPastEvents = function () { @@ -13,6 +16,7 @@ Events.prototype.findPastEvents = function () { }); }; /** + * Возвращает новую коллекцию, содержащую только будущие события * @return {Events} */ Events.prototype.findFutureEvents = function () { @@ -22,15 +26,17 @@ Events.prototype.findFutureEvents = function () { }); }; /** + * Возвращает новую коллекцию, содержащую только события этой недели * @return {Events} */ Events.prototype.findThisWeekEvents = function () { 'use strict'; return this.filter(function (event) { - return event.startDate > getWeekStartDate() && event.startDate < getWeekEndDate(); + return event.startDate > Utils.getWeekStartDate() && event.startDate < Utils.getWeekEndDate(); }); }; /** + * Возвращает новую коллекцию, содержащую только события 'Drunken feast' * @return {Events} */ Events.prototype.findPartyEvents = function () { @@ -40,16 +46,18 @@ Events.prototype.findPartyEvents = function () { }); }; /** + * Возвращает новую коллекцию, содержащую только те события, напоминание которых сработает ночью * @return {Events} */ Events.prototype.findNightAlarms = function () { 'use strict'; return this.filter(function (event) { - var alarm = getNextAlarmTime(event); + var alarm = event.getNextAlarmTime(); return alarm.getHours() > 0 && alarm.getHours() < 8; }); }; /** + * Сортирует коллекцию по дате начала события * @return {Events} */ Events.prototype.sortByStartDate = function (asc) { @@ -59,13 +67,12 @@ Events.prototype.sortByStartDate = function (asc) { }, asc); }; /** + * Сортирует коллекцию по следующей дате периодического события * @return {Events} */ Events.prototype.sortByNextHappenDate = function (asc) { 'use strict'; return this.sortBy(function (a, b) { - return getNextHappenDate(b) - getNextHappenDate(a); + return b.getNextHappenDate() - a.getNextHappenDate(); }, asc); -}; - -Events.prototype.constructor = Events; \ No newline at end of file +}; \ No newline at end of file diff --git a/event-model.js b/event-model.js index d01f725..54a8458 100644 --- a/event-model.js +++ b/event-model.js @@ -1,3 +1,4 @@ +/*jslint devel: true */ function checkStartDate(date) { 'use strict'; if (date === null) { @@ -90,80 +91,79 @@ function checkAlert(alert) { * @return {Event} */ var Event = function (data) { + 'use strict'; Model.apply(this, arguments); }; inherits(Event, Model); +Event.prototype.constructor = Event; + /** * Функция, валидирующая объект Event * * @return {Event} */ -Event.prototype = - { - constructor : Event, - validate : function () { - 'use strict'; - this.startDate = checkStartDate(this.startDate); - if (this.startDate === null) { - return; - } - this.endDate = checkEndDate(this.endDate, this.startDate); - if (this.endDate === null) { - return; - } - this.repeat = checkRepeat(this.repeat); - if (this.repeat === null) { - return; - } - this.alert = checkAlert(this.alert); - if (this.alert === null) { - return; - } - return this; - }, - /** - * Вычисляет когда в следующий раз случится периодическое событие - * - * @return {Date} - */ - getNextHappenDate : function() { - 'use strict'; - var nhd, today; - if (!this.nextHappenDate) { - today = new Date(); - nhd = this.startDate; - while (nhd < today) { - nhd = Utils.addDateTime(nhd, this.repeat.value); - } - this.nextHappenDate = nhd; - } - return this.nextHappenDate; - }, - /** - * Вычисляет следующее время напоминания для периодических событий - * - * @param {Event} event Событие - * - * @return {Date} - */ - getNextAlarmTime : function() { - 'use strict'; - var nhd = this.getNextHappenDate(); - return Utils.addDateTime(nhd, event.alert.value); - }, - /** - * Функция проверяет, нужно ли напомнить о событии - * - * @param {Event} event Событие - * - * @return {Boolean} - */ - isAlertTime : function() { - 'use strict'; - var today, diff; - today = new Date(); - diff = today - this.getNextAlarmTime(); - return diff > -500 && diff < 500; +Event.prototype.validate = function () { + 'use strict'; + this.startDate = checkStartDate(this.startDate); + if (this.startDate === null) { + return; + } + this.endDate = checkEndDate(this.endDate, this.startDate); + if (this.endDate === null) { + return; + } + this.repeat = checkRepeat(this.repeat); + if (this.repeat === null) { + return; + } + this.alert = checkAlert(this.alert); + if (this.alert === null) { + return; + } + return this; +}; +/** + * Вычисляет когда в следующий раз случится периодическое событие + * + * @return {Date} + */ +Event.prototype.getNextHappenDate = function () { + 'use strict'; + var nhd, today; + if (!this.nextHappenDate) { + today = new Date(); + nhd = this.startDate; + while (nhd < today) { + nhd = Utils.addDateTime(nhd, this.repeat.value); } - }; \ No newline at end of file + this.nextHappenDate = nhd; + } + return this.nextHappenDate; +}; +/** + * Вычисляет следующее время напоминания для периодических событий + * + * @param {Event} event Событие + * + * @return {Date} + */ +Event.prototype.getNextAlarmTime = function () { + 'use strict'; + var nhd = this.getNextHappenDate(); + return Utils.addDateTime(nhd, this.alert.value); +}; +/** + * Функция проверяет, нужно ли напомнить о событии + * + * @param {Event} event Событие + * + * @return {Boolean} + */ +Event.prototype.isAlertTime = function () { + 'use strict'; + var today, diff; + today = new Date(); + diff = today - this.getNextAlarmTime(); + return diff > -500 && diff < 500; +}; \ No newline at end of file diff --git a/model.js b/model.js index addca58..3158a77 100644 --- a/model.js +++ b/model.js @@ -1,42 +1,52 @@ -var Model = function (data) { - "use strict"; - var propName; - for (propName in data) { - this[propName] = data[propName]; - } - -}; - -/** - * @param {Object} attributes - * - * @example - * item.set({title: "March 20", content: "In his eyes she eclipses..."}); - */ -Model.prototype.set = function (attributes) { - "use strict"; - var attribute; - for (attribute in attributes) { - this[attribute] = attributes[attribute]; - } -}; -/** - * @param {String} attribute - */ -Model.prototype.get = function (attribute) { - if (this.hasOwnProperty(attribute)) { - return this[attribute]; - } -}; -/** - * @param {Object} attributes - */ -Model.prototype.validate = function (attributes) {throw new Error('this is Abstract method')}; - -function inherits(Constructor, SuperConstructor) { - var F = function () {}; // , - // - F.prototype = SuperConstructor.prototype; - // __proto__ = prototype - Constructor.prototype = new F(); +var Model = function (data) { + "use strict"; + var propName; + for (propName in data) { + if (data.hasOwnProperty(propName)) { + this[propName] = data[propName]; + } + } + +}; + +Model.prototype = + { + /** Мутатор + * @param {Object} attributes + * + * @example + * item.set({title: "March 20", notes: "In his eyes she eclipses..."}); + */ + set : function (attributes) { + "use strict"; + var attribute; + for (attribute in attributes) { + if (attributes.hasOwnProperty(attribute)) { + this[attribute] = attributes[attribute]; + } + } + }, + /** Аксессор + * @param {String} attribute + */ + get : function (attribute) { + "use strict"; + if (this.hasOwnProperty(attribute)) { + return this[attribute]; + } + }, + /** Валидатор + * @param {Object} attributes + */ + validate : function (attributes) { + "use strict"; + console.log('this is Abstract method'); + } + }; + +function inherits(Constructor, SuperConstructor) { + "use strict"; + var F = function () {}; + F.prototype = SuperConstructor.prototype; + Constructor.prototype = new F(); } \ No newline at end of file From db3c4bc40c5e82cb5488d8293ae2ea0e5733ce02 Mon Sep 17 00:00:00 2001 From: Borisov Dmitry Date: Sat, 17 Nov 2012 01:43:12 +0600 Subject: [PATCH 08/13] unused files --- event-random.js | 133 ------------------------------------------------ event-utils.js | 122 -------------------------------------------- 2 files changed, 255 deletions(-) delete mode 100644 event-random.js delete mode 100644 event-utils.js diff --git a/event-random.js b/event-random.js deleted file mode 100644 index a8298f8..0000000 --- a/event-random.js +++ /dev/null @@ -1,133 +0,0 @@ -/*jslint plusplus: true*/ -var activities = ["Studying", "Drunken feast", "Karaoke singing", "Hanging around"]; -var locations = ["My home", "My work", "My friend's house", "1905 Sq.", "UrFU", "Unknown"]; - -/** - * Возвращает случайное число в интервале [min, max] - * - * @param {Number} min нижний предел - * @param {Number} max верхний предел - * - * @return {Number} - */ -function getRandomInt(min, max) { - 'use strict'; - return Math.floor(Math.random() * (max - min + 1)) + min; -} - -/** - * Возвращает случайный элемент массива - * - * @param {Array} arr массив - * - * @return {Object} - */ -function getRandomElement(arr) { - 'use strict'; - return arr[getRandomInt(0, arr.length - 1)]; -} - -/** - * Возвращает сгенерированную строку из случайных символов - * - * @return {String} - */ -function getRandomString() { - 'use strict'; - var chars, length, str, i; - chars = "01234 56789 ABCDE FGHIJ KLMNO PQRST UVWXT Zabcd efghi klmno pqrst uvwxy z"; - chars = chars.split(''); - length = getRandomInt(4, chars.length); - str = ''; - for (i = 0; i < length; i++) { - str += getRandomElement(chars); - } - return str; -} - -/** - * Возвращает случайное собственное свойство объекта - * - * @param {Object} obj объект - * - * @return {Object} - */ -function getRandomPropertyVal(obj) { - 'use strict'; - var keys, prop; - keys = []; - for (prop in obj) { - if (obj.hasOwnProperty(prop)) { - keys.push(prop); - } - } - return obj[getRandomElement(keys)]; -} - -/** - * Возвращает сгенерированную дату начала события - * Вычисляется как текущая дата начала события + случайное число дней от -28 до 28 - * - * @return {Date} - */ -function getRandomStartDate() { - 'use strict'; - var startDate = new Date(); - startDate.setDate(startDate.getDate() + getRandomInt(-28, 28)); - startDate.setHours(getRandomInt(0, 23)); - startDate.setMinutes(getRandomInt(0, 59)); - return startDate; -} - -/** - * Возвращает сгенерированную дату окончания события - * Вычисляется как дата начала события + случайное число часов от 1 до 23 - * @param {Number|Date} startDate Начало события - * - * @return {Date} - */ -function getRandomEndDate(startDate) { - 'use strict'; - var endDate = new Date(startDate.getTime()); - endDate.setHours(startDate.getHours() + getRandomInt(1, 23)); - endDate.setMinutes(getRandomInt(0, 59)); - return endDate; -} - -/** - * Возвращает сгенерированный случайным образом объект Event - * - * @return {Event} - */ -function getRandomEvent() { - 'use strict'; - var title, location, starts, ends, repeat, alert, notes; - title = getRandomElement(activities); - location = getRandomElement(locations); - starts = getRandomStartDate(); - ends = getRandomEndDate(starts); - repeat = getRandomPropertyVal(REPEAT); - alert = getRandomPropertyVal(ALERT); - notes = getRandomString(); - return new Event({ - title: title, - location: location, - startDate: starts, - endDate: ends, - repeat: repeat, - alert: alert, - notes: notes - }); -} - -function getRandomEventCollection(size) { - 'use strict'; - var i, events; - events = new Events(); - for (i = 0; i < size; i++) { - events.add(getRandomEvent()); - } - return events; -} - -var events = getRandomEventCollection(20); \ No newline at end of file diff --git a/event-utils.js b/event-utils.js deleted file mode 100644 index bd1c19b..0000000 --- a/event-utils.js +++ /dev/null @@ -1,122 +0,0 @@ -function inherits(Constructor, SuperConstructor) { - var F = function () {}; // Временный, чистый конструктор - // Сохраняем ссылку - F.prototype = SuperConstructor.prototype; - // Применяем __proto__ = prototype - Constructor.prototype = new F(); -} - -/** - * Добавляет к дате кол-во лет, месяцев, дней и т.д определенных в параметре - * Параметр добавления даты должен иметь формат + dd.MM.YY hh:mm - * @param {Number|Date} date Дата - * @param {String} dateTimeStr Строка в формате '+ dd.MM.YY hh:mm' - * - * @return {Date} - */ -function addDateTime(date, dateTimeStr) { - 'use strict'; - var result, splitted, sign, addDate, dd, mm, yy, addTime, hh, min; - splitted = checkAddTime(dateTimeStr); - result = new Date(date.getTime()); - if (splitted) { - if (splitted[1] === '-') { - sign = -1; - } else { - sign = 1; - } - addDate = splitted[2].split('.'); - addTime = splitted[3].split(':'); - result.setDate(result.getDate() + sign * addDate[0]); - result.setMonth(result.getMonth() + sign * addDate[1]); - result.setYear(result.getYear() + sign * addDate[2]); - result.setHours(result.getHours() + sign * addTime[0]); - result.setMinutes(result.getMinutes() + sign * addTime[1]); - } else { - console.log("Add time in 'addDateTime' function must have format '+ dd.MM.YY hh:mm'"); - } - return result; -} - -/** - * Вычисляет когда в следующий раз случится периодическое событие - * - * @param {Event} event Событие - * - * @return {Date} - */ -function getNextHappenDate(event) { - 'use strict'; - var nhd, today; - if (!event.nextHappenDate) { - today = new Date(); - nhd = event.startDate; - while (nhd < today) { - nhd = addDateTime(nhd, event.repeat.value); - } - event.nextHappenDate = nhd; - } - return event.nextHappenDate; -} - -/** - * Вычисляет следующее время напоминания для периодических событий - * - * @param {Event} event Событие - * - * @return {Date} - */ -function getNextAlarmTime(event) { - 'use strict'; - var nhd = getNextHappenDate(event); - return addDateTime(nhd, event.alert.value); -} - -/** - * Функция проверяет, нужно ли напомнить о событии - * - * @param {Event} event Событие - * - * @return {Boolean} - */ -function isAlertTime(event) { - 'use strict'; - var today, diff; - today = new Date(); - diff = today - getNextAlarmTime(event); - return diff > -500 && diff < 500; -} - -/** - * Вычисляет дату начала недели - * - * @param {Date} [date="new Date()"] Дата - * - * @return {Date} - */ -function getWeekStartDate(date) { - 'use strict'; - var startOfWeek; - date = date || new Date(); - startOfWeek = new Date(date.getTime()); - startOfWeek.setDate(date.getDate() - date.getDay() + 1); - startOfWeek.setHours(0); - startOfWeek.setMinutes(0); - return startOfWeek; -} - -/** - * Вычисляет дату конца недели - * - * @param {Date} [date="new Date()"] Дата - * - * @return {Date} - */ -function getWeekEndDate(date) { - 'use strict'; - var startOfWeek, endOfWeek; - startOfWeek = getWeekStartDate(date); - endOfWeek = new Date(startOfWeek.getTime()); - endOfWeek.setDate(startOfWeek.getDate() + 7); - return endOfWeek; -} \ No newline at end of file From 78d1f8a5e7b6e2201d7de2b2e07a6879e6e047fd Mon Sep 17 00:00:00 2001 From: Dmitry Borisov Date: Fri, 23 Nov 2012 18:00:54 +0600 Subject: [PATCH 09/13] iefe --- event-model.js | 311 +++++++++++++++++++++++++------------------------ model.js | 78 ++++++------- utils.js | 15 ++- 3 files changed, 203 insertions(+), 201 deletions(-) diff --git a/event-model.js b/event-model.js index 54a8458..226b79f 100644 --- a/event-model.js +++ b/event-model.js @@ -1,169 +1,172 @@ /*jslint devel: true */ -function checkStartDate(date) { - 'use strict'; - if (date === null) { - date = new Date(); - } else if (!(date instanceof Date && isFinite(date))) { - console.log("Start date is invalid, check syntax"); - date = null; +var Event = (function () { + function checkStartDate(date) { + 'use strict'; + if (date === null) { + date = new Date(); + } else if (!(date instanceof Date && isFinite(date))) { + console.log("Start date is invalid, check syntax"); + date = null; + } + return date; } - return date; -} -function checkEndDate(endDate, startDate) { - 'use strict'; - var date; - if (endDate === null) { - date = startDate; - date.setHours(startDate.getHours() + 1); - } else if (endDate instanceof Date && isFinite(endDate)) { - if (endDate < startDate) { - console.log("End date should be after start date"); - date = null; + function checkEndDate(endDate, startDate) { + 'use strict'; + var date; + if (endDate === null) { + date = startDate; + date.setHours(startDate.getHours() + 1); + } else if (endDate instanceof Date && isFinite(endDate)) { + if (endDate < startDate) { + console.log("End date should be after start date"); + date = null; + } else { + date = endDate; + } } else { - date = endDate; + console.log("End date is invalid, check syntax"); + date = null; } - } else { - console.log("End date is invalid, check syntax"); - date = null; + return date; } - return date; -} -function checkAddTime(addTime) { - 'use strict'; - var re, splitted; - re = "([+-]) (\\d?\\d.\\d?\\d.\\d?\\d) (\\d?\\d:\\d?\\d)"; - splitted = addTime.match(re); - if (splitted === null || splitted.length !== 4) { - splitted = null; + function checkAddTime(addTime) { + 'use strict'; + var re, splitted; + re = "([+-]) (\\d?\\d.\\d?\\d.\\d?\\d) (\\d?\\d:\\d?\\d)"; + splitted = addTime.match(re); + if (splitted === null || splitted.length !== 4) { + splitted = null; + } + return splitted; } - return splitted; -} -function checkRepeat(repeat) { - 'use strict'; - if (repeat === null) { - repeat = Const.REPEAT.NEVER; - } else if (!(repeat.title && repeat.value)) { - console.log("Unknown type of 'repeat' variable"); - repeat = null; - } else if (!checkAddTime(repeat.value)) { - console.log("Add time in 'repeat' variable must have format '+ dd.MM.YY hh:mm'"); - repeat = null; + function checkRepeat(repeat) { + 'use strict'; + if (repeat === null) { + repeat = Const.REPEAT.NEVER; + } else if (!(repeat.title && repeat.value)) { + console.log("Unknown type of 'repeat' variable"); + repeat = null; + } else if (!checkAddTime(repeat.value)) { + console.log("Add time in 'repeat' variable must have format '+ dd.MM.YY hh:mm'"); + repeat = null; + } + return repeat; } - return repeat; -} -function checkAlert(alert) { - 'use strict'; - if (alert === null) { - alert = Const.ALERT.NONE; - } else if (!(alert.title && alert.value)) { - console.log("Unknown type of 'alert' variable"); - alert = null; - } else if (!checkAddTime(alert.value)) { - console.log("Add time in 'alert' variable must have format '+ dd.MM.YY hh:mm'"); - alert = null; + function checkAlert(alert) { + 'use strict'; + if (alert === null) { + alert = Const.ALERT.NONE; + } else if (!(alert.title && alert.value)) { + console.log("Unknown type of 'alert' variable"); + alert = null; + } else if (!checkAddTime(alert.value)) { + console.log("Add time in 'alert' variable must have format '+ dd.MM.YY hh:mm'"); + alert = null; + } + return alert; } - return alert; -} -/** - * Создает объект Event - * - * @param {String} [title="New Event"] Имя события - * @param {String} [location] Место события - * @param {Number|Date} [starts="new Date()"] Начало события - * @param {Number|Date} [ends="starts + 1"] Конец события - * @param {Object} [repeat="Const.REPEAT.NEVER"] Периодичность события - * @param {Object} [alert="Const.ALERT.NONE"] Предупреждение - * @param {String} [notes] Заметки - * - * @example - * new Event({title: "Лекция JavaScript", - * location: "УРГУ", - * startDate: new Date('2011-10-10T14:48:00'), - * endDate: new Date('2011-10-10T15:48:00'), - * repeat: REPEAT.WEEK, - * alert: ALERT.B30MIN, - * notes: "Вспомнить, что проходили на прошлом занятии"}) - * - * @return {Event} - */ -var Event = function (data) { - 'use strict'; - Model.apply(this, arguments); -}; -inherits(Event, Model); + /** + * Создает объект Event + * + * @param {String} [title="New Event"] Имя события + * @param {String} [location] Место события + * @param {Number|Date} [starts="new Date()"] Начало события + * @param {Number|Date} [ends="starts + 1"] Конец события + * @param {Object} [repeat="Const.REPEAT.NEVER"] Периодичность события + * @param {Object} [alert="Const.ALERT.NONE"] Предупреждение + * @param {String} [notes] Заметки + * + * @example + * new Event({title: "Лекция JavaScript", + * location: "УРГУ", + * startDate: new Date('2011-10-10T14:48:00'), + * endDate: new Date('2011-10-10T15:48:00'), + * repeat: REPEAT.WEEK, + * alert: ALERT.B30MIN, + * notes: "Вспомнить, что проходили на прошлом занятии"}) + * + * @return {Event} + */ + var Event = function (data) { + 'use strict'; + Model.apply(this, arguments); + }; + inherits(Event, Model); -Event.prototype.constructor = Event; + Event.prototype.constructor = Event; -/** - * Функция, валидирующая объект Event - * - * @return {Event} - */ -Event.prototype.validate = function () { - 'use strict'; - this.startDate = checkStartDate(this.startDate); - if (this.startDate === null) { - return; - } - this.endDate = checkEndDate(this.endDate, this.startDate); - if (this.endDate === null) { - return; - } - this.repeat = checkRepeat(this.repeat); - if (this.repeat === null) { - return; - } - this.alert = checkAlert(this.alert); - if (this.alert === null) { - return; - } - return this; -}; -/** - * Вычисляет когда в следующий раз случится периодическое событие - * - * @return {Date} - */ -Event.prototype.getNextHappenDate = function () { - 'use strict'; - var nhd, today; - if (!this.nextHappenDate) { - today = new Date(); - nhd = this.startDate; - while (nhd < today) { - nhd = Utils.addDateTime(nhd, this.repeat.value); + /** + * Функция, валидирующая объект Event + * + * @return {Event} + */ + Event.prototype.validate = function () { + 'use strict'; + this.startDate = checkStartDate(this.startDate); + if (this.startDate === null) { + return; } - this.nextHappenDate = nhd; - } - return this.nextHappenDate; -}; -/** - * Вычисляет следующее время напоминания для периодических событий - * - * @param {Event} event Событие - * - * @return {Date} - */ -Event.prototype.getNextAlarmTime = function () { - 'use strict'; - var nhd = this.getNextHappenDate(); - return Utils.addDateTime(nhd, this.alert.value); -}; -/** - * Функция проверяет, нужно ли напомнить о событии - * - * @param {Event} event Событие - * - * @return {Boolean} - */ -Event.prototype.isAlertTime = function () { - 'use strict'; - var today, diff; - today = new Date(); - diff = today - this.getNextAlarmTime(); - return diff > -500 && diff < 500; -}; \ No newline at end of file + this.endDate = checkEndDate(this.endDate, this.startDate); + if (this.endDate === null) { + return; + } + this.repeat = checkRepeat(this.repeat); + if (this.repeat === null) { + return; + } + this.alert = checkAlert(this.alert); + if (this.alert === null) { + return; + } + return this; + }; + /** + * Вычисляет когда в следующий раз случится периодическое событие + * + * @return {Date} + */ + Event.prototype.getNextHappenDate = function () { + 'use strict'; + var nhd, today; + if (!this.nextHappenDate) { + today = new Date(); + nhd = this.startDate; + while (nhd < today) { + nhd = Utils.addDateTime(nhd, this.repeat.value); + } + this.nextHappenDate = nhd; + } + return this.nextHappenDate; + }; + /** + * Вычисляет следующее время напоминания для периодических событий + * + * @param {Event} event Событие + * + * @return {Date} + */ + Event.prototype.getNextAlarmTime = function () { + 'use strict'; + var nhd = this.getNextHappenDate(); + return Utils.addDateTime(nhd, this.alert.value); + }; + /** + * Функция проверяет, нужно ли напомнить о событии + * + * @param {Event} event Событие + * + * @return {Boolean} + */ + Event.prototype.isAlertTime = function () { + 'use strict'; + var today, diff; + today = new Date(); + diff = today - this.getNextAlarmTime(); + return diff > -500 && diff < 500; + }; + return Event; +}()); \ No newline at end of file diff --git a/model.js b/model.js index 3158a77..f5c43d7 100644 --- a/model.js +++ b/model.js @@ -1,48 +1,48 @@ -var Model = function (data) { +var Model = (function () { "use strict"; - var propName; - for (propName in data) { - if (data.hasOwnProperty(propName)) { - this[propName] = data[propName]; + var Model = function (data) { + var propName; + for (propName in data) { + if (data.hasOwnProperty(propName)) { + this[propName] = data[propName]; + } } - } -}; + }; -Model.prototype = - { - /** Мутатор - * @param {Object} attributes - * - * @example - * item.set({title: "March 20", notes: "In his eyes she eclipses..."}); - */ - set : function (attributes) { - "use strict"; - var attribute; - for (attribute in attributes) { - if (attributes.hasOwnProperty(attribute)) { - this[attribute] = attributes[attribute]; + Model.prototype = + { + /** Мутатор + * @param {Object} attributes + * + * @example + * item.set({title: "March 20", notes: "In his eyes she eclipses..."}); + */ + set : function (attributes) { + var attribute; + for (attribute in attributes) { + if (attributes.hasOwnProperty(attribute)) { + this[attribute] = attributes[attribute]; + } } + }, + /** Аксессор + * @param {String} attribute + */ + get : function (attribute) { + if (this.hasOwnProperty(attribute)) { + return this[attribute]; + } + }, + /** Валидатор + * @param {Object} attributes + */ + validate : function (attributes) { + console.log('this is Abstract method'); } - }, - /** Аксессор - * @param {String} attribute - */ - get : function (attribute) { - "use strict"; - if (this.hasOwnProperty(attribute)) { - return this[attribute]; - } - }, - /** Валидатор - * @param {Object} attributes - */ - validate : function (attributes) { - "use strict"; - console.log('this is Abstract method'); - } - }; + }; + return Model; +}()); function inherits(Constructor, SuperConstructor) { "use strict"; diff --git a/utils.js b/utils.js index 130ba67..b28e326 100644 --- a/utils.js +++ b/utils.js @@ -122,14 +122,13 @@ var Utils = (function () { * @return {Event} */ getRandomEvent : function () { - var title, location, starts, ends, repeat, alert, notes; - title = this.getRandomElement(this.activities); - location = this.getRandomElement(this.locations); - starts = this.getRandomStartDate(); - ends = this.getRandomEndDate(starts); - repeat = this.getRandomPropertyVal(this.repeat); - alert = this.getRandomPropertyVal(this.alert); - notes = this.getRandomString(); + var title = this.getRandomElement(this.activities), + location = this.getRandomElement(this.locations), + starts = this.getRandomStartDate(), + ends = this.getRandomEndDate(starts), + repeat = this.getRandomPropertyVal(this.repeat), + alert = this.getRandomPropertyVal(this.alert), + notes = this.getRandomString(); return new Event({ title: title, location: location, From dd055707bdc2f2c63b01d40c92ba8606fb96f296 Mon Sep 17 00:00:00 2001 From: Borisov Dmitry Date: Sun, 25 Nov 2012 13:40:49 +0600 Subject: [PATCH 10/13] iefe everywhere --- collection.js | 100 +++++++++++++++--------------- event-collection.js | 148 +++++++++++++++++++++----------------------- event-model.js | 25 +------- utils.js | 13 ++++ 4 files changed, 138 insertions(+), 148 deletions(-) diff --git a/collection.js b/collection.js index ef12f6b..e80cf34 100644 --- a/collection.js +++ b/collection.js @@ -1,55 +1,55 @@ -var Collection = function (items) { +var Collection = (function () { 'use strict'; - var item; - this.items = []; - for (item in items) { - if (items.hasOwnProperty(item)) { - if (items[item].validate()) { - this.items.push(items[item]); + var Collection = function (items) { + var item; + this.items = []; + for (item in items) { + if (items.hasOwnProperty(item)) { + if (items[item].validate()) { + this.items.push(items[item]); + } } } - } -}; + }; -/** - * @return {Collection} - */ -Collection.prototype = - { - add : function (model) { - 'use strict'; - if (model.validate()) { - this.items.push(model); + /** + * @return {Collection} + */ + Collection.prototype = + { + add : function (model) { + if (model.validate()) { + this.items.push(model); + } + }, + /** + * Фильтрация коллекции по правилам, определенным в функции selector + * + * @param {Function} selector + * + * @see https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/filter + * + * @return {Collection} + */ + filter : function (selector) { + var tmp = this.items.filter(selector); + return new this.constructor(tmp); + }, + /** + * Сортировка коллекции по правилам, определенным в функции selector + * + * @param {Function} selector + * @param {Boolean} desc + * + * @return {Collection} + */ + sortBy : function (selector, desc) { + this.items.sort(selector); + if (desc) { + this.items.reverse(); + } + return this; } - }, - /** - * Фильтрация коллекции по правилам, определенным в функции selector - * - * @param {Function} selector - * - * @see https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/filter - * - * @return {Collection} - */ - filter : function (selector) { - 'use strict'; - var tmp = this.items.filter(selector); - return new this.constructor(tmp); - }, - /** - * Сортировка коллекции по правилам, определенным в функции selector - * - * @param {Function} selector - * @param {Boolean} asc - * - * @return {Collection} - */ - sortBy : function (selector, asc) { - 'use strict'; - this.items.sort(selector); - if (asc) { - this.items.reverse(); - } - return this; - } - }; \ No newline at end of file + }; + return Collection; +}()); \ No newline at end of file diff --git a/event-collection.js b/event-collection.js index af7bd44..6cf0687 100644 --- a/event-collection.js +++ b/event-collection.js @@ -1,78 +1,74 @@ -var Events = function (items) { +var Events = (function () { 'use strict'; - Collection.apply(this, arguments); -}; -inherits(Events, Collection); + var Events = function (items) { + Collection.apply(this, arguments); + }; + inherits(Events, Collection); -Events.prototype.constructor = Events; -/** - * Возвращает новую коллекцию, содержащую только прошедшие события - * @return {Events} - */ -Events.prototype.findPastEvents = function () { - 'use strict'; - return this.filter(function (event) { - return event.endDate < new Date(); - }); -}; -/** - * Возвращает новую коллекцию, содержащую только будущие события - * @return {Events} - */ -Events.prototype.findFutureEvents = function () { - 'use strict'; - return this.filter(function (event) { - return event.startDate > new Date(); - }); -}; -/** - * Возвращает новую коллекцию, содержащую только события этой недели - * @return {Events} - */ -Events.prototype.findThisWeekEvents = function () { - 'use strict'; - return this.filter(function (event) { - return event.startDate > Utils.getWeekStartDate() && event.startDate < Utils.getWeekEndDate(); - }); -}; -/** - * Возвращает новую коллекцию, содержащую только события 'Drunken feast' - * @return {Events} - */ -Events.prototype.findPartyEvents = function () { - 'use strict'; - return this.filter(function (event) { - return event.title === 'Drunken feast'; - }); -}; -/** - * Возвращает новую коллекцию, содержащую только те события, напоминание которых сработает ночью - * @return {Events} - */ -Events.prototype.findNightAlarms = function () { - 'use strict'; - return this.filter(function (event) { - var alarm = event.getNextAlarmTime(); - return alarm.getHours() > 0 && alarm.getHours() < 8; - }); -}; -/** - * Сортирует коллекцию по дате начала события - * @return {Events} - */ -Events.prototype.sortByStartDate = function (asc) { - 'use strict'; - return this.sortBy(function (a, b) { - return b.startDate - a.startDate; - }, asc); -}; -/** - * Сортирует коллекцию по следующей дате периодического события - * @return {Events} - */ -Events.prototype.sortByNextHappenDate = function (asc) { - 'use strict'; - return this.sortBy(function (a, b) { - return b.getNextHappenDate() - a.getNextHappenDate(); - }, asc); -}; \ No newline at end of file + Events.prototype.constructor = Events; + /** + * Возвращает новую коллекцию, содержащую только прошедшие события + * @return {Events} + */ + Events.prototype.findPastEvents = function () { + return this.filter(function (event) { + return event.endDate < new Date(); + }); + }; + /** + * Возвращает новую коллекцию, содержащую только будущие события + * @return {Events} + */ + Events.prototype.findFutureEvents = function () { + return this.filter(function (event) { + return event.startDate > new Date(); + }); + }; + /** + * Возвращает новую коллекцию, содержащую только события этой недели + * @return {Events} + */ + Events.prototype.findThisWeekEvents = function () { + return this.filter(function (event) { + return event.startDate > Utils.getWeekStartDate() && event.startDate < Utils.getWeekEndDate(); + }); + }; + /** + * Возвращает новую коллекцию, содержащую только события 'Drunken feast' + * @return {Events} + */ + Events.prototype.findPartyEvents = function () { + return this.filter(function (event) { + return event.title === 'Drunken feast'; + }); + }; + /** + * Возвращает новую коллекцию, содержащую только те события, напоминание которых сработает ночью + * @return {Events} + */ + Events.prototype.findNightAlarms = function () { + return this.filter(function (event) { + var alarm = event.getNextAlarmTime(); + return alarm.getHours() > 0 && alarm.getHours() < 8; + }); + }; + /** + * Сортирует коллекцию по дате начала события + * @return {Events} + */ + Events.prototype.sortByStartDate = function (asc) { + return this.sortBy(function (a, b) { + return a.startDate - b.startDate; + }, asc); + }; + /** + * Сортирует коллекцию по следующей дате периодического события + * @return {Events} + */ + Events.prototype.sortByNextHappenDate = function (asc) { + return this.sortBy(function (a, b) { + return a.getNextHappenDate() - b.getNextHappenDate(); + }, asc); + }; + return Events; +}()); \ No newline at end of file diff --git a/event-model.js b/event-model.js index 226b79f..7ef8a18 100644 --- a/event-model.js +++ b/event-model.js @@ -1,7 +1,7 @@ /*jslint devel: true */ var Event = (function () { + 'use strict'; function checkStartDate(date) { - 'use strict'; if (date === null) { date = new Date(); } else if (!(date instanceof Date && isFinite(date))) { @@ -12,7 +12,6 @@ var Event = (function () { } function checkEndDate(endDate, startDate) { - 'use strict'; var date; if (endDate === null) { date = startDate; @@ -31,25 +30,13 @@ var Event = (function () { return date; } - function checkAddTime(addTime) { - 'use strict'; - var re, splitted; - re = "([+-]) (\\d?\\d.\\d?\\d.\\d?\\d) (\\d?\\d:\\d?\\d)"; - splitted = addTime.match(re); - if (splitted === null || splitted.length !== 4) { - splitted = null; - } - return splitted; - } - function checkRepeat(repeat) { - 'use strict'; if (repeat === null) { repeat = Const.REPEAT.NEVER; } else if (!(repeat.title && repeat.value)) { console.log("Unknown type of 'repeat' variable"); repeat = null; - } else if (!checkAddTime(repeat.value)) { + } else if (!Utils.checkAddTime(repeat.value)) { console.log("Add time in 'repeat' variable must have format '+ dd.MM.YY hh:mm'"); repeat = null; } @@ -57,13 +44,12 @@ var Event = (function () { } function checkAlert(alert) { - 'use strict'; if (alert === null) { alert = Const.ALERT.NONE; } else if (!(alert.title && alert.value)) { console.log("Unknown type of 'alert' variable"); alert = null; - } else if (!checkAddTime(alert.value)) { + } else if (!Utils.checkAddTime(alert.value)) { console.log("Add time in 'alert' variable must have format '+ dd.MM.YY hh:mm'"); alert = null; } @@ -92,7 +78,6 @@ var Event = (function () { * @return {Event} */ var Event = function (data) { - 'use strict'; Model.apply(this, arguments); }; inherits(Event, Model); @@ -105,7 +90,6 @@ var Event = (function () { * @return {Event} */ Event.prototype.validate = function () { - 'use strict'; this.startDate = checkStartDate(this.startDate); if (this.startDate === null) { return; @@ -130,7 +114,6 @@ var Event = (function () { * @return {Date} */ Event.prototype.getNextHappenDate = function () { - 'use strict'; var nhd, today; if (!this.nextHappenDate) { today = new Date(); @@ -150,7 +133,6 @@ var Event = (function () { * @return {Date} */ Event.prototype.getNextAlarmTime = function () { - 'use strict'; var nhd = this.getNextHappenDate(); return Utils.addDateTime(nhd, this.alert.value); }; @@ -162,7 +144,6 @@ var Event = (function () { * @return {Boolean} */ Event.prototype.isAlertTime = function () { - 'use strict'; var today, diff; today = new Date(); diff = today - this.getNextAlarmTime(); diff --git a/utils.js b/utils.js index b28e326..e954c73 100644 --- a/utils.js +++ b/utils.js @@ -150,6 +150,16 @@ var Utils = (function () { } }; + function checkAddTime(addTime) { + var re, splitted; + re = "([+-]) (\\d?\\d.\\d?\\d.\\d?\\d) (\\d?\\d:\\d?\\d)"; + splitted = addTime.match(re); + if (splitted === null || splitted.length !== 4) { + splitted = null; + } + return splitted; + } + /** * Добавляет к дате кол-во лет, месяцев, дней и т.д определенных в параметре * Параметр добавления даты должен иметь формат + dd.MM.YY hh:mm @@ -216,6 +226,9 @@ var Utils = (function () { randomEventCollection: function (size) { return new Random(Const).getRandomEventCollection(size); }, + checkAddTime: function (addTime) { + return checkAddTime(addTime); + }, addDateTime: function (date, dateTimeStr) { return addDateTime(date, dateTimeStr); }, From eb4972115af7e3812cda391ee86361ed858f7402 Mon Sep 17 00:00:00 2001 From: Borisov Dmitry Date: Sun, 25 Nov 2012 22:54:42 +0600 Subject: [PATCH 11/13] add validation logic --- collection.js | 6 ++--- event-collection.html | 1 + event-model.js | 53 ++++++++++++++++++------------------------- validation.js | 30 ++++++++++++++++++++++++ 4 files changed, 55 insertions(+), 35 deletions(-) create mode 100644 validation.js diff --git a/collection.js b/collection.js index e80cf34..2ba6438 100644 --- a/collection.js +++ b/collection.js @@ -5,7 +5,7 @@ var Collection = (function () { this.items = []; for (item in items) { if (items.hasOwnProperty(item)) { - if (items[item].validate()) { + if (items[item].validate().valid) { this.items.push(items[item]); } } @@ -18,9 +18,7 @@ var Collection = (function () { Collection.prototype = { add : function (model) { - if (model.validate()) { - this.items.push(model); - } + this.items.push(model); }, /** * Фильтрация коллекции по правилам, определенным в функции selector diff --git a/event-collection.html b/event-collection.html index 46fa1f9..c23371e 100644 --- a/event-collection.html +++ b/event-collection.html @@ -17,6 +17,7 @@ + diff --git a/event-model.js b/event-model.js index 7ef8a18..b6608f7 100644 --- a/event-model.js +++ b/event-model.js @@ -1,56 +1,57 @@ -/*jslint devel: true */ var Event = (function () { 'use strict'; - function checkStartDate(date) { + function checkStartDate(date, validator) { if (date === null) { date = new Date(); } else if (!(date instanceof Date && isFinite(date))) { - console.log("Start date is invalid, check syntax"); + validator.addError("startDate", "Start date is invalid, check syntax"); date = null; } return date; } - function checkEndDate(endDate, startDate) { + function checkEndDate(endDate, startDate, validator) { var date; if (endDate === null) { date = startDate; - date.setHours(startDate.getHours() + 1); + if (date !== null) { + date.setHours(startDate.getHours() + 1); + } } else if (endDate instanceof Date && isFinite(endDate)) { if (endDate < startDate) { - console.log("End date should be after start date"); + validator.addError("endDate", "End date should be after start date"); date = null; } else { date = endDate; } } else { - console.log("End date is invalid, check syntax"); + validator.addError("endDate", "End date is invalid, check syntax"); date = null; } return date; } - function checkRepeat(repeat) { + function checkRepeat(repeat, validator) { if (repeat === null) { repeat = Const.REPEAT.NEVER; } else if (!(repeat.title && repeat.value)) { - console.log("Unknown type of 'repeat' variable"); + validator.addError("repeat", "Unknown type of 'repeat' variable"); repeat = null; } else if (!Utils.checkAddTime(repeat.value)) { - console.log("Add time in 'repeat' variable must have format '+ dd.MM.YY hh:mm'"); + validator.addError("repeat", "Add time in 'repeat' variable must have format '+ dd.MM.YY hh:mm'"); repeat = null; } return repeat; } - function checkAlert(alert) { + function checkAlert(alert, validator) { if (alert === null) { alert = Const.ALERT.NONE; } else if (!(alert.title && alert.value)) { - console.log("Unknown type of 'alert' variable"); + validator.addError("alert", "Unknown type of 'alert' variable"); alert = null; } else if (!Utils.checkAddTime(alert.value)) { - console.log("Add time in 'alert' variable must have format '+ dd.MM.YY hh:mm'"); + validator.addError("alert", "Add time in 'alert' variable must have format '+ dd.MM.YY hh:mm'"); alert = null; } return alert; @@ -87,26 +88,16 @@ var Event = (function () { /** * Функция, валидирующая объект Event * - * @return {Event} + * @return {ValidationResult} */ Event.prototype.validate = function () { - this.startDate = checkStartDate(this.startDate); - if (this.startDate === null) { - return; - } - this.endDate = checkEndDate(this.endDate, this.startDate); - if (this.endDate === null) { - return; - } - this.repeat = checkRepeat(this.repeat); - if (this.repeat === null) { - return; - } - this.alert = checkAlert(this.alert); - if (this.alert === null) { - return; - } - return this; + var result = new ValidationResult(true); + this.startDate = checkStartDate(this.startDate, result); + this.endDate = checkEndDate(this.endDate, this.startDate, result); + this.repeat = checkRepeat(this.repeat, result); + this.alert = checkAlert(this.alert, result); + result.log(); + return result; }; /** * Вычисляет когда в следующий раз случится периодическое событие diff --git a/validation.js b/validation.js new file mode 100644 index 0000000..e4e9f19 --- /dev/null +++ b/validation.js @@ -0,0 +1,30 @@ +/*jslint devel: true */ +var ValidationResult = (function () { + "use strict"; + var ValidationError = function (fieldName, errorText) { + this.fieldName = fieldName; + this.errorText = errorText; + }, ValidationResult = function (valid) { + this.valid = valid; + this.errors = []; + }; + + ValidationResult.prototype = + { + addError : function (fieldName, errorText) { + this.errors.push(new ValidationError(fieldName, errorText)); + this.valid = false; + }, + log : function () { + var error; + if (!this.valid) { + for (error in this.errors) { + if (this.errors.hasOwnProperty(error)) { + console.log(error.errorText); + } + } + } + } + }; + return ValidationResult; +}()); \ No newline at end of file From 21bca18b8e3372b03b9e5b59a9200ccd394c5bd0 Mon Sep 17 00:00:00 2001 From: Borisov Dmitry Date: Sun, 25 Nov 2012 23:38:33 +0600 Subject: [PATCH 12/13] validation msg fix --- validation.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/validation.js b/validation.js index e4e9f19..40cfac0 100644 --- a/validation.js +++ b/validation.js @@ -20,7 +20,7 @@ var ValidationResult = (function () { if (!this.valid) { for (error in this.errors) { if (this.errors.hasOwnProperty(error)) { - console.log(error.errorText); + console.log(this.errors[error].errorText); } } } From fb5e6e1224cb9d7fa5ee33d81a55329844b6d77d Mon Sep 17 00:00:00 2001 From: Borisov Dmitry Date: Tue, 27 Nov 2012 00:52:40 +0600 Subject: [PATCH 13/13] one random event func --- utils.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/utils.js b/utils.js index e954c73..8eeba66 100644 --- a/utils.js +++ b/utils.js @@ -223,6 +223,9 @@ var Utils = (function () { } return { + randomEvent: function () { + return new Random(Const).getRandomEvent(); + }, randomEventCollection: function (size) { return new Random(Const).getRandomEventCollection(size); },