Commit 55518e17 authored by Olivier Robin's avatar Olivier Robin Committed by Commit Bot

Send input event on element change.

Some javascript frameworks (e.g. React) or pages have a cache version of input fields in
pages.
This cache will override the autofill value of the fields.
When value is changed, events must be sent to update these cache.
When a user type in a field, the following events are usually sent:
- keydown
- input
- change
- keyup
By testing, most framework use use one of these events, and some framework use
the data field of the event as new value.

Send these events when updating fields.

Bug: 783025, 728631, 732360
Cq-Include-Trybots: master.tryserver.chromium.mac:ios-simulator-cronet;master.tryserver.chromium.mac:ios-simulator-full-configs
Change-Id: I147a4471ecd2e389cfca57d2aa9d78f61360aa61
Reviewed-on: https://chromium-review.googlesource.com/771674
Commit-Queue: Olivier Robin <olivierrobin@chromium.org>
Reviewed-by: default avatarMoe Ahmadi <mahmadi@chromium.org>
Reviewed-by: default avatarPeter Lee <pkl@chromium.org>
Cr-Commit-Position: refs/heads/master@{#520946}
parent 991bff76
...@@ -639,8 +639,7 @@ __gCrWeb.autofill['fillForm'] = function(data, forceFillFieldName) { ...@@ -639,8 +639,7 @@ __gCrWeb.autofill['fillForm'] = function(data, forceFillFieldName) {
} else if (__gCrWeb.autofill.isSelectElement(element)) { } else if (__gCrWeb.autofill.isSelectElement(element)) {
if (element.value !== value) { if (element.value !== value) {
element.value = value; element.value = value;
__gCrWeb.common.createAndDispatchHTMLEvent(element, 'change', true, __gCrWeb.common.notifyElementValueChanged(element);
false);
} }
} }
// TODO(bondd): Handle __gCrWeb.autofill.isCheckableElement(element) == // TODO(bondd): Handle __gCrWeb.autofill.isCheckableElement(element) ==
...@@ -693,8 +692,7 @@ __gCrWeb.autofill['clearAutofilledFields'] = function(formName) { ...@@ -693,8 +692,7 @@ __gCrWeb.autofill['clearAutofilledFields'] = function(formName) {
// TODO(bondd): Store initial values and reset to the correct one here. // TODO(bondd): Store initial values and reset to the correct one here.
if (element.selectedIndex != 0) { if (element.selectedIndex != 0) {
element.selectedIndex = 0; element.selectedIndex = 0;
__gCrWeb.common.createAndDispatchHTMLEvent(element, 'change', true, __gCrWeb.common.notifyElementValueChanged(element);
false);
} }
} else if (__gCrWeb.autofill.isCheckableElement(element)) { } else if (__gCrWeb.autofill.isCheckableElement(element)) {
// TODO(bondd): Handle checkable elements. They aren't properly supported // TODO(bondd): Handle checkable elements. They aren't properly supported
...@@ -1853,7 +1851,7 @@ __gCrWeb.autofill.fillFormField = function(data, field) { ...@@ -1853,7 +1851,7 @@ __gCrWeb.autofill.fillFormField = function(data, field) {
} else if (__gCrWeb.autofill.isSelectElement(field)) { } else if (__gCrWeb.autofill.isSelectElement(field)) {
if (field.value !== data['value']) { if (field.value !== data['value']) {
field.value = data['value']; field.value = data['value'];
__gCrWeb.common.createAndDispatchHTMLEvent(field, 'change', true, false); __gCrWeb.common.notifyElementValueChanged(field);
} }
} else { } else {
if (__gCrWeb.autofill.isCheckableElement(field)) { if (__gCrWeb.autofill.isCheckableElement(field)) {
......
...@@ -254,7 +254,7 @@ __gCrWeb['common'] = __gCrWeb.common; ...@@ -254,7 +254,7 @@ __gCrWeb['common'] = __gCrWeb.common;
var checkedChanged = input.checked !== nowChecked; var checkedChanged = input.checked !== nowChecked;
input.checked = nowChecked; input.checked = nowChecked;
if (checkedChanged) { if (checkedChanged) {
__gCrWeb.common.createAndDispatchHTMLEvent(input, 'change', true, false); __gCrWeb.common.notifyElementValueChanged(input);
} }
}; };
...@@ -287,7 +287,7 @@ __gCrWeb['common'] = __gCrWeb.common; ...@@ -287,7 +287,7 @@ __gCrWeb['common'] = __gCrWeb.common;
var valueChanged = sanitizedValue !== input.value; var valueChanged = sanitizedValue !== input.value;
input.value = sanitizedValue; input.value = sanitizedValue;
if (valueChanged) { if (valueChanged) {
__gCrWeb.common.createAndDispatchHTMLEvent(input, 'change', true, false); __gCrWeb.common.notifyElementValueChanged(input);
} }
}; };
...@@ -597,6 +597,20 @@ __gCrWeb['common'] = __gCrWeb.common; ...@@ -597,6 +597,20 @@ __gCrWeb['common'] = __gCrWeb.common;
return null; return null;
}; };
/**
* Creates and sends notification that element has changed.
*
* Most handlers react to 'change' or 'input' event, so sent both.
*
* @param {Element} element The element that changed.
*/
__gCrWeb.common.notifyElementValueChanged = function(element) {
__gCrWeb.common.createAndDispatchHTMLEvent(element, 'keydown', true, false);
__gCrWeb.common.createAndDispatchHTMLEvent(element, 'change', true, false);
__gCrWeb.common.createAndDispatchHTMLEvent(element, 'input', true, false);
__gCrWeb.common.createAndDispatchHTMLEvent(element, 'keyup', true, false);
};
/** /**
* Creates and dispatches an HTML event. * Creates and dispatches an HTML event.
* *
...@@ -612,6 +626,8 @@ __gCrWeb['common'] = __gCrWeb.common; ...@@ -612,6 +626,8 @@ __gCrWeb['common'] = __gCrWeb.common;
var changeEvent = var changeEvent =
/** @type {!Event} */(element.ownerDocument.createEvent('HTMLEvents')); /** @type {!Event} */(element.ownerDocument.createEvent('HTMLEvents'));
changeEvent.initEvent(type, bubbles, cancelable); changeEvent.initEvent(type, bubbles, cancelable);
// Some frameworks will use the data field to update their cache value.
changeEvent.data = element.value;
// A timer is used to avoid reentering JavaScript evaluation. // A timer is used to avoid reentering JavaScript evaluation.
window.setTimeout(function() { window.setTimeout(function() {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment