Home | History | Annotate | Download | only in UIProcess
      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 "config.h"
     27 #include "WebFrameProxy.h"
     28 
     29 #include "WebCertificateInfo.h"
     30 #include "WebContext.h"
     31 #include "WebFormSubmissionListenerProxy.h"
     32 #include "WebFramePolicyListenerProxy.h"
     33 #include "WebPageMessages.h"
     34 #include "WebPageProxy.h"
     35 #include <WebCore/DOMImplementation.h>
     36 #include <WebCore/Image.h>
     37 #include <wtf/text/WTFString.h>
     38 
     39 using namespace WebCore;
     40 using namespace std;
     41 
     42 namespace WebKit {
     43 
     44 WebFrameProxy::WebFrameProxy(WebPageProxy* page, uint64_t frameID)
     45     : m_page(page)
     46     , m_parentFrame(0)
     47     , m_nextSibling(0)
     48     , m_previousSibling(0)
     49     , m_firstChild(0)
     50     , m_lastChild(0)
     51     , m_loadState(LoadStateFinished)
     52     , m_isFrameSet(false)
     53     , m_frameID(frameID)
     54 {
     55     WebContext::statistics().wkFrameCount++;
     56 }
     57 
     58 WebFrameProxy::~WebFrameProxy()
     59 {
     60     WebContext::statistics().wkFrameCount--;
     61 }
     62 
     63 void WebFrameProxy::disconnect()
     64 {
     65     m_page = 0;
     66     m_parentFrame = 0;
     67     m_nextSibling = 0;
     68     m_previousSibling = 0;
     69     m_firstChild = 0;
     70     m_lastChild = 0;
     71 
     72     if (m_activeListener) {
     73         m_activeListener->invalidate();
     74         m_activeListener = 0;
     75     }
     76 }
     77 
     78 bool WebFrameProxy::isMainFrame() const
     79 {
     80     if (!m_page)
     81         return false;
     82 
     83     return this == m_page->mainFrame();
     84 }
     85 
     86 void WebFrameProxy::stopLoading() const
     87 {
     88     if (!m_page)
     89         return;
     90 
     91     if (!m_page->isValid())
     92         return;
     93 
     94     m_page->process()->send(Messages::WebPage::StopLoadingFrame(m_frameID), m_page->pageID());
     95 }
     96 
     97 bool WebFrameProxy::canProvideSource() const
     98 {
     99     return isDisplayingMarkupDocument();
    100 }
    101 
    102 bool WebFrameProxy::canShowMIMEType(const String& mimeType) const
    103 {
    104     if (!m_page)
    105         return false;
    106 
    107     if (m_page->canShowMIMEType(mimeType))
    108         return true;
    109 
    110 #if PLATFORM(MAC)
    111     // On Mac, we can show PDFs in the main frame.
    112     if (isMainFrame() && !mimeType.isEmpty())
    113         return WebContext::pdfAndPostScriptMIMETypes().contains(mimeType);
    114 #endif
    115 
    116     return false;
    117 }
    118 
    119 bool WebFrameProxy::isDisplayingStandaloneImageDocument() const
    120 {
    121     return Image::supportsType(m_MIMEType);
    122 }
    123 
    124 bool WebFrameProxy::isDisplayingMarkupDocument() const
    125 {
    126     // FIXME: This check should be moved to somewhere in WebCore.
    127     // FIXME: This returns false when displaying a web archive.
    128     return m_MIMEType == "text/html" || m_MIMEType == "image/svg+xml" || DOMImplementation::isXMLMIMEType(m_MIMEType);
    129 }
    130 
    131 void WebFrameProxy::didStartProvisionalLoad(const String& url)
    132 {
    133     ASSERT(m_loadState == LoadStateFinished);
    134     ASSERT(m_provisionalURL.isEmpty());
    135     m_loadState = LoadStateProvisional;
    136     m_provisionalURL = url;
    137 }
    138 
    139 void WebFrameProxy::didReceiveServerRedirectForProvisionalLoad(const String& url)
    140 {
    141     ASSERT(m_loadState == LoadStateProvisional);
    142     m_provisionalURL = url;
    143 }
    144 
    145 void WebFrameProxy::didFailProvisionalLoad()
    146 {
    147     ASSERT(m_loadState == LoadStateProvisional);
    148     m_loadState = LoadStateFinished;
    149     m_provisionalURL = String();
    150 }
    151 
    152 void WebFrameProxy::didCommitLoad(const String& contentType, const PlatformCertificateInfo& certificateInfo)
    153 {
    154     ASSERT(m_loadState == LoadStateProvisional);
    155     m_loadState = LoadStateCommitted;
    156     m_url = m_provisionalURL;
    157     m_provisionalURL = String();
    158     m_title = String();
    159     m_MIMEType = contentType;
    160     m_isFrameSet = false;
    161     m_certificateInfo = WebCertificateInfo::create(certificateInfo);
    162 }
    163 
    164 void WebFrameProxy::didFinishLoad()
    165 {
    166     ASSERT(m_loadState == LoadStateCommitted);
    167     ASSERT(m_provisionalURL.isEmpty());
    168     m_loadState = LoadStateFinished;
    169 }
    170 
    171 void WebFrameProxy::didFailLoad()
    172 {
    173     ASSERT(m_loadState == LoadStateCommitted);
    174     ASSERT(m_provisionalURL.isEmpty());
    175     m_loadState = LoadStateFinished;
    176     m_title = String();
    177 }
    178 
    179 void WebFrameProxy::didSameDocumentNavigation(const String& url)
    180 {
    181     m_url = url;
    182 }
    183 
    184 void WebFrameProxy::didChangeTitle(const String& title)
    185 {
    186     m_title = title;
    187 }
    188 
    189 void WebFrameProxy::appendChild(WebFrameProxy* child)
    190 {
    191     ASSERT(child->page() == page());
    192     ASSERT(!child->m_parentFrame);
    193     ASSERT(!child->m_nextSibling);
    194     ASSERT(!child->m_previousSibling);
    195 
    196     child->m_parentFrame = this;
    197 
    198     WebFrameProxy* oldLast = m_lastChild;
    199     m_lastChild = child;
    200 
    201     if (oldLast) {
    202         ASSERT(!oldLast->m_nextSibling);
    203         child->m_previousSibling = oldLast;
    204         oldLast->m_nextSibling = child;
    205     } else
    206         m_firstChild = child;
    207 }
    208 
    209 void WebFrameProxy::removeChild(WebFrameProxy* child)
    210 {
    211     child->m_parentFrame = 0;
    212 
    213     WebFrameProxy*& newLocationForNext = m_firstChild == child ? m_firstChild : child->m_previousSibling->m_nextSibling;
    214     WebFrameProxy*& newLocationForPrevious = m_lastChild == child ? m_lastChild : child->m_nextSibling->m_previousSibling;
    215     swap(newLocationForNext, child->m_nextSibling);
    216     swap(newLocationForPrevious, child->m_previousSibling);
    217     child->m_previousSibling = 0;
    218     child->m_nextSibling = 0;
    219 }
    220 
    221 bool WebFrameProxy::isDescendantOf(const WebFrameProxy* ancestor) const
    222 {
    223     if (!ancestor)
    224         return false;
    225 
    226     if (m_page != ancestor->m_page)
    227         return false;
    228 
    229     for (const WebFrameProxy* frame = this; frame; frame = frame->m_parentFrame) {
    230         if (frame == ancestor)
    231             return true;
    232     }
    233 
    234     return false;
    235 }
    236 
    237 void WebFrameProxy::dumpFrameTreeToSTDOUT(unsigned indent)
    238 {
    239     if (!indent && m_parentFrame)
    240         printf("NOTE: Printing subtree.\n");
    241 
    242     for (unsigned i = 0; i < indent; ++i)
    243         printf(" ");
    244     printf("| FRAME %d %s\n", (int)m_frameID, m_url.utf8().data());
    245 
    246     for (WebFrameProxy* child = m_firstChild; child; child = child->m_nextSibling)
    247         child->dumpFrameTreeToSTDOUT(indent + 4);
    248 }
    249 
    250 void WebFrameProxy::didRemoveFromHierarchy()
    251 {
    252     if (m_parentFrame)
    253         m_parentFrame->removeChild(this);
    254 }
    255 
    256 PassRefPtr<ImmutableArray> WebFrameProxy::childFrames()
    257 {
    258     if (!m_firstChild)
    259         return ImmutableArray::create();
    260 
    261     Vector<RefPtr<APIObject> > vector;
    262     for (WebFrameProxy* child = m_firstChild; child; child = child->m_nextSibling)
    263         vector.append(child);
    264 
    265     return ImmutableArray::adopt(vector);
    266 }
    267 
    268 void WebFrameProxy::receivedPolicyDecision(WebCore::PolicyAction action, uint64_t listenerID)
    269 {
    270     if (!m_page)
    271         return;
    272 
    273     ASSERT(m_activeListener);
    274     ASSERT(m_activeListener->listenerID() == listenerID);
    275     m_page->receivedPolicyDecision(action, this, listenerID);
    276 }
    277 
    278 WebFramePolicyListenerProxy* WebFrameProxy::setUpPolicyListenerProxy(uint64_t listenerID)
    279 {
    280     if (m_activeListener)
    281         m_activeListener->invalidate();
    282     m_activeListener = WebFramePolicyListenerProxy::create(this, listenerID);
    283     return static_cast<WebFramePolicyListenerProxy*>(m_activeListener.get());
    284 }
    285 
    286 WebFormSubmissionListenerProxy* WebFrameProxy::setUpFormSubmissionListenerProxy(uint64_t listenerID)
    287 {
    288     if (m_activeListener)
    289         m_activeListener->invalidate();
    290     m_activeListener = WebFormSubmissionListenerProxy::create(this, listenerID);
    291     return static_cast<WebFormSubmissionListenerProxy*>(m_activeListener.get());
    292 }
    293 
    294 void WebFrameProxy::getWebArchive(PassRefPtr<DataCallback> callback)
    295 {
    296     if (!m_page) {
    297         callback->invalidate();
    298         return;
    299     }
    300 
    301     m_page->getWebArchiveOfFrame(this, callback);
    302 }
    303 
    304 void WebFrameProxy::getMainResourceData(PassRefPtr<DataCallback> callback)
    305 {
    306     if (!m_page) {
    307         callback->invalidate();
    308         return;
    309     }
    310 
    311     m_page->getMainResourceDataOfFrame(this, callback);
    312 }
    313 
    314 void WebFrameProxy::getResourceData(WebURL* resourceURL, PassRefPtr<DataCallback> callback)
    315 {
    316     if (!m_page) {
    317         callback->invalidate();
    318         return;
    319     }
    320 
    321     m_page->getResourceDataFromFrame(this, resourceURL, callback);
    322 }
    323 
    324 } // namespace WebKit
    325