OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/renderer/autofill/form_autofill_util.h" | 5 #include "chrome/renderer/autofill/form_autofill_util.h" |
6 | 6 |
7 #include <map> | 7 #include <map> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/memory/scoped_vector.h" | 10 #include "base/memory/scoped_vector.h" |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
48 using autofill::ExtractAutofillableElements; | 48 using autofill::ExtractAutofillableElements; |
49 using autofill::IsAutofillableInputElement; | 49 using autofill::IsAutofillableInputElement; |
50 using autofill::IsCheckableElement; | 50 using autofill::IsCheckableElement; |
51 using autofill::IsSelectElement; | 51 using autofill::IsSelectElement; |
52 using autofill::IsTextInput; | 52 using autofill::IsTextInput; |
53 | 53 |
54 // The maximum length allowed for form data. | 54 // The maximum length allowed for form data. |
55 const size_t kMaxDataLength = 1024; | 55 const size_t kMaxDataLength = 1024; |
56 | 56 |
57 bool IsOptionElement(const WebElement& element) { | 57 bool IsOptionElement(const WebElement& element) { |
58 return element.hasTagName("option"); | 58 CR_DEFINE_STATIC_LOCAL(WebString, kOption, ("option")); |
59 return element.hasTagName(kOption); | |
59 } | 60 } |
60 | 61 |
61 bool IsScriptElement(const WebElement& element) { | 62 bool IsScriptElement(const WebElement& element) { |
62 return element.hasTagName("script"); | 63 CR_DEFINE_STATIC_LOCAL(WebString, kScript, ("script")); |
64 return element.hasTagName(kScript); | |
63 } | 65 } |
64 | 66 |
65 bool IsNoScriptElement(const WebElement& element) { | 67 bool IsNoScriptElement(const WebElement& element) { |
66 return element.hasTagName("noscript"); | 68 CR_DEFINE_STATIC_LOCAL(WebString, kNoScript, ("noscript")); |
69 return element.hasTagName(kNoScript); | |
67 } | 70 } |
68 | 71 |
69 bool HasTagName(const WebNode& node, const WebKit::WebString& tag) { | 72 bool HasTagName(const WebNode& node, const WebKit::WebString& tag) { |
70 return node.isElementNode() && node.toConst<WebElement>().hasTagName(tag); | 73 return node.isElementNode() && node.toConst<WebElement>().hasTagName(tag); |
71 } | 74 } |
72 | 75 |
73 bool IsAutofillableElement(const WebFormControlElement& element) { | 76 bool IsAutofillableElement(const WebFormControlElement& element) { |
74 const WebInputElement* input_element = toWebInputElement(&element); | 77 const WebInputElement* input_element = toWebInputElement(&element); |
75 return IsAutofillableInputElement(input_element) || IsSelectElement(element); | 78 return IsAutofillableInputElement(input_element) || IsSelectElement(element); |
76 } | 79 } |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
175 // a previous sibling of |element|, | 178 // a previous sibling of |element|, |
176 // e.g. Some Text <input ...> | 179 // e.g. Some Text <input ...> |
177 // or Some <span>Text</span> <input ...> | 180 // or Some <span>Text</span> <input ...> |
178 // or <p>Some Text</p><input ...> | 181 // or <p>Some Text</p><input ...> |
179 // or <label>Some Text</label> <input ...> | 182 // or <label>Some Text</label> <input ...> |
180 // or Some Text <img><input ...> | 183 // or Some Text <img><input ...> |
181 // or <b>Some Text</b><br/> <input ...>. | 184 // or <b>Some Text</b><br/> <input ...>. |
182 string16 InferLabelFromPrevious(const WebFormControlElement& element) { | 185 string16 InferLabelFromPrevious(const WebFormControlElement& element) { |
183 string16 inferred_label; | 186 string16 inferred_label; |
184 WebNode previous = element; | 187 WebNode previous = element; |
188 CR_DEFINE_STATIC_LOCAL(WebString, kBold, ("b")); | |
189 CR_DEFINE_STATIC_LOCAL(WebString, kStrong, ("strong")); | |
190 CR_DEFINE_STATIC_LOCAL(WebString, kSpan, ("span")); | |
191 CR_DEFINE_STATIC_LOCAL(WebString, kFont, ("font")); | |
192 CR_DEFINE_STATIC_LOCAL(WebString, kImage, ("img")); | |
193 CR_DEFINE_STATIC_LOCAL(WebString, kBreak, ("br")); | |
194 CR_DEFINE_STATIC_LOCAL(WebString, kPage, ("p")); | |
195 CR_DEFINE_STATIC_LOCAL(WebString, kLabel, ("label")); | |
Ilya Sherman
2013/02/11 05:50:30
nit: Please define these closer to where they're a
Albert Bodenhamer
2013/02/11 17:37:51
Done.
| |
185 while (true) { | 196 while (true) { |
186 previous = previous.previousSibling(); | 197 previous = previous.previousSibling(); |
187 if (previous.isNull()) | 198 if (previous.isNull()) |
188 break; | 199 break; |
189 | 200 |
190 // Skip over comments. | 201 // Skip over comments. |
191 WebNode::NodeType node_type = previous.nodeType(); | 202 WebNode::NodeType node_type = previous.nodeType(); |
192 if (node_type == WebNode::CommentNode) | 203 if (node_type == WebNode::CommentNode) |
193 continue; | 204 continue; |
194 | 205 |
195 // Otherwise, only consider normal HTML elements and their contents. | 206 // Otherwise, only consider normal HTML elements and their contents. |
196 if (node_type != WebNode::TextNode && | 207 if (node_type != WebNode::TextNode && |
197 node_type != WebNode::ElementNode) | 208 node_type != WebNode::ElementNode) |
198 break; | 209 break; |
199 | 210 |
200 // A label might be split across multiple "lightweight" nodes. | 211 // A label might be split across multiple "lightweight" nodes. |
201 // Coalesce any text contained in multiple consecutive | 212 // Coalesce any text contained in multiple consecutive |
202 // (a) plain text nodes or | 213 // (a) plain text nodes or |
203 // (b) inline HTML elements that are essentially equivalent to text nodes. | 214 // (b) inline HTML elements that are essentially equivalent to text nodes. |
204 if (previous.isTextNode() || | 215 if (previous.isTextNode() || |
205 HasTagName(previous, "b") || HasTagName(previous, "strong") || | 216 HasTagName(previous, kBold) || HasTagName(previous, kStrong) || |
206 HasTagName(previous, "span") || HasTagName(previous, "font")) { | 217 HasTagName(previous, kSpan) || HasTagName(previous, kFont)) { |
207 string16 value = FindChildText(previous); | 218 string16 value = FindChildText(previous); |
208 // A text node's value will be empty if it is for a line break. | 219 // A text node's value will be empty if it is for a line break. |
209 bool add_space = previous.isTextNode() && value.empty(); | 220 bool add_space = previous.isTextNode() && value.empty(); |
210 inferred_label = | 221 inferred_label = |
211 CombineAndCollapseWhitespace(value, inferred_label, add_space); | 222 CombineAndCollapseWhitespace(value, inferred_label, add_space); |
212 continue; | 223 continue; |
213 } | 224 } |
214 | 225 |
215 // If we have identified a partial label and have reached a non-lightweight | 226 // If we have identified a partial label and have reached a non-lightweight |
216 // element, consider the label to be complete. | 227 // element, consider the label to be complete. |
217 string16 trimmed_label; | 228 string16 trimmed_label; |
218 TrimWhitespace(inferred_label, TRIM_ALL, &trimmed_label); | 229 TrimWhitespace(inferred_label, TRIM_ALL, &trimmed_label); |
219 if (!trimmed_label.empty()) | 230 if (!trimmed_label.empty()) |
220 break; | 231 break; |
221 | 232 |
222 // <img> and <br> tags often appear between the input element and its | 233 // <img> and <br> tags often appear between the input element and its |
223 // label text, so skip over them. | 234 // label text, so skip over them. |
224 if (HasTagName(previous, "img") || HasTagName(previous, "br")) | 235 if (HasTagName(previous, kImage) || HasTagName(previous, kBreak)) |
225 continue; | 236 continue; |
226 | 237 |
227 // We only expect <p> and <label> tags to contain the full label text. | 238 // We only expect <p> and <label> tags to contain the full label text. |
228 if (HasTagName(previous, "p") || HasTagName(previous, "label")) | 239 if (HasTagName(previous, kPage) || HasTagName(previous, kLabel)) |
229 inferred_label = FindChildText(previous); | 240 inferred_label = FindChildText(previous); |
230 | 241 |
231 break; | 242 break; |
232 } | 243 } |
233 | 244 |
234 TrimWhitespace(inferred_label, TRIM_ALL, &inferred_label); | 245 TrimWhitespace(inferred_label, TRIM_ALL, &inferred_label); |
235 return inferred_label; | 246 return inferred_label; |
236 } | 247 } |
237 | 248 |
238 // Helper for |InferLabelForElement()| that infers a label, if possible, from | 249 // Helper for |InferLabelForElement()| that infers a label, if possible, from |
239 // enclosing list item, | 250 // enclosing list item, |
240 // e.g. <li>Some Text<input ...><input ...><input ...></tr> | 251 // e.g. <li>Some Text<input ...><input ...><input ...></tr> |
241 string16 InferLabelFromListItem(const WebFormControlElement& element) { | 252 string16 InferLabelFromListItem(const WebFormControlElement& element) { |
242 WebNode parent = element.parentNode(); | 253 WebNode parent = element.parentNode(); |
254 CR_DEFINE_STATIC_LOCAL(WebString, kListItem, ("li")); | |
243 while (!parent.isNull() && parent.isElementNode() && | 255 while (!parent.isNull() && parent.isElementNode() && |
244 !parent.to<WebElement>().hasTagName("li")) { | 256 !parent.to<WebElement>().hasTagName(kListItem)) { |
245 parent = parent.parentNode(); | 257 parent = parent.parentNode(); |
246 } | 258 } |
247 | 259 |
248 if (!parent.isNull() && HasTagName(parent, "li")) | 260 if (!parent.isNull() && HasTagName(parent, kListItem)) |
249 return FindChildText(parent); | 261 return FindChildText(parent); |
250 | 262 |
251 return string16(); | 263 return string16(); |
252 } | 264 } |
253 | 265 |
254 // Helper for |InferLabelForElement()| that infers a label, if possible, from | 266 // Helper for |InferLabelForElement()| that infers a label, if possible, from |
255 // surrounding table structure, | 267 // surrounding table structure, |
256 // e.g. <tr><td>Some Text</td><td><input ...></td></tr> | 268 // e.g. <tr><td>Some Text</td><td><input ...></td></tr> |
257 // or <tr><th>Some Text</th><td><input ...></td></tr> | 269 // or <tr><th>Some Text</th><td><input ...></td></tr> |
258 // or <tr><td><b>Some Text</b></td><td><b><input ...></b></td></tr> | 270 // or <tr><td><b>Some Text</b></td><td><b><input ...></b></td></tr> |
259 // or <tr><th><b>Some Text</b></th><td><b><input ...></b></td></tr> | 271 // or <tr><th><b>Some Text</b></th><td><b><input ...></b></td></tr> |
260 string16 InferLabelFromTableColumn(const WebFormControlElement& element) { | 272 string16 InferLabelFromTableColumn(const WebFormControlElement& element) { |
273 CR_DEFINE_STATIC_LOCAL(WebString, kTableCell, ("td")); | |
274 CR_DEFINE_STATIC_LOCAL(WebString, kTableHeader, ("th")); | |
261 WebNode parent = element.parentNode(); | 275 WebNode parent = element.parentNode(); |
262 while (!parent.isNull() && parent.isElementNode() && | 276 while (!parent.isNull() && parent.isElementNode() && |
263 !parent.to<WebElement>().hasTagName("td")) { | 277 !parent.to<WebElement>().hasTagName(kTableCell)) { |
264 parent = parent.parentNode(); | 278 parent = parent.parentNode(); |
265 } | 279 } |
266 | 280 |
267 if (parent.isNull()) | 281 if (parent.isNull()) |
268 return string16(); | 282 return string16(); |
269 | 283 |
270 // Check all previous siblings, skipping non-element nodes, until we find a | 284 // Check all previous siblings, skipping non-element nodes, until we find a |
271 // non-empty text block. | 285 // non-empty text block. |
272 string16 inferred_label; | 286 string16 inferred_label; |
273 WebNode previous = parent.previousSibling(); | 287 WebNode previous = parent.previousSibling(); |
274 while (inferred_label.empty() && !previous.isNull()) { | 288 while (inferred_label.empty() && !previous.isNull()) { |
275 if (HasTagName(previous, "td") || HasTagName(previous, "th")) | 289 if (HasTagName(previous, kTableCell) || HasTagName(previous, kTableHeader)) |
276 inferred_label = FindChildText(previous); | 290 inferred_label = FindChildText(previous); |
277 | 291 |
278 previous = previous.previousSibling(); | 292 previous = previous.previousSibling(); |
279 } | 293 } |
280 | 294 |
281 return inferred_label; | 295 return inferred_label; |
282 } | 296 } |
283 | 297 |
284 // Helper for |InferLabelForElement()| that infers a label, if possible, from | 298 // Helper for |InferLabelForElement()| that infers a label, if possible, from |
285 // surrounding table structure, | 299 // surrounding table structure, |
286 // e.g. <tr><td>Some Text</td></tr><tr><td><input ...></td></tr> | 300 // e.g. <tr><td>Some Text</td></tr><tr><td><input ...></td></tr> |
287 string16 InferLabelFromTableRow(const WebFormControlElement& element) { | 301 string16 InferLabelFromTableRow(const WebFormControlElement& element) { |
302 CR_DEFINE_STATIC_LOCAL(WebString, kTableRow, ("tr")); | |
288 WebNode parent = element.parentNode(); | 303 WebNode parent = element.parentNode(); |
289 while (!parent.isNull() && parent.isElementNode() && | 304 while (!parent.isNull() && parent.isElementNode() && |
290 !parent.to<WebElement>().hasTagName("tr")) { | 305 !parent.to<WebElement>().hasTagName(kTableRow)) { |
291 parent = parent.parentNode(); | 306 parent = parent.parentNode(); |
292 } | 307 } |
293 | 308 |
294 if (parent.isNull()) | 309 if (parent.isNull()) |
295 return string16(); | 310 return string16(); |
296 | 311 |
297 // Check all previous siblings, skipping non-element nodes, until we find a | 312 // Check all previous siblings, skipping non-element nodes, until we find a |
298 // non-empty text block. | 313 // non-empty text block. |
299 string16 inferred_label; | 314 string16 inferred_label; |
300 WebNode previous = parent.previousSibling(); | 315 WebNode previous = parent.previousSibling(); |
301 while (inferred_label.empty() && !previous.isNull()) { | 316 while (inferred_label.empty() && !previous.isNull()) { |
302 if (HasTagName(previous, "tr")) | 317 if (HasTagName(previous, kTableRow)) |
303 inferred_label = FindChildText(previous); | 318 inferred_label = FindChildText(previous); |
304 | 319 |
305 previous = previous.previousSibling(); | 320 previous = previous.previousSibling(); |
306 } | 321 } |
307 | 322 |
308 return inferred_label; | 323 return inferred_label; |
309 } | 324 } |
310 | 325 |
311 // Helper for |InferLabelForElement()| that infers a label, if possible, from | 326 // Helper for |InferLabelForElement()| that infers a label, if possible, from |
312 // a surrounding div table, | 327 // a surrounding div table, |
313 // e.g. <div>Some Text<span><input ...></span></div> | 328 // e.g. <div>Some Text<span><input ...></span></div> |
314 // e.g. <div>Some Text</div><div><input ...></div> | 329 // e.g. <div>Some Text</div><div><input ...></div> |
315 string16 InferLabelFromDivTable(const WebFormControlElement& element) { | 330 string16 InferLabelFromDivTable(const WebFormControlElement& element) { |
331 CR_DEFINE_STATIC_LOCAL(WebString, kDiv, ("div")); | |
332 CR_DEFINE_STATIC_LOCAL(WebString, kTable, ("table")); | |
333 CR_DEFINE_STATIC_LOCAL(WebString, kFieldSet, ("fieldset")); | |
316 WebNode node = element.parentNode(); | 334 WebNode node = element.parentNode(); |
317 bool looking_for_parent = true; | 335 bool looking_for_parent = true; |
318 | 336 |
319 // Search the sibling and parent <div>s until we find a candidate label. | 337 // Search the sibling and parent <div>s until we find a candidate label. |
320 string16 inferred_label; | 338 string16 inferred_label; |
321 while (inferred_label.empty() && !node.isNull()) { | 339 while (inferred_label.empty() && !node.isNull()) { |
322 if (HasTagName(node, "div")) { | 340 if (HasTagName(node, kDiv)) { |
323 looking_for_parent = false; | 341 looking_for_parent = false; |
324 inferred_label = FindChildText(node); | 342 inferred_label = FindChildText(node); |
325 } else if (looking_for_parent && | 343 } else if (looking_for_parent && |
326 (HasTagName(node, "table") || HasTagName(node, "fieldset"))) { | 344 (HasTagName(node, kTable) || HasTagName(node, kFieldSet))) { |
327 // If the element is in a table or fieldset, its label most likely is too. | 345 // If the element is in a table or fieldset, its label most likely is too. |
328 break; | 346 break; |
329 } | 347 } |
330 | 348 |
331 if (node.previousSibling().isNull()) { | 349 if (node.previousSibling().isNull()) { |
332 // If there are no more siblings, continue walking up the tree. | 350 // If there are no more siblings, continue walking up the tree. |
333 looking_for_parent = true; | 351 looking_for_parent = true; |
334 } | 352 } |
335 | 353 |
336 if (looking_for_parent) | 354 if (looking_for_parent) |
337 node = node.parentNode(); | 355 node = node.parentNode(); |
338 else | 356 else |
339 node = node.previousSibling(); | 357 node = node.previousSibling(); |
340 } | 358 } |
341 | 359 |
342 return inferred_label; | 360 return inferred_label; |
343 } | 361 } |
344 | 362 |
345 // Helper for |InferLabelForElement()| that infers a label, if possible, from | 363 // Helper for |InferLabelForElement()| that infers a label, if possible, from |
346 // a surrounding definition list, | 364 // a surrounding definition list, |
347 // e.g. <dl><dt>Some Text</dt><dd><input ...></dd></dl> | 365 // e.g. <dl><dt>Some Text</dt><dd><input ...></dd></dl> |
348 // e.g. <dl><dt><b>Some Text</b></dt><dd><b><input ...></b></dd></dl> | 366 // e.g. <dl><dt><b>Some Text</b></dt><dd><b><input ...></b></dd></dl> |
349 string16 InferLabelFromDefinitionList(const WebFormControlElement& element) { | 367 string16 InferLabelFromDefinitionList(const WebFormControlElement& element) { |
368 CR_DEFINE_STATIC_LOCAL(WebString, kDefinitionData, ("dd")); | |
369 CR_DEFINE_STATIC_LOCAL(WebString, kDefinitionTag, ("dt")); | |
350 WebNode parent = element.parentNode(); | 370 WebNode parent = element.parentNode(); |
351 while (!parent.isNull() && parent.isElementNode() && | 371 while (!parent.isNull() && parent.isElementNode() && |
352 !parent.to<WebElement>().hasTagName("dd")) | 372 !parent.to<WebElement>().hasTagName(kDefinitionData)) |
353 parent = parent.parentNode(); | 373 parent = parent.parentNode(); |
354 | 374 |
355 if (parent.isNull() || !HasTagName(parent, "dd")) | 375 if (parent.isNull() || !HasTagName(parent, kDefinitionData)) |
356 return string16(); | 376 return string16(); |
357 | 377 |
358 // Skip by any intervening text nodes. | 378 // Skip by any intervening text nodes. |
359 WebNode previous = parent.previousSibling(); | 379 WebNode previous = parent.previousSibling(); |
360 while (!previous.isNull() && previous.isTextNode()) | 380 while (!previous.isNull() && previous.isTextNode()) |
361 previous = previous.previousSibling(); | 381 previous = previous.previousSibling(); |
362 | 382 |
363 if (previous.isNull() || !HasTagName(previous, "dt")) | 383 if (previous.isNull() || !HasTagName(previous, kDefinitionTag)) |
364 return string16(); | 384 return string16(); |
365 | 385 |
366 return FindChildText(previous); | 386 return FindChildText(previous); |
367 } | 387 } |
368 | 388 |
369 // Infers corresponding label for |element| from surrounding context in the DOM, | 389 // Infers corresponding label for |element| from surrounding context in the DOM, |
370 // e.g. the contents of the preceding <p> tag or text element. | 390 // e.g. the contents of the preceding <p> tag or text element. |
371 string16 InferLabelForElement(const WebFormControlElement& element) { | 391 string16 InferLabelForElement(const WebFormControlElement& element) { |
372 string16 inferred_label = InferLabelFromPrevious(element); | 392 string16 inferred_label = InferLabelFromPrevious(element); |
373 if (!inferred_label.empty()) | 393 if (!inferred_label.empty()) |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
586 } | 606 } |
587 | 607 |
588 bool IsAutofillableInputElement(const WebInputElement* element) { | 608 bool IsAutofillableInputElement(const WebInputElement* element) { |
589 // TODO(ramankk): Uncomment IsCheckableElement part once we have solution | 609 // TODO(ramankk): Uncomment IsCheckableElement part once we have solution |
590 // for the observed performance regression. | 610 // for the observed performance regression. |
591 return IsTextInput(element); // || IsCheckableElement(element); | 611 return IsTextInput(element); // || IsCheckableElement(element); |
592 } | 612 } |
593 | 613 |
594 const string16 GetFormIdentifier(const WebFormElement& form) { | 614 const string16 GetFormIdentifier(const WebFormElement& form) { |
595 string16 identifier = form.name(); | 615 string16 identifier = form.name(); |
616 CR_DEFINE_STATIC_LOCAL(WebString, kId, ("id")); | |
596 if (identifier.empty()) | 617 if (identifier.empty()) |
597 identifier = form.getAttribute(WebString("id")); | 618 identifier = form.getAttribute(kId); |
598 | 619 |
599 return identifier; | 620 return identifier; |
600 } | 621 } |
601 | 622 |
602 bool ClickElement(const WebDocument& document, | 623 bool ClickElement(const WebDocument& document, |
603 const WebElementDescriptor& element_descriptor) { | 624 const WebElementDescriptor& element_descriptor) { |
604 WebString web_descriptor = WebString::fromUTF8(element_descriptor.descriptor); | 625 WebString web_descriptor = WebString::fromUTF8(element_descriptor.descriptor); |
605 WebKit::WebElement element; | 626 WebKit::WebElement element; |
606 | 627 |
607 switch (element_descriptor.retrieval_method) { | 628 switch (element_descriptor.retrieval_method) { |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
656 | 677 |
657 autofillable_elements->push_back(element); | 678 autofillable_elements->push_back(element); |
658 } | 679 } |
659 } | 680 } |
660 | 681 |
661 void WebFormControlElementToFormField(const WebFormControlElement& element, | 682 void WebFormControlElementToFormField(const WebFormControlElement& element, |
662 ExtractMask extract_mask, | 683 ExtractMask extract_mask, |
663 FormFieldData* field) { | 684 FormFieldData* field) { |
664 DCHECK(field); | 685 DCHECK(field); |
665 DCHECK(!element.isNull()); | 686 DCHECK(!element.isNull()); |
687 CR_DEFINE_STATIC_LOCAL(WebString, kAutocomplete, ("autocomplete")); | |
666 | 688 |
667 // The label is not officially part of a WebFormControlElement; however, the | 689 // The label is not officially part of a WebFormControlElement; however, the |
668 // labels for all form control elements are scraped from the DOM and set in | 690 // labels for all form control elements are scraped from the DOM and set in |
669 // WebFormElementToFormData. | 691 // WebFormElementToFormData. |
670 field->name = element.nameForAutofill(); | 692 field->name = element.nameForAutofill(); |
671 field->form_control_type = UTF16ToUTF8(element.formControlType()); | 693 field->form_control_type = UTF16ToUTF8(element.formControlType()); |
672 field->autocomplete_attribute = | 694 field->autocomplete_attribute = |
673 UTF16ToUTF8(element.getAttribute("autocomplete")); | 695 UTF16ToUTF8(element.getAttribute(kAutocomplete)); |
674 if (field->autocomplete_attribute.size() > kMaxDataLength) { | 696 if (field->autocomplete_attribute.size() > kMaxDataLength) { |
675 // Discard overly long attribute values to avoid DOS-ing the browser | 697 // Discard overly long attribute values to avoid DOS-ing the browser |
676 // process. However, send over a default string to indicate that the | 698 // process. However, send over a default string to indicate that the |
677 // attribute was present. | 699 // attribute was present. |
678 field->autocomplete_attribute = "x-max-data-length-exceeded"; | 700 field->autocomplete_attribute = "x-max-data-length-exceeded"; |
679 } | 701 } |
680 | 702 |
681 if (!IsAutofillableElement(element)) | 703 if (!IsAutofillableElement(element)) |
682 return; | 704 return; |
683 | 705 |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
734 field->value = value; | 756 field->value = value; |
735 } | 757 } |
736 | 758 |
737 bool WebFormElementToFormData( | 759 bool WebFormElementToFormData( |
738 const WebKit::WebFormElement& form_element, | 760 const WebKit::WebFormElement& form_element, |
739 const WebKit::WebFormControlElement& form_control_element, | 761 const WebKit::WebFormControlElement& form_control_element, |
740 RequirementsMask requirements, | 762 RequirementsMask requirements, |
741 ExtractMask extract_mask, | 763 ExtractMask extract_mask, |
742 FormData* form, | 764 FormData* form, |
743 FormFieldData* field) { | 765 FormFieldData* field) { |
766 CR_DEFINE_STATIC_LOCAL(WebString, kLabel, ("label")); | |
767 CR_DEFINE_STATIC_LOCAL(WebString, kFor, ("for")); | |
768 CR_DEFINE_STATIC_LOCAL(WebString, kHidden, ("hidden")); | |
769 | |
744 const WebFrame* frame = form_element.document().frame(); | 770 const WebFrame* frame = form_element.document().frame(); |
745 if (!frame) | 771 if (!frame) |
746 return false; | 772 return false; |
747 | 773 |
748 if (requirements & REQUIRE_AUTOCOMPLETE && !form_element.autoComplete()) | 774 if (requirements & REQUIRE_AUTOCOMPLETE && !form_element.autoComplete()) |
749 return false; | 775 return false; |
750 | 776 |
751 form->name = GetFormIdentifier(form_element); | 777 form->name = GetFormIdentifier(form_element); |
752 form->method = form_element.method(); | 778 form->method = form_element.method(); |
753 form->origin = frame->document().url(); | 779 form->origin = frame->document().url(); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
799 // If we failed to extract any fields, give up. Also, to avoid overly | 825 // If we failed to extract any fields, give up. Also, to avoid overly |
800 // expensive computation, we impose a maximum number of allowable fields. | 826 // expensive computation, we impose a maximum number of allowable fields. |
801 if (form_fields.empty() || form_fields.size() > kMaxParseableFields) | 827 if (form_fields.empty() || form_fields.size() > kMaxParseableFields) |
802 return false; | 828 return false; |
803 | 829 |
804 // Loop through the label elements inside the form element. For each label | 830 // Loop through the label elements inside the form element. For each label |
805 // element, get the corresponding form control element, use the form control | 831 // element, get the corresponding form control element, use the form control |
806 // element's name as a key into the <name, FormFieldData> map to find the | 832 // element's name as a key into the <name, FormFieldData> map to find the |
807 // previously created FormFieldData and set the FormFieldData's label to the | 833 // previously created FormFieldData and set the FormFieldData's label to the |
808 // label.firstChild().nodeValue() of the label element. | 834 // label.firstChild().nodeValue() of the label element. |
809 WebNodeList labels = form_element.getElementsByTagName("label"); | 835 WebNodeList labels = form_element.getElementsByTagName(kLabel); |
810 for (unsigned i = 0; i < labels.length(); ++i) { | 836 for (unsigned i = 0; i < labels.length(); ++i) { |
811 WebLabelElement label = labels.item(i).to<WebLabelElement>(); | 837 WebLabelElement label = labels.item(i).to<WebLabelElement>(); |
812 WebFormControlElement field_element = | 838 WebFormControlElement field_element = |
813 label.correspondingControl().to<WebFormControlElement>(); | 839 label.correspondingControl().to<WebFormControlElement>(); |
814 | 840 |
815 string16 element_name; | 841 string16 element_name; |
816 if (field_element.isNull()) { | 842 if (field_element.isNull()) { |
817 // Sometimes site authors will incorrectly specify the corresponding | 843 // Sometimes site authors will incorrectly specify the corresponding |
818 // field element's name rather than its id, so we compensate here. | 844 // field element's name rather than its id, so we compensate here. |
819 element_name = label.getAttribute("for"); | 845 element_name = label.getAttribute(kFor); |
820 } else if ( | 846 } else if ( |
821 !field_element.isFormControlElement() || | 847 !field_element.isFormControlElement() || |
822 field_element.formControlType() == WebString::fromUTF8("hidden")) { | 848 field_element.formControlType() == kHidden) { |
823 continue; | 849 continue; |
824 } else { | 850 } else { |
825 element_name = field_element.nameForAutofill(); | 851 element_name = field_element.nameForAutofill(); |
826 } | 852 } |
827 | 853 |
828 std::map<string16, FormFieldData*>::iterator iter = | 854 std::map<string16, FormFieldData*>::iterator iter = |
829 name_map.find(element_name); | 855 name_map.find(element_name); |
830 if (iter != name_map.end()) { | 856 if (iter != name_map.end()) { |
831 string16 label_text = FindChildText(label); | 857 string16 label_text = FindChildText(label); |
832 | 858 |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
987 continue; | 1013 continue; |
988 | 1014 |
989 if (input_element->isAutofilled()) | 1015 if (input_element->isAutofilled()) |
990 return true; | 1016 return true; |
991 } | 1017 } |
992 | 1018 |
993 return false; | 1019 return false; |
994 } | 1020 } |
995 | 1021 |
996 } // namespace autofill | 1022 } // namespace autofill |
OLD | NEW |