Home | History | Annotate | Download | only in frame
      1 /*
      2  * Copyright (C) 1998, 1999 Torben Weis <weis (at) kde.org>
      3  *                     1999 Lars Knoll <knoll (at) kde.org>
      4  *                     1999 Antti Koivisto <koivisto (at) kde.org>
      5  *                     2000 Simon Hausmann <hausmann (at) kde.org>
      6  *                     2000 Stefan Schimanski <1Stein (at) gmx.de>
      7  *                     2001 George Staikos <staikos (at) kde.org>
      8  * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
      9  * Copyright (C) 2005 Alexey Proskuryakov <ap (at) nypop.com>
     10  * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
     11  * Copyright (C) 2008 Eric Seidel <eric (at) webkit.org>
     12  * Copyright (C) 2008 Google Inc.
     13  *
     14  * This library is free software; you can redistribute it and/or
     15  * modify it under the terms of the GNU Library General Public
     16  * License as published by the Free Software Foundation; either
     17  * version 2 of the License, or (at your option) any later version.
     18  *
     19  * This library is distributed in the hope that it will be useful,
     20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     22  * Library General Public License for more details.
     23  *
     24  * You should have received a copy of the GNU Library General Public License
     25  * along with this library; see the file COPYING.LIB.  If not, write to
     26  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     27  * Boston, MA 02110-1301, USA.
     28  */
     29 
     30 #include "config.h"
     31 #include "core/frame/Frame.h"
     32 
     33 #include "core/dom/DocumentType.h"
     34 #include "core/events/Event.h"
     35 #include "core/frame/LocalDOMWindow.h"
     36 #include "core/frame/FrameDestructionObserver.h"
     37 #include "core/frame/FrameHost.h"
     38 #include "core/frame/Settings.h"
     39 #include "core/html/HTMLFrameElementBase.h"
     40 #include "core/inspector/InspectorInstrumentation.h"
     41 #include "core/loader/EmptyClients.h"
     42 #include "core/loader/FrameLoaderClient.h"
     43 #include "core/page/Chrome.h"
     44 #include "core/page/ChromeClient.h"
     45 #include "core/page/EventHandler.h"
     46 #include "core/page/FocusController.h"
     47 #include "core/page/Page.h"
     48 #include "core/rendering/RenderPart.h"
     49 #include "public/platform/WebLayer.h"
     50 #include "wtf/PassOwnPtr.h"
     51 #include "wtf/RefCountedLeakCounter.h"
     52 
     53 namespace WebCore {
     54 
     55 using namespace HTMLNames;
     56 
     57 DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, frameCounter, ("Frame"));
     58 
     59 Frame::Frame(FrameClient* client, FrameHost* host, FrameOwner* owner)
     60     : m_treeNode(this)
     61     , m_host(host)
     62     , m_owner(owner)
     63     , m_client(client)
     64     , m_remotePlatformLayer(0)
     65 {
     66     ASSERT(page());
     67 
     68 #ifndef NDEBUG
     69     frameCounter.increment();
     70 #endif
     71 
     72     if (m_owner) {
     73         page()->incrementSubframeCount();
     74         if (m_owner->isLocal())
     75             toHTMLFrameOwnerElement(m_owner)->setContentFrame(*this);
     76     } else {
     77         page()->setMainFrame(this);
     78     }
     79 }
     80 
     81 Frame::~Frame()
     82 {
     83     disconnectOwnerElement();
     84     setDOMWindow(nullptr);
     85 
     86     // FIXME: We should not be doing all this work inside the destructor
     87 
     88 #ifndef NDEBUG
     89     frameCounter.decrement();
     90 #endif
     91 
     92     HashSet<FrameDestructionObserver*>::iterator stop = m_destructionObservers.end();
     93     for (HashSet<FrameDestructionObserver*>::iterator it = m_destructionObservers.begin(); it != stop; ++it)
     94         (*it)->frameDestroyed();
     95 }
     96 
     97 void Frame::addDestructionObserver(FrameDestructionObserver* observer)
     98 {
     99     m_destructionObservers.add(observer);
    100 }
    101 
    102 void Frame::removeDestructionObserver(FrameDestructionObserver* observer)
    103 {
    104     m_destructionObservers.remove(observer);
    105 }
    106 
    107 FrameHost* Frame::host() const
    108 {
    109     return m_host;
    110 }
    111 
    112 Page* Frame::page() const
    113 {
    114     if (m_host)
    115         return &m_host->page();
    116     return 0;
    117 }
    118 
    119 Settings* Frame::settings() const
    120 {
    121     if (m_host)
    122         return &m_host->settings();
    123     return 0;
    124 }
    125 
    126 void Frame::setDOMWindow(PassRefPtrWillBeRawPtr<LocalDOMWindow> domWindow)
    127 {
    128     if (m_domWindow)
    129         m_domWindow->reset();
    130     m_domWindow = domWindow;
    131 }
    132 
    133 static ChromeClient& emptyChromeClient()
    134 {
    135     DEFINE_STATIC_LOCAL(EmptyChromeClient, client, ());
    136     return client;
    137 }
    138 
    139 ChromeClient& Frame::chromeClient() const
    140 {
    141     if (Page* page = this->page())
    142         return page->chrome().client();
    143     return emptyChromeClient();
    144 }
    145 
    146 RenderPart* Frame::ownerRenderer() const
    147 {
    148     if (!deprecatedLocalOwner())
    149         return 0;
    150     RenderObject* object = deprecatedLocalOwner()->renderer();
    151     if (!object)
    152         return 0;
    153     // FIXME: If <object> is ever fixed to disassociate itself from frames
    154     // that it has started but canceled, then this can turn into an ASSERT
    155     // since ownerElement() would be 0 when the load is canceled.
    156     // https://bugs.webkit.org/show_bug.cgi?id=18585
    157     if (!object->isRenderPart())
    158         return 0;
    159     return toRenderPart(object);
    160 }
    161 
    162 
    163 void Frame::willDetachFrameHost()
    164 {
    165     HashSet<FrameDestructionObserver*>::iterator stop = m_destructionObservers.end();
    166     for (HashSet<FrameDestructionObserver*>::iterator it = m_destructionObservers.begin(); it != stop; ++it)
    167         (*it)->willDetachFrameHost();
    168 
    169     // FIXME: Page should take care of updating focus/scrolling instead of Frame.
    170     // FIXME: It's unclear as to why this is called more than once, but it is,
    171     // so page() could be null.
    172     if (page() && page()->focusController().focusedFrame() == this)
    173         page()->focusController().setFocusedFrame(nullptr);
    174 }
    175 
    176 void Frame::detachFromFrameHost()
    177 {
    178     m_host = 0;
    179 }
    180 
    181 bool Frame::isMainFrame() const
    182 {
    183     Page* page = this->page();
    184     return page && this == page->mainFrame();
    185 }
    186 
    187 void Frame::disconnectOwnerElement()
    188 {
    189     if (m_owner) {
    190         if (m_owner->isLocal())
    191             toHTMLFrameOwnerElement(m_owner)->clearContentFrame();
    192         if (page())
    193             page()->decrementSubframeCount();
    194     }
    195     m_owner = 0;
    196 }
    197 
    198 HTMLFrameOwnerElement* Frame::deprecatedLocalOwner() const
    199 {
    200     return m_owner && m_owner->isLocal() ? toHTMLFrameOwnerElement(m_owner) : 0;
    201 }
    202 
    203 } // namespace WebCore
    204