The form team would like to re-factor HTMLFormControlElement class, because class hierarchy isn't match the specification and some use of isFormControlControl isn't clear. We'll make HTMLFormControlElement is base class of HTML*Element which is in HTMLFormControlCollection[1], which is "listed element" of form and fieldset[2], 1. button 2. fieldset 3. input 4. keygen 5. object 6. output 7. select 8. textarea. As of this change following classes won't be derived from HTMLFormControlElement 1. legend (bug 80239) 2. meter (bug 80380) 3. option (bug 79764) 4. optgroup (bug 80234) 5. progress (bug 80239) Also, we'll introduce new predicate method into HTMLElement to replace isFormControl predicate with clear intention: # Frame::searchForLabelsBeforeElement #* NOW: backward walker stops when hits isFormControl. #* SHOULD: backward walker stops when hits label-able element. # ValidityState::validationMessage #* NOW: bool isTextAreaElement = element->isFormControlElement() && element->hasTagName(textareaTag); #* SHOULD: bool isTextAreaElement = element->isFormAssociateElement() && element->hasTagName(textareaTag); # ValidityState::setCustomErrorMessage #* NOW if (m_control->isFormControlElement()) static_cast<HTMLFormControlElement*>(m_control)->setNeedsValidityCheck(); #* SHOULD if (m_control->canValidate()) static_cast<ValidatableElement*>(m_control)->setNeedsValidityCheck(); # allowsAuthorShadowRoot in ShadowRoot.cpp #* NOW: // FIXME: ValidationMessage recreates shadow root dynamically. if (eleemnt->isFormControl()) return false; #* SHOULD if (element->canValidate()) return false; # SelectorChecker::checkOneSelector #* NOW: case CSSSelector::PseudoAutofill: if (!element || !element->isFormControlElement()) break; if (HTMLInputElement* inputElement = element->toInputElement()) return inputElement->isAutofilled(); #* SHOULD: // We don't need to check isFormControlElement if (HTMLInputElement* inputElement = element ? element->toInputElement() : 0) return inputElement->isAutofilled(); #* NOW: case CSSSelector::PseudoEnabled: if (element && element->isFormControlElement()) return element->isEnabledFormControl(); break; #* SHOULD: case CSSSelector::PseudoEnabled: if (element && element->hasCSSPseudoClassEnabled()) return !element->disabled(); # toHTMLElement in FormAssociateElement.cpp #* NOW: if (associatedElement->isFormControlElement()) { // This is reinterpret_cast rather than static_cast. return static_cast<const HTMLFormControlElement*>(associatedElement); } #* SHOULD: TBD # RenderLayer::resize #* NOW: if (resize != RESIZE_VERTICAL && difference.width()) { if (element->isFormControlElement()) { // Make implicit margins from the theme explicit (see <http://bugs.webkit.org/show_bug.cgi?id=9547>). #* SHOULD: TBD # CSSStyleSelector::canShareStyleWithElement #* NOW: if (m_element->isFormControlElement() && !canShareStyleWithControl(element)) return false; #* SHOULD if (!canShareStyleWithControl(element)) return false; # ContextMenuController::populate #* NOW if (!m_hitTestResult.isContentEditable() && (node->isElementNode() && static_cast<Element*>(node)->isFormControlElement())) #* SHOULD TBD # FormSubmission::create #* NOW: if (node && node->isElementNode() && toElement(node)->isFormControlElement()) #* SHOULD: if (node && node->isElementNode() && toElement(node)->isSubmittableElement()) # isClickableControl in HTMLSummaryElement #* NOW: if (element->isFormControlElement()) return true; #* SHOULDE: if (element->isClickable()) return true; # scanForForm in FrameSelection.cpp #* NOW: if (node->isHTMLElement() && toHTMLElement(node)->isFormControlElement()) return static_cast<HTMLFormControlElement*>(node)->form(); #* SHOULD: if (node->isHTMLElement() && toHTMLElement(node)->isFormAssociatedElement()) { // Note: static_cast to HTMLFormAssocaitedElement may not work. return static_cast<HTMLFormAssociatedElement*>(node)->form(); } # HTMLFormElement::submitImplicitly #* NOW: if (!formAssociatedElement->isFormControlElement()) continue; #* SHOULD: if (!formAssociatedElement->isSubmittableElement()) continue; # HTMLFormElement::validateInteractively #* NOW: if (m_associatedElements[i]->isFormControlElement()) static_cast<HTMLFormControlElement*>(m_associatedElements[i])->hideVisibleValidationMessage(); #* SHOULD: if (m_associatedElements[i]->canValidate()) # TextIterator::advance #* NOW: if (... static_cast<Element*>(renderer->node())->isFormControlElement()))) { // Why form control handled as replaced element? m_handledNode = handleReplacedElement(); } #* SHOULD: TBD # nodeAsLabelableFormControl in HTMLLabelElement.cpp #* NOW: if (... || !static_cast<Element*>(node)->isFormControlElement()) #* SHOULD: if (... !static_cast<Element*>(node)->isLabelable()) # AccessibilityRenderObject::isControl #* NOW: return node && ((node->isElementNode() && static_cast<Element*>(node)->isFormControlElement()) #* SHOULD: TBD # AccessibilityRenderObject::isRequired #* NOW: if (n && (n->isElementNode() && static_cast<Element*>(n)->isFormControlElement())) return static_cast<HTMLFormControlElement*>(n)->required(); #* SHOULD: if (n && (n->isElementNode() && static_cast<Element*>(n)->canValidate())) return static_cast<ValidatableElement*>(n)->required(); # toTextControlElement in WebKit/blackberry/WebKitSupport/DOMSupport.cpp #* NOW: if (!element->isFormControlElement()) return 0; HTMLFormControlElement* formElement = static_cast<HTMLFormControlElement*>(element); if (!formElement->isTextFormControl()) return 0; #* SHOULD: TBD # findPasswordFormFields in WebKit/chromium/src/WebPasswordFormUtils.cpp #* NOW: if (!formElements[i]->isFormControlElement()) continue; HTMLFormControlElement* formElement = static_cast<HTMLFormControlElement*>(formElements[i]); if (formElement->isActivatedSubmit()) fields->submit = formElement; #* SHOULD: TBD # WebElement::isFormControlElement #* NOW: return constUnwrap<Element>()->isFormControlElement(); #* SHOULD: This is OK. == References == [1] HTMLFormControlCollection http://www.whatwg.org/specs/web-apps/current-work/multipage/common-dom-interfaces.html#htmlformcontrolscollection-0 [2] Listed Element http://www.whatwg.org/specs/web-apps/current-work/multipage/forms.html#category-listed
<rdar://problem/72058636>
All dependent bugs are now fixed. Should we need to track this 2012 bug further? Thanks!