Document::securityOrigin() should return a reference.
[WebKit-https.git] / Source / WebKit2 / WebProcess / WebPage / WebFrame.cpp
index 7f65cd0..3629d4a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2010-2016 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 
 #include "APIArray.h"
 #include "DownloadManager.h"
+#include "FrameInfoData.h"
+#include "InjectedBundleFileHandle.h"
 #include "InjectedBundleHitTestResult.h"
 #include "InjectedBundleNodeHandle.h"
 #include "InjectedBundleRangeHandle.h"
 #include "InjectedBundleScriptWorld.h"
+#include "NetworkConnectionToWebProcessMessages.h"
+#include "NetworkProcessConnection.h"
 #include "PluginView.h"
 #include "WKAPICast.h"
 #include "WKBundleAPICast.h"
 #include "WebChromeClient.h"
+#include "WebCoreArgumentCoders.h"
 #include "WebDocumentLoader.h"
 #include "WebPage.h"
 #include "WebPageProxyMessages.h"
 #include <WebCore/Chrome.h>
 #include <WebCore/DocumentLoader.h>
 #include <WebCore/EventHandler.h>
+#include <WebCore/File.h>
 #include <WebCore/Frame.h>
+#include <WebCore/FrameSnapshotting.h>
 #include <WebCore/FrameView.h>
 #include <WebCore/HTMLFormElement.h>
 #include <WebCore/HTMLFrameOwnerElement.h>
 #include <WebCore/HTMLInputElement.h>
 #include <WebCore/HTMLNames.h>
+#include <WebCore/HTMLSelectElement.h>
 #include <WebCore/HTMLTextAreaElement.h>
+#include <WebCore/ImageBuffer.h>
 #include <WebCore/JSCSSStyleDeclaration.h>
 #include <WebCore/JSElement.h>
+#include <WebCore/JSFile.h>
 #include <WebCore/JSRange.h>
 #include <WebCore/MainFrame.h>
 #include <WebCore/NetworkingContext.h>
 #include <WebCore/Page.h>
 #include <WebCore/PluginDocument.h>
 #include <WebCore/RenderTreeAsText.h>
-#include <WebCore/ResourceBuffer.h>
-#include <WebCore/ResourceLoader.h>
 #include <WebCore/ScriptController.h>
 #include <WebCore/SecurityOrigin.h>
+#include <WebCore/SubresourceLoader.h>
 #include <WebCore/TextIterator.h>
 #include <WebCore/TextResourceDecoder.h>
 #include <wtf/text/StringBuilder.h>
 #include <WebCore/LegacyWebArchive.h>
 #endif
 
-#if ENABLE(NETWORK_PROCESS)
-#include "NetworkConnectionToWebProcessMessages.h"
-#include "NetworkProcessConnection.h"
-#include "WebCoreArgumentCoders.h"
-#endif
-
 #ifndef NDEBUG
 #include <wtf/RefCountedLeakCounter.h>
 #endif
@@ -108,39 +111,39 @@ static uint64_t generateListenerID()
 
 PassRefPtr<WebFrame> WebFrame::createWithCoreMainFrame(WebPage* page, WebCore::Frame* coreFrame)
 {
-    RefPtr<WebFrame> frame = create(std::unique_ptr<WebFrameLoaderClient>(static_cast<WebFrameLoaderClient*>(&coreFrame->loader().client())));
-    page->send(Messages::WebPageProxy::DidCreateMainFrame(frame->frameID()));
+    auto frame = create(std::unique_ptr<WebFrameLoaderClient>(static_cast<WebFrameLoaderClient*>(&coreFrame->loader().client())));
+    page->send(Messages::WebPageProxy::DidCreateMainFrame(frame->frameID()), page->pageID(), IPC::SendOption::DispatchMessageEvenWhenWaitingForSyncReply);
 
     frame->m_coreFrame = coreFrame;
     frame->m_coreFrame->tree().setName(String());
     frame->m_coreFrame->init();
-    return frame.release();
+    return frame;
 }
 
 PassRefPtr<WebFrame> WebFrame::createSubframe(WebPage* page, const String& frameName, HTMLFrameOwnerElement* ownerElement)
 {
-    RefPtr<WebFrame> frame = create(std::make_unique<WebFrameLoaderClient>());
-    page->send(Messages::WebPageProxy::DidCreateSubframe(frame->frameID()));
+    auto frame = create(std::make_unique<WebFrameLoaderClient>());
+    page->send(Messages::WebPageProxy::DidCreateSubframe(frame->frameID()), page->pageID(), IPC::SendOption::DispatchMessageEvenWhenWaitingForSyncReply);
 
-    RefPtr<Frame> coreFrame = Frame::create(page->corePage(), ownerElement, frame->m_frameLoaderClient.get());
-    frame->m_coreFrame = coreFrame.get();
+    Ref<WebCore::Frame> coreFrame = Frame::create(page->corePage(), ownerElement, frame->m_frameLoaderClient.get());
+    frame->m_coreFrame = coreFrame.ptr();
     frame->m_coreFrame->tree().setName(frameName);
     if (ownerElement) {
         ASSERT(ownerElement->document().frame());
-        ownerElement->document().frame()->tree().appendChild(coreFrame.release());
+        ownerElement->document().frame()->tree().appendChild(WTFMove(coreFrame));
     }
     frame->m_coreFrame->init();
-    return frame.release();
+    return frame;
 }
 
 PassRefPtr<WebFrame> WebFrame::create(std::unique_ptr<WebFrameLoaderClient> frameLoaderClient)
 {
-    RefPtr<WebFrame> frame = adoptRef(new WebFrame(std::move(frameLoaderClient)));
+    auto frame = adoptRef(*new WebFrame(WTFMove(frameLoaderClient)));
 
     // Add explict ref() that will be balanced in WebFrameLoaderClient::frameLoaderDestroyed().
     frame->ref();
 
-    return frame.release();
+    return WTFMove(frame);
 }
 
 WebFrame::WebFrame(std::unique_ptr<WebFrameLoaderClient> frameLoaderClient)
@@ -148,12 +151,15 @@ WebFrame::WebFrame(std::unique_ptr<WebFrameLoaderClient> frameLoaderClient)
     , m_policyListenerID(0)
     , m_policyFunction(0)
     , m_policyDownloadID(0)
-    , m_frameLoaderClient(std::move(frameLoaderClient))
+    , m_frameLoaderClient(WTFMove(frameLoaderClient))
     , m_loadListener(0)
     , m_frameID(generateFrameID())
+#if PLATFORM(IOS)
+    , m_firstLayerTreeTransactionIDAfterDidCommitLoad(0)
+#endif
 {
     m_frameLoaderClient->setWebFrame(this);
-    WebProcess::shared().addWebFrame(m_frameID, this);
+    WebProcess::singleton().addWebFrame(m_frameID, this);
 
 #ifndef NDEBUG
     webFrameCounter.increment();
@@ -189,9 +195,22 @@ WebFrame* WebFrame::fromCoreFrame(Frame& frame)
     return webFrameLoaderClient->webFrame();
 }
 
+FrameInfoData WebFrame::info() const
+{
+    FrameInfoData info;
+
+    info.isMainFrame = isMainFrame();
+    // FIXME: This should use the full request.
+    info.request = ResourceRequest(URL(URL(), url()));
+    info.securityOrigin = SecurityOriginData::fromFrame(m_coreFrame);
+    info.frameID = m_frameID;
+    
+    return info;
+}
+
 void WebFrame::invalidate()
 {
-    WebProcess::shared().removeWebFrame(m_frameID);
+    WebProcess::singleton().removeWebFrame(m_frameID);
     m_coreFrame = 0;
 }
 
@@ -211,12 +230,12 @@ void WebFrame::invalidatePolicyListener()
     if (!m_policyListenerID)
         return;
 
-    m_policyDownloadID = 0;
+    m_policyDownloadID = { };
     m_policyListenerID = 0;
     m_policyFunction = 0;
 }
 
-void WebFrame::didReceivePolicyDecision(uint64_t listenerID, PolicyAction action, uint64_t navigationID, uint64_t downloadID)
+void WebFrame::didReceivePolicyDecision(uint64_t listenerID, PolicyAction action, uint64_t navigationID, DownloadID downloadID)
 {
     if (!m_coreFrame)
         return;
@@ -229,70 +248,54 @@ void WebFrame::didReceivePolicyDecision(uint64_t listenerID, PolicyAction action
 
     ASSERT(m_policyFunction);
 
-    FramePolicyFunction function = std::move(m_policyFunction);
+    FramePolicyFunction function = WTFMove(m_policyFunction);
 
     invalidatePolicyListener();
 
     m_policyDownloadID = downloadID;
     if (navigationID) {
-        WebDocumentLoader& documentLoader = static_cast<WebDocumentLoader&>(*m_coreFrame->loader().policyDocumentLoader());
-        documentLoader.setNavigationID(navigationID);
+        if (WebDocumentLoader* documentLoader = static_cast<WebDocumentLoader*>(m_coreFrame->loader().policyDocumentLoader()))
+            documentLoader->setNavigationID(navigationID);
     }
 
     function(action);
 }
 
-void WebFrame::startDownload(const WebCore::ResourceRequest& request)
+void WebFrame::startDownload(const WebCore::ResourceRequest& request, const String& suggestedName)
 {
-    ASSERT(m_policyDownloadID);
+    ASSERT(m_policyDownloadID.downloadID());
 
-    uint64_t policyDownloadID = m_policyDownloadID;
-    m_policyDownloadID = 0;
-
-#if ENABLE(NETWORK_PROCESS)
-    if (WebProcess::shared().usesNetworkProcess()) {
-        WebProcess::shared().networkConnection()->connection()->send(Messages::NetworkConnectionToWebProcess::StartDownload(page()->sessionID(), policyDownloadID, request), 0);
-        return;
-    }
-#endif
+    auto policyDownloadID = m_policyDownloadID;
+    m_policyDownloadID = { };
 
-    WebProcess::shared().downloadManager().startDownload(policyDownloadID, request);
+    auto& webProcess = WebProcess::singleton();
+    SessionID sessionID = page() ? page()->sessionID() : SessionID::defaultSessionID();
+    webProcess.networkConnection().connection().send(Messages::NetworkConnectionToWebProcess::StartDownload(sessionID, policyDownloadID, request, suggestedName), 0);
 }
 
-void WebFrame::convertMainResourceLoadToDownload(DocumentLoader* documentLoader, const ResourceRequest& request, const ResourceResponse& response)
+void WebFrame::convertMainResourceLoadToDownload(DocumentLoader* documentLoader, SessionID sessionID, const ResourceRequest& request, const ResourceResponse& response)
 {
-    ASSERT(m_policyDownloadID);
-
-    uint64_t policyDownloadID = m_policyDownloadID;
-    m_policyDownloadID = 0;
-
-    ResourceLoader* mainResourceLoader = documentLoader->mainResourceLoader();
+    ASSERT(m_policyDownloadID.downloadID());
 
-#if ENABLE(NETWORK_PROCESS)
-    if (WebProcess::shared().usesNetworkProcess()) {
-        // Use 0 to indicate that there is no main resource loader.
-        // This can happen if the main resource is in the WebCore memory cache.
-        uint64_t mainResourceLoadIdentifier;
-        if (mainResourceLoader)
-            mainResourceLoadIdentifier = mainResourceLoader->identifier();
-        else
-            mainResourceLoadIdentifier = 0;
+    auto policyDownloadID = m_policyDownloadID;
+    m_policyDownloadID = { };
 
-        WebProcess::shared().networkConnection()->connection()->send(Messages::NetworkConnectionToWebProcess::ConvertMainResourceLoadToDownload(mainResourceLoadIdentifier, policyDownloadID, request, response), 0);
-        return;
-    }
-#endif
+    SubresourceLoader* mainResourceLoader = documentLoader->mainResourceLoader();
 
-    if (!mainResourceLoader) {
-        // The main resource has already been loaded. Start a new download instead.
-        WebProcess::shared().downloadManager().startDownload(policyDownloadID, request);
-        return;
-    }
+    auto& webProcess = WebProcess::singleton();
+    // Use 0 to indicate that the resource load can't be converted and a new download must be started.
+    // This can happen if there is no loader because the main resource is in the WebCore memory cache,
+    // or because the conversion was attempted when not calling SubresourceLoader::didReceiveResponse().
+    uint64_t mainResourceLoadIdentifier;
+    if (mainResourceLoader)
+        mainResourceLoadIdentifier = mainResourceLoader->identifier();
+    else
+        mainResourceLoadIdentifier = 0;
 
-    WebProcess::shared().downloadManager().convertHandleToDownload(policyDownloadID, documentLoader->mainResourceLoader()->handle(), request, response);
+    webProcess.networkConnection().connection().send(Messages::NetworkConnectionToWebProcess::ConvertMainResourceLoadToDownload(sessionID, mainResourceLoadIdentifier, policyDownloadID, request, response), 0);
 }
 
-String WebFrame::source() const 
+String WebFrame::source() const
 {
     if (!m_coreFrame)
         return String();
@@ -305,7 +308,7 @@ String WebFrame::source() const
     DocumentLoader* documentLoader = m_coreFrame->loader().activeDocumentLoader();
     if (!documentLoader)
         return String();
-    RefPtr<ResourceBuffer> mainResourceData = documentLoader->mainResourceData();
+    RefPtr<SharedBuffer> mainResourceData = documentLoader->mainResourceData();
     if (!mainResourceData)
         return String();
     return decoder->encoding().decode(mainResourceData->data(), mainResourceData->size());
@@ -341,9 +344,7 @@ String WebFrame::contentsAsString() const
 
     RefPtr<Range> range = document->createRange();
 
-    ExceptionCode ec = 0;
-    range->selectNode(documentElement.get(), ec);
-    if (ec)
+    if (range->selectNode(*documentElement).hasException())
         return String();
 
     return plainText(range.get());
@@ -408,16 +409,16 @@ String WebFrame::url() const
     return documentLoader->url().string();
 }
 
-WebCore::CertificateInfo WebFrame::certificateInfo() const
+CertificateInfo WebFrame::certificateInfo() const
 {
     if (!m_coreFrame)
-        return CertificateInfo();
+        return { };
 
     DocumentLoader* documentLoader = m_coreFrame->loader().documentLoader();
     if (!documentLoader)
-        return CertificateInfo();
+        return { };
 
-    return CertificateInfo(documentLoader->response());
+    return valueOrCompute(documentLoader->response().certificateInfo(), [] { return CertificateInfo(); });
 }
 
 String WebFrame::innerText() const
@@ -439,7 +440,7 @@ WebFrame* WebFrame::parentFrame() const
     return WebFrame::fromCoreFrame(*m_coreFrame->ownerElement()->document().frame());
 }
 
-PassRefPtr<API::Array> WebFrame::childFrames()
+Ref<API::Array> WebFrame::childFrames()
 {
     if (!m_coreFrame)
         return API::Array::create();
@@ -457,7 +458,7 @@ PassRefPtr<API::Array> WebFrame::childFrames()
         vector.uncheckedAppend(webFrame);
     }
 
-    return API::Array::create(std::move(vector));
+    return API::Array::create(WTFMove(vector));
 }
 
 String WebFrame::layerTreeAsText() const
@@ -481,7 +482,7 @@ bool WebFrame::allowsFollowingLink(const WebCore::URL& url) const
     if (!m_coreFrame)
         return true;
         
-    return m_coreFrame->document()->securityOrigin()->canDisplay(url);
+    return m_coreFrame->document()->securityOrigin().canDisplay(url);
 }
 
 JSGlobalContextRef WebFrame::jsContext()
@@ -504,6 +505,35 @@ bool WebFrame::handlesPageScaleGesture() const
     return pluginView && pluginView->handlesPageScaleFactor();
 }
 
+bool WebFrame::requiresUnifiedScaleFactor() const
+{
+    if (!m_coreFrame->document()->isPluginDocument())
+        return 0;
+
+    PluginDocument* pluginDocument = static_cast<PluginDocument*>(m_coreFrame->document());
+    PluginView* pluginView = static_cast<PluginView*>(pluginDocument->pluginWidget());
+    return pluginView && pluginView->requiresUnifiedScaleFactor();
+}
+
+void WebFrame::setAccessibleName(const String& accessibleName)
+{
+    if (!AXObjectCache::accessibilityEnabled())
+        return;
+    
+    if (!m_coreFrame)
+        return;
+
+    auto* document = m_coreFrame->document();
+    if (!document)
+        return;
+    
+    auto* rootObject = document->axObjectCache()->rootObject();
+    if (!rootObject)
+        return;
+
+    rootObject->setAccessibleName(accessibleName);
+}
+
 IntRect WebFrame::contentBounds() const
 {    
     if (!m_coreFrame)
@@ -551,7 +581,7 @@ IntSize WebFrame::scrollOffset() const
     if (!view)
         return IntSize();
 
-    return view->scrollOffset();
+    return toIntSize(view->scrollPosition());
 }
 
 bool WebFrame::hasHorizontalScrollbar() const
@@ -583,7 +613,7 @@ PassRefPtr<InjectedBundleHitTestResult> WebFrame::hitTest(const IntPoint point)
     if (!m_coreFrame)
         return 0;
 
-    return InjectedBundleHitTestResult::create(m_coreFrame->eventHandler().hitTestResultAtPoint(point, HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::IgnoreClipping | HitTestRequest::DisallowShadowContent));
+    return InjectedBundleHitTestResult::create(m_coreFrame->eventHandler().hitTestResultAtPoint(point, HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::IgnoreClipping | HitTestRequest::DisallowUserAgentShadowContent));
 }
 
 bool WebFrame::getDocumentBackgroundColor(double* red, double* green, double* blue, double* alpha)
@@ -612,10 +642,10 @@ bool WebFrame::containsAnyFormElements() const
     if (!document)
         return false;
 
-    for (Node* node = document->documentElement(); node; node = NodeTraversal::next(node)) {
-        if (!node->isElementNode())
+    for (Node* node = document->documentElement(); node; node = NodeTraversal::next(*node)) {
+        if (!is<Element>(*node))
             continue;
-        if (isHTMLFormElement(node))
+        if (is<HTMLFormElement>(*node))
             return true;
     }
     return false;
@@ -630,10 +660,10 @@ bool WebFrame::containsAnyFormControls() const
     if (!document)
         return false;
 
-    for (Node* node = document->documentElement(); node; node = NodeTraversal::next(node)) {
-        if (!node->isElementNode())
+    for (Node* node = document->documentElement(); node; node = NodeTraversal::next(*node)) {
+        if (!is<Element>(*node))
             continue;
-        if (isHTMLInputElement(node) || isHTMLSelectElement(node) || isHTMLTextAreaElement(node))
+        if (is<HTMLInputElement>(*node) || is<HTMLSelectElement>(*node) || is<HTMLTextAreaElement>(*node))
             return true;
     }
     return false;
@@ -654,7 +684,7 @@ WebFrame* WebFrame::frameForContext(JSContextRef context)
     if (strcmp(globalObjectObj->classInfo()->className, "JSDOMWindowShell") != 0)
         return 0;
 
-    Frame* frame = static_cast<JSDOMWindowShell*>(globalObjectObj)->window()->impl().frame();
+    Frame* frame = static_cast<JSDOMWindowShell*>(globalObjectObj)->window()->wrapped().frame();
     return WebFrame::fromCoreFrame(*frame);
 }
 
@@ -682,12 +712,24 @@ JSValueRef WebFrame::jsWrapperForWorld(InjectedBundleRangeHandle* rangeHandle, I
     return toRef(exec, toJS(exec, globalObject, rangeHandle->coreRange()));
 }
 
+JSValueRef WebFrame::jsWrapperForWorld(InjectedBundleFileHandle* fileHandle, InjectedBundleScriptWorld* world)
+{
+    if (!m_coreFrame)
+        return nullptr;
+
+    JSDOMWindow* globalObject = m_coreFrame->script().globalObject(world->coreWorld());
+    ExecState* exec = globalObject->globalExec();
+
+    JSLockHolder lock(exec);
+    return toRef(exec, toJS(exec, globalObject, fileHandle->coreFile()));
+}
+
 String WebFrame::counterValue(JSObjectRef element)
 {
     if (!toJS(element)->inherits(JSElement::info()))
         return String();
 
-    return counterValueForElement(&jsCast<JSElement*>(toJS(element))->impl());
+    return counterValueForElement(&jsCast<JSElement*>(toJS(element))->wrapped());
 }
 
 String WebFrame::provisionalURL() const
@@ -765,7 +807,7 @@ void WebFrame::documentLoaderDetached(uint64_t navigationID)
 #if PLATFORM(COCOA)
 RetainPtr<CFDataRef> WebFrame::webArchiveData(FrameFilterFunction callback, void* context)
 {
-    RefPtr<LegacyWebArchive> archive = LegacyWebArchive::create(coreFrame()->document(), [this, callback, context](Frame& frame) -> bool {
+    RefPtr<LegacyWebArchive> archive = LegacyWebArchive::create(*coreFrame()->document(), [this, callback, context](Frame& frame) -> bool {
         if (!callback)
             return true;
 
@@ -781,5 +823,25 @@ RetainPtr<CFDataRef> WebFrame::webArchiveData(FrameFilterFunction callback, void
     return archive->rawDataRepresentation();
 }
 #endif
+
+PassRefPtr<ShareableBitmap> WebFrame::createSelectionSnapshot() const
+{
+    std::unique_ptr<ImageBuffer> snapshot = snapshotSelection(*coreFrame(), WebCore::SnapshotOptionsForceBlackText);
+    if (!snapshot)
+        return nullptr;
+
+    auto sharedSnapshot = ShareableBitmap::createShareable(snapshot->internalSize(), ShareableBitmap::SupportsAlpha);
+    if (!sharedSnapshot)
+        return nullptr;
+
+    // FIXME: We should consider providing a way to use subpixel antialiasing for the snapshot
+    // if we're compositing this image onto a solid color (e.g. the modern find indicator style).
+    auto graphicsContext = sharedSnapshot->createGraphicsContext();
+    float deviceScaleFactor = coreFrame()->page()->deviceScaleFactor();
+    graphicsContext->scale(deviceScaleFactor);
+    graphicsContext->drawConsumingImageBuffer(WTFMove(snapshot), FloatPoint());
+
+    return WTFMove(sharedSnapshot);
+}
     
 } // namespace WebKit