Unreviewed, rolling out r213633.
[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 "Frame.h"
32 #include "FrameLoader.h"
33 #include "FrameLoaderClient.h"
34 #include "HTMLBodyElement.h"
35 #include "HTMLNames.h"
36 #include "Length.h"
37 #include "MouseEvent.h"
38 #include "RenderFrameSet.h"
39 #include "Text.h"
40
41 namespace WebCore {
42
43 using namespace HTMLNames;
44
45 HTMLFrameSetElement::HTMLFrameSetElement(const QualifiedName& tagName, Document& document)
46     : HTMLElement(tagName, document)
47     , m_totalRows(1)
48     , m_totalCols(1)
49     , m_border(6)
50     , m_borderSet(false)
51     , m_borderColorSet(false)
52     , m_frameborder(true)
53     , m_frameborderSet(false)
54     , m_noresize(false)
55 {
56     ASSERT(hasTagName(framesetTag));
57     setHasCustomStyleResolveCallbacks();
58 }
59
60 Ref<HTMLFrameSetElement> HTMLFrameSetElement::create(const QualifiedName& tagName, Document& document)
61 {
62     return adoptRef(*new HTMLFrameSetElement(tagName, document));
63 }
64
65 bool HTMLFrameSetElement::isPresentationAttribute(const QualifiedName& name) const
66 {
67     if (name == bordercolorAttr)
68         return true;
69     return HTMLElement::isPresentationAttribute(name);
70 }
71
72 void HTMLFrameSetElement::collectStyleForPresentationAttribute(const QualifiedName& name, const AtomicString& value, MutableStyleProperties& style)
73 {
74     if (name == bordercolorAttr)
75         addHTMLColorToStyle(style, CSSPropertyBorderColor, value);
76     else
77         HTMLElement::collectStyleForPresentationAttribute(name, value, style);
78 }
79
80 void HTMLFrameSetElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
81 {
82     if (name == rowsAttr) {
83         // FIXME: What is the right thing to do when removing this attribute?
84         // Why not treat it the same way we treat setting it to the empty string?
85         if (!value.isNull()) {
86             m_rowLengths = newLengthArray(value.string(), m_totalRows);
87             // FIXME: Would be nice to optimize the case where m_rowLengths did not change.
88             invalidateStyleForSubtree();
89         }
90         return;
91     }
92
93     if (name == colsAttr) {
94         // FIXME: What is the right thing to do when removing this attribute?
95         // Why not treat it the same way we treat setting it to the empty string?
96         if (!value.isNull()) {
97             m_colLengths = newLengthArray(value.string(), m_totalCols);
98             // FIXME: Would be nice to optimize the case where m_colLengths did not change.
99             invalidateStyleForSubtree();
100         }
101         return;
102     }
103
104     if (name == frameborderAttr) {
105         if (!value.isNull()) {
106             if (equalLettersIgnoringASCIICase(value, "no") || value == "0") {
107                 m_frameborder = false;
108                 m_frameborderSet = true;
109             } else if (equalLettersIgnoringASCIICase(value, "yes") || value == "1") {
110                 m_frameborderSet = true;
111             }
112         } else {
113             m_frameborder = false;
114             m_frameborderSet = false;
115         }
116         // FIXME: Do we need to trigger repainting?
117         return;
118     }
119
120     if (name == noresizeAttr) {
121         // FIXME: This should set m_noresize to false if the value is null.
122         m_noresize = true;
123         return;
124     }
125
126     if (name == borderAttr) {
127         if (!value.isNull()) {
128             m_border = value.toInt();
129             m_borderSet = true;
130         } else
131             m_borderSet = false;
132         // FIXME: Do we need to trigger repainting?
133         return;
134     }
135
136     if (name == bordercolorAttr) {
137         m_borderColorSet = !value.isEmpty();
138         // FIXME: Clearly wrong: This can overwrite the value inherited from the parent frameset.
139         // FIXME: Do we need to trigger repainting?
140         return;
141     }
142
143     auto& eventName = HTMLBodyElement::eventNameForWindowEventHandlerAttribute(name);
144     if (!eventName.isNull()) {
145         document().setWindowAttributeEventListener(eventName, name, value);
146         return;
147     }
148
149     HTMLElement::parseAttribute(name, value);
150 }
151
152 bool HTMLFrameSetElement::rendererIsNeeded(const RenderStyle& style)
153 {
154     // For compatibility, frames render even when display: none is set.
155     // However, we delay creating a renderer until stylesheets have loaded. 
156     return !style.isPlaceholderStyle();
157 }
158
159 RenderPtr<RenderElement> HTMLFrameSetElement::createElementRenderer(RenderStyle&& style, const RenderTreePosition&)
160 {
161     if (style.hasContent())
162         return RenderElement::createFor(*this, WTFMove(style));
163     
164     return createRenderer<RenderFrameSet>(*this, WTFMove(style));
165 }
166
167 HTMLFrameSetElement* HTMLFrameSetElement::findContaining(Element* descendant)
168 {
169     return ancestorsOfType<HTMLFrameSetElement>(*descendant).first();
170 }
171
172 void HTMLFrameSetElement::willAttachRenderers()
173 {
174     // Inherit default settings from parent frameset.
175     // FIXME: This is not dynamic.
176     const HTMLFrameSetElement* containingFrameSet = findContaining(this);
177     if (!containingFrameSet)
178         return;
179     if (!m_frameborderSet)
180         m_frameborder = containingFrameSet->hasFrameBorder();
181     if (m_frameborder) {
182         if (!m_borderSet)
183             m_border = containingFrameSet->border();
184         if (!m_borderColorSet)
185             m_borderColorSet = containingFrameSet->hasBorderColor();
186     }
187     if (!m_noresize)
188         m_noresize = containingFrameSet->noResize();
189 }
190
191 void HTMLFrameSetElement::defaultEventHandler(Event& event)
192 {
193     if (is<MouseEvent>(event) && !m_noresize && is<RenderFrameSet>(renderer())) {
194         if (downcast<RenderFrameSet>(*renderer()).userResize(downcast<MouseEvent>(event))) {
195             event.setDefaultHandled();
196             return;
197         }
198     }
199     HTMLElement::defaultEventHandler(event);
200 }
201
202 void HTMLFrameSetElement::willRecalcStyle(Style::Change)
203 {
204     if (needsStyleRecalc() && renderer())
205         renderer()->setNeedsLayout();
206 }
207
208 Node::InsertionNotificationRequest HTMLFrameSetElement::insertedInto(ContainerNode& insertionPoint)
209 {
210     HTMLElement::insertedInto(insertionPoint);
211     if (insertionPoint.isConnected()) {
212         if (Frame* frame = document().frame())
213             frame->loader().client().dispatchDidBecomeFrameset(document().isFrameSet());
214     }
215
216     return InsertionDone;
217 }
218
219 void HTMLFrameSetElement::removedFrom(ContainerNode& insertionPoint)
220 {
221     HTMLElement::removedFrom(insertionPoint);
222     if (insertionPoint.isConnected()) {
223         if (Frame* frame = document().frame())
224             frame->loader().client().dispatchDidBecomeFrameset(document().isFrameSet());
225     }
226 }
227
228 } // namespace WebCore