d8d02838a2da15bd028f69e4acd974b544ff666c
[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 "Attribute.h"
28 #include "CSSPropertyNames.h"
29 #include "Document.h"
30 #include "Event.h"
31 #include "EventNames.h"
32 #include "Frame.h"
33 #include "FrameLoader.h"
34 #include "FrameLoaderClient.h"
35 #include "HTMLNames.h"
36 #include "Length.h"
37 #include "MouseEvent.h"
38 #include "NodeRenderingContext.h"
39 #include "RenderFrameSet.h"
40 #include "ScriptEventListener.h"
41 #include "Text.h"
42
43 namespace WebCore {
44
45 using namespace HTMLNames;
46
47 HTMLFrameSetElement::HTMLFrameSetElement(const QualifiedName& tagName, Document* document)
48     : HTMLElement(tagName, document)
49     , m_totalRows(1)
50     , m_totalCols(1)
51     , m_border(6)
52     , m_borderSet(false)
53     , m_borderColorSet(false)
54     , m_frameborder(true)
55     , m_frameborderSet(false)
56     , m_noresize(false)
57 {
58     ASSERT(hasTagName(framesetTag));
59     setHasCustomStyleResolveCallbacks();
60 }
61
62 PassRefPtr<HTMLFrameSetElement> HTMLFrameSetElement::create(const QualifiedName& tagName, Document* document)
63 {
64     return adoptRef(new HTMLFrameSetElement(tagName, document));
65 }
66
67 bool HTMLFrameSetElement::isPresentationAttribute(const QualifiedName& name) const
68 {
69     if (name == bordercolorAttr)
70         return true;
71     return HTMLElement::isPresentationAttribute(name);
72 }
73
74 void HTMLFrameSetElement::collectStyleForPresentationAttribute(const QualifiedName& name, const AtomicString& value, MutableStylePropertySet* style)
75 {
76     if (name == bordercolorAttr)
77         addHTMLColorToStyle(style, CSSPropertyBorderColor, value);
78     else
79         HTMLElement::collectStyleForPresentationAttribute(name, value, style);
80 }
81
82 void HTMLFrameSetElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
83 {
84     if (name == rowsAttr) {
85         if (!value.isNull()) {
86             m_rowLengths = newLengthArray(value.string(), m_totalRows);
87             setNeedsStyleRecalc();
88         }
89     } else if (name == colsAttr) {
90         if (!value.isNull()) {
91             m_colLengths = newLengthArray(value.string(), m_totalCols);
92             setNeedsStyleRecalc();
93         }
94     } else if (name == frameborderAttr) {
95         if (!value.isNull()) {
96             if (equalIgnoringCase(value, "no") || equalIgnoringCase(value, "0")) {
97                 m_frameborder = false;
98                 m_frameborderSet = true;
99             } else if (equalIgnoringCase(value, "yes") || equalIgnoringCase(value, "1")) {
100                 m_frameborderSet = true;
101             }
102         } else {
103             m_frameborder = false;
104             m_frameborderSet = false;
105         }
106     } else if (name == noresizeAttr) {
107         m_noresize = true;
108     } else if (name == borderAttr) {
109         if (!value.isNull()) {
110             m_border = value.toInt();
111             m_borderSet = true;
112         } else
113             m_borderSet = false;
114     } else if (name == bordercolorAttr)
115         m_borderColorSet = !value.isEmpty();
116     else if (name == onloadAttr)
117         document()->setWindowAttributeEventListener(eventNames().loadEvent, createAttributeEventListener(document()->frame(), name, value));
118     else if (name == onbeforeunloadAttr)
119         document()->setWindowAttributeEventListener(eventNames().beforeunloadEvent, createAttributeEventListener(document()->frame(), name, value));
120     else if (name == onunloadAttr)
121         document()->setWindowAttributeEventListener(eventNames().unloadEvent, createAttributeEventListener(document()->frame(), name, value));
122     else if (name == onblurAttr)
123         document()->setWindowAttributeEventListener(eventNames().blurEvent, createAttributeEventListener(document()->frame(), name, value));
124     else if (name == onfocusAttr)
125         document()->setWindowAttributeEventListener(eventNames().focusEvent, createAttributeEventListener(document()->frame(), name, value));
126     else if (name == onfocusinAttr)
127         document()->setWindowAttributeEventListener(eventNames().focusinEvent, createAttributeEventListener(document()->frame(), name, value));
128     else if (name == onfocusoutAttr)
129         document()->setWindowAttributeEventListener(eventNames().focusoutEvent, createAttributeEventListener(document()->frame(), name, value));
130 #if ENABLE(ORIENTATION_EVENTS)
131     else if (name == onorientationchangeAttr)
132         document()->setWindowAttributeEventListener(eventNames().orientationchangeEvent, createAttributeEventListener(document()->frame(), name, value));
133 #endif
134     else if (name == onhashchangeAttr)
135         document()->setWindowAttributeEventListener(eventNames().hashchangeEvent, createAttributeEventListener(document()->frame(), name, value));
136     else if (name == onresizeAttr)
137         document()->setWindowAttributeEventListener(eventNames().resizeEvent, createAttributeEventListener(document()->frame(), name, value));
138     else if (name == onscrollAttr)
139         document()->setWindowAttributeEventListener(eventNames().scrollEvent, createAttributeEventListener(document()->frame(), name, value));
140     else if (name == onstorageAttr)
141         document()->setWindowAttributeEventListener(eventNames().storageEvent, createAttributeEventListener(document()->frame(), name, value));
142     else if (name == ononlineAttr)
143         document()->setWindowAttributeEventListener(eventNames().onlineEvent, createAttributeEventListener(document()->frame(), name, value));
144     else if (name == onofflineAttr)
145         document()->setWindowAttributeEventListener(eventNames().offlineEvent, createAttributeEventListener(document()->frame(), name, value));
146     else if (name == onpopstateAttr)
147         document()->setWindowAttributeEventListener(eventNames().popstateEvent, createAttributeEventListener(document()->frame(), name, value));
148     else
149         HTMLElement::parseAttribute(name, value);
150 }
151
152 bool HTMLFrameSetElement::rendererIsNeeded(const NodeRenderingContext& context)
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 context.style()->isStyleAvailable();
157 }
158
159 RenderObject *HTMLFrameSetElement::createRenderer(RenderArena *arena, RenderStyle *style)
160 {
161     if (style->hasContent())
162         return RenderObject::createObject(this, style);
163     
164     return new (arena) RenderFrameSet(this);
165 }
166
167 void HTMLFrameSetElement::willAttachRenderers()
168 {
169     // Inherit default settings from parent frameset
170     // FIXME: This is not dynamic.
171     for (ContainerNode* node = parentNode(); node; node = node->parentNode()) {
172         if (!node->hasTagName(framesetTag))
173             continue;
174         HTMLFrameSetElement* frameset = static_cast<HTMLFrameSetElement*>(node);
175         if (!m_frameborderSet)
176             m_frameborder = frameset->hasFrameBorder();
177         if (m_frameborder) {
178             if (!m_borderSet)
179                 m_border = frameset->border();
180             if (!m_borderColorSet)
181                 m_borderColorSet = frameset->hasBorderColor();
182         }
183         if (!m_noresize)
184             m_noresize = frameset->noResize();
185     }
186 }
187
188 void HTMLFrameSetElement::defaultEventHandler(Event* evt)
189 {
190     if (evt->isMouseEvent() && !m_noresize && renderer() && renderer()->isFrameSet()) {
191         if (toRenderFrameSet(renderer())->userResize(static_cast<MouseEvent*>(evt))) {
192             evt->setDefaultHandled();
193             return;
194         }
195     }
196     HTMLElement::defaultEventHandler(evt);
197 }
198
199 bool HTMLFrameSetElement::willRecalcStyle(Style::Change)
200 {
201     if (needsStyleRecalc() && renderer()) {
202         renderer()->setNeedsLayout(true);
203         clearNeedsStyleRecalc();
204     }
205     return true;
206 }
207
208 Node::InsertionNotificationRequest HTMLFrameSetElement::insertedInto(ContainerNode* insertionPoint)
209 {
210     HTMLElement::insertedInto(insertionPoint);
211     if (insertionPoint->inDocument()) {
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->inDocument()) {
223         if (Frame* frame = document()->frame())
224             frame->loader().client()->dispatchDidBecomeFrameset(document()->isFrameSet());
225     }
226 }
227
228 } // namespace WebCore