initial import
[vuplus_webkit] / 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 "FrameLoaderClient.h"
34 #include "HTMLNames.h"
35 #include "Length.h"
36 #include "MouseEvent.h"
37 #include "NodeRenderingContext.h"
38 #include "RenderFrameSet.h"
39 #include "ScriptEventListener.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     
59     setHasCustomWillOrDidRecalcStyle();
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::mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const
68 {
69     if (attrName == bordercolorAttr) {
70         result = eUniversal;
71         return true;
72     }
73
74     return HTMLElement::mapToEntry(attrName, result);
75 }
76
77 void HTMLFrameSetElement::parseMappedAttribute(Attribute* attr)
78 {
79     if (attr->name() == rowsAttr) {
80         if (!attr->isNull()) {
81             m_rowLengths = newLengthArray(attr->value().string(), m_totalRows);
82             setNeedsStyleRecalc();
83         }
84     } else if (attr->name() == colsAttr) {
85         if (!attr->isNull()) {
86             m_colLengths = newLengthArray(attr->value().string(), m_totalCols);
87             setNeedsStyleRecalc();
88         }
89     } else if (attr->name() == frameborderAttr) {
90         if (!attr->isNull()) {
91             // false or "no" or "0"..
92             if (attr->value().toInt() == 0) {
93                 m_frameborder = false;
94                 m_border = 0;
95             }
96             m_frameborderSet = true;
97         } else {
98             m_frameborder = false;
99             m_frameborderSet = false;
100         }
101     } else if (attr->name() == noresizeAttr) {
102         m_noresize = true;
103     } else if (attr->name() == borderAttr) {
104         if (!attr->isNull()) {
105             m_border = attr->value().toInt();
106             if (!m_border)
107                 m_frameborder = false;
108             m_borderSet = true;
109         } else
110             m_borderSet = false;
111     } else if (attr->name() == bordercolorAttr) {
112         m_borderColorSet = attr->decl();
113         if (!attr->decl() && !attr->isEmpty()) {
114             addCSSColor(attr, CSSPropertyBorderColor, attr->value());
115             m_borderColorSet = true;
116         }
117     } else if (attr->name() == onloadAttr)
118         document()->setWindowAttributeEventListener(eventNames().loadEvent, createAttributeEventListener(document()->frame(), attr));
119     else if (attr->name() == onbeforeunloadAttr)
120         document()->setWindowAttributeEventListener(eventNames().beforeunloadEvent, createAttributeEventListener(document()->frame(), attr));
121     else if (attr->name() == onunloadAttr)
122         document()->setWindowAttributeEventListener(eventNames().unloadEvent, createAttributeEventListener(document()->frame(), attr));
123     else if (attr->name() == onblurAttr)
124         document()->setWindowAttributeEventListener(eventNames().blurEvent, createAttributeEventListener(document()->frame(), attr));
125     else if (attr->name() == onfocusAttr)
126         document()->setWindowAttributeEventListener(eventNames().focusEvent, createAttributeEventListener(document()->frame(), attr));
127     else if (attr->name() == onfocusinAttr)
128         document()->setWindowAttributeEventListener(eventNames().focusinEvent, createAttributeEventListener(document()->frame(), attr));
129     else if (attr->name() == onfocusoutAttr)
130         document()->setWindowAttributeEventListener(eventNames().focusoutEvent, createAttributeEventListener(document()->frame(), attr));
131 #if ENABLE(ORIENTATION_EVENTS)
132     else if (attr->name() == onorientationchangeAttr)
133         document()->setWindowAttributeEventListener(eventNames().orientationchangeEvent, createAttributeEventListener(document()->frame(), attr));
134 #endif
135     else if (attr->name() == onhashchangeAttr)
136         document()->setWindowAttributeEventListener(eventNames().hashchangeEvent, createAttributeEventListener(document()->frame(), attr));
137     else if (attr->name() == onresizeAttr)
138         document()->setWindowAttributeEventListener(eventNames().resizeEvent, createAttributeEventListener(document()->frame(), attr));
139     else if (attr->name() == onscrollAttr)
140         document()->setWindowAttributeEventListener(eventNames().scrollEvent, createAttributeEventListener(document()->frame(), attr));
141     else if (attr->name() == onstorageAttr)
142         document()->setWindowAttributeEventListener(eventNames().storageEvent, createAttributeEventListener(document()->frame(), attr));
143     else if (attr->name() == ononlineAttr)
144         document()->setWindowAttributeEventListener(eventNames().onlineEvent, createAttributeEventListener(document()->frame(), attr));
145     else if (attr->name() == onofflineAttr)
146         document()->setWindowAttributeEventListener(eventNames().offlineEvent, createAttributeEventListener(document()->frame(), attr));
147     else if (attr->name() == onpopstateAttr)
148         document()->setWindowAttributeEventListener(eventNames().popstateEvent, createAttributeEventListener(document()->frame(), attr));
149     else
150         HTMLElement::parseMappedAttribute(attr);
151 }
152
153 bool HTMLFrameSetElement::rendererIsNeeded(const NodeRenderingContext& context)
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 context.style()->isStyleAvailable();
158 }
159
160 RenderObject *HTMLFrameSetElement::createRenderer(RenderArena *arena, RenderStyle *style)
161 {
162     if (style->hasContent())
163         return RenderObject::createObject(this, style);
164     
165     return new (arena) RenderFrameSet(this);
166 }
167
168 void HTMLFrameSetElement::attach()
169 {
170     // Inherit default settings from parent frameset
171     // FIXME: This is not dynamic.
172     for (ContainerNode* node = parentNode(); node; node = node->parentNode()) {
173         if (node->hasTagName(framesetTag)) {
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             break;
186         }
187     }
188
189     HTMLElement::attach();
190 }
191
192 void HTMLFrameSetElement::defaultEventHandler(Event* evt)
193 {
194     if (evt->isMouseEvent() && !m_noresize && renderer() && renderer()->isFrameSet()) {
195         if (toRenderFrameSet(renderer())->userResize(static_cast<MouseEvent*>(evt))) {
196             evt->setDefaultHandled();
197             return;
198         }
199     }
200     HTMLElement::defaultEventHandler(evt);
201 }
202
203 bool HTMLFrameSetElement::willRecalcStyle(StyleChange)
204 {
205     if (needsStyleRecalc() && renderer()) {
206         renderer()->setNeedsLayout(true);
207         clearNeedsStyleRecalc();
208     }
209     return true;
210 }
211
212 void HTMLFrameSetElement::insertedIntoDocument()
213 {
214     HTMLElement::insertedIntoDocument();
215     if (Frame* frame = document()->frame())
216         frame->loader()->client()->dispatchDidBecomeFrameset(document()->isFrameSet());
217 }
218
219 void HTMLFrameSetElement::removedFromDocument()
220 {
221     HTMLElement::removedFromDocument();
222     if (Frame* frame = document()->frame())
223         frame->loader()->client()->dispatchDidBecomeFrameset(document()->isFrameSet());
224 }
225
226 } // namespace WebCore