Commit 53742f61 authored by Olivier Robin's avatar Olivier Robin Committed by Commit Bot

Autofill support AngularJS fields

Data bound fields need to have the backend value updated before sending
the input event.
Example website:
- nordstrom.com
- walgreens.com

Bug: 788099
Cq-Include-Trybots: master.tryserver.chromium.mac:ios-simulator-cronet;master.tryserver.chromium.mac:ios-simulator-full-configs
Change-Id: I5b8467a76d15b6ad83061730b3a627f274342c27
Reviewed-on: https://chromium-review.googlesource.com/787433
Commit-Queue: Olivier Robin <olivierrobin@chromium.org>
Reviewed-by: default avatarPeter Lee <pkl@chromium.org>
Reviewed-by: default avatarMathieu Perreault <mathp@chromium.org>
Cr-Commit-Position: refs/heads/master@{#520963}
parent 7ead6c96
...@@ -230,6 +230,38 @@ __gCrWeb['common'] = __gCrWeb.common; ...@@ -230,6 +230,38 @@ __gCrWeb['common'] = __gCrWeb.common;
element.type === 'number'; element.type === 'number';
}; };
/**
* Sets the value of a data-bound input using AngularJS.
*
* The method first set the value using the val() method. Then, if input is
* bound to a model value, it sets the model value.
* Documentation of relevant modules of AngularJS can be found at
* https://docs.angularjs.org/guide/databinding
* https://docs.angularjs.org/api/auto/service/$injector
* https://docs.angularjs.org/api/ng/service/$parse
*
* @param {string} value The value the input element will be set.
* @param {Element} input The input element of which the value is set.
**/
function setInputElementAngularValue_(value, input) {
if (!input || !window['angular']) {
return;
}
var angular_element = window['angular'].element(input);
if (!angular_element) {
return;
}
angular_element.val(value);
var angular_model = angular_element.data('ngModel');
if (!angular_model) {
return;
}
angular_element.injector().invoke(['$parse', function(parse) {
var setter = parse(angular_model);
setter.assign(angular_element.scope(), value);
}])
}
/** /**
* Sets the value of an input and dispatches a change event if * Sets the value of an input and dispatches a change event if
* |shouldSendChangeEvent|. * |shouldSendChangeEvent|.
...@@ -245,19 +277,16 @@ __gCrWeb['common'] = __gCrWeb.common; ...@@ -245,19 +277,16 @@ __gCrWeb['common'] = __gCrWeb.common;
* void setChecked(bool nowChecked, TextFieldEventBehavior eventBehavior) * void setChecked(bool nowChecked, TextFieldEventBehavior eventBehavior)
* in chromium/src/third_party/WebKit/Source/core/html/HTMLInputElement.cpp. * in chromium/src/third_party/WebKit/Source/core/html/HTMLInputElement.cpp.
* *
* @param {(string|boolean)} value The value the input element will be set. * @param {string} value The value the input element will be set.
* For text input, it is the value to set in the field.
* For select, it is the value of the option to select.
* For checkable element, it is the checked value (true/false).
* @param {Element} input The input element of which the value is set. * @param {Element} input The input element of which the value is set.
* @param {boolean} shouldSendChangeEvent Whether a change event should be * @param {boolean} shouldSendChangeEvent Whether a change event should be
* dispatched. * dispatched.
*/ */
__gCrWeb.common.setInputElementValue = function( __gCrWeb.common.setInputElementValue = function(
value, input, shouldSendChangeEvent) { value, input, shouldSendChangeEvent) {
if (!input) { if (!input) {
return; return;
} }
var changed = false; var changed = false;
if (input.type === 'checkbox' || input.type === 'radio') { if (input.type === 'checkbox' || input.type === 'radio') {
changed = input.checked !== value; changed = input.checked !== value;
...@@ -271,10 +300,15 @@ __gCrWeb['common'] = __gCrWeb.common; ...@@ -271,10 +300,15 @@ __gCrWeb['common'] = __gCrWeb.common;
// autofill and this method is only used for autofill for now, there is no // autofill and this method is only used for autofill for now, there is no
// such check in this implementation. // such check in this implementation.
var sanitizedValue = __gCrWeb.common.sanitizeValueForInputElement( var sanitizedValue = __gCrWeb.common.sanitizeValueForInputElement(
/** @type {string} */ (value), input); value, input);
changed = sanitizedValue !== input.value; changed = sanitizedValue !== input.value;
input.value = sanitizedValue; input.value = sanitizedValue;
} }
if (window['angular']) {
// The page uses the AngularJS framework. Update the angular value before
// sending events.
setInputElementAngularValue_(value, input);
}
if (changed && shouldSendChangeEvent) { if (changed && shouldSendChangeEvent) {
__gCrWeb.common.notifyElementValueChanged(input); __gCrWeb.common.notifyElementValueChanged(input);
} }
......
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