Bug 1301310 - Hide input date/time picker only when input element blurs. r=mossop

If we rely on XUL panel's default behavior, the picker is hidden and opened
again when we jump from one inner field to another with a mouse click, this is
because XUL pannel gets hidden when user clicks outside it with
noautohide=false. In order to avoid this, we should close it explicitly only
when input element blurs.

MozReview-Commit-ID: GxPxd0wPWgM

--HG--
extra : rebase_source : 3bac43a57da51a341d7ec4bb7b86807f55308f39
This commit is contained in:
Jessica Jong 2017-04-20 15:04:10 +08:00
Родитель 2c46cd7788
Коммит f005bb88d4
4 изменённых файлов: 26 добавлений и 19 удалений

Просмотреть файл

@ -165,6 +165,7 @@
hidden="true"
orient="vertical"
noautofocus="true"
noautohide="true"
consumeoutsideclicks="false"
level="parent"
tabspecific="true">

Просмотреть файл

@ -1134,6 +1134,9 @@
capture: true,
mozSystemGroup: true
});
// This is to close the picker when input element blurs.
this.mInputElement.addEventListener("blur", this,
{ mozSystemGroup: true });
]]>
</constructor>
@ -1589,12 +1592,17 @@
<parameter name="aEvent"/>
<body>
<![CDATA[
this.log("onBlur originalTarget: " + aEvent.originalTarget);
this.log("onBlur originalTarget: " + aEvent.originalTarget +
" target: " + aEvent.target);
if (document.activeElement == this.mInputElement) {
return;
}
if (aEvent.target == this.mInputElement && this.mIsPickerOpen) {
this.mInputElement.closeDateTimePicker();
}
let target = aEvent.originalTarget;
target.setAttribute("typeBuffer", "");
this.setInputValueFromFields();
@ -1610,11 +1618,14 @@
this.log("onKeyPress key: " + aEvent.key);
switch (aEvent.key) {
// Close picker on Enter or Space key.
// Close picker on Enter, Escape or Space key.
case "Enter":
case "Escape":
case " ": {
this.mInputElement.closeDateTimePicker();
aEvent.preventDefault();
if (this.mIsPickerOpen) {
this.mInputElement.closeDateTimePicker();
aEvent.preventDefault();
}
break;
}
case "Backspace": {
@ -1670,7 +1681,7 @@
if (aEvent.originalTarget == this.mResetButton) {
this.clearInputFields(false);
} else {
} else if (!this.mIsPickerOpen) {
this.mInputElement.openDateTimePicker(this.getCurrentValue());
}
]]>

Просмотреть файл

@ -28,11 +28,11 @@
// Notify DateTimePickerHelper.jsm that binding is ready.
this.dispatchEvent(new CustomEvent("DateTimePickerBindingReady"));
]]></constructor>
<method name="loadPicker">
<method name="openPicker">
<parameter name="type"/>
<parameter name="anchor"/>
<parameter name="detail"/>
<body><![CDATA[
this.hidden = false;
this.type = type;
this.pickerState = {};
// TODO: Resize picker according to content zoom level
@ -55,17 +55,20 @@
break;
}
}
this.hidden = false;
this.openPopup(anchor, "after_start", 0, 0);
]]></body>
</method>
<method name="closePicker">
<body><![CDATA[
this.hidden = true;
this.setInputBoxValue(true);
this.pickerState = {};
this.type = undefined;
this.dateTimePopupFrame.removeEventListener("load", this, true);
this.dateTimePopupFrame.contentDocument.removeEventListener("message", this);
this.dateTimePopupFrame.setAttribute("src", "");
this.hidePopup();
this.hidden = true;
]]></body>
</method>
<method name="setPopupValue">
@ -310,12 +313,5 @@
</method>
</implementation>
<handlers>
<handler event="popuphiding">
<![CDATA[
this.closePicker();
]]>
</handler>
</handlers>
</binding>
</bindings>

Просмотреть файл

@ -136,9 +136,9 @@ this.DateTimePickerHelper = {
return;
}
// The datetimepopup binding is only attached when it is needed.
// Check if loadPicker method is present to determine if binding has
// Check if openPicker method is present to determine if binding has
// been attached. If not, attach the binding first before calling it.
if (!this.picker.loadPicker) {
if (!this.picker.openPicker) {
let bindingPromise = new Promise(resolve => {
this.picker.addEventListener("DateTimePickerBindingReady",
resolve, {once: true});
@ -146,10 +146,9 @@ this.DateTimePickerHelper = {
this.picker.setAttribute("active", true);
yield bindingPromise;
}
this.picker.loadPicker(type, detail);
// The arrow panel needs an anchor to work. The popupAnchor (this._anchor)
// is a transparent div that the arrow can point to.
this.picker.openPopup(this._anchor, "after_start", 0, 0);
this.picker.openPicker(type, this._anchor, detail);
this.addPickerListeners();
}),