summaryrefslogtreecommitdiffstats
path: root/toolkit/content/widgets/datekeeper.js
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/content/widgets/datekeeper.js')
-rw-r--r--toolkit/content/widgets/datekeeper.js171
1 files changed, 105 insertions, 66 deletions
diff --git a/toolkit/content/widgets/datekeeper.js b/toolkit/content/widgets/datekeeper.js
index de01fdade..9777ee647 100644
--- a/toolkit/content/widgets/datekeeper.js
+++ b/toolkit/content/widgets/datekeeper.js
@@ -6,41 +6,72 @@
/**
* DateKeeper keeps track of the date states.
- *
- * @param {Object} date parts
- * {
- * {Number} year
- * {Number} month
- * {Number} day
- * }
- * {Object} options
- * {
- * {Number} firstDayOfWeek [optional]
- * {Array<Number>} weekends [optional]
- * {Number} calViewSize [optional]
- * }
*/
-function DateKeeper({ year, month, day }, { firstDayOfWeek = 0, weekends = [0], calViewSize = 42 }) {
- this.state = {
- firstDayOfWeek, weekends, calViewSize,
- dateObj: new Date(0),
- years: [],
- months: [],
- days: []
- };
- this.state.weekHeaders = this._getWeekHeaders(firstDayOfWeek);
- this._update(year, month, day);
+function DateKeeper(props) {
+ this.init(props);
}
{
const DAYS_IN_A_WEEK = 7,
MONTHS_IN_A_YEAR = 12,
YEAR_VIEW_SIZE = 200,
- YEAR_BUFFER_SIZE = 10;
+ YEAR_BUFFER_SIZE = 10,
+ // The min and max values are derived from the ECMAScript spec:
+ // http://ecma-international.org/ecma-262/5.1/#sec-15.9.1.1
+ MIN_DATE = -8640000000000000,
+ MAX_DATE = 8640000000000000;
DateKeeper.prototype = {
+ get year() {
+ return this.state.dateObj.getUTCFullYear();
+ },
+
+ get month() {
+ return this.state.dateObj.getUTCMonth();
+ },
+
+ get day() {
+ return this.state.dateObj.getUTCDate();
+ },
+
+ get selection() {
+ return this.state.selection;
+ },
+
+ /**
+ * Initialize DateKeeper
+ * @param {Number} year
+ * @param {Number} month
+ * @param {Number} day
+ * @param {String} min
+ * @param {String} max
+ * @param {Number} firstDayOfWeek
+ * @param {Array<Number>} weekends
+ * @param {Number} calViewSize
+ */
+ init({ year, month, day, min, max, firstDayOfWeek = 0, weekends = [0], calViewSize = 42 }) {
+ const today = new Date();
+ const isDateSet = year != undefined && month != undefined && day != undefined;
+
+ this.state = {
+ firstDayOfWeek, weekends, calViewSize,
+ min: new Date(min != undefined ? min : MIN_DATE),
+ max: new Date(max != undefined ? max : MAX_DATE),
+ today: this._newUTCDate(today.getFullYear(), today.getMonth(), today.getDate()),
+ weekHeaders: this._getWeekHeaders(firstDayOfWeek, weekends),
+ years: [],
+ months: [],
+ days: [],
+ selection: { year, month, day },
+ };
+
+ this.state.dateObj = isDateSet ?
+ this._newUTCDate(year, month, day) :
+ new Date(this.state.today);
+ },
/**
- * Set new date
+ * Set new date. The year is always treated as full year, so the short-form
+ * is not supported.
* @param {Object} date parts
* {
* {Number} year [optional]
@@ -48,17 +79,21 @@ function DateKeeper({ year, month, day }, { firstDayOfWeek = 0, weekends = [0],
* {Number} date [optional]
* }
*/
- set({ year = this.state.year, month = this.state.month, day = this.state.day }) {
- this._update(year, month, day);
+ set({ year = this.year, month = this.month, day = this.day }) {
+ // Use setUTCFullYear so that year 99 doesn't get parsed as 1999
+ this.state.dateObj.setUTCFullYear(year, month, day);
},
/**
- * Set date with value
- * @param {Number} value: Date value
+ * Set selection date
+ * @param {Number} year
+ * @param {Number} month
+ * @param {Number} day
*/
- setValue(value) {
- const dateObj = new Date(value);
- this._update(dateObj.getUTCFullYear(), dateObj.getUTCMonth(), dateObj.getUTCDate());
+ setSelection({ year, month, day }) {
+ this.state.selection.year = year;
+ this.state.selection.month = month;
+ this.state.selection.day = day;
},
/**
@@ -66,8 +101,10 @@ function DateKeeper({ year, month, day }, { firstDayOfWeek = 0, weekends = [0],
* @param {Number} month
*/
setMonth(month) {
- const lastDayOfMonth = this._newUTCDate(this.state.year, month + 1, 0).getUTCDate();
- this._update(this.state.year, month, Math.min(this.state.day, lastDayOfMonth));
+ const lastDayOfMonth = this._newUTCDate(this.year, month + 1, 0).getUTCDate();
+ this.set({ year: this.year,
+ month,
+ day: Math.min(this.day, lastDayOfMonth) });
},
/**
@@ -75,8 +112,10 @@ function DateKeeper({ year, month, day }, { firstDayOfWeek = 0, weekends = [0],
* @param {Number} year
*/
setYear(year) {
- const lastDayOfMonth = this._newUTCDate(year, this.state.month + 1, 0).getUTCDate();
- this._update(year, this.state.month, Math.min(this.state.day, lastDayOfMonth));
+ const lastDayOfMonth = this._newUTCDate(year, this.month + 1, 0).getUTCDate();
+ this.set({ year,
+ month: this.month,
+ day: Math.min(this.day, lastDayOfMonth) });
},
/**
@@ -84,22 +123,10 @@ function DateKeeper({ year, month, day }, { firstDayOfWeek = 0, weekends = [0],
* @param {Number} offset
*/
setMonthByOffset(offset) {
- const lastDayOfMonth = this._newUTCDate(this.state.year, this.state.month + offset + 1, 0).getUTCDate();
- this._update(this.state.year, this.state.month + offset, Math.min(this.state.day, lastDayOfMonth));
- },
-
- /**
- * Update the states.
- * @param {Number} year [description]
- * @param {Number} month [description]
- * @param {Number} day [description]
- */
- _update(year, month, day) {
- // Use setUTCFullYear so that year 99 doesn't get parsed as 1999
- this.state.dateObj.setUTCFullYear(year, month, day);
- this.state.year = this.state.dateObj.getUTCFullYear();
- this.state.month = this.state.dateObj.getUTCMonth();
- this.state.day = this.state.dateObj.getUTCDate();
+ const lastDayOfMonth = this._newUTCDate(this.year, this.month + offset + 1, 0).getUTCDate();
+ this.set({ year: this.year,
+ month: this.month + offset,
+ day: Math.min(this.day, lastDayOfMonth) });
},
/**
@@ -111,7 +138,6 @@ function DateKeeper({ year, month, day }, { firstDayOfWeek = 0, weekends = [0],
* }
*/
getMonths() {
- // TODO: add min/max and step support
let months = [];
for (let i = 0; i < MONTHS_IN_A_YEAR; i++) {
@@ -133,12 +159,11 @@ function DateKeeper({ year, month, day }, { firstDayOfWeek = 0, weekends = [0],
* }
*/
getYears() {
- // TODO: add min/max and step support
let years = [];
const firstItem = this.state.years[0];
const lastItem = this.state.years[this.state.years.length - 1];
- const currentYear = this.state.dateObj.getUTCFullYear();
+ const currentYear = this.year;
// Generate new years array when the year is outside of the first &
// last item range. If not, return the cached result.
@@ -161,30 +186,43 @@ function DateKeeper({ year, month, day }, { firstDayOfWeek = 0, weekends = [0],
* Get days for calendar
* @return {Array<Object>}
* {
- * {Number} dateValue
- * {Number} textContent
+ * {Date} dateObj
* {Array<String>} classNames
+ * {Boolean} enabled
* }
*/
getDays() {
- // TODO: add min/max and step support
- let firstDayOfMonth = this._getFirstCalendarDate(this.state.dateObj, this.state.firstDayOfWeek);
+ // TODO: add step support
+ const firstDayOfMonth = this._getFirstCalendarDate(this.state.dateObj, this.state.firstDayOfWeek);
+ const month = this.month;
let days = [];
- let month = this.state.dateObj.getUTCMonth();
for (let i = 0; i < this.state.calViewSize; i++) {
- let dateObj = this._newUTCDate(firstDayOfMonth.getUTCFullYear(), firstDayOfMonth.getUTCMonth(), firstDayOfMonth.getUTCDate() + i);
+ const dateObj = this._newUTCDate(firstDayOfMonth.getUTCFullYear(), firstDayOfMonth.getUTCMonth(), firstDayOfMonth.getUTCDate() + i);
let classNames = [];
+ let enabled = true;
if (this.state.weekends.includes(dateObj.getUTCDay())) {
classNames.push("weekend");
}
if (month != dateObj.getUTCMonth()) {
classNames.push("outside");
}
+ if (this.state.selection.year == dateObj.getUTCFullYear() &&
+ this.state.selection.month == dateObj.getUTCMonth() &&
+ this.state.selection.day == dateObj.getUTCDate()) {
+ classNames.push("selection");
+ }
+ if (dateObj.getTime() < this.state.min.getTime() || dateObj.getTime() > this.state.max.getTime()) {
+ classNames.push("out-of-range");
+ enabled = false;
+ }
+ if (this.state.today.getTime() == dateObj.getTime()) {
+ classNames.push("today");
+ }
days.push({
- dateValue: dateObj.getTime(),
- textContent: dateObj.getUTCDate(),
- classNames
+ dateObj,
+ classNames,
+ enabled,
});
}
return days;
@@ -193,20 +231,21 @@ function DateKeeper({ year, month, day }, { firstDayOfWeek = 0, weekends = [0],
/**
* Get week headers for calendar
* @param {Number} firstDayOfWeek
+ * @param {Array<Number>} weekends
* @return {Array<Object>}
* {
* {Number} textContent
* {Array<String>} classNames
* }
*/
- _getWeekHeaders(firstDayOfWeek) {
+ _getWeekHeaders(firstDayOfWeek, weekends) {
let headers = [];
let dayOfWeek = firstDayOfWeek;
for (let i = 0; i < DAYS_IN_A_WEEK; i++) {
headers.push({
textContent: dayOfWeek % DAYS_IN_A_WEEK,
- classNames: this.state.weekends.includes(dayOfWeek % DAYS_IN_A_WEEK) ? ["weekend"] : []
+ classNames: weekends.includes(dayOfWeek % DAYS_IN_A_WEEK) ? ["weekend"] : []
});
dayOfWeek++;
}