OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) | 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) |
4 * (C) 2001 Dirk Mueller (mueller@kde.org) | 4 * (C) 2001 Dirk Mueller (mueller@kde.org) |
5 * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved. | 5 * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved. |
6 * (C) 2006 Alexey Proskuryakov (ap@nypop.com) | 6 * (C) 2006 Alexey Proskuryakov (ap@nypop.com) |
7 * | 7 * |
8 * This library is free software; you can redistribute it and/or | 8 * This library is free software; you can redistribute it and/or |
9 * modify it under the terms of the GNU Library General Public | 9 * modify it under the terms of the GNU Library General Public |
10 * License as published by the Free Software Foundation; either | 10 * License as published by the Free Software Foundation; either |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
43 | 43 |
44 namespace WebCore { | 44 namespace WebCore { |
45 | 45 |
46 using namespace HTMLNames; | 46 using namespace HTMLNames; |
47 using namespace std; | 47 using namespace std; |
48 | 48 |
49 HTMLFormControlElement::HTMLFormControlElement(const QualifiedName& tagName, Doc
ument* document, HTMLFormElement* form) | 49 HTMLFormControlElement::HTMLFormControlElement(const QualifiedName& tagName, Doc
ument* document, HTMLFormElement* form) |
50 : LabelableElement(tagName, document) | 50 : LabelableElement(tagName, document) |
51 , m_fieldSetAncestor(0) | 51 , m_fieldSetAncestor(0) |
52 , m_legendAncestor(0) | 52 , m_legendAncestor(0) |
53 , m_ancestorsValid(false) | 53 , m_fieldSetAncestorValid(false) |
54 , m_disabled(false) | 54 , m_disabled(false) |
55 , m_readOnly(false) | 55 , m_readOnly(false) |
56 , m_required(false) | 56 , m_required(false) |
57 , m_valueMatchesRenderer(false) | 57 , m_valueMatchesRenderer(false) |
| 58 , m_dataListAncestorState(Unknown) |
58 , m_willValidateInitialized(false) | 59 , m_willValidateInitialized(false) |
59 , m_willValidate(true) | 60 , m_willValidate(true) |
60 , m_isValid(true) | 61 , m_isValid(true) |
61 , m_wasChangedSinceLastFormControlChangeEvent(false) | 62 , m_wasChangedSinceLastFormControlChangeEvent(false) |
62 , m_hasAutofocused(false) | 63 , m_hasAutofocused(false) |
63 , m_hasDataListAncestor(false) | |
64 { | 64 { |
65 setForm(form ? form : findFormAncestor()); | 65 setForm(form ? form : findFormAncestor()); |
66 setHasCustomWillOrDidRecalcStyle(); | 66 setHasCustomWillOrDidRecalcStyle(); |
67 } | 67 } |
68 | 68 |
69 HTMLFormControlElement::~HTMLFormControlElement() | 69 HTMLFormControlElement::~HTMLFormControlElement() |
70 { | 70 { |
71 } | 71 } |
72 | 72 |
73 void HTMLFormControlElement::detach() | 73 void HTMLFormControlElement::detach() |
(...skipping 20 matching lines...) Expand all Loading... |
94 void HTMLFormControlElement::setFormMethod(const String& value) | 94 void HTMLFormControlElement::setFormMethod(const String& value) |
95 { | 95 { |
96 setAttribute(formmethodAttr, value); | 96 setAttribute(formmethodAttr, value); |
97 } | 97 } |
98 | 98 |
99 bool HTMLFormControlElement::formNoValidate() const | 99 bool HTMLFormControlElement::formNoValidate() const |
100 { | 100 { |
101 return fastHasAttribute(formnovalidateAttr); | 101 return fastHasAttribute(formnovalidateAttr); |
102 } | 102 } |
103 | 103 |
104 void HTMLFormControlElement::updateAncestors() const | 104 void HTMLFormControlElement::updateFieldSetAndLegendAncestor() const |
105 { | 105 { |
106 m_fieldSetAncestor = 0; | 106 m_fieldSetAncestor = 0; |
107 m_legendAncestor = 0; | 107 m_legendAncestor = 0; |
108 m_hasDataListAncestor = false; | |
109 for (ContainerNode* ancestor = parentNode(); ancestor; ancestor = ancestor->
parentNode()) { | 108 for (ContainerNode* ancestor = parentNode(); ancestor; ancestor = ancestor->
parentNode()) { |
110 if (!m_legendAncestor && ancestor->hasTagName(legendTag)) | 109 if (!m_legendAncestor && ancestor->hasTagName(legendTag)) |
111 m_legendAncestor = static_cast<HTMLLegendElement*>(ancestor); | 110 m_legendAncestor = static_cast<HTMLLegendElement*>(ancestor); |
112 if (!m_fieldSetAncestor && ancestor->hasTagName(fieldsetTag)) | 111 if (ancestor->hasTagName(fieldsetTag)) { |
113 m_fieldSetAncestor = static_cast<HTMLFieldSetElement*>(ancestor); | 112 m_fieldSetAncestor = static_cast<HTMLFieldSetElement*>(ancestor); |
114 if (!m_hasDataListAncestor && ancestor->hasTagName(datalistTag)) | |
115 m_hasDataListAncestor = true; | |
116 if (m_hasDataListAncestor && m_fieldSetAncestor) | |
117 break; | 113 break; |
| 114 } |
118 } | 115 } |
119 m_ancestorsValid = true; | 116 m_fieldSetAncestorValid = true; |
120 } | 117 } |
121 | 118 |
122 void HTMLFormControlElement::parseAttribute(Attribute* attr) | 119 void HTMLFormControlElement::parseAttribute(Attribute* attr) |
123 { | 120 { |
124 if (attr->name() == formAttr) | 121 if (attr->name() == formAttr) |
125 formAttributeChanged(); | 122 formAttributeChanged(); |
126 else if (attr->name() == disabledAttr) { | 123 else if (attr->name() == disabledAttr) { |
127 bool oldDisabled = m_disabled; | 124 bool oldDisabled = m_disabled; |
128 m_disabled = !attr->isNull(); | 125 m_disabled = !attr->isNull(); |
129 if (oldDisabled != m_disabled) | 126 if (oldDisabled != m_disabled) |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
220 } | 217 } |
221 | 218 |
222 void HTMLFormControlElement::didMoveToNewDocument(Document* oldDocument) | 219 void HTMLFormControlElement::didMoveToNewDocument(Document* oldDocument) |
223 { | 220 { |
224 FormAssociatedElement::didMoveToNewDocument(oldDocument); | 221 FormAssociatedElement::didMoveToNewDocument(oldDocument); |
225 HTMLElement::didMoveToNewDocument(oldDocument); | 222 HTMLElement::didMoveToNewDocument(oldDocument); |
226 } | 223 } |
227 | 224 |
228 Node::InsertionNotificationRequest HTMLFormControlElement::insertedInto(Node* in
sertionPoint) | 225 Node::InsertionNotificationRequest HTMLFormControlElement::insertedInto(Node* in
sertionPoint) |
229 { | 226 { |
| 227 m_dataListAncestorState = Unknown; |
| 228 setNeedsWillValidateCheck(); |
230 HTMLElement::insertedInto(insertionPoint); | 229 HTMLElement::insertedInto(insertionPoint); |
231 FormAssociatedElement::insertedInto(insertionPoint); | 230 FormAssociatedElement::insertedInto(insertionPoint); |
232 m_ancestorsValid = false; | |
233 setNeedsWillValidateCheck(); | |
234 return InsertionDone; | 231 return InsertionDone; |
235 } | 232 } |
236 | 233 |
237 void HTMLFormControlElement::removedFrom(Node* insertionPoint) | 234 void HTMLFormControlElement::removedFrom(Node* insertionPoint) |
238 { | 235 { |
| 236 m_fieldSetAncestorValid = false; |
| 237 m_dataListAncestorState = Unknown; |
239 HTMLElement::removedFrom(insertionPoint); | 238 HTMLElement::removedFrom(insertionPoint); |
240 FormAssociatedElement::removedFrom(insertionPoint); | 239 FormAssociatedElement::removedFrom(insertionPoint); |
241 m_ancestorsValid = false; | |
242 } | 240 } |
243 | 241 |
244 const AtomicString& HTMLFormControlElement::formControlName() const | 242 const AtomicString& HTMLFormControlElement::formControlName() const |
245 { | 243 { |
246 const AtomicString& name = getNameAttribute(); | 244 const AtomicString& name = getNameAttribute(); |
247 return name.isNull() ? emptyAtom : name; | 245 return name.isNull() ? emptyAtom : name; |
248 } | 246 } |
249 | 247 |
250 void HTMLFormControlElement::setName(const AtomicString& value) | 248 void HTMLFormControlElement::setName(const AtomicString& value) |
251 { | 249 { |
(...skipping 20 matching lines...) Expand all Loading... |
272 { | 270 { |
273 setChangedSinceLastFormControlChangeEvent(true); | 271 setChangedSinceLastFormControlChangeEvent(true); |
274 HTMLElement::dispatchInputEvent(); | 272 HTMLElement::dispatchInputEvent(); |
275 } | 273 } |
276 | 274 |
277 bool HTMLFormControlElement::disabled() const | 275 bool HTMLFormControlElement::disabled() const |
278 { | 276 { |
279 if (m_disabled) | 277 if (m_disabled) |
280 return true; | 278 return true; |
281 | 279 |
282 if (!m_ancestorsValid) | 280 if (!m_fieldSetAncestorValid) |
283 updateAncestors(); | 281 updateFieldSetAndLegendAncestor(); |
284 | 282 |
285 // Form controls in the first legend element inside a fieldset are not affec
ted by fieldset.disabled. | 283 // Form controls in the first legend element inside a fieldset are not affec
ted by fieldset.disabled. |
286 if (m_fieldSetAncestor && m_fieldSetAncestor->disabled()) | 284 if (m_fieldSetAncestor && m_fieldSetAncestor->disabled()) |
287 return !(m_legendAncestor && m_legendAncestor == m_fieldSetAncestor->leg
end()); | 285 return !(m_legendAncestor && m_legendAncestor == m_fieldSetAncestor->leg
end()); |
288 return false; | 286 return false; |
289 } | 287 } |
290 | 288 |
291 void HTMLFormControlElement::setDisabled(bool b) | 289 void HTMLFormControlElement::setDisabled(bool b) |
292 { | 290 { |
293 setAttribute(disabledAttr, b ? "" : 0); | 291 setAttribute(disabledAttr, b ? "" : 0); |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
352 } | 350 } |
353 | 351 |
354 short HTMLFormControlElement::tabIndex() const | 352 short HTMLFormControlElement::tabIndex() const |
355 { | 353 { |
356 // Skip the supportsFocus check in HTMLElement. | 354 // Skip the supportsFocus check in HTMLElement. |
357 return Element::tabIndex(); | 355 return Element::tabIndex(); |
358 } | 356 } |
359 | 357 |
360 bool HTMLFormControlElement::recalcWillValidate() const | 358 bool HTMLFormControlElement::recalcWillValidate() const |
361 { | 359 { |
362 return !m_hasDataListAncestor && !m_disabled && !m_readOnly; | 360 if (m_dataListAncestorState == Unknown) { |
| 361 for (ContainerNode* ancestor = parentNode(); ancestor; ancestor = ancest
or->parentNode()) { |
| 362 if (!m_legendAncestor && ancestor->hasTagName(datalistTag)) { |
| 363 m_dataListAncestorState = InsideDataList; |
| 364 break; |
| 365 } |
| 366 } |
| 367 if (m_dataListAncestorState == Unknown) |
| 368 m_dataListAncestorState = NotInsideDataList; |
| 369 } |
| 370 return m_dataListAncestorState == NotInsideDataList && !m_disabled && !m_rea
dOnly; |
363 } | 371 } |
364 | 372 |
365 bool HTMLFormControlElement::willValidate() const | 373 bool HTMLFormControlElement::willValidate() const |
366 { | 374 { |
367 if (!m_willValidateInitialized || !m_ancestorsValid) { | 375 if (!m_willValidateInitialized || m_dataListAncestorState == Unknown) { |
368 if (!m_ancestorsValid) | |
369 updateAncestors(); | |
370 | |
371 m_willValidateInitialized = true; | 376 m_willValidateInitialized = true; |
372 m_willValidate = recalcWillValidate(); | 377 m_willValidate = recalcWillValidate(); |
373 } else { | 378 } else { |
374 // If the following assertion fails, setNeedsWillValidateCheck() is not | 379 // If the following assertion fails, setNeedsWillValidateCheck() is not |
375 // called correctly when something which changes recalcWillValidate() re
sult | 380 // called correctly when something which changes recalcWillValidate() re
sult |
376 // is updated. | 381 // is updated. |
377 ASSERT(m_willValidate == recalcWillValidate()); | 382 ASSERT(m_willValidate == recalcWillValidate()); |
378 } | 383 } |
379 return m_willValidate; | 384 return m_willValidate; |
380 } | 385 } |
381 | 386 |
382 void HTMLFormControlElement::setNeedsWillValidateCheck() | 387 void HTMLFormControlElement::setNeedsWillValidateCheck() |
383 { | 388 { |
384 if (!m_ancestorsValid) | |
385 updateAncestors(); | |
386 | |
387 // We need to recalculate willValidate immediately because willValidate chan
ge can causes style change. | 389 // We need to recalculate willValidate immediately because willValidate chan
ge can causes style change. |
388 bool newWillValidate = recalcWillValidate(); | 390 bool newWillValidate = recalcWillValidate(); |
389 if (m_willValidateInitialized && m_willValidate == newWillValidate) | 391 if (m_willValidateInitialized && m_willValidate == newWillValidate) |
390 return; | 392 return; |
391 m_willValidateInitialized = true; | 393 m_willValidateInitialized = true; |
392 m_willValidate = newWillValidate; | 394 m_willValidate = newWillValidate; |
393 setNeedsStyleRecalc(); | 395 setNeedsStyleRecalc(); |
394 if (!m_willValidate) | 396 if (!m_willValidate) |
395 hideVisibleValidationMessage(); | 397 hideVisibleValidationMessage(); |
396 } | 398 } |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
504 HTMLFormControlElement* HTMLFormControlElement::enclosingFormControlElement(Node
* node) | 506 HTMLFormControlElement* HTMLFormControlElement::enclosingFormControlElement(Node
* node) |
505 { | 507 { |
506 for (; node; node = node->parentNode()) { | 508 for (; node; node = node->parentNode()) { |
507 if (node->isElementNode() && toElement(node)->isFormControlElement()) | 509 if (node->isElementNode() && toElement(node)->isFormControlElement()) |
508 return static_cast<HTMLFormControlElement*>(node); | 510 return static_cast<HTMLFormControlElement*>(node); |
509 } | 511 } |
510 return 0; | 512 return 0; |
511 } | 513 } |
512 | 514 |
513 } // namespace Webcore | 515 } // namespace Webcore |
OLD | NEW |