Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / third_party / WebKit / Source / core / html / HTMLSummaryElement.cpp
blobb517bbc5f33fbd278868c7876c0cd411815bf69f
1 /*
2 * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies)
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public License
15 * along with this library; see the file COPYING.LIB. If not, write to
16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
21 #include "config.h"
22 #include "core/html/HTMLSummaryElement.h"
24 #include "bindings/core/v8/ExceptionStatePlaceholder.h"
25 #include "core/HTMLNames.h"
26 #include "core/dom/shadow/ComposedTreeTraversal.h"
27 #include "core/dom/shadow/ShadowRoot.h"
28 #include "core/events/KeyboardEvent.h"
29 #include "core/html/HTMLContentElement.h"
30 #include "core/html/HTMLDetailsElement.h"
31 #include "core/html/shadow/DetailsMarkerControl.h"
32 #include "core/html/shadow/ShadowElementNames.h"
33 #include "core/layout/LayoutBlockFlow.h"
35 namespace blink {
37 using namespace HTMLNames;
39 PassRefPtrWillBeRawPtr<HTMLSummaryElement> HTMLSummaryElement::create(Document& document)
41 RefPtrWillBeRawPtr<HTMLSummaryElement> summary = adoptRefWillBeNoop(new HTMLSummaryElement(document));
42 summary->ensureUserAgentShadowRoot();
43 return summary.release();
46 HTMLSummaryElement::HTMLSummaryElement(Document& document)
47 : HTMLElement(summaryTag, document)
51 LayoutObject* HTMLSummaryElement::createLayoutObject(const ComputedStyle&)
53 return new LayoutBlockFlow(this);
56 void HTMLSummaryElement::didAddUserAgentShadowRoot(ShadowRoot& root)
58 RefPtrWillBeRawPtr<DetailsMarkerControl> markerControl = DetailsMarkerControl::create(document());
59 markerControl->setIdAttribute(ShadowElementNames::detailsMarker());
60 root.appendChild(markerControl);
61 root.appendChild(HTMLContentElement::create(document()));
64 HTMLDetailsElement* HTMLSummaryElement::detailsElement() const
66 Node* parent = parentNode();
67 if (isHTMLDetailsElement(parent))
68 return toHTMLDetailsElement(parent);
69 Element* host = shadowHost();
70 if (isHTMLDetailsElement(host))
71 return toHTMLDetailsElement(host);
72 return nullptr;
75 Element* HTMLSummaryElement::markerControl()
77 return ensureUserAgentShadowRoot().getElementById(ShadowElementNames::detailsMarker());
80 bool HTMLSummaryElement::isMainSummary() const
82 if (HTMLDetailsElement* details = detailsElement())
83 return details->findMainSummary() == this;
85 return false;
88 static bool isClickableControl(Node* node)
90 if (!node->isElementNode())
91 return false;
92 Element* element = toElement(node);
93 if (element->isFormControlElement())
94 return true;
95 Element* host = element->shadowHost();
96 return host && host->isFormControlElement();
99 bool HTMLSummaryElement::supportsFocus() const
101 return isMainSummary();
104 void HTMLSummaryElement::defaultEventHandler(Event* event)
106 if (isMainSummary() && layoutObject()) {
107 if (event->type() == EventTypeNames::DOMActivate && !isClickableControl(event->target()->toNode())) {
108 if (HTMLDetailsElement* details = detailsElement())
109 details->toggleOpen();
110 event->setDefaultHandled();
111 return;
114 if (event->isKeyboardEvent()) {
115 if (event->type() == EventTypeNames::keydown && toKeyboardEvent(event)->keyIdentifier() == "U+0020") {
116 setActive(true);
117 // No setDefaultHandled() - IE dispatches a keypress in this case.
118 return;
120 if (event->type() == EventTypeNames::keypress) {
121 switch (toKeyboardEvent(event)->charCode()) {
122 case '\r':
123 dispatchSimulatedClick(event);
124 event->setDefaultHandled();
125 return;
126 case ' ':
127 // Prevent scrolling down the page.
128 event->setDefaultHandled();
129 return;
132 if (event->type() == EventTypeNames::keyup && toKeyboardEvent(event)->keyIdentifier() == "U+0020") {
133 if (active())
134 dispatchSimulatedClick(event);
135 event->setDefaultHandled();
136 return;
141 HTMLElement::defaultEventHandler(event);
144 bool HTMLSummaryElement::willRespondToMouseClickEvents()
146 if (isMainSummary() && layoutObject())
147 return true;
149 return HTMLElement::willRespondToMouseClickEvents();