Home | History | Annotate | Download | only in html
      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 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 
     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 
     59 HTMLFrameSetElement::~HTMLFrameSetElement()
     60 {
     61     if (m_rows)
     62         delete [] m_rows;
     63     if (m_cols)
     64         delete [] m_cols;
     65 }
     66 
     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 
     76 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 
     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 #if ENABLE(ORIENTATION_EVENTS)
    139     else if (attr->name() == onorientationchangeAttr)
    140         document()->setWindowAttributeEventListener(eventNames().orientationchangeEvent, createAttributeEventListener(document()->frame(), attr));
    141 #endif
    142     else if (attr->name() == onhashchangeAttr)
    143         document()->setWindowAttributeEventListener(eventNames().hashchangeEvent, createAttributeEventListener(document()->frame(), attr));
    144     else if (attr->name() == onresizeAttr)
    145         document()->setWindowAttributeEventListener(eventNames().resizeEvent, createAttributeEventListener(document()->frame(), attr));
    146     else if (attr->name() == onscrollAttr)
    147         document()->setWindowAttributeEventListener(eventNames().scrollEvent, createAttributeEventListener(document()->frame(), attr));
    148     else if (attr->name() == onstorageAttr)
    149         document()->setWindowAttributeEventListener(eventNames().storageEvent, createAttributeEventListener(document()->frame(), attr));
    150     else if (attr->name() == ononlineAttr)
    151         document()->setWindowAttributeEventListener(eventNames().onlineEvent, createAttributeEventListener(document()->frame(), attr));
    152     else if (attr->name() == onofflineAttr)
    153         document()->setWindowAttributeEventListener(eventNames().offlineEvent, createAttributeEventListener(document()->frame(), attr));
    154     else if (attr->name() == onpopstateAttr)
    155         document()->setWindowAttributeEventListener(eventNames().popstateEvent, createAttributeEventListener(document()->frame(), attr));
    156     else
    157         HTMLElement::parseMappedAttribute(attr);
    158 }
    159 
    160 bool HTMLFrameSetElement::rendererIsNeeded(RenderStyle *style)
    161 {
    162     // For compatibility, frames render even when display: none is set.
    163     // However, we delay creating a renderer until stylesheets have loaded.
    164     return style->isStyleAvailable();
    165 }
    166 
    167 RenderObject *HTMLFrameSetElement::createRenderer(RenderArena *arena, RenderStyle *style)
    168 {
    169     if (style->contentData())
    170         return RenderObject::createObject(this, style);
    171 
    172     return new (arena) RenderFrameSet(this);
    173 }
    174 
    175 void HTMLFrameSetElement::attach()
    176 {
    177     // Inherit default settings from parent frameset
    178     // FIXME: This is not dynamic.
    179     for (Node* node = parentNode(); node; node = node->parentNode()) {
    180         if (node->hasTagName(framesetTag)) {
    181             HTMLFrameSetElement* frameset = static_cast<HTMLFrameSetElement*>(node);
    182             if (!frameBorderSet)
    183                 frameborder = frameset->hasFrameBorder();
    184             if (frameborder) {
    185                 if (!m_borderSet)
    186                     m_border = frameset->border();
    187                 if (!m_borderColorSet)
    188                     m_borderColorSet = frameset->hasBorderColor();
    189             }
    190             if (!noresize)
    191                 noresize = frameset->noResize();
    192             break;
    193         }
    194     }
    195 
    196     HTMLElement::attach();
    197 }
    198 
    199 void HTMLFrameSetElement::defaultEventHandler(Event* evt)
    200 {
    201     if (evt->isMouseEvent() && !noresize && renderer()) {
    202         if (toRenderFrameSet(renderer())->userResize(static_cast<MouseEvent*>(evt))) {
    203             evt->setDefaultHandled();
    204             return;
    205         }
    206     }
    207     HTMLElement::defaultEventHandler(evt);
    208 }
    209 
    210 void HTMLFrameSetElement::recalcStyle(StyleChange ch)
    211 {
    212     if (needsStyleRecalc() && renderer()) {
    213         renderer()->setNeedsLayout(true);
    214 #ifdef FLATTEN_FRAMESET
    215         static_cast<RenderFrameSet*>(renderer())->setGridNeedsLayout();
    216 #endif
    217         setNeedsStyleRecalc(NoStyleChange);
    218     }
    219     HTMLElement::recalcStyle(ch);
    220 }
    221 
    222 String HTMLFrameSetElement::cols() const
    223 {
    224     return getAttribute(colsAttr);
    225 }
    226 
    227 void HTMLFrameSetElement::setCols(const String &value)
    228 {
    229     setAttribute(colsAttr, value);
    230 }
    231 
    232 String HTMLFrameSetElement::rows() const
    233 {
    234     return getAttribute(rowsAttr);
    235 }
    236 
    237 void HTMLFrameSetElement::setRows(const String &value)
    238 {
    239     setAttribute(rowsAttr, value);
    240 }
    241 
    242 } // namespace WebCore
    243