| Index: chrome/renderer/autofill/form_cache.cc
|
| diff --git a/chrome/renderer/autofill/form_cache.cc b/chrome/renderer/autofill/form_cache.cc
|
| index f7bec0342a014e362d700f47fe520ddbeb65cdab..5be9ab83bbb7791a7035c5e23483de15ed4b506a 100644
|
| --- a/chrome/renderer/autofill/form_cache.cc
|
| +++ b/chrome/renderer/autofill/form_cache.cc
|
| @@ -43,6 +43,32 @@ const size_t kRequiredAutofillFields = 3;
|
|
|
| namespace autofill {
|
|
|
| +// Helper function to discard state of various WebFormElements when they go out
|
| +// of web frame's scope. This is done to release memory that we no longer need
|
| +// to hold.
|
| +// K should inherit from WebFormControlElement as the function looks to extract
|
| +// WebFormElement for K.form().
|
| +template <class K, class V>
|
| +void RemoveOldElements(const WebFrame& frame, std::map<const K, V>* states) {
|
| + std::vector<K> to_remove;
|
| + for (typename std::map<const K, V>::const_iterator it = states->begin();
|
| + it != states->end(); ++it) {
|
| + WebFormElement form_element = it->first.form();
|
| + if (form_element.isNull()) {
|
| + to_remove.push_back(it->first);
|
| + } else {
|
| + const WebFrame* element_frame = form_element.document().frame();
|
| + if (!element_frame || element_frame == &frame)
|
| + to_remove.push_back(it->first);
|
| + }
|
| + }
|
| +
|
| + for (typename std::vector<K>::const_iterator it = to_remove.begin();
|
| + it != to_remove.end(); ++it) {
|
| + states->erase(*it);
|
| + }
|
| +}
|
| +
|
| FormCache::FormCache() {
|
| }
|
|
|
| @@ -80,6 +106,12 @@ void FormCache::ExtractForms(const WebFrame& frame,
|
| element.toConst<WebSelectElement>();
|
| initial_select_values_.insert(std::make_pair(select_element,
|
| select_element.value()));
|
| + } else {
|
| + const WebInputElement input_element =
|
| + element.toConst<WebInputElement>();
|
| + if (IsCheckableElement(&input_element))
|
| + initial_checked_state_.insert(
|
| + std::make_pair(input_element, input_element.isChecked()));
|
| }
|
| }
|
|
|
| @@ -119,25 +151,8 @@ void FormCache::ResetFrame(const WebFrame& frame) {
|
| web_documents_.erase(*it);
|
| }
|
|
|
| - std::vector<WebSelectElement> select_values_to_delete;
|
| - for (std::map<const WebSelectElement, string16>::const_iterator it =
|
| - initial_select_values_.begin();
|
| - it != initial_select_values_.end(); ++it) {
|
| - WebFormElement form_element = it->first.form();
|
| - if (form_element.isNull()) {
|
| - select_values_to_delete.push_back(it->first);
|
| - } else {
|
| - const WebFrame* element_frame = form_element.document().frame();
|
| - if (!element_frame || element_frame == &frame)
|
| - select_values_to_delete.push_back(it->first);
|
| - }
|
| - }
|
| -
|
| - for (std::vector<WebSelectElement>::const_iterator it =
|
| - select_values_to_delete.begin();
|
| - it != select_values_to_delete.end(); ++it) {
|
| - initial_select_values_.erase(*it);
|
| - }
|
| + RemoveOldElements(frame, &initial_select_values_);
|
| + RemoveOldElements(frame, &initial_checked_state_);
|
| }
|
|
|
| bool FormCache::ClearFormWithElement(const WebInputElement& element) {
|
| @@ -165,8 +180,7 @@ bool FormCache::ClearFormWithElement(const WebInputElement& element) {
|
| int length = input_element->value().length();
|
| input_element->setSelectionRange(length, length);
|
| }
|
| - } else {
|
| - DCHECK(IsSelectElement(control_element));
|
| + } else if (IsSelectElement(control_element)) {
|
| WebSelectElement select_element = control_element.to<WebSelectElement>();
|
|
|
| std::map<const WebSelectElement, string16>::const_iterator
|
| @@ -176,6 +190,15 @@ bool FormCache::ClearFormWithElement(const WebInputElement& element) {
|
| select_element.setValue(initial_value_iter->second);
|
| select_element.dispatchFormControlChangeEvent();
|
| }
|
| + } else {
|
| + WebInputElement input_element = control_element.to<WebInputElement>();
|
| + DCHECK(IsCheckableElement(&input_element));
|
| + std::map<const WebInputElement, bool>::const_iterator it =
|
| + initial_checked_state_.find(input_element);
|
| + if (it != initial_checked_state_.end() &&
|
| + input_element.isChecked() != it->second) {
|
| + input_element.setChecked(it->second, true);
|
| + }
|
| }
|
| }
|
|
|
|
|