• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 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 "Event.h"
30 #include "EventNames.h"
31 #include "HTMLNames.h"
32 #include "ScriptEventListener.h"
33 #include "Length.h"
34 #include "MappedAttribute.h"
35 #include "MouseEvent.h"
36 #include "RenderFrameSet.h"
37 #include "Text.h"
38 
39 namespace WebCore {
40 
41 using namespace HTMLNames;
42 
HTMLFrameSetElement(const QualifiedName & tagName,Document * doc)43 HTMLFrameSetElement::HTMLFrameSetElement(const QualifiedName& tagName, Document *doc)
44     : HTMLElement(tagName, doc)
45     , m_rows(0)
46     , m_cols(0)
47     , m_totalRows(1)
48     , m_totalCols(1)
49     , m_border(6)
50     , m_borderSet(false)
51     , m_borderColorSet(false)
52     , frameborder(true)
53     , frameBorderSet(false)
54     , noresize(false)
55 {
56     ASSERT(hasTagName(framesetTag));
57 }
58 
~HTMLFrameSetElement()59 HTMLFrameSetElement::~HTMLFrameSetElement()
60 {
61     if (m_rows)
62         delete [] m_rows;
63     if (m_cols)
64         delete [] m_cols;
65 }
66 
checkDTD(const Node * newChild)67 bool HTMLFrameSetElement::checkDTD(const Node* newChild)
68 {
69     // FIXME: Old code had adjacent double returns and seemed to want to do something with NOFRAMES (but didn't).
70     // What is the correct behavior?
71     if (newChild->isTextNode())
72         return static_cast<const Text*>(newChild)->containsOnlyWhitespace();
73     return newChild->hasTagName(framesetTag) || newChild->hasTagName(frameTag);
74 }
75 
mapToEntry(const QualifiedName & attrName,MappedAttributeEntry & result) const76 bool HTMLFrameSetElement::mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const
77 {
78     if (attrName == bordercolorAttr) {
79         result = eUniversal;
80         return true;
81     }
82 
83     return HTMLElement::mapToEntry(attrName, result);
84 }
85 
parseMappedAttribute(MappedAttribute * attr)86 void HTMLFrameSetElement::parseMappedAttribute(MappedAttribute *attr)
87 {
88     if (attr->name() == rowsAttr) {
89         if (!attr->isNull()) {
90             if (m_rows) delete [] m_rows;
91             m_rows = newLengthArray(attr->value().string(), m_totalRows);
92             setNeedsStyleRecalc();
93         }
94     } else if (attr->name() == colsAttr) {
95         if (!attr->isNull()) {
96             delete [] m_cols;
97             m_cols = newLengthArray(attr->value().string(), m_totalCols);
98             setNeedsStyleRecalc();
99         }
100     } else if (attr->name() == frameborderAttr) {
101         if (!attr->isNull()) {
102             // false or "no" or "0"..
103             if (attr->value().toInt() == 0) {
104                 frameborder = false;
105                 m_border = 0;
106             }
107             frameBorderSet = true;
108         } else {
109             frameborder = false;
110             frameBorderSet = false;
111         }
112     } else if (attr->name() == noresizeAttr) {
113         noresize = true;
114     } else if (attr->name() == borderAttr) {
115         if (!attr->isNull()) {
116             m_border = attr->value().toInt();
117             if (!m_border)
118                 frameborder = false;
119             m_borderSet = true;
120         } else
121             m_borderSet = false;
122     } else if (attr->name() == bordercolorAttr) {
123         m_borderColorSet = attr->decl();
124         if (!attr->decl() && !attr->isEmpty()) {
125             addCSSColor(attr, CSSPropertyBorderColor, attr->value());
126             m_borderColorSet = true;
127         }
128     } else if (attr->name() == onloadAttr)
129         document()->setWindowAttributeEventListener(eventNames().loadEvent, createAttributeEventListener(document()->frame(), attr));
130     else if (attr->name() == onbeforeunloadAttr)
131         document()->setWindowAttributeEventListener(eventNames().beforeunloadEvent, createAttributeEventListener(document()->frame(), attr));
132     else if (attr->name() == onunloadAttr)
133         document()->setWindowAttributeEventListener(eventNames().unloadEvent, createAttributeEventListener(document()->frame(), attr));
134     else if (attr->name() == onblurAttr)
135         document()->setWindowAttributeEventListener(eventNames().blurEvent, createAttributeEventListener(document()->frame(), attr));
136     else if (attr->name() == onfocusAttr)
137         document()->setWindowAttributeEventListener(eventNames().focusEvent, createAttributeEventListener(document()->frame(), attr));
138     else if (attr->name() == onhashchangeAttr)
139         document()->setWindowAttributeEventListener(eventNames().hashchangeEvent, createAttributeEventListener(document()->frame(), attr));
140     else if (attr->name() == onresizeAttr)
141         document()->setWindowAttributeEventListener(eventNames().resizeEvent, createAttributeEventListener(document()->frame(), attr));
142     else if (attr->name() == onscrollAttr)
143         document()->setWindowAttributeEventListener(eventNames().scrollEvent, createAttributeEventListener(document()->frame(), attr));
144     else if (attr->name() == onstorageAttr)
145         document()->setWindowAttributeEventListener(eventNames().storageEvent, createAttributeEventListener(document()->frame(), attr));
146     else if (attr->name() == ononlineAttr)
147         document()->setWindowAttributeEventListener(eventNames().onlineEvent, createAttributeEventListener(document()->frame(), attr));
148     else if (attr->name() == onofflineAttr)
149         document()->setWindowAttributeEventListener(eventNames().offlineEvent, createAttributeEventListener(document()->frame(), attr));
150     else
151         HTMLElement::parseMappedAttribute(attr);
152 }
153 
rendererIsNeeded(RenderStyle * style)154 bool HTMLFrameSetElement::rendererIsNeeded(RenderStyle *style)
155 {
156     // For compatibility, frames render even when display: none is set.
157     // However, we delay creating a renderer until stylesheets have loaded.
158     return style->isStyleAvailable();
159 }
160 
createRenderer(RenderArena * arena,RenderStyle * style)161 RenderObject *HTMLFrameSetElement::createRenderer(RenderArena *arena, RenderStyle *style)
162 {
163     if (style->contentData())
164         return RenderObject::createObject(this, style);
165 
166     return new (arena) RenderFrameSet(this);
167 }
168 
attach()169 void HTMLFrameSetElement::attach()
170 {
171     // Inherit default settings from parent frameset
172     // FIXME: This is not dynamic.
173     for (Node* node = parentNode(); node; node = node->parentNode()) {
174         if (node->hasTagName(framesetTag)) {
175             HTMLFrameSetElement* frameset = static_cast<HTMLFrameSetElement*>(node);
176             if (!frameBorderSet)
177                 frameborder = frameset->hasFrameBorder();
178             if (frameborder) {
179                 if (!m_borderSet)
180                     m_border = frameset->border();
181                 if (!m_borderColorSet)
182                     m_borderColorSet = frameset->hasBorderColor();
183             }
184             if (!noresize)
185                 noresize = frameset->noResize();
186             break;
187         }
188     }
189 
190     HTMLElement::attach();
191 }
192 
defaultEventHandler(Event * evt)193 void HTMLFrameSetElement::defaultEventHandler(Event* evt)
194 {
195     if (evt->isMouseEvent() && !noresize && renderer()) {
196         if (toRenderFrameSet(renderer())->userResize(static_cast<MouseEvent*>(evt))) {
197             evt->setDefaultHandled();
198             return;
199         }
200     }
201     HTMLElement::defaultEventHandler(evt);
202 }
203 
recalcStyle(StyleChange ch)204 void HTMLFrameSetElement::recalcStyle(StyleChange ch)
205 {
206     if (needsStyleRecalc() && renderer()) {
207         renderer()->setNeedsLayout(true);
208 #ifdef FLATTEN_FRAMESET
209         static_cast<RenderFrameSet*>(renderer())->setGridNeedsLayout();
210 #endif
211         setNeedsStyleRecalc(NoStyleChange);
212     }
213     HTMLElement::recalcStyle(ch);
214 }
215 
cols() const216 String HTMLFrameSetElement::cols() const
217 {
218     return getAttribute(colsAttr);
219 }
220 
setCols(const String & value)221 void HTMLFrameSetElement::setCols(const String &value)
222 {
223     setAttribute(colsAttr, value);
224 }
225 
rows() const226 String HTMLFrameSetElement::rows() const
227 {
228     return getAttribute(rowsAttr);
229 }
230 
setRows(const String & value)231 void HTMLFrameSetElement::setRows(const String &value)
232 {
233     setAttribute(rowsAttr, value);
234 }
235 
onblur() const236 EventListener* HTMLFrameSetElement::onblur() const
237 {
238     return document()->getWindowAttributeEventListener(eventNames().blurEvent);
239 }
240 
setOnblur(PassRefPtr<EventListener> eventListener)241 void HTMLFrameSetElement::setOnblur(PassRefPtr<EventListener> eventListener)
242 {
243     document()->setAttributeEventListener(eventNames().blurEvent, eventListener);
244 }
245 
onerror() const246 EventListener* HTMLFrameSetElement::onerror() const
247 {
248     return document()->getWindowAttributeEventListener(eventNames().errorEvent);
249 }
250 
setOnerror(PassRefPtr<EventListener> eventListener)251 void HTMLFrameSetElement::setOnerror(PassRefPtr<EventListener> eventListener)
252 {
253     document()->setAttributeEventListener(eventNames().errorEvent, eventListener);
254 }
255 
onfocus() const256 EventListener* HTMLFrameSetElement::onfocus() const
257 {
258     return document()->getWindowAttributeEventListener(eventNames().focusEvent);
259 }
260 
setOnfocus(PassRefPtr<EventListener> eventListener)261 void HTMLFrameSetElement::setOnfocus(PassRefPtr<EventListener> eventListener)
262 {
263     document()->setAttributeEventListener(eventNames().focusEvent, eventListener);
264 }
265 
onload() const266 EventListener* HTMLFrameSetElement::onload() const
267 {
268     return document()->getWindowAttributeEventListener(eventNames().loadEvent);
269 }
270 
setOnload(PassRefPtr<EventListener> eventListener)271 void HTMLFrameSetElement::setOnload(PassRefPtr<EventListener> eventListener)
272 {
273     document()->setAttributeEventListener(eventNames().loadEvent, eventListener);
274 }
275 
onbeforeunload() const276 EventListener* HTMLFrameSetElement::onbeforeunload() const
277 {
278     return document()->getWindowAttributeEventListener(eventNames().beforeunloadEvent);
279 }
280 
setOnbeforeunload(PassRefPtr<EventListener> eventListener)281 void HTMLFrameSetElement::setOnbeforeunload(PassRefPtr<EventListener> eventListener)
282 {
283     document()->setAttributeEventListener(eventNames().beforeunloadEvent, eventListener);
284 }
285 
onmessage() const286 EventListener* HTMLFrameSetElement::onmessage() const
287 {
288     return document()->getWindowAttributeEventListener(eventNames().messageEvent);
289 }
290 
setOnmessage(PassRefPtr<EventListener> eventListener)291 void HTMLFrameSetElement::setOnmessage(PassRefPtr<EventListener> eventListener)
292 {
293     document()->setAttributeEventListener(eventNames().messageEvent, eventListener);
294 }
295 
onoffline() const296 EventListener* HTMLFrameSetElement::onoffline() const
297 {
298     return document()->getWindowAttributeEventListener(eventNames().offlineEvent);
299 }
300 
setOnoffline(PassRefPtr<EventListener> eventListener)301 void HTMLFrameSetElement::setOnoffline(PassRefPtr<EventListener> eventListener)
302 {
303     document()->setAttributeEventListener(eventNames().offlineEvent, eventListener);
304 }
305 
ononline() const306 EventListener* HTMLFrameSetElement::ononline() const
307 {
308     return document()->getWindowAttributeEventListener(eventNames().onlineEvent);
309 }
310 
setOnonline(PassRefPtr<EventListener> eventListener)311 void HTMLFrameSetElement::setOnonline(PassRefPtr<EventListener> eventListener)
312 {
313     document()->setAttributeEventListener(eventNames().onlineEvent, eventListener);
314 }
315 
onresize() const316 EventListener* HTMLFrameSetElement::onresize() const
317 {
318     return document()->getWindowAttributeEventListener(eventNames().resizeEvent);
319 }
320 
setOnresize(PassRefPtr<EventListener> eventListener)321 void HTMLFrameSetElement::setOnresize(PassRefPtr<EventListener> eventListener)
322 {
323     document()->setAttributeEventListener(eventNames().resizeEvent, eventListener);
324 }
325 
onstorage() const326 EventListener* HTMLFrameSetElement::onstorage() const
327 {
328     return document()->getWindowAttributeEventListener(eventNames().storageEvent);
329 }
330 
setOnstorage(PassRefPtr<EventListener> eventListener)331 void HTMLFrameSetElement::setOnstorage(PassRefPtr<EventListener> eventListener)
332 {
333     document()->setAttributeEventListener(eventNames().storageEvent, eventListener);
334 }
335 
onunload() const336 EventListener* HTMLFrameSetElement::onunload() const
337 {
338     return document()->getWindowAttributeEventListener(eventNames().unloadEvent);
339 }
340 
setOnunload(PassRefPtr<EventListener> eventListener)341 void HTMLFrameSetElement::setOnunload(PassRefPtr<EventListener> eventListener)
342 {
343     document()->setAttributeEventListener(eventNames().unloadEvent, eventListener);
344 }
345 
346 } // namespace WebCore
347