15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/*
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *           (C) 1999 Antti Koivisto (koivisto@kde.org)
45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *           (C) 2001 Dirk Mueller (mueller@kde.org)
55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2004, 2005, 2006, 2007, 2010 Apple Inc. All rights reserved.
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *           (C) 2006 Alexey Proskuryakov (ap@nypop.com)
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is free software; you can redistribute it and/or
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modify it under the terms of the GNU Library General Public
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * License as published by the Free Software Foundation; either
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * version 2 of the License, or (at your option) any later version.
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is distributed in the hope that it will be useful,
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * but WITHOUT ANY WARRANTY; without even the implied warranty of
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Library General Public License for more details.
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * You should have received a copy of the GNU Library General Public License
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * along with this library; see the file COPYING.LIB.  If not, write to
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Boston, MA 02110-1301, USA.
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */
245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h"
2653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/html/HTMLLabelElement.h"
275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
285d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#include "core/HTMLNames.h"
2976c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)#include "core/dom/Document.h"
30e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)#include "core/dom/ElementTraversal.h"
31323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)#include "core/editing/FrameSelection.h"
32d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)#include "core/events/MouseEvent.h"
33323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)#include "core/frame/LocalFrame.h"
3453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/html/FormAssociatedElement.h"
357242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "core/page/EventHandler.h"
365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
37c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink {
385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)using namespace HTMLNames;
405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
417242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucciinline HTMLLabelElement::HTMLLabelElement(Document& document, HTMLFormElement* form)
4251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    : HTMLElement(labelTag, document)
435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
447242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    FormAssociatedElement::associateByParser(form);
455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
477242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano TucciPassRefPtrWillBeRawPtr<HTMLLabelElement> HTMLLabelElement::create(Document& document, HTMLFormElement* form)
487242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{
497242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    RefPtrWillBeRawPtr<HTMLLabelElement> labelElement = adoptRefWillBeNoop(new HTMLLabelElement(document, form));
507242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    return labelElement.release();
517242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci}
525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
53521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)bool HTMLLabelElement::rendererIsFocusable() const
545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
5581a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    HTMLLabelElement* that = const_cast<HTMLLabelElement*>(this);
5681a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    return that->isContentEditable();
575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)LabelableElement* HTMLLabelElement::control() const
605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const AtomicString& controlId = getAttribute(forAttr);
625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (controlId.isNull()) {
635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Search the children and descendants of the label element for a form element.
645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // per http://dev.w3.org/html5/spec/Overview.html#the-label-element
655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // the form element must be "labelable form-associated element".
66c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        for (LabelableElement* element = Traversal<LabelableElement>::next(*this, this); element; element = Traversal<LabelableElement>::next(*element, this)) {
67c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            if (element->supportLabels())
68c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)                return element;
695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
72591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch
738abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    if (Element* element = treeScope().getElementById(controlId)) {
74c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        if (isLabelableElement(*element) && toLabelableElement(*element).supportLabels())
75591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch            return toLabelableElement(element);
76591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    }
77591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch
78591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    return 0;
795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)HTMLFormElement* HTMLLabelElement::formOwner() const
825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
837242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    return FormAssociatedElement::form();
845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)void HTMLLabelElement::setActive(bool down)
875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (down == active())
895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Update our status first.
9251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    HTMLElement::setActive(down);
935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Also update our corresponding control.
955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (HTMLElement* element = control())
9651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        element->setActive(down);
975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void HTMLLabelElement::setHovered(bool over)
1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (over == hovered())
1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
10302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Update our status first.
1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    HTMLElement::setHovered(over);
1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Also update our corresponding control.
1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (HTMLElement* element = control())
1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        element->setHovered(over);
1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
112bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)bool HTMLLabelElement::isInteractiveContent() const
113bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles){
114bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    return true;
115bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)}
116bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)
117bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)bool HTMLLabelElement::isInInteractiveContent(Node* node) const
118bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles){
119bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    if (!containsIncludingShadowDOM(node))
120bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        return false;
121bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    while (node && this != node) {
122bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        if (node->isHTMLElement() && toHTMLElement(node)->isInteractiveContent())
123bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)            return true;
124bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        node = node->parentOrShadowHostNode();
125bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    }
126bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    return false;
127bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)}
128bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)
1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void HTMLLabelElement::defaultEventHandler(Event* evt)
1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    static bool processingClick = false;
1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1331e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    if (evt->type() == EventTypeNames::click && !processingClick) {
134323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        RefPtrWillBeRawPtr<HTMLElement> element = control();
1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // If we can't find a control or if the control received the click
1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // event, then there's no need for us to do anything.
1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!element || (evt->target() && element->containsIncludingShadowDOM(evt->target()->toNode())))
1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return;
1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
141bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        if (evt->target() && isInInteractiveContent(evt->target()->toNode()))
142bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)            return;
143bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)
1447242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        //   Behaviour of label element is as follows:
1457242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        //     - If there is double click, two clicks will be passed to control
1467242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        //       element. Control element will *not* be focused.
1477242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        //     - If there is selection of label element by dragging, no click
1487242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        //       event is passed. Also, no focus on control element.
1497242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        //     - If there is already a selection on label element and then label
1507242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        //       is clicked, then click event is passed to control element and
1517242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        //       control element is focused.
1527242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
1537242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        bool isLabelTextSelected = false;
1547242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
1557242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        // If the click is not simulated and the text of the label element
1567242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        // is selected by dragging over it, then return without passing the
1577242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        // click event to control element.
1587242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        // Note: a click event may be not a mouse event if created by
1597242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        // document.createEvent().
1607242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        if (evt->isMouseEvent() && !toMouseEvent(evt)->isSimulated()) {
1617242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            if (LocalFrame* frame = document().frame()) {
1627242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci                // Check if there is a selection and click is not on the
1637242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci                // selection.
1647242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci                if (frame->selection().isRange() && !frame->eventHandler().mouseDownWasSingleClickInSelection())
1657242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci                    isLabelTextSelected = true;
1667242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci                // If selection is there and is single click i.e. text is
1677242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci                // selected by dragging over label text, then return.
1687242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci                // Click count >=2, meaning double click or triple click,
1697242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci                // should pass click event to control element.
1707242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci                // Only in case of drag, *neither* we pass the click event,
1717242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci                // *nor* we focus the control element.
1727242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci                if (isLabelTextSelected && frame->eventHandler().clickCount() == 1)
1737242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci                    return;
1747242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            }
1757242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        }
1767242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        processingClick = true;
1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1798abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)        document().updateLayoutIgnorePendingStylesheets();
1807242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        if (element->isMouseFocusable()) {
1817242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            // If the label is *not* selected, or if the click happened on
1827242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            // selection of label, only then focus the control element.
1837242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            // In case of double click or triple click, selection will be there,
1847242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            // so do not focus the control element.
1857242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            if (!isLabelTextSelected)
1867242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci                element->focus(true, FocusTypeMouse);
1877242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        }
188f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)
189f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)        // Click the corresponding control.
190f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)        element->dispatchSimulatedClick(evt);
1915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        processingClick = false;
19302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        evt->setDefaultHandled();
1955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
19602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
1975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    HTMLElement::defaultEventHandler(evt);
1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool HTMLLabelElement::willRespondToMouseClickEvents()
2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (control() && control()->willRespondToMouseClickEvents())
2035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return true;
2045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return HTMLElement::willRespondToMouseClickEvents();
2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
20809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)void HTMLLabelElement::focus(bool, FocusType type)
2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // to match other browsers, always restore previous selection
2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (HTMLElement* element = control())
21209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        element->focus(true, type);
2135267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    if (isFocusable())
21409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        HTMLElement::focus(true, type);
2155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void HTMLLabelElement::accessKeyAction(bool sendMouseEvents)
2185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (HTMLElement* element = control())
2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        element->accessKeyAction(sendMouseEvents);
2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    else
2225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        HTMLElement::accessKeyAction(sendMouseEvents);
2235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
225c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)void HTMLLabelElement::updateLabel(TreeScope& scope, const AtomicString& oldForAttributeValue, const AtomicString& newForAttributeValue)
226c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles){
227c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (!inDocument())
228c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        return;
229c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
230c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (oldForAttributeValue == newForAttributeValue)
231c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        return;
232c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
233c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (!oldForAttributeValue.isEmpty())
2347242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        scope.removeLabel(oldForAttributeValue, this);
235c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (!newForAttributeValue.isEmpty())
2367242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        scope.addLabel(newForAttributeValue, this);
237c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)}
238c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
239c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)void HTMLLabelElement::attributeWillChange(const QualifiedName& name, const AtomicString& oldValue, const AtomicString& newValue)
240c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles){
241c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (name == HTMLNames::forAttr) {
242c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        TreeScope& scope = treeScope();
243c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        if (scope.shouldCacheLabelsByForAttribute())
244c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            updateLabel(scope, oldValue, newValue);
245c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    }
246c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    HTMLElement::attributeWillChange(name, oldValue, newValue);
247c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)}
248c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
249c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)Node::InsertionNotificationRequest HTMLLabelElement::insertedInto(ContainerNode* insertionPoint)
250c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles){
251c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    InsertionNotificationRequest result = HTMLElement::insertedInto(insertionPoint);
2527242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    FormAssociatedElement::insertedInto(insertionPoint);
253c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (insertionPoint->isInTreeScope()) {
254c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        TreeScope& scope = insertionPoint->treeScope();
255c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        if (scope == treeScope() && scope.shouldCacheLabelsByForAttribute())
256c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            updateLabel(scope, nullAtom, fastGetAttribute(forAttr));
257c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    }
258c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    return result;
259c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)}
260c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
261c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)void HTMLLabelElement::removedFrom(ContainerNode* insertionPoint)
262c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles){
263c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (insertionPoint->isInTreeScope() && treeScope() == document()) {
264c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        TreeScope& treeScope = insertionPoint->treeScope();
265c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        if (treeScope.shouldCacheLabelsByForAttribute())
266c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            updateLabel(treeScope, fastGetAttribute(forAttr), nullAtom);
267c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    }
268c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    HTMLElement::removedFrom(insertionPoint);
2697242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    FormAssociatedElement::removedFrom(insertionPoint);
2707242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci}
2717242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
2727242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccivoid HTMLLabelElement::trace(Visitor* visitor)
2737242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{
2747242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    HTMLElement::trace(visitor);
2757242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    FormAssociatedElement::trace(visitor);
2767242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci}
2777242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
2787242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccivoid HTMLLabelElement::parseAttribute(const QualifiedName& attributeName, const AtomicString& attributeValue)
2797242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{
2807242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    if (attributeName == formAttr)
2817242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        formAttributeChanged();
2827242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    else
2837242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        HTMLElement::parseAttribute(attributeName, attributeValue);
284c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)}
285c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
2865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} // namespace
287