DOM event handling should pass Event around by reference.
[WebKit-https.git] / Source / WebCore / html / HTMLFrameSetElement.cpp
1 /*
2  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
4  *           (C) 2000 Simon Hausmann (hausmann@kde.org)
5  *           (C) 2001 Dirk Mueller (mueller@kde.org)
6  * Copyright (C) 2004, 2006, 2009, 2010 Apple Inc. All rights reserved.
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public License
19  * along with this library; see the file COPYING.LIB.  If not, write to
20  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21  * Boston, MA 02110-1301, USA.
22  */
23
24 #include "config.h"
25 #include "HTMLFrameSetElement.h"
26
27 #include "CSSPropertyNames.h"
28 #include "Document.h"
29 #include "ElementIterator.h"
30 #include "Event.h"
31 #include "EventNames.h"
32 #include "Frame.h"
33 #include "FrameLoader.h"
34 #include "FrameLoaderClient.h"
35 #include "HTMLBodyElement.h"
36 #include "HTMLNames.h"
37 #include "Length.h"
38 #include "MouseEvent.h"
39 #include "RenderFrameSet.h"
40 #include "Text.h"
41
42 namespace WebCore {
43
44 using namespace HTMLNames;
45
46 HTMLFrameSetElement::HTMLFrameSetElement(const QualifiedName& tagName, Document& document)
47     : HTMLElement(tagName, document)
48     , m_totalRows(1)
49     , m_totalCols(1)
50     , m_border(6)
51     , m_borderSet(false)
52     , m_borderColorSet(false)
53     , m_frameborder(true)
54     , m_frameborderSet(false)
55     , m_noresize(false)
56 {
57     ASSERT(hasTagName(framesetTag));
58     setHasCustomStyleResolveCallbacks();
59 }
60
61 Ref<HTMLFrameSetElement> HTMLFrameSetElement::create(const QualifiedName& tagName, Document& document)
62 {
63     return adoptRef(*new HTMLFrameSetElement(tagName, document));
64 }
65
66 bool HTMLFrameSetElement::isPresentationAttribute(const QualifiedName& name) const
67 {
68     if (name == bordercolorAttr)
69         return true;
70     return HTMLElement::isPresentationAttribute(name);
71 }
72
73 void HTMLFrameSetElement::collectStyleForPresentationAttribute(const QualifiedName& name, const AtomicString& value, MutableStyleProperties& style)
74 {
75     if (name == bordercolorAttr)
76         addHTMLColorToStyle(style, CSSPropertyBorderColor, value);
77     else
78         HTMLElement::collectStyleForPresentationAttribute(name, value, style);
79 }
80
81 void HTMLFrameSetElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
82 {
83     if (name == rowsAttr) {
84         // FIXME: What is the right thing to do when removing this attribute?
85         // Why not treat it the same way we treat setting it to the empty string?
86         if (!value.isNull()) {
87             m_rowLengths = newLengthArray(value.string(), m_totalRows);
88             // FIXME: Would be nice to optimize the case where m_rowLengths did not change.
89             setNeedsStyleRecalc();
90         }
91         return;
92     }
93
94     if (name == colsAttr) {
95         // FIXME: What is the right thing to do when removing this attribute?
96         // Why not treat it the same way we treat setting it to the empty string?
97         if (!value.isNull()) {
98             m_colLengths = newLengthArray(value.string(), m_totalCols);
99             // FIXME: Would be nice to optimize the case where m_colLengths did not change.
100             setNeedsStyleRecalc();
101         }
102         return;
103     }
104
105     if (name == frameborderAttr) {
106         if (!value.isNull()) {
107             if (equalLettersIgnoringASCIICase(value, "no") || value == "0") {
108                 m_frameborder = false;
109                 m_frameborderSet = true;
110             } else if (equalLettersIgnoringASCIICase(value, "yes") || value == "1") {
111                 m_frameborderSet = true;
112             }
113         } else {
114             m_frameborder = false;
115             m_frameborderSet = false;
116         }
117         // FIXME: Do we need to trigger repainting?
118         return;
119     }
120
121     if (name == noresizeAttr) {
122         // FIXME: This should set m_noresize to false if the value is null.
123         m_noresize = true;
124         return;
125     }
126
127     if (name == borderAttr) {
128         if (!value.isNull()) {
129             m_border = value.toInt();
130             m_borderSet = true;
131         } else
132             m_borderSet = false;
133         // FIXME: Do we need to trigger repainting?
134         return;
135     }
136
137     if (name == bordercolorAttr) {
138         m_borderColorSet = !value.isEmpty();
139         // FIXME: Clearly wrong: This can overwrite the value inherited from the parent frameset.
140         // FIXME: Do we need to trigger repainting?
141         return;
142     }
143
144     auto& eventName = HTMLBodyElement::eventNameForWindowEventHandlerAttribute(name);
145     if (!eventName.isNull()) {
146         document().setWindowAttributeEventListener(eventName, name, value);
147         return;
148     }
149
150     HTMLElement::parseAttribute(name, value);
151 }
152
153 bool HTMLFrameSetElement::rendererIsNeeded(const RenderStyle& style)
154 {
155     // For compatibility, frames render even when display: none is set.
156     // However, we delay creating a renderer until stylesheets have loaded. 
157     return !style.isPlaceholderStyle();
158 }
159
160 RenderPtr<RenderElement> HTMLFrameSetElement::createElementRenderer(RenderStyle&& style, const RenderTreePosition&)
161 {
162     if (style.hasContent())
163         return RenderElement::createFor(*this, WTFMove(style));
164     
165     return createRenderer<RenderFrameSet>(*this, WTFMove(style));
166 }
167
168 HTMLFrameSetElement* HTMLFrameSetElement::findContaining(Element* descendant)
169 {
170     return ancestorsOfType<HTMLFrameSetElement>(*descendant).first();
171 }
172
173 void HTMLFrameSetElement::willAttachRenderers()
174 {
175     // Inherit default settings from parent frameset.
176     // FIXME: This is not dynamic.
177     const HTMLFrameSetElement* containingFrameSet = findContaining(this);
178     if (!containingFrameSet)
179         return;
180     if (!m_frameborderSet)
181         m_frameborder = containingFrameSet->hasFrameBorder();
182     if (m_frameborder) {
183         if (!m_borderSet)
184             m_border = containingFrameSet->border();
185         if (!m_borderColorSet)
186             m_borderColorSet = containingFrameSet->hasBorderColor();
187     }
188     if (!m_noresize)
189         m_noresize = containingFrameSet->noResize();
190 }
191
192 void HTMLFrameSetElement::defaultEventHandler(Event& event)
193 {
194     if (is<MouseEvent>(event) && !m_noresize && is<RenderFrameSet>(renderer())) {
195         if (downcast<RenderFrameSet>(*renderer()).userResize(downcast<MouseEvent>(event))) {
196             event.setDefaultHandled();
197             return;
198         }
199     }
200     HTMLElement::defaultEventHandler(event);
201 }
202
203 bool HTMLFrameSetElement::willRecalcStyle(Style::Change)
204 {
205     if (needsStyleRecalc() && renderer()) {
206         renderer()->setNeedsLayout();
207         clearNeedsStyleRecalc();
208     }
209     return true;
210 }
211
212 Node::InsertionNotificationRequest HTMLFrameSetElement::insertedInto(ContainerNode& insertionPoint)
213 {
214     HTMLElement::insertedInto(insertionPoint);
215     if (insertionPoint.inDocument()) {
216         if (Frame* frame = document().frame())
217             frame->loader().client().dispatchDidBecomeFrameset(document().isFrameSet());
218     }
219
220     return InsertionDone;
221 }
222
223 void HTMLFrameSetElement::removedFrom(ContainerNode& insertionPoint)
224 {
225     HTMLElement::removedFrom(insertionPoint);
226     if (insertionPoint.inDocument()) {
227         if (Frame* frame = document().frame())
228             frame->loader().client().dispatchDidBecomeFrameset(document().isFrameSet());
229     }
230 }
231
232 } // namespace WebCore