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