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