webengine/osswebengine/WebCore/html/HTMLFrameElementBase.cpp
changeset 0 dd21522fd290
child 68 92a765b5b3e7
equal deleted inserted replaced
-1:000000000000 0:dd21522fd290
       
     1 /**
       
     2  * This file is part of the DOM implementation for KDE.
       
     3  *
       
     4  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
       
     5  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
       
     6  *           (C) 2000 Simon Hausmann (hausmann@kde.org)
       
     7  *           (C) 2001 Dirk Mueller (mueller@kde.org)
       
     8  * Copyright (C) 2004, 2006 Apple Computer, Inc.
       
     9  *
       
    10  * This library is free software; you can redistribute it and/or
       
    11  * modify it under the terms of the GNU Library General Public
       
    12  * License as published by the Free Software Foundation; either
       
    13  * version 2 of the License, or (at your option) any later version.
       
    14  *
       
    15  * This library is distributed in the hope that it will be useful,
       
    16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       
    18  * Library General Public License for more details.
       
    19  *
       
    20  * You should have received a copy of the GNU Library General Public License
       
    21  * along with this library; see the file COPYING.LIB.  If not, write to
       
    22  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
       
    23  * Boston, MA 02110-1301, USA.
       
    24  */
       
    25 #include "config.h"
       
    26 #include "HTMLFrameElementBase.h"
       
    27 
       
    28 #include "CSSHelper.h"
       
    29 #include "Document.h"
       
    30 #include "EventNames.h"
       
    31 #include "FocusController.h"
       
    32 #include "Frame.h"
       
    33 #include "FrameLoader.h"
       
    34 #include "FrameTree.h"
       
    35 #include "FrameView.h"
       
    36 #include "HTMLFrameSetElement.h"
       
    37 #include "HTMLNames.h"
       
    38 #include "KURL.h"
       
    39 #include "Page.h"
       
    40 #include "RenderFrame.h"
       
    41 #include "Settings.h"
       
    42 
       
    43 namespace WebCore {
       
    44 
       
    45 using namespace EventNames;
       
    46 using namespace HTMLNames;
       
    47 
       
    48 HTMLFrameElementBase::HTMLFrameElementBase(const QualifiedName& tagName, Document *doc)
       
    49     : HTMLFrameOwnerElement(tagName, doc)
       
    50     , m_scrolling(ScrollbarAuto)
       
    51     , m_marginWidth(-1)
       
    52     , m_marginHeight(-1)
       
    53     , m_noResize(false)
       
    54     , m_viewSource(false)
       
    55     , m_shouldOpenURLAfterAttach(false)
       
    56 {
       
    57 }
       
    58 
       
    59 bool HTMLFrameElementBase::isURLAllowed(const AtomicString& URLString) const
       
    60 {
       
    61     if (URLString.isEmpty())
       
    62         return true;
       
    63 
       
    64     KURL completeURL(document()->completeURL(URLString.deprecatedString()));
       
    65     completeURL.setRef(DeprecatedString::null);
       
    66 
       
    67     // Don't allow more than 200 total frames in a set. This seems
       
    68     // like a reasonable upper bound, and otherwise mutually recursive
       
    69     // frameset pages can quickly bring the program to its knees with
       
    70     // exponential growth in the number of frames.
       
    71 
       
    72     // FIXME: This limit could be higher, but WebKit has some
       
    73     // algorithms that happen while loading which appear to be N^2 or
       
    74     // worse in the number of frames
       
    75     if (Frame* parentFrame = document()->frame())
       
    76         if (parentFrame->page()->frameCount() > 200)
       
    77             return false;
       
    78 
       
    79     // We allow one level of self-reference because some sites depend on that.
       
    80     // But we don't allow more than one.
       
    81     bool foundSelfReference = false;
       
    82     for (Frame* frame = document()->frame(); frame; frame = frame->tree()->parent()) {
       
    83         KURL frameURL = frame->loader()->url();
       
    84         frameURL.setRef(DeprecatedString::null);
       
    85         if (frameURL == completeURL) {
       
    86             if (foundSelfReference)
       
    87                 return false;
       
    88             foundSelfReference = true;
       
    89         }
       
    90     }
       
    91     
       
    92     return true;
       
    93 }
       
    94 
       
    95 void HTMLFrameElementBase::openURL()
       
    96 {
       
    97     ASSERT(!m_name.isEmpty());
       
    98 
       
    99     if (!isURLAllowed(m_URL))
       
   100         return;
       
   101 
       
   102     if (m_URL.isEmpty())
       
   103         m_URL = "about:blank";
       
   104 
       
   105     Frame* parentFrame = document()->frame();
       
   106     if (!parentFrame)
       
   107         return;
       
   108 
       
   109     parentFrame->loader()->requestFrame(this, m_URL, m_name);
       
   110     if (contentFrame())
       
   111         contentFrame()->setInViewSourceMode(viewSourceMode());
       
   112 }
       
   113 
       
   114 void HTMLFrameElementBase::parseMappedAttribute(MappedAttribute *attr)
       
   115 {
       
   116     if (attr->name() == srcAttr)
       
   117         setLocation(parseURL(attr->value()));
       
   118     else if (attr->name() == idAttr) {
       
   119         // Important to call through to base for the id attribute so the hasID bit gets set.
       
   120         HTMLFrameOwnerElement::parseMappedAttribute(attr);
       
   121         m_name = attr->value();
       
   122     } else if (attr->name() == nameAttr) {
       
   123         m_name = attr->value();
       
   124         // FIXME: If we are already attached, this doesn't actually change the frame's name.
       
   125         // FIXME: If we are already attached, this doesn't check for frame name
       
   126         // conflicts and generate a unique frame name.
       
   127     } else if (attr->name() == marginwidthAttr) {
       
   128         m_marginWidth = attr->value().toInt();
       
   129         // FIXME: If we are already attached, this has no effect.
       
   130     } else if (attr->name() == marginheightAttr) {
       
   131         m_marginHeight = attr->value().toInt();
       
   132         // FIXME: If we are already attached, this has no effect.
       
   133     } else if (attr->name() == noresizeAttr) {
       
   134         m_noResize = true;
       
   135         // FIXME: If we are already attached, this has no effect.
       
   136     } else if (attr->name() == scrollingAttr) {
       
   137         // Auto and yes both simply mean "allow scrolling." No means "don't allow scrolling."
       
   138         if (equalIgnoringCase(attr->value(), "auto") || equalIgnoringCase(attr->value(), "yes"))
       
   139             m_scrolling = ScrollbarAuto;
       
   140         else if (equalIgnoringCase(attr->value(), "no"))
       
   141             m_scrolling = ScrollbarAlwaysOff;
       
   142         // FIXME: If we are already attached, this has no effect.
       
   143     } else if (attr->name() == viewsourceAttr) {
       
   144         m_viewSource = !attr->isNull();
       
   145         if (contentFrame())
       
   146             contentFrame()->setInViewSourceMode(viewSourceMode());
       
   147     } else if (attr->name() == onloadAttr) {
       
   148         setHTMLEventListener(loadEvent, attr);
       
   149     } else if (attr->name() == onbeforeunloadAttr) {
       
   150         // FIXME: should <frame> elements have beforeunload handlers?
       
   151         setHTMLEventListener(beforeunloadEvent, attr);
       
   152     } else if (attr->name() == onunloadAttr) {
       
   153         setHTMLEventListener(unloadEvent, attr);
       
   154     } else
       
   155         HTMLFrameOwnerElement::parseMappedAttribute(attr);
       
   156 }
       
   157 
       
   158 void HTMLFrameElementBase::setNameAndOpenURL()
       
   159 {
       
   160     m_name = getAttribute(nameAttr);
       
   161     if (m_name.isNull())
       
   162         m_name = getAttribute(idAttr);
       
   163     
       
   164     if (Frame* parentFrame = document()->frame())
       
   165         m_name = parentFrame->tree()->uniqueChildName(m_name);
       
   166     
       
   167     openURL();
       
   168 }
       
   169 
       
   170 void HTMLFrameElementBase::setNameAndOpenURLCallback(Node* n)
       
   171 {
       
   172     static_cast<HTMLFrameElementBase*>(n)->setNameAndOpenURL();
       
   173 }
       
   174 
       
   175 void HTMLFrameElementBase::insertedIntoDocument()
       
   176 {
       
   177     HTMLFrameOwnerElement::insertedIntoDocument();
       
   178     
       
   179     // We delay frame loading until after the render tree is fully constructed.
       
   180     // Othewise, a synchronous load that executed JavaScript would see incorrect 
       
   181     // (0) values for the frame's renderer-dependent properties, like width.
       
   182     m_shouldOpenURLAfterAttach = true;
       
   183 }
       
   184 
       
   185 void HTMLFrameElementBase::removedFromDocument()
       
   186 {
       
   187     m_shouldOpenURLAfterAttach = false;
       
   188 
       
   189     HTMLFrameOwnerElement::removedFromDocument();
       
   190 }
       
   191 
       
   192 void HTMLFrameElementBase::attach()
       
   193 {
       
   194     if (m_shouldOpenURLAfterAttach) {
       
   195         m_shouldOpenURLAfterAttach = false;
       
   196         queuePostAttachCallback(&HTMLFrameElementBase::setNameAndOpenURLCallback, this);
       
   197     }
       
   198 
       
   199     HTMLFrameOwnerElement::attach();
       
   200     
       
   201     if (RenderPart* renderPart = static_cast<RenderPart*>(renderer()))
       
   202         if (Frame* frame = contentFrame())
       
   203             renderPart->setWidget(frame->view());
       
   204 }
       
   205 
       
   206 void HTMLFrameElementBase::willRemove()
       
   207 {
       
   208     if (Frame* frame = contentFrame()) {
       
   209         frame->disconnectOwnerElement();
       
   210         frame->loader()->frameDetached();
       
   211     }
       
   212 
       
   213     HTMLFrameOwnerElement::willRemove();
       
   214 }
       
   215 
       
   216 String HTMLFrameElementBase::location() const
       
   217 {
       
   218     return src();
       
   219 }
       
   220 
       
   221 void HTMLFrameElementBase::setLocation(const String& str)
       
   222 {
       
   223     Settings* settings = document()->settings();
       
   224     if (settings && settings->needsAcrobatFrameReloadingQuirk() && m_URL == str)
       
   225         return;
       
   226 
       
   227     m_URL = AtomicString(str);
       
   228 
       
   229     if (inDocument())
       
   230         openURL();
       
   231 }
       
   232 
       
   233 bool HTMLFrameElementBase::isFocusable() const
       
   234 {
       
   235     return renderer();
       
   236 }
       
   237 
       
   238 void HTMLFrameElementBase::setFocus(bool received)
       
   239 {
       
   240     HTMLFrameOwnerElement::setFocus(received);
       
   241     if (Page* page = document()->page())
       
   242         page->focusController()->setFocusedFrame(received ? contentFrame() : 0);
       
   243 }
       
   244 
       
   245 bool HTMLFrameElementBase::isURLAttribute(Attribute *attr) const
       
   246 {
       
   247     return attr->name() == srcAttr;
       
   248 }
       
   249 
       
   250 String HTMLFrameElementBase::frameBorder() const
       
   251 {
       
   252     return getAttribute(frameborderAttr);
       
   253 }
       
   254 
       
   255 void HTMLFrameElementBase::setFrameBorder(const String &value)
       
   256 {
       
   257     setAttribute(frameborderAttr, value);
       
   258 }
       
   259 
       
   260 String HTMLFrameElementBase::longDesc() const
       
   261 {
       
   262     return getAttribute(longdescAttr);
       
   263 }
       
   264 
       
   265 void HTMLFrameElementBase::setLongDesc(const String &value)
       
   266 {
       
   267     setAttribute(longdescAttr, value);
       
   268 }
       
   269 
       
   270 String HTMLFrameElementBase::marginHeight() const
       
   271 {
       
   272     return getAttribute(marginheightAttr);
       
   273 }
       
   274 
       
   275 void HTMLFrameElementBase::setMarginHeight(const String &value)
       
   276 {
       
   277     setAttribute(marginheightAttr, value);
       
   278 }
       
   279 
       
   280 String HTMLFrameElementBase::marginWidth() const
       
   281 {
       
   282     return getAttribute(marginwidthAttr);
       
   283 }
       
   284 
       
   285 void HTMLFrameElementBase::setMarginWidth(const String &value)
       
   286 {
       
   287     setAttribute(marginwidthAttr, value);
       
   288 }
       
   289 
       
   290 String HTMLFrameElementBase::name() const
       
   291 {
       
   292     return getAttribute(nameAttr);
       
   293 }
       
   294 
       
   295 void HTMLFrameElementBase::setName(const String &value)
       
   296 {
       
   297     setAttribute(nameAttr, value);
       
   298 }
       
   299 
       
   300 void HTMLFrameElementBase::setNoResize(bool noResize)
       
   301 {
       
   302     setAttribute(noresizeAttr, noResize ? "" : 0);
       
   303 }
       
   304 
       
   305 String HTMLFrameElementBase::scrolling() const
       
   306 {
       
   307     return getAttribute(scrollingAttr);
       
   308 }
       
   309 
       
   310 void HTMLFrameElementBase::setScrolling(const String &value)
       
   311 {
       
   312     setAttribute(scrollingAttr, value);
       
   313 }
       
   314 
       
   315 String HTMLFrameElementBase::src() const
       
   316 {
       
   317     return document()->completeURL(getAttribute(srcAttr));
       
   318 }
       
   319 
       
   320 void HTMLFrameElementBase::setSrc(const String &value)
       
   321 {
       
   322     setAttribute(srcAttr, value);
       
   323 }
       
   324 
       
   325 int HTMLFrameElementBase::width() const
       
   326 {
       
   327     if (!renderer())
       
   328         return 0;
       
   329     
       
   330     document()->updateLayoutIgnorePendingStylesheets();
       
   331     return renderer()->width();
       
   332 }
       
   333 
       
   334 int HTMLFrameElementBase::height() const
       
   335 {
       
   336     if (!renderer())
       
   337         return 0;
       
   338     
       
   339     document()->updateLayoutIgnorePendingStylesheets();
       
   340     return renderer()->height();
       
   341 }
       
   342 
       
   343 } // namespace WebCore