Use getElementBoundingRect and element.ownerGlobal in FormSubmitObserver

This commit is contained in:
wolfbeast 2019-01-02 17:15:29 +01:00 • committed by Roy Tam
commit 86a99f1fe3

View file

@ -104,13 +104,13 @@ FormSubmitObserver.prototype =
return; return;
} }
// Insure that this is the FormSubmitObserver associated with the form // Ensure that this is the FormSubmitObserver associated with the
// element / window this notification is about. // element / window this notification is about.
if (this._content != aFormElement.ownerDocument.defaultView.top.document.defaultView) { let element = aInvalidElements.queryElementAt(0, Ci.nsISupports);
if (this._content != element.ownerGlobal.top.document.defaultView) {
return; return;
} }
let element = aInvalidElements.queryElementAt(0, Ci.nsISupports);
if (!(element instanceof HTMLInputElement || if (!(element instanceof HTMLInputElement ||
element instanceof HTMLTextAreaElement || element instanceof HTMLTextAreaElement ||
element instanceof HTMLSelectElement || element instanceof HTMLSelectElement ||
@ -118,6 +118,9 @@ FormSubmitObserver.prototype =
return; return;
} }
// Update validation message before showing notification
this._validationMessage = element.validationMessage;
// Don't connect up to the same element more than once. // Don't connect up to the same element more than once.
if (this._element == element) { if (this._element == element) {
this._showPopup(element); this._showPopup(element);
@ -127,8 +130,6 @@ FormSubmitObserver.prototype =
element.focus(); element.focus();
this._validationMessage = element.validationMessage;
// Watch for input changes which may change the validation message. // Watch for input changes which may change the validation message.
element.addEventListener("input", this, false); element.addEventListener("input", this, false);
@ -189,18 +190,17 @@ FormSubmitObserver.prototype =
// Note, this is relative to the browser and needs to be translated // Note, this is relative to the browser and needs to be translated
// in chrome. // in chrome.
panelData.contentRect = this._msgRect(aElement); panelData.contentRect = BrowserUtils.getElementBoundingRect(aElement);
// We want to show the popup at the middle of checkbox and radio buttons // We want to show the popup at the middle of checkbox and radio buttons
// and where the content begin for the other elements. // and where the content begin for the other elements.
let offset = 0; let offset = 0;
let position = "";
if (aElement.tagName == 'INPUT' && if (aElement.tagName == 'INPUT' &&
(aElement.type == 'radio' || aElement.type == 'checkbox')) { (aElement.type == 'radio' || aElement.type == 'checkbox')) {
panelData.position = "bottomcenter topleft"; panelData.position = "bottomcenter topleft";
} else { } else {
let win = aElement.ownerDocument.defaultView; let win = aElement.ownerGlobal;
let style = win.getComputedStyle(aElement, null); let style = win.getComputedStyle(aElement, null);
if (style.direction == 'rtl') { if (style.direction == 'rtl') {
offset = parseInt(style.paddingRight) + parseInt(style.borderRightWidth); offset = parseInt(style.paddingRight) + parseInt(style.borderRightWidth);
@ -231,21 +231,5 @@ FormSubmitObserver.prototype =
(target.ownerDocument && target.ownerDocument == this._content.document)); (target.ownerDocument && target.ownerDocument == this._content.document));
}, },
/*
* Return a message manager rect for the element's bounding client rect
* in top level browser coords.
*/
_msgRect: function (aElement) {
let domRect = aElement.getBoundingClientRect();
let zoomFactor = this._getWindowUtils().fullZoom;
let { offsetX, offsetY } = BrowserUtils.offsetToTopLevelWindow(this._content, aElement);
return {
left: (domRect.left + offsetX) * zoomFactor,
top: (domRect.top + offsetY) * zoomFactor,
width: domRect.width * zoomFactor,
height: domRect.height * zoomFactor
};
},
QueryInterface : XPCOMUtils.generateQI([Ci.nsIFormSubmitObserver]) QueryInterface : XPCOMUtils.generateQI([Ci.nsIFormSubmitObserver])
}; };