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