WebKit2/WebProcess/WebPage/WebFrame.cpp
changeset 0 4f2f89ce4247
equal deleted inserted replaced
-1:000000000000 0:4f2f89ce4247
       
     1 /*
       
     2  * Copyright (C) 2010 Apple Inc. All rights reserved.
       
     3  *
       
     4  * Redistribution and use in source and binary forms, with or without
       
     5  * modification, are permitted provided that the following conditions
       
     6  * are met:
       
     7  * 1. Redistributions of source code must retain the above copyright
       
     8  *    notice, this list of conditions and the following disclaimer.
       
     9  * 2. Redistributions in binary form must reproduce the above copyright
       
    10  *    notice, this list of conditions and the following disclaimer in the
       
    11  *    documentation and/or other materials provided with the distribution.
       
    12  *
       
    13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
       
    14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
       
    15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
       
    16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
       
    17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
       
    18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
       
    19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
       
    20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
       
    21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
       
    22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
       
    23  * THE POSSIBILITY OF SUCH DAMAGE.
       
    24  */
       
    25 
       
    26 #include "WebFrame.h"
       
    27 
       
    28 #include "WebPage.h"
       
    29 #include <WebCore/AnimationController.h>
       
    30 #include <WebCore/Frame.h>
       
    31 #include <WebCore/HTMLFrameOwnerElement.h>
       
    32 #include <WebCore/PlatformString.h>
       
    33 
       
    34 #ifndef NDEBUG
       
    35 #include <wtf/RefCountedLeakCounter.h>
       
    36 #endif
       
    37 
       
    38 using namespace WebCore;
       
    39 
       
    40 namespace WebKit {
       
    41 
       
    42 #ifndef NDEBUG
       
    43 static WTF::RefCountedLeakCounter webFrameCounter("WebFrame");
       
    44 #endif
       
    45 
       
    46 static uint64_t generateFrameID()
       
    47 {
       
    48     static uint64_t uniqueFrameID = 1;
       
    49     return uniqueFrameID++;
       
    50 }
       
    51 
       
    52 static uint64_t generateListenerID()
       
    53 {
       
    54     static uint64_t uniqueListenerID = 1;
       
    55     return uniqueListenerID++;
       
    56 }
       
    57 
       
    58 PassRefPtr<WebFrame> WebFrame::createMainFrame(WebPage* page)
       
    59 {
       
    60     return create(page, String(), 0);
       
    61 }
       
    62 
       
    63 PassRefPtr<WebFrame> WebFrame::createSubframe(WebPage* page, const String& frameName, HTMLFrameOwnerElement* ownerElement)
       
    64 {
       
    65     return create(page, frameName, ownerElement);
       
    66 }
       
    67 
       
    68 PassRefPtr<WebFrame> WebFrame::create(WebPage* page, const String& frameName, HTMLFrameOwnerElement* ownerElement)
       
    69 {
       
    70     RefPtr<WebFrame> frame = adoptRef(new WebFrame(page, frameName, ownerElement));
       
    71     
       
    72     // Add explict ref() that will be balanced in WebFrameLoaderClient::frameLoaderDestroyed().
       
    73     frame->ref();
       
    74     
       
    75     return frame.release();
       
    76 }
       
    77 
       
    78 WebFrame::WebFrame(WebPage* page, const String& frameName, HTMLFrameOwnerElement* ownerElement)
       
    79     : m_page(page)
       
    80     , m_coreFrame(0)
       
    81     , m_policyListenerID(0)
       
    82     , m_policyFunction(0)
       
    83     , m_frameLoaderClient(this)
       
    84     , m_loadListener(0)
       
    85     , m_frameID(generateFrameID())
       
    86 {
       
    87     m_page->addWebFrame(m_frameID, this);
       
    88 
       
    89     RefPtr<Frame> frame = Frame::create(page->corePage(), ownerElement, &m_frameLoaderClient);
       
    90     m_coreFrame = frame.get();
       
    91 
       
    92     frame->tree()->setName(frameName);
       
    93 
       
    94     if (ownerElement) {
       
    95         ASSERT(ownerElement->document()->frame());
       
    96         ownerElement->document()->frame()->tree()->appendChild(frame);
       
    97     }
       
    98 
       
    99     frame->init();
       
   100 
       
   101 #ifndef NDEBUG
       
   102     webFrameCounter.increment();
       
   103 #endif
       
   104 }
       
   105 
       
   106 WebFrame::~WebFrame()
       
   107 {
       
   108     ASSERT(!m_coreFrame);
       
   109 
       
   110 #ifndef NDEBUG
       
   111     webFrameCounter.decrement();
       
   112 #endif
       
   113 }
       
   114 
       
   115 void WebFrame::invalidate()
       
   116 {
       
   117     m_page->removeWebFrame(m_frameID);
       
   118     m_coreFrame = 0;
       
   119 }
       
   120 
       
   121 uint64_t WebFrame::setUpPolicyListener(WebCore::FramePolicyFunction policyFunction)
       
   122 {
       
   123     // FIXME: <rdar://5634381> We need to support multiple active policy listeners.
       
   124 
       
   125     invalidatePolicyListener();
       
   126 
       
   127     m_policyListenerID = generateListenerID();
       
   128     m_policyFunction = policyFunction;
       
   129     return m_policyListenerID;
       
   130 }
       
   131 
       
   132 void WebFrame::invalidatePolicyListener()
       
   133 {
       
   134     if (!m_policyListenerID)
       
   135         return;
       
   136 
       
   137     m_policyListenerID = 0;
       
   138     m_policyFunction = 0;
       
   139 }
       
   140 
       
   141 void WebFrame::didReceivePolicyDecision(uint64_t listenerID, PolicyAction action)
       
   142 {
       
   143     if (!m_coreFrame)
       
   144         return;
       
   145 
       
   146     if (!m_policyListenerID)
       
   147         return;
       
   148 
       
   149     if (listenerID != m_policyListenerID)
       
   150         return;
       
   151 
       
   152     ASSERT(m_policyFunction);
       
   153 
       
   154     FramePolicyFunction function = m_policyFunction;
       
   155 
       
   156     invalidatePolicyListener();
       
   157 
       
   158     (m_coreFrame->loader()->policyChecker()->*function)(action);
       
   159 }
       
   160 
       
   161 bool WebFrame::isMainFrame() const
       
   162 {
       
   163     return m_page->mainFrame() == this;
       
   164 }
       
   165 
       
   166 String WebFrame::name() const
       
   167 {
       
   168     if (!m_coreFrame)
       
   169         return String();
       
   170 
       
   171     return m_coreFrame->tree()->name();
       
   172 }
       
   173 
       
   174 String WebFrame::url() const
       
   175 {
       
   176     if (!m_coreFrame)
       
   177         return String();
       
   178 
       
   179     return m_coreFrame->loader()->url().string();
       
   180 }
       
   181 
       
   182 String WebFrame::innerText() const
       
   183 {
       
   184     if (!m_coreFrame)
       
   185         return String();
       
   186 
       
   187     return m_coreFrame->document()->documentElement()->innerText();
       
   188 }
       
   189 
       
   190 static void childFrameRef(const void* frame)
       
   191 {
       
   192     static_cast<WebFrame*>(const_cast<void*>(frame))->ref();
       
   193 }
       
   194 
       
   195 static void childFrameDeref(const void* frame)
       
   196 {
       
   197     static_cast<WebFrame*>(const_cast<void*>(frame))->deref();
       
   198 }
       
   199 
       
   200 PassRefPtr<ImmutableArray> WebFrame::childFrames()
       
   201 {
       
   202     if (!m_coreFrame)
       
   203         return ImmutableArray::create();
       
   204 
       
   205     size_t size = m_coreFrame->tree()->childCount();
       
   206     if (!size)
       
   207         return ImmutableArray::create();
       
   208 
       
   209     void** array = new void*[size];
       
   210     unsigned i = 0;
       
   211     for (Frame* child = m_coreFrame->tree()->firstChild(); child; child = child->tree()->nextSibling(), ++i) {
       
   212         WebFrame* webFrame = static_cast<WebFrameLoaderClient*>(child->loader()->client())->webFrame();
       
   213         webFrame->ref();
       
   214         array[i] = webFrame;
       
   215     }
       
   216 
       
   217     ImmutableArray::ImmutableArrayCallbacks callbacks = {
       
   218         childFrameRef,
       
   219         childFrameDeref
       
   220     };
       
   221     return ImmutableArray::adopt(array, size, &callbacks);
       
   222 }
       
   223 
       
   224 unsigned WebFrame::numberOfActiveAnimations()
       
   225 {
       
   226     if (!m_coreFrame)
       
   227         return 0;
       
   228 
       
   229     AnimationController* controller = m_coreFrame->animation();
       
   230     if (!controller)
       
   231         return 0;
       
   232 
       
   233     return controller->numberOfActiveAnimations();
       
   234 }
       
   235 
       
   236 bool WebFrame::pauseAnimationOnElementWithId(const String& animationName, const String& elementID, double time)
       
   237 {
       
   238     if (!m_coreFrame)
       
   239         return false;
       
   240 
       
   241     AnimationController* controller = m_coreFrame->animation();
       
   242     if (!controller)
       
   243         return false;
       
   244 
       
   245     if (!m_coreFrame->document())
       
   246         return false;
       
   247 
       
   248     Node* coreNode = m_coreFrame->document()->getElementById(elementID);
       
   249     if (!coreNode || !coreNode->renderer())
       
   250         return false;
       
   251 
       
   252     return controller->pauseAnimationAtTime(coreNode->renderer(), animationName, time);
       
   253 }
       
   254 
       
   255 
       
   256 } // namespace WebKit