| 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 |