Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(149)

Side by Side Diff: Source/web/WebSearchableFormData.cpp

Issue 1305063008: Clean WebSearchableFormData.cpp up. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2009 Google Inc. All rights reserved. 2 * Copyright (C) 2009 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
45 #include "public/web/WebInputElement.h" 45 #include "public/web/WebInputElement.h"
46 #include "wtf/text/TextEncoding.h" 46 #include "wtf/text/TextEncoding.h"
47 47
48 namespace blink { 48 namespace blink {
49 49
50 using namespace HTMLNames; 50 using namespace HTMLNames;
51 51
52 namespace { 52 namespace {
53 53
54 // Gets the encoding for the form. 54 // Gets the encoding for the form.
55 void GetFormEncoding(const HTMLFormElement* form, WTF::TextEncoding* encoding) 55 // TODO(tkent): Use FormDataBuilder::encodingFromAcceptCharset().
56 void getFormEncoding(const HTMLFormElement& form, WTF::TextEncoding* encoding)
56 { 57 {
57 String str(form->getAttribute(HTMLNames::accept_charsetAttr)); 58 String str(form.fastGetAttribute(HTMLNames::accept_charsetAttr));
58 str.replace(',', ' '); 59 str.replace(',', ' ');
59 Vector<String> charsets; 60 Vector<String> charsets;
60 str.split(' ', charsets); 61 str.split(' ', charsets);
61 for (Vector<String>::const_iterator i(charsets.begin()); i != charsets.end() ; ++i) { 62 for (const String& charset : charsets) {
62 *encoding = WTF::TextEncoding(*i); 63 *encoding = WTF::TextEncoding(charset);
63 if (encoding->isValid()) 64 if (encoding->isValid())
64 return; 65 return;
65 } 66 }
66 if (!form->document().loader()) 67 if (form.document().loader())
67 return; 68 *encoding = WTF::TextEncoding(form.document().encoding());
68 *encoding = WTF::TextEncoding(form->document().encoding());
69 } 69 }
70 70
71 // Returns true if the submit request results in an HTTP URL. 71 // Returns true if the submit request results in an HTTP URL.
72 bool IsHTTPFormSubmit(const HTMLFormElement* form) 72 bool isHTTPFormSubmit(const HTMLFormElement& form)
73 { 73 {
74 // FIXME: This function is insane. This is an overly complicated way to get this information. 74 // FIXME: This function is insane. This is an overly complicated way to get
75 String action(form->action()); 75 // this information.
76 // The isNull() check is trying to avoid completeURL returning KURL() when p assed a null string. 76 String action(form.action());
77 return form->document().completeURL(action.isNull() ? "" : action).protocolI s("http"); 77 // The isNull() check is trying to avoid completeURL returning KURL() when
78 // passed a null string.
79 return form.document().completeURL(action.isNull() ? "" : action).protocolIs ("http");
78 } 80 }
79 81
80 // If the form does not have an activated submit button, the first submit 82 // If the form does not have an activated submit button, the first submit
81 // button is returned. 83 // button is returned.
82 HTMLFormControlElement* GetButtonToActivate(HTMLFormElement* form) 84 HTMLFormControlElement* buttonToActivate(const HTMLFormElement& form)
83 { 85 {
84 HTMLFormControlElement* firstSubmitButton = nullptr; 86 HTMLFormControlElement* firstSubmitButton = nullptr;
85 const FormAssociatedElement::List& element = form->associatedElements(); 87 for (auto& element : form.associatedElements()) {
86 for (FormAssociatedElement::List::const_iterator i(element.begin()); i != el ement.end(); ++i) { 88 if (!element->isFormControlElement())
87 if (!(*i)->isFormControlElement())
88 continue; 89 continue;
89 HTMLFormControlElement* control = toHTMLFormControlElement(*i); 90 HTMLFormControlElement* control = toHTMLFormControlElement(element);
90 if (control->isActivatedSubmit()) { 91 if (control->isActivatedSubmit()) {
91 // There's a button that is already activated for submit, return nul lptr. 92 // There's a button that is already activated for submit, return
93 // nullptr.
92 return nullptr; 94 return nullptr;
93 } 95 }
94 if (!firstSubmitButton && control->isSuccessfulSubmitButton()) 96 if (!firstSubmitButton && control->isSuccessfulSubmitButton())
95 firstSubmitButton = control; 97 firstSubmitButton = control;
96 } 98 }
97 return firstSubmitButton; 99 return firstSubmitButton;
98 } 100 }
99 101
100 // Returns true if the selected state of all the options matches the default 102 // Returns true if the selected state of all the options matches the default
101 // selected state. 103 // selected state.
102 bool IsSelectInDefaultState(HTMLSelectElement* select) 104 bool isSelectInDefaultState(const HTMLSelectElement& select)
103 { 105 {
104 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement>>& listItems = select- >listItems(); 106 const WillBeHeapVector<RawPtrWillBeMember<HTMLElement>>& listItems = select. listItems();
105 if (select->multiple() || select->size() > 1) { 107 if (select.multiple() || select.size() > 1) {
106 for (WillBeHeapVector<RawPtrWillBeMember<HTMLElement>>::const_iterator i (listItems.begin()); i != listItems.end(); ++i) { 108 for (const auto& item : listItems) {
107 if (!isHTMLOptionElement(*i)) 109 if (!isHTMLOptionElement(*item))
108 continue; 110 continue;
109 HTMLOptionElement* optionElement = toHTMLOptionElement(*i); 111 HTMLOptionElement* optionElement = toHTMLOptionElement(item);
110 if (optionElement->selected() != optionElement->hasAttribute(selecte dAttr)) 112 if (optionElement->selected() != optionElement->fastHasAttribute(sel ectedAttr))
111 return false; 113 return false;
112 } 114 }
113 return true; 115 return true;
114 } 116 }
115 117
116 // The select is rendered as a combobox (called menulist in WebKit). At 118 // The select is rendered as a combobox (called menulist in WebKit). At
117 // least one item is selected, determine which one. 119 // least one item is selected, determine which one.
118 HTMLOptionElement* initialSelected = nullptr; 120 HTMLOptionElement* initialSelected = nullptr;
119 for (WillBeHeapVector<RawPtrWillBeMember<HTMLElement>>::const_iterator i(lis tItems.begin()); i != listItems.end(); ++i) { 121 for (const auto& item : listItems) {
120 if (!isHTMLOptionElement(*i)) 122 if (!isHTMLOptionElement(*item))
121 continue; 123 continue;
122 HTMLOptionElement* optionElement = toHTMLOptionElement(*i); 124 HTMLOptionElement* optionElement = toHTMLOptionElement(item);
123 if (optionElement->hasAttribute(selectedAttr)) { 125 if (optionElement->fastHasAttribute(selectedAttr)) {
124 // The page specified the option to select. 126 // The page specified the option to select.
125 initialSelected = optionElement; 127 initialSelected = optionElement;
126 break; 128 break;
127 } 129 }
128 if (!initialSelected) 130 if (!initialSelected)
129 initialSelected = optionElement; 131 initialSelected = optionElement;
130 } 132 }
131 return !initialSelected || initialSelected->selected(); 133 return !initialSelected || initialSelected->selected();
132 } 134 }
133 135
134 // Returns true if the form element is in its default state, false otherwise. 136 // Returns true if the form element is in its default state, false otherwise.
135 // The default state is the state of the form element on initial load of the 137 // The default state is the state of the form element on initial load of the
136 // page, and varies depending upon the form element. For example, a checkbox is 138 // page, and varies depending upon the form element. For example, a checkbox is
137 // in its default state if the checked state matches the state of the checked at tribute. 139 // in its default state if the checked state matches the state of the checked
138 bool IsInDefaultState(HTMLFormControlElement* formElement) 140 // attribute.
141 bool isInDefaultState(const HTMLFormControlElement& formElement)
139 { 142 {
140 ASSERT(formElement); 143 if (isHTMLInputElement(formElement)) {
141 if (isHTMLInputElement(*formElement)) { 144 const HTMLInputElement& inputElement = toHTMLInputElement(formElement);
142 const HTMLInputElement& inputElement = toHTMLInputElement(*formElement);
143 if (inputElement.type() == InputTypeNames::checkbox || inputElement.type () == InputTypeNames::radio) 145 if (inputElement.type() == InputTypeNames::checkbox || inputElement.type () == InputTypeNames::radio)
144 return inputElement.checked() == inputElement.hasAttribute(checkedAt tr); 146 return inputElement.checked() == inputElement.fastHasAttribute(check edAttr);
145 } else if (isHTMLSelectElement(*formElement)) { 147 } else if (isHTMLSelectElement(formElement)) {
146 return IsSelectInDefaultState(toHTMLSelectElement(formElement)); 148 return isSelectInDefaultState(toHTMLSelectElement(formElement));
147 } 149 }
148 return true; 150 return true;
149 } 151 }
150 152
151 // Look for a suitable search text field in a given HTMLFormElement 153 // Look for a suitable search text field in a given HTMLFormElement
152 // Return nothing if one of those items are found: 154 // Return nothing if one of those items are found:
153 // - A text area field 155 // - A text area field
154 // - A file upload field 156 // - A file upload field
155 // - A Password field 157 // - A Password field
156 // - More than one text field 158 // - More than one text field
157 HTMLInputElement* findSuitableSearchInputElement(const HTMLFormElement* form) 159 HTMLInputElement* findSuitableSearchInputElement(const HTMLFormElement& form)
158 { 160 {
159 HTMLInputElement* textElement = nullptr; 161 HTMLInputElement* textElement = nullptr;
160 const FormAssociatedElement::List& element = form->associatedElements(); 162 for (const auto& item : form.associatedElements()) {
161 for (FormAssociatedElement::List::const_iterator i(element.begin()); i != el ement.end(); ++i) { 163 if (!item->isFormControlElement())
162 if (!(*i)->isFormControlElement())
163 continue; 164 continue;
164 165
165 HTMLFormControlElement* control = toHTMLFormControlElement(*i); 166 HTMLFormControlElement& control = toHTMLFormControlElement(*item);
166 167
167 if (control->isDisabledFormControl() || control->name().isNull()) 168 if (control.isDisabledFormControl() || control.name().isNull())
168 continue; 169 continue;
169 170
170 if (!IsInDefaultState(control) || isHTMLTextAreaElement(*control)) 171 if (!isInDefaultState(control) || isHTMLTextAreaElement(control))
171 return nullptr; 172 return nullptr;
172 173
173 if (isHTMLInputElement(*control) && control->willValidate()) { 174 if (isHTMLInputElement(control) && control.willValidate()) {
174 const HTMLInputElement& input = toHTMLInputElement(*control); 175 const HTMLInputElement& input = toHTMLInputElement(control);
175 176
176 // Return nothing if a file upload field or a password field are fou nd. 177 // Return nothing if a file upload field or a password field are
178 // found.
177 if (input.type() == InputTypeNames::file || input.type() == InputTyp eNames::password) 179 if (input.type() == InputTypeNames::file || input.type() == InputTyp eNames::password)
178 return nullptr; 180 return nullptr;
179 181
180 if (input.isTextField()) { 182 if (input.isTextField()) {
181 if (textElement) { 183 if (textElement) {
182 // The auto-complete bar only knows how to fill in one value . 184 // The auto-complete bar only knows how to fill in one
183 // This form has multiple fields; don't treat it as searchab le. 185 // value. This form has multiple fields; don't treat it as
186 // searchable.
184 return nullptr; 187 return nullptr;
185 } 188 }
186 textElement = toHTMLInputElement(control); 189 textElement = toHTMLInputElement(&control);
187 } 190 }
188 } 191 }
189 } 192 }
190 return textElement; 193 return textElement;
191 } 194 }
192 195
193 // Build a search string based on a given HTMLFormElement and HTMLInputElement 196 // Build a search string based on a given HTMLFormElement and HTMLInputElement
194 // 197 //
195 // Search string output example from www.google.com: 198 // Search string output example from www.google.com:
196 // "hl=en&source=hp&biw=1085&bih=854&q={searchTerms}&btnG=Google+Search&aq=f&aqi =&aql=&oq=" 199 // "hl=en&source=hp&biw=1085&bih=854&q={searchTerms}&btnG=Google+Search&aq=f&aqi =&aql=&oq="
197 // 200 //
198 // Return false if the provided HTMLInputElement is not found in the form 201 // Return false if the provided HTMLInputElement is not found in the form
199 bool buildSearchString(const HTMLFormElement* form, Vector<char>* encodedString, WTF::TextEncoding* encoding, const HTMLInputElement* textElement) 202 bool buildSearchString(const HTMLFormElement& form, Vector<char>* encodedString, const WTF::TextEncoding& encoding, const HTMLInputElement* textElement)
200 { 203 {
201 bool isElementFound = false; 204 bool isElementFound = false;
202 205 for (const auto& item : form.associatedElements()) {
203 const FormAssociatedElement::List& elements = form->associatedElements(); 206 if (!item->isFormControlElement())
204 for (FormAssociatedElement::List::const_iterator i(elements.begin()); i != e lements.end(); ++i) {
205 if (!(*i)->isFormControlElement())
206 continue; 207 continue;
207 208
208 HTMLFormControlElement* control = toHTMLFormControlElement(*i); 209 HTMLFormControlElement& control = toHTMLFormControlElement(*item);
209 210 if (control.isDisabledFormControl() || control.name().isNull())
210 if (control->isDisabledFormControl() || control->name().isNull())
211 continue; 211 continue;
212 212
213 DOMFormData* formData = DOMFormData::create(*encoding); 213 DOMFormData* formData = DOMFormData::create(encoding);
214 if (!control->appendFormData(*formData, false)) 214 if (!control.appendFormData(*formData, false))
215 continue; 215 continue;
216 216
217 for (const FormDataList::Item& item : formData->items()) { 217 for (const FormDataList::Item& item : formData->items()) {
218 if (!encodedString->isEmpty()) 218 if (!encodedString->isEmpty())
219 encodedString->append('&'); 219 encodedString->append('&');
220 FormDataBuilder::encodeStringAsFormData(*encodedString, item.key()); 220 FormDataBuilder::encodeStringAsFormData(*encodedString, item.key());
221 encodedString->append('='); 221 encodedString->append('=');
222 if (control == textElement) { 222 if (&control == textElement) {
223 encodedString->append("{searchTerms}", 13); 223 encodedString->append("{searchTerms}", 13);
224 isElementFound = true; 224 isElementFound = true;
225 } else { 225 } else {
226 FormDataBuilder::encodeStringAsFormData(*encodedString, item.dat a()); 226 FormDataBuilder::encodeStringAsFormData(*encodedString, item.dat a());
227 } 227 }
228 } 228 }
229 } 229 }
230 return isElementFound; 230 return isElementFound;
231 } 231 }
232
232 } // namespace 233 } // namespace
233 234
234 WebSearchableFormData::WebSearchableFormData(const WebFormElement& form, const W ebInputElement& selectedInputElement) 235 WebSearchableFormData::WebSearchableFormData(const WebFormElement& form, const W ebInputElement& selectedInputElement)
235 { 236 {
236 RefPtrWillBeRawPtr<HTMLFormElement> formElement = static_cast<PassRefPtrWill BeRawPtr<HTMLFormElement>>(form); 237 RefPtrWillBeRawPtr<HTMLFormElement> formElement = static_cast<PassRefPtrWill BeRawPtr<HTMLFormElement>>(form);
237 HTMLInputElement* inputElement = static_cast<PassRefPtrWillBeRawPtr<HTMLInpu tElement>>(selectedInputElement).get(); 238 HTMLInputElement* inputElement = static_cast<PassRefPtrWillBeRawPtr<HTMLInpu tElement>>(selectedInputElement).get();
238 239
239 // Only consider forms that GET data. 240 // Only consider forms that GET data.
240 // Allow HTTPS only when an input element is provided. 241 // Allow HTTPS only when an input element is provided.
241 if (equalIgnoringCase(formElement->getAttribute(methodAttr), "post") 242 if (equalIgnoringCase(formElement->getAttribute(methodAttr), "post")
242 || (!IsHTTPFormSubmit(formElement.get()) && !inputElement)) 243 || (!isHTTPFormSubmit(*formElement) && !inputElement))
243 return; 244 return;
244 245
245 Vector<char> encodedString;
246 WTF::TextEncoding encoding; 246 WTF::TextEncoding encoding;
247 247 getFormEncoding(*formElement, &encoding);
248 GetFormEncoding(formElement.get(), &encoding);
249 if (!encoding.isValid()) { 248 if (!encoding.isValid()) {
250 // Need a valid encoding to encode the form elements. 249 // Need a valid encoding to encode the form elements.
251 // If the encoding isn't found webkit ends up replacing the params with 250 // If the encoding isn't found webkit ends up replacing the params with
252 // empty strings. So, we don't try to do anything here. 251 // empty strings. So, we don't try to do anything here.
253 return; 252 return;
254 } 253 }
255 254
256 // Look for a suitable search text field in the form when a 255 // Look for a suitable search text field in the form when a
257 // selectedInputElement is not provided. 256 // selectedInputElement is not provided.
258 if (!inputElement) { 257 if (!inputElement) {
259 inputElement = findSuitableSearchInputElement(formElement.get()); 258 inputElement = findSuitableSearchInputElement(*formElement);
260 259
261 // Return if no suitable text element has been found. 260 // Return if no suitable text element has been found.
262 if (!inputElement) 261 if (!inputElement)
263 return; 262 return;
264 } 263 }
265 264
266 HTMLFormControlElement* firstSubmitButton = GetButtonToActivate(formElement. get()); 265 HTMLFormControlElement* firstSubmitButton = buttonToActivate(*formElement);
267 if (firstSubmitButton) { 266 if (firstSubmitButton) {
268 // The form does not have an active submit button, make the first button 267 // The form does not have an active submit button, make the first button
269 // active. We need to do this, otherwise the URL will not contain the 268 // active. We need to do this, otherwise the URL will not contain the
270 // name of the submit button. 269 // name of the submit button.
271 firstSubmitButton->setActivatedSubmit(true); 270 firstSubmitButton->setActivatedSubmit(true);
272 } 271 }
273 272
274 bool isValidSearchString = buildSearchString(formElement.get(), &encodedStri ng, &encoding, inputElement); 273 Vector<char> encodedString;
274 bool isValidSearchString = buildSearchString(*formElement, &encodedString, e ncoding, inputElement);
275 275
276 if (firstSubmitButton) 276 if (firstSubmitButton)
277 firstSubmitButton->setActivatedSubmit(false); 277 firstSubmitButton->setActivatedSubmit(false);
278 278
279 // Return if the search string is not valid. 279 // Return if the search string is not valid.
280 if (!isValidSearchString) 280 if (!isValidSearchString)
281 return; 281 return;
282 282
283 String action(formElement->action()); 283 String action(formElement->action());
284 KURL url(formElement->document().completeURL(action.isNull() ? "" : action)) ; 284 KURL url(formElement->document().completeURL(action.isNull() ? "" : action)) ;
285 RefPtr<FormData> formData = FormData::create(encodedString); 285 RefPtr<FormData> formData = FormData::create(encodedString);
286 url.setQuery(formData->flattenToString()); 286 url.setQuery(formData->flattenToString());
287 m_url = url; 287 m_url = url;
288 m_encoding = String(encoding.name()); 288 m_encoding = String(encoding.name());
289 } 289 }
290 290
291 } // namespace blink 291 } // namespace blink
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698