1
0
mirror of https://github.com/roytam1/UXP.git synced 2026-05-29 16:58:28 +00:00

Bug 1320225: [DateTimeInput] Integration of input type=date input box with picker (part 1)

This commit is contained in:
janekptacijarabaci
2018-02-14 14:03:55 +01:00
committed by Roy Tam
parent a13a3afc1b
commit ee07b11c03
4 changed files with 113 additions and 42 deletions
+19 -19
View File
@@ -11,7 +11,7 @@
* {
* {Number} year
* {Number} month
* {Number} date
* {Number} day
* }
* {Object} options
* {
@@ -20,7 +20,7 @@
* {Number} calViewSize [optional]
* }
*/
function DateKeeper({ year, month, date }, { firstDayOfWeek = 0, weekends = [0], calViewSize = 42 }) {
function DateKeeper({ year, month, day }, { firstDayOfWeek = 0, weekends = [0], calViewSize = 42 }) {
this.state = {
firstDayOfWeek, weekends, calViewSize,
dateObj: new Date(0),
@@ -29,7 +29,7 @@ function DateKeeper({ year, month, date }, { firstDayOfWeek = 0, weekends = [0],
days: []
};
this.state.weekHeaders = this._getWeekHeaders(firstDayOfWeek);
this._update(year, month, date);
this._update(year, month, day);
}
{
@@ -48,8 +48,8 @@ function DateKeeper({ year, month, date }, { firstDayOfWeek = 0, weekends = [0],
* {Number} date [optional]
* }
*/
set({ year = this.state.year, month = this.state.month, date = this.state.date }) {
this._update(year, month, date);
set({ year = this.state.year, month = this.state.month, day = this.state.day }) {
this._update(year, month, day);
},
/**
@@ -62,44 +62,44 @@ function DateKeeper({ year, month, date }, { firstDayOfWeek = 0, weekends = [0],
},
/**
* Set month. Makes sure the date is <= the last day of the month
* Set month. Makes sure the day is <= the last day of the month
* @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.date, lastDayOfMonth));
this._update(this.state.year, month, Math.min(this.state.day, lastDayOfMonth));
},
/**
* Set year. Makes sure the date is <= the last day of the month
* Set year. Makes sure the day is <= the last day of the month
* @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.date, lastDayOfMonth));
this._update(year, this.state.month, Math.min(this.state.day, lastDayOfMonth));
},
/**
* Set month by offset. Makes sure the date is <= the last day of the month
* Set month by offset. Makes sure the day is <= the last day of the month
* @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.date, lastDayOfMonth));
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} date [description]
* @param {Number} day [description]
*/
_update(year, month, date) {
_update(year, month, day) {
// Use setUTCFullYear so that year 99 doesn't get parsed as 1999
this.state.dateObj.setUTCFullYear(year, month, date);
this.state.dateObj.setUTCFullYear(year, month, day);
this.state.year = this.state.dateObj.getUTCFullYear();
this.state.month = this.state.dateObj.getUTCMonth();
this.state.date = this.state.dateObj.getUTCDate();
this.state.day = this.state.dateObj.getUTCDate();
},
/**
@@ -201,14 +201,14 @@ function DateKeeper({ year, month, date }, { firstDayOfWeek = 0, weekends = [0],
*/
_getWeekHeaders(firstDayOfWeek) {
let headers = [];
let day = firstDayOfWeek;
let dayOfWeek = firstDayOfWeek;
for (let i = 0; i < DAYS_IN_A_WEEK; i++) {
headers.push({
textContent: day % DAYS_IN_A_WEEK,
classNames: this.state.weekends.includes(day % DAYS_IN_A_WEEK) ? ["weekend"] : []
textContent: dayOfWeek % DAYS_IN_A_WEEK,
classNames: this.state.weekends.includes(dayOfWeek % DAYS_IN_A_WEEK) ? ["weekend"] : []
});
day++;
dayOfWeek++;
}
return headers;
},
+29 -15
View File
@@ -37,13 +37,13 @@ function DatePicker(context) {
const now = new Date();
const { year = now.getFullYear(),
month = now.getMonth(),
date = now.getDate(),
day = now.getDate(),
locale } = this.props;
// TODO: Use calendar info API to get first day of week & weekends
// (Bug 1287503)
const dateKeeper = new DateKeeper({
year, month, date
year, month, day
}, {
calViewSize: CAL_VIEW_SIZE,
firstDayOfWeek: 0,
@@ -68,6 +68,7 @@ function DatePicker(context) {
this.state.isDateSet = true;
this._update();
this._dispatchState();
this._closePopup();
},
setYear: year => {
dateKeeper.setYear(year);
@@ -148,23 +149,32 @@ function DatePicker(context) {
this.context.monthYearView.classList.add("hidden");
},
/**
* Use postMessage to close the picker.
*/
_closePopup() {
window.postMessage({
name: "ClosePopup"
}, "*");
},
/**
* Use postMessage to pass the state of picker to the panel.
*/
_dispatchState() {
const { year, month, date } = this.state.dateKeeper.state;
const { isYearSet, isMonthSet, isDateSet } = this.state;
const { year, month, day } = this.state.dateKeeper.state;
const { isYearSet, isMonthSet, isDaySet } = this.state;
// The panel is listening to window for postMessage event, so we
// do postMessage to itself to send data to input boxes.
window.postMessage({
name: "DatePickerPopupChanged",
name: "PickerPopupChanged",
detail: {
year,
month,
date,
day,
isYearSet,
isMonthSet,
isDateSet
isDaySet
}
}, "*");
},
@@ -221,11 +231,11 @@ function DatePicker(context) {
*/
handleMessage(event) {
switch (event.data.name) {
case "DatePickerSetValue": {
case "PickerSetValue": {
this.set(event.data.detail);
break;
}
case "DatePickerInit": {
case "PickerInit": {
this.init(event.data.detail);
break;
}
@@ -242,18 +252,22 @@ function DatePicker(context) {
* {Number} date [optional]
* }
*/
set(dateState) {
if (dateState.year != undefined) {
set({ year, month, day }) {
const { dateKeeper } = this.state;
if (year != undefined) {
this.state.isYearSet = true;
}
if (dateState.month != undefined) {
if (month != undefined) {
this.state.isMonthSet = true;
}
if (dateState.date != undefined) {
this.state.isDateSet = true;
if (day != undefined) {
this.state.isDaySet = true;
}
this.state.dateKeeper.set(dateState);
dateKeeper.set({
year, month, day
});
this._update();
}
};
+62 -5
View File
@@ -20,6 +20,8 @@
</field>
<field name="TIME_PICKER_WIDTH" readonly="true">"12em"</field>
<field name="TIME_PICKER_HEIGHT" readonly="true">"21em"</field>
<field name="DATE_PICKER_WIDTH" readonly="true">"23.1em"</field>
<field name="DATE_PICKER_HEIGHT" readonly="true">"20.7em"</field>
<method name="loadPicker">
<parameter name="type"/>
<parameter name="detail"/>
@@ -38,6 +40,14 @@
this.dateTimePopupFrame.style.height = this.TIME_PICKER_HEIGHT;
break;
}
case "date": {
this.detail = detail;
this.dateTimePopupFrame.addEventListener("load", this, true);
this.dateTimePopupFrame.setAttribute("src", "chrome://global/content/datepicker.xhtml");
this.dateTimePopupFrame.style.width = this.DATE_PICKER_WIDTH;
this.dateTimePopupFrame.style.height = this.DATE_PICKER_HEIGHT;
break;
}
}
]]></body>
</method>
@@ -48,7 +58,7 @@
this.pickerState = {};
this.type = undefined;
this.dateTimePopupFrame.removeEventListener("load", this, true);
this.dateTimePopupFrame.contentDocument.removeEventListener("TimePickerPopupChanged", this, false);
this.dateTimePopupFrame.contentDocument.removeEventListener("message", this, false);
this.dateTimePopupFrame.setAttribute("src", "");
]]></body>
</method>
@@ -58,25 +68,39 @@
switch (this.type) {
case "time": {
this.postMessageToPicker({
name: "TimePickerSetValue",
name: "PickerSetValue",
detail: data.value
});
break;
}
case "date": {
const { year, month, day } = data.value;
this.postMessageToPicker({
name: "PickerSetValue",
detail: {
year,
// Month value from input box starts from 1 instead of 0
month: month == undefined ? undefined : month - 1,
day
}
});
break;
}
}
]]></body>
</method>
<method name="initPicker">
<parameter name="detail"/>
<body><![CDATA[
const locale = Components.classes["@mozilla.org/chrome/chrome-registry;1"].getService(Ci.nsIXULChromeRegistry).getSelectedLocale("global");
switch (this.type) {
case "time": {
const { hour, minute } = detail.value;
const format = detail.format || "12";
const locale = Components.classes["@mozilla.org/chrome/chrome-registry;1"].getService(Ci.nsIXULChromeRegistry).getSelectedLocale("global");
this.postMessageToPicker({
name: "TimePickerInit",
name: "PickerInit",
detail: {
hour,
minute,
@@ -89,6 +113,20 @@
});
break;
}
case "date": {
const { year, month, day } = detail.value;
this.postMessageToPicker({
name: "PickerInit",
detail: {
year,
// Month value from input box starts from 1 instead of 0
month: month == undefined ? undefined : month - 1,
day,
locale
}
});
break;
}
}
]]></body>
</method>
@@ -112,6 +150,10 @@
}
break;
}
case "date": {
this.sendPickerValueChanged(this.pickerState);
break;
}
}
]]></body>
</method>
@@ -128,6 +170,17 @@
}));
break;
}
case "date": {
this.dispatchEvent(new CustomEvent("DateTimePickerValueChanged", {
detail: {
year: value.year,
// Month value from input box starts from 1 instead of 0
month: value.month == undefined ? undefined : value.month + 1,
day: value.day
}
}));
break;
}
}
]]></body>
</method>
@@ -155,11 +208,15 @@
}
switch (aEvent.data.name) {
case "TimePickerPopupChanged": {
case "PickerPopupChanged": {
this.pickerState = aEvent.data.detail;
this.setInputBoxValue();
break;
}
case "ClosePopup": {
this.closePicker();
break;
}
}
]]></body>
</method>
+3 -3
View File
@@ -206,7 +206,7 @@ function TimePicker(context) {
// The panel is listening to window for postMessage event, so we
// do postMessage to itself to send data to input boxes.
window.postMessage({
name: "TimePickerPopupChanged",
name: "PickerPopupChanged",
detail: {
hour,
minute,
@@ -248,11 +248,11 @@ function TimePicker(context) {
*/
handleMessage(event) {
switch (event.data.name) {
case "TimePickerSetValue": {
case "PickerSetValue": {
this.set(event.data.detail);
break;
}
case "TimePickerInit": {
case "PickerInit": {
this.init(event.data.detail);
break;
}