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:
@@ -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;
|
||||
},
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user