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 43namespace WebCore { 44 45using namespace HTMLNames; 46 47HTMLFrameSetElement::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 60 setHasCustomStyleCallbacks(); 61} 62 63PassRefPtr<HTMLFrameSetElement> HTMLFrameSetElement::create(const QualifiedName& tagName, Document* document) 64{ 65 return adoptRef(new HTMLFrameSetElement(tagName, document)); 66} 67 68bool HTMLFrameSetElement::isPresentationAttribute(const QualifiedName& name) const 69{ 70 if (name == bordercolorAttr) 71 return true; 72 return HTMLElement::isPresentationAttribute(name); 73} 74 75void HTMLFrameSetElement::collectStyleForPresentationAttribute(const QualifiedName& name, const AtomicString& value, MutableStylePropertySet* style) 76{ 77 if (name == bordercolorAttr) 78 addHTMLColorToStyle(style, CSSPropertyBorderColor, value); 79 else 80 HTMLElement::collectStyleForPresentationAttribute(name, value, style); 81} 82 83void HTMLFrameSetElement::parseAttribute(const QualifiedName& name, const AtomicString& value) 84{ 85 if (name == rowsAttr) { 86 if (!value.isNull()) { 87 m_rowLengths = newLengthArray(value.string(), m_totalRows); 88 setNeedsStyleRecalc(); 89 } 90 } else if (name == colsAttr) { 91 if (!value.isNull()) { 92 m_colLengths = newLengthArray(value.string(), m_totalCols); 93 setNeedsStyleRecalc(); 94 } 95 } else if (name == frameborderAttr) { 96 if (!value.isNull()) { 97 if (equalIgnoringCase(value, "no") || equalIgnoringCase(value, "0")) { 98 m_frameborder = false; 99 m_frameborderSet = true; 100 } else if (equalIgnoringCase(value, "yes") || equalIgnoringCase(value, "1")) { 101 m_frameborderSet = true; 102 } 103 } else { 104 m_frameborder = false; 105 m_frameborderSet = false; 106 } 107 } else if (name == noresizeAttr) { 108 m_noresize = true; 109 } else if (name == borderAttr) { 110 if (!value.isNull()) { 111 m_border = value.toInt(); 112 m_borderSet = true; 113 } else 114 m_borderSet = false; 115 } else if (name == bordercolorAttr) 116 m_borderColorSet = !value.isEmpty(); 117 else if (name == onloadAttr) 118 document()->setWindowAttributeEventListener(eventNames().loadEvent, createAttributeEventListener(document()->frame(), name, value)); 119 else if (name == onbeforeunloadAttr) 120 document()->setWindowAttributeEventListener(eventNames().beforeunloadEvent, createAttributeEventListener(document()->frame(), name, value)); 121 else if (name == onunloadAttr) 122 document()->setWindowAttributeEventListener(eventNames().unloadEvent, createAttributeEventListener(document()->frame(), name, value)); 123 else if (name == onblurAttr) 124 document()->setWindowAttributeEventListener(eventNames().blurEvent, createAttributeEventListener(document()->frame(), name, value)); 125 else if (name == onfocusAttr) 126 document()->setWindowAttributeEventListener(eventNames().focusEvent, createAttributeEventListener(document()->frame(), name, value)); 127 else if (name == onfocusinAttr) 128 document()->setWindowAttributeEventListener(eventNames().focusinEvent, createAttributeEventListener(document()->frame(), name, value)); 129 else if (name == onfocusoutAttr) 130 document()->setWindowAttributeEventListener(eventNames().focusoutEvent, createAttributeEventListener(document()->frame(), name, value)); 131#if ENABLE(ORIENTATION_EVENTS) 132 else if (name == onorientationchangeAttr) 133 document()->setWindowAttributeEventListener(eventNames().orientationchangeEvent, createAttributeEventListener(document()->frame(), name, value)); 134#endif 135 else if (name == onhashchangeAttr) 136 document()->setWindowAttributeEventListener(eventNames().hashchangeEvent, createAttributeEventListener(document()->frame(), name, value)); 137 else if (name == onresizeAttr) 138 document()->setWindowAttributeEventListener(eventNames().resizeEvent, createAttributeEventListener(document()->frame(), name, value)); 139 else if (name == onscrollAttr) 140 document()->setWindowAttributeEventListener(eventNames().scrollEvent, createAttributeEventListener(document()->frame(), name, value)); 141 else if (name == onstorageAttr) 142 document()->setWindowAttributeEventListener(eventNames().storageEvent, createAttributeEventListener(document()->frame(), name, value)); 143 else if (name == ononlineAttr) 144 document()->setWindowAttributeEventListener(eventNames().onlineEvent, createAttributeEventListener(document()->frame(), name, value)); 145 else if (name == onofflineAttr) 146 document()->setWindowAttributeEventListener(eventNames().offlineEvent, createAttributeEventListener(document()->frame(), name, value)); 147 else if (name == onpopstateAttr) 148 document()->setWindowAttributeEventListener(eventNames().popstateEvent, createAttributeEventListener(document()->frame(), name, value)); 149 else 150 HTMLElement::parseAttribute(name, value); 151} 152 153bool 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 160RenderObject *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 168void HTMLFrameSetElement::attach(const AttachContext& context) 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(context); 190} 191 192void 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 203bool HTMLFrameSetElement::willRecalcStyle(StyleChange) 204{ 205 if (needsStyleRecalc() && renderer()) { 206 renderer()->setNeedsLayout(true); 207 clearNeedsStyleRecalc(); 208 } 209 return true; 210} 211 212Node::InsertionNotificationRequest HTMLFrameSetElement::insertedInto(ContainerNode* insertionPoint) 213{ 214 HTMLElement::insertedInto(insertionPoint); 215 if (insertionPoint->inDocument()) { 216 if (Frame* frame = document()->frame()) 217 frame->loader()->client()->dispatchDidBecomeFrameset(document()->isFrameSet()); 218 } 219 220 return InsertionDone; 221} 222 223void HTMLFrameSetElement::removedFrom(ContainerNode* insertionPoint) 224{ 225 HTMLElement::removedFrom(insertionPoint); 226 if (insertionPoint->inDocument()) { 227 if (Frame* frame = document()->frame()) 228 frame->loader()->client()->dispatchDidBecomeFrameset(document()->isFrameSet()); 229 } 230} 231 232} // namespace WebCore 233