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