1 /* 2 * Copyright (C) 1999 Lars Knoll (knoll (at) kde.org) 3 * (C) 1999 Antti Koivisto (koivisto (at) kde.org) 4 * (C) 2000 Simon Hausmann (hausmann (at) kde.org) 5 * (C) 2001 Dirk Mueller (mueller (at) 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 "core/html/HTMLFrameSetElement.h" 26 27 #include "bindings/core/v8/ScriptEventListener.h" 28 #include "core/CSSPropertyNames.h" 29 #include "core/HTMLNames.h" 30 #include "core/dom/Document.h" 31 #include "core/events/Event.h" 32 #include "core/events/MouseEvent.h" 33 #include "core/frame/LocalFrame.h" 34 #include "core/html/HTMLCollection.h" 35 #include "core/html/HTMLFrameElement.h" 36 #include "core/loader/FrameLoaderClient.h" 37 #include "core/rendering/RenderFrameSet.h" 38 39 namespace blink { 40 41 using namespace HTMLNames; 42 43 inline HTMLFrameSetElement::HTMLFrameSetElement(Document& document) 44 : HTMLElement(framesetTag, document) 45 , m_border(6) 46 , m_borderSet(false) 47 , m_borderColorSet(false) 48 , m_frameborder(true) 49 , m_frameborderSet(false) 50 , m_noresize(false) 51 { 52 setHasCustomStyleCallbacks(); 53 } 54 55 DEFINE_NODE_FACTORY(HTMLFrameSetElement) 56 57 bool HTMLFrameSetElement::isPresentationAttribute(const QualifiedName& name) const 58 { 59 if (name == bordercolorAttr) 60 return true; 61 return HTMLElement::isPresentationAttribute(name); 62 } 63 64 void HTMLFrameSetElement::collectStyleForPresentationAttribute(const QualifiedName& name, const AtomicString& value, MutableStylePropertySet* style) 65 { 66 if (name == bordercolorAttr) 67 addHTMLColorToStyle(style, CSSPropertyBorderColor, value); 68 else 69 HTMLElement::collectStyleForPresentationAttribute(name, value, style); 70 } 71 72 void HTMLFrameSetElement::parseAttribute(const QualifiedName& name, const AtomicString& value) 73 { 74 if (name == rowsAttr) { 75 if (!value.isNull()) { 76 m_rowLengths = parseListOfDimensions(value.string()); 77 setNeedsStyleRecalc(SubtreeStyleChange); 78 } 79 } else if (name == colsAttr) { 80 if (!value.isNull()) { 81 m_colLengths = parseListOfDimensions(value.string()); 82 setNeedsStyleRecalc(SubtreeStyleChange); 83 } 84 } else if (name == frameborderAttr) { 85 if (!value.isNull()) { 86 if (equalIgnoringCase(value, "no") || equalIgnoringCase(value, "0")) { 87 m_frameborder = false; 88 m_frameborderSet = true; 89 } else if (equalIgnoringCase(value, "yes") || equalIgnoringCase(value, "1")) { 90 m_frameborderSet = true; 91 } 92 } else { 93 m_frameborder = false; 94 m_frameborderSet = false; 95 } 96 } else if (name == noresizeAttr) { 97 m_noresize = true; 98 } else if (name == borderAttr) { 99 if (!value.isNull()) { 100 m_border = value.toInt(); 101 m_borderSet = true; 102 } else 103 m_borderSet = false; 104 } else if (name == bordercolorAttr) 105 m_borderColorSet = !value.isEmpty(); 106 else if (name == onloadAttr) 107 document().setWindowAttributeEventListener(EventTypeNames::load, createAttributeEventListener(document().frame(), name, value, eventParameterName())); 108 else if (name == onbeforeunloadAttr) 109 document().setWindowAttributeEventListener(EventTypeNames::beforeunload, createAttributeEventListener(document().frame(), name, value, eventParameterName())); 110 else if (name == onunloadAttr) 111 document().setWindowAttributeEventListener(EventTypeNames::unload, createAttributeEventListener(document().frame(), name, value, eventParameterName())); 112 else if (name == onpagehideAttr) 113 document().setWindowAttributeEventListener(EventTypeNames::pagehide, createAttributeEventListener(document().frame(), name, value, eventParameterName())); 114 else if (name == onpageshowAttr) 115 document().setWindowAttributeEventListener(EventTypeNames::pageshow, createAttributeEventListener(document().frame(), name, value, eventParameterName())); 116 else if (name == onblurAttr) 117 document().setWindowAttributeEventListener(EventTypeNames::blur, createAttributeEventListener(document().frame(), name, value, eventParameterName())); 118 else if (name == onerrorAttr) 119 document().setWindowAttributeEventListener(EventTypeNames::error, createAttributeEventListener(document().frame(), name, value, eventParameterName())); 120 else if (name == onfocusAttr) 121 document().setWindowAttributeEventListener(EventTypeNames::focus, createAttributeEventListener(document().frame(), name, value, eventParameterName())); 122 else if (name == onfocusinAttr) 123 document().setWindowAttributeEventListener(EventTypeNames::focusin, createAttributeEventListener(document().frame(), name, value, eventParameterName())); 124 else if (name == onfocusoutAttr) 125 document().setWindowAttributeEventListener(EventTypeNames::focusout, createAttributeEventListener(document().frame(), name, value, eventParameterName())); 126 else if (RuntimeEnabledFeatures::orientationEventEnabled() && name == onorientationchangeAttr) 127 document().setWindowAttributeEventListener(EventTypeNames::orientationchange, createAttributeEventListener(document().frame(), name, value, eventParameterName())); 128 else if (name == onhashchangeAttr) 129 document().setWindowAttributeEventListener(EventTypeNames::hashchange, createAttributeEventListener(document().frame(), name, value, eventParameterName())); 130 else if (name == onmessageAttr) 131 document().setWindowAttributeEventListener(EventTypeNames::message, createAttributeEventListener(document().frame(), name, value, eventParameterName())); 132 else if (name == onresizeAttr) 133 document().setWindowAttributeEventListener(EventTypeNames::resize, createAttributeEventListener(document().frame(), name, value, eventParameterName())); 134 else if (name == onscrollAttr) 135 document().setWindowAttributeEventListener(EventTypeNames::scroll, createAttributeEventListener(document().frame(), name, value, eventParameterName())); 136 else if (name == onstorageAttr) 137 document().setWindowAttributeEventListener(EventTypeNames::storage, createAttributeEventListener(document().frame(), name, value, eventParameterName())); 138 else if (name == ononlineAttr) 139 document().setWindowAttributeEventListener(EventTypeNames::online, createAttributeEventListener(document().frame(), name, value, eventParameterName())); 140 else if (name == onofflineAttr) 141 document().setWindowAttributeEventListener(EventTypeNames::offline, createAttributeEventListener(document().frame(), name, value, eventParameterName())); 142 else if (name == onpopstateAttr) 143 document().setWindowAttributeEventListener(EventTypeNames::popstate, createAttributeEventListener(document().frame(), name, value, eventParameterName())); 144 else if (name == onlanguagechangeAttr) 145 document().setWindowAttributeEventListener(EventTypeNames::languagechange, createAttributeEventListener(document().frame(), name, value, eventParameterName())); 146 else 147 HTMLElement::parseAttribute(name, value); 148 } 149 150 bool HTMLFrameSetElement::rendererIsNeeded(const RenderStyle& style) 151 { 152 // For compatibility, frames render even when display: none is set. 153 // However, we delay creating a renderer until stylesheets have loaded. 154 return style.isStyleAvailable(); 155 } 156 157 RenderObject* HTMLFrameSetElement::createRenderer(RenderStyle *style) 158 { 159 if (style->hasContent()) 160 return RenderObject::createObject(this, style); 161 162 return new RenderFrameSet(this); 163 } 164 165 void HTMLFrameSetElement::attach(const AttachContext& context) 166 { 167 // Inherit default settings from parent frameset 168 // FIXME: This is not dynamic. 169 if (HTMLFrameSetElement* frameset = Traversal<HTMLFrameSetElement>::firstAncestor(*this)) { 170 if (!m_frameborderSet) 171 m_frameborder = frameset->hasFrameBorder(); 172 if (m_frameborder) { 173 if (!m_borderSet) 174 m_border = frameset->border(); 175 if (!m_borderColorSet) 176 m_borderColorSet = frameset->hasBorderColor(); 177 } 178 if (!m_noresize) 179 m_noresize = frameset->noResize(); 180 } 181 182 HTMLElement::attach(context); 183 } 184 185 void HTMLFrameSetElement::defaultEventHandler(Event* evt) 186 { 187 if (evt->isMouseEvent() && !m_noresize && renderer() && renderer()->isFrameSet()) { 188 if (toRenderFrameSet(renderer())->userResize(toMouseEvent(evt))) { 189 evt->setDefaultHandled(); 190 return; 191 } 192 } 193 HTMLElement::defaultEventHandler(evt); 194 } 195 196 Node::InsertionNotificationRequest HTMLFrameSetElement::insertedInto(ContainerNode* insertionPoint) 197 { 198 if (insertionPoint->inDocument() && document().frame()) { 199 // A document using <frameset> likely won't literally have a body, but as far as the client is concerned, the frameset is effectively the body. 200 document().frame()->loader().client()->dispatchWillInsertBody(); 201 } 202 return HTMLElement::insertedInto(insertionPoint); 203 } 204 205 void HTMLFrameSetElement::willRecalcStyle(StyleRecalcChange) 206 { 207 if (needsStyleRecalc() && renderer()) { 208 renderer()->setNeedsLayoutAndFullPaintInvalidation(); 209 clearNeedsStyleRecalc(); 210 } 211 } 212 213 LocalDOMWindow* HTMLFrameSetElement::anonymousNamedGetter(const AtomicString& name) 214 { 215 Element* frameElement = children()->namedItem(name); 216 if (!isHTMLFrameElement(frameElement)) 217 return 0; 218 Document* document = toHTMLFrameElement(frameElement)->contentDocument(); 219 if (!document || !document->frame()) 220 return 0; 221 return document->domWindow(); 222 } 223 224 } // namespace blink 225