PDFPlugin should take advantage of threaded scrolling
[WebKit-https.git] / Source / WebKit2 / WebProcess / WebPage / WebFrame.cpp
index 2624476..250b42b 100644 (file)
 #include "config.h"
 #include "WebFrame.h"
 
+#include "APIArray.h"
 #include "DownloadManager.h"
+#include "InjectedBundleFileHandle.h"
+#include "InjectedBundleHitTestResult.h"
 #include "InjectedBundleNodeHandle.h"
 #include "InjectedBundleRangeHandle.h"
 #include "InjectedBundleScriptWorld.h"
+#include "PluginView.h"
+#include "WKAPICast.h"
+#include "WKBundleAPICast.h"
 #include "WebChromeClient.h"
+#include "WebDocumentLoader.h"
 #include "WebPage.h"
 #include "WebPageProxyMessages.h"
 #include "WebProcess.h"
 #include <JavaScriptCore/JSContextRef.h>
 #include <JavaScriptCore/JSLock.h>
 #include <JavaScriptCore/JSValueRef.h>
-#include <WebCore/AnimationController.h>
 #include <WebCore/ArchiveResource.h>
-#include <WebCore/CSSComputedStyleDeclaration.h>
+#include <WebCore/CertificateInfo.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/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/NodeTraversal.h>
 #include <WebCore/Page.h>
+#include <WebCore/PluginDocument.h>
 #include <WebCore/RenderTreeAsText.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>
 
+#if PLATFORM(COCOA)
+#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
@@ -66,9 +96,7 @@ using namespace WebCore;
 
 namespace WebKit {
 
-#ifndef NDEBUG
-static WTF::RefCountedLeakCounter webFrameCounter("WebFrame");
-#endif
+DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, webFrameCounter, ("WebFrame"));
 
 static uint64_t generateFrameID()
 {
@@ -82,32 +110,36 @@ static uint64_t generateListenerID()
     return uniqueListenerID++;
 }
 
-PassRefPtr<WebFrame> WebFrame::createMainFrame(WebPage* page)
+PassRefPtr<WebFrame> WebFrame::createWithCoreMainFrame(WebPage* page, WebCore::Frame* coreFrame)
 {
-    RefPtr<WebFrame> frame = create();
-
-    page->send(Messages::WebPageProxy::DidCreateMainFrame(frame->frameID()));
-
-    frame->init(page, String(), 0);
+    RefPtr<WebFrame> frame = create(std::unique_ptr<WebFrameLoaderClient>(static_cast<WebFrameLoaderClient*>(&coreFrame->loader().client())));
+    page->send(Messages::WebPageProxy::DidCreateMainFrame(frame->frameID()), page->pageID(), IPC::DispatchMessageEvenWhenWaitingForSyncReply);
 
+    frame->m_coreFrame = coreFrame;
+    frame->m_coreFrame->tree().setName(String());
+    frame->m_coreFrame->init();
     return frame.release();
 }
 
 PassRefPtr<WebFrame> WebFrame::createSubframe(WebPage* page, const String& frameName, HTMLFrameOwnerElement* ownerElement)
 {
-    RefPtr<WebFrame> frame = create();
-
-    WebFrame* parentFrame = static_cast<WebFrameLoaderClient*>(ownerElement->document()->frame()->loader()->client())->webFrame();
-    page->send(Messages::WebPageProxy::DidCreateSubframe(frame->frameID(), parentFrame->frameID()));
-
-    frame->init(page, frameName, ownerElement);
+    RefPtr<WebFrame> frame = create(std::make_unique<WebFrameLoaderClient>());
+    page->send(Messages::WebPageProxy::DidCreateSubframe(frame->frameID()), page->pageID(), IPC::DispatchMessageEvenWhenWaitingForSyncReply);
 
+    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(WTF::move(coreFrame));
+    }
+    frame->m_coreFrame->init();
     return frame.release();
 }
 
-PassRefPtr<WebFrame> WebFrame::create()
+PassRefPtr<WebFrame> WebFrame::create(std::unique_ptr<WebFrameLoaderClient> frameLoaderClient)
 {
-    RefPtr<WebFrame> frame = adoptRef(new WebFrame);
+    RefPtr<WebFrame> frame = adoptRef(new WebFrame(WTF::move(frameLoaderClient)));
 
     // Add explict ref() that will be balanced in WebFrameLoaderClient::frameLoaderDestroyed().
     frame->ref();
@@ -115,16 +147,20 @@ PassRefPtr<WebFrame> WebFrame::create()
     return frame.release();
 }
 
-WebFrame::WebFrame()
+WebFrame::WebFrame(std::unique_ptr<WebFrameLoaderClient> frameLoaderClient)
     : m_coreFrame(0)
     , m_policyListenerID(0)
     , m_policyFunction(0)
     , m_policyDownloadID(0)
-    , m_frameLoaderClient(this)
+    , m_frameLoaderClient(WTF::move(frameLoaderClient))
     , m_loadListener(0)
     , m_frameID(generateFrameID())
+#if PLATFORM(IOS)
+    , m_firstLayerTreeTransactionIDAfterDidCommitLoad(0)
+#endif
 {
-    WebProcess::shared().addWebFrame(m_frameID, this);
+    m_frameLoaderClient->setWebFrame(this);
+    WebProcess::singleton().addWebFrame(m_frameID, this);
 
 #ifndef NDEBUG
     webFrameCounter.increment();
@@ -140,35 +176,29 @@ WebFrame::~WebFrame()
 #endif
 }
 
-void WebFrame::init(WebPage* page, const String& frameName, HTMLFrameOwnerElement* ownerElement)
-{
-    RefPtr<Frame> frame = Frame::create(page->corePage(), ownerElement, &m_frameLoaderClient);
-    m_coreFrame = frame.get();
-
-    frame->tree()->setName(frameName);
-
-    if (ownerElement) {
-        ASSERT(ownerElement->document()->frame());
-        ownerElement->document()->frame()->tree()->appendChild(frame);
-    }
-
-    frame->init();
-}
-
 WebPage* WebFrame::page() const
 { 
     if (!m_coreFrame)
         return 0;
     
-    if (WebCore::Page* page = m_coreFrame->page())
-        return static_cast<WebChromeClient*>(page->chrome()->client())->page();
+    if (Page* page = m_coreFrame->page())
+        return WebPage::fromCorePage(page);
 
     return 0;
 }
 
+WebFrame* WebFrame::fromCoreFrame(Frame& frame)
+{
+    auto* webFrameLoaderClient = toWebFrameLoaderClient(frame.loader().client());
+    if (!webFrameLoaderClient)
+        return nullptr;
+
+    return webFrameLoaderClient->webFrame();
+}
+
 void WebFrame::invalidate()
 {
-    WebProcess::shared().removeWebFrame(m_frameID);
+    WebProcess::singleton().removeWebFrame(m_frameID);
     m_coreFrame = 0;
 }
 
@@ -193,7 +223,7 @@ void WebFrame::invalidatePolicyListener()
     m_policyFunction = 0;
 }
 
-void WebFrame::didReceivePolicyDecision(uint64_t listenerID, PolicyAction action, uint64_t downloadID)
+void WebFrame::didReceivePolicyDecision(uint64_t listenerID, PolicyAction action, uint64_t navigationID, uint64_t downloadID)
 {
     if (!m_coreFrame)
         return;
@@ -206,30 +236,70 @@ void WebFrame::didReceivePolicyDecision(uint64_t listenerID, PolicyAction action
 
     ASSERT(m_policyFunction);
 
-    FramePolicyFunction function = m_policyFunction;
+    FramePolicyFunction function = WTF::move(m_policyFunction);
 
     invalidatePolicyListener();
 
     m_policyDownloadID = downloadID;
+    if (navigationID) {
+        if (WebDocumentLoader* documentLoader = static_cast<WebDocumentLoader*>(m_coreFrame->loader().policyDocumentLoader()))
+            documentLoader->setNavigationID(navigationID);
+    }
 
-    (m_coreFrame->loader()->policyChecker()->*function)(action);
+    function(action);
 }
 
 void WebFrame::startDownload(const WebCore::ResourceRequest& request)
 {
     ASSERT(m_policyDownloadID);
 
-    DownloadManager::shared().startDownload(m_policyDownloadID, page(), request);
-
+    uint64_t policyDownloadID = m_policyDownloadID;
     m_policyDownloadID = 0;
+
+    auto& webProcess = WebProcess::singleton();
+#if ENABLE(NETWORK_PROCESS)
+    if (webProcess.usesNetworkProcess()) {
+        webProcess.networkConnection()->connection()->send(Messages::NetworkConnectionToWebProcess::StartDownload(page()->sessionID(), policyDownloadID, request), 0);
+        return;
+    }
+#endif
+
+    webProcess.downloadManager().startDownload(policyDownloadID, request);
 }
 
-void WebFrame::convertHandleToDownload(ResourceHandle* handle, const ResourceRequest& request, const ResourceRequest& initialRequest, const ResourceResponse& response)
+void WebFrame::convertMainResourceLoadToDownload(DocumentLoader* documentLoader, const ResourceRequest& request, const ResourceResponse& response)
 {
     ASSERT(m_policyDownloadID);
 
-    DownloadManager::shared().convertHandleToDownload(m_policyDownloadID, page(), handle, request, initialRequest, response);
+    uint64_t policyDownloadID = m_policyDownloadID;
     m_policyDownloadID = 0;
+
+    SubresourceLoader* mainResourceLoader = documentLoader->mainResourceLoader();
+
+    auto& webProcess = WebProcess::singleton();
+#if ENABLE(NETWORK_PROCESS)
+    if (webProcess.usesNetworkProcess()) {
+        // 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.networkConnection()->connection()->send(Messages::NetworkConnectionToWebProcess::ConvertMainResourceLoadToDownload(mainResourceLoadIdentifier, policyDownloadID, request, response), 0);
+        return;
+    }
+#endif
+
+    if (!mainResourceLoader) {
+        // The main resource has already been loaded. Start a new download instead.
+        webProcess.downloadManager().startDownload(policyDownloadID, request);
+        return;
+    }
+
+    webProcess.downloadManager().convertHandleToDownload(policyDownloadID, documentLoader->mainResourceLoader()->handle(), request, response);
 }
 
 String WebFrame::source() const 
@@ -242,7 +312,7 @@ String WebFrame::source() const
     TextResourceDecoder* decoder = document->decoder();
     if (!decoder)
         return String();
-    DocumentLoader* documentLoader = m_coreFrame->loader()->activeDocumentLoader();
+    DocumentLoader* documentLoader = m_coreFrame->loader().activeDocumentLoader();
     if (!documentLoader)
         return String();
     RefPtr<SharedBuffer> mainResourceData = documentLoader->mainResourceData();
@@ -258,10 +328,14 @@ String WebFrame::contentsAsString() const
 
     if (isFrameSet()) {
         StringBuilder builder;
-        for (Frame* child = m_coreFrame->tree()->firstChild(); child; child = child->tree()->nextSibling()) {
+        for (Frame* child = m_coreFrame->tree().firstChild(); child; child = child->tree().nextSibling()) {
             if (!builder.isEmpty())
                 builder.append(' ');
-            builder.append(static_cast<WebFrameLoaderClient*>(child->loader()->client())->webFrame()->contentsAsString());
+
+            WebFrame* webFrame = WebFrame::fromCoreFrame(*child);
+            ASSERT(webFrame);
+
+            builder.append(webFrame->contentsAsString());
         }
         // FIXME: It may make sense to use toStringPreserveCapacity() here.
         return builder.toString();
@@ -290,7 +364,7 @@ String WebFrame::selectionAsString() const
     if (!m_coreFrame)
         return String();
 
-    return m_coreFrame->displayStringModifiedByEncoding(m_coreFrame->editor()->selectedText());
+    return m_coreFrame->displayStringModifiedByEncoding(m_coreFrame->editor().selectedText());
 }
 
 IntSize WebFrame::size() const
@@ -318,10 +392,10 @@ bool WebFrame::isFrameSet() const
 
 bool WebFrame::isMainFrame() const
 {
-    if (WebPage* p = page())
-        return p->mainFrame() == this;
+    if (!m_coreFrame)
+        return false;
 
-    return false;
+    return m_coreFrame->isMainFrame();
 }
 
 String WebFrame::name() const
@@ -329,7 +403,7 @@ String WebFrame::name() const
     if (!m_coreFrame)
         return String();
 
-    return m_coreFrame->tree()->uniqueName();
+    return m_coreFrame->tree().uniqueName();
 }
 
 String WebFrame::url() const
@@ -337,13 +411,25 @@ String WebFrame::url() const
     if (!m_coreFrame)
         return String();
 
-    DocumentLoader* documentLoader = m_coreFrame->loader()->documentLoader();
+    DocumentLoader* documentLoader = m_coreFrame->loader().documentLoader();
     if (!documentLoader)
         return String();
 
     return documentLoader->url().string();
 }
 
+WebCore::CertificateInfo WebFrame::certificateInfo() const
+{
+    if (!m_coreFrame)
+        return CertificateInfo();
+
+    DocumentLoader* documentLoader = m_coreFrame->loader().documentLoader();
+    if (!documentLoader)
+        return CertificateInfo();
+
+    return documentLoader->response().certificateInfo();
+}
+
 String WebFrame::innerText() const
 {
     if (!m_coreFrame)
@@ -355,132 +441,106 @@ String WebFrame::innerText() const
     return m_coreFrame->document()->documentElement()->innerText();
 }
 
-PassRefPtr<ImmutableArray> WebFrame::childFrames()
+WebFrame* WebFrame::parentFrame() const
+{
+    if (!m_coreFrame || !m_coreFrame->ownerElement())
+        return 0;
+
+    return WebFrame::fromCoreFrame(*m_coreFrame->ownerElement()->document().frame());
+}
+
+Ref<API::Array> WebFrame::childFrames()
 {
     if (!m_coreFrame)
-        return ImmutableArray::create();
+        return API::Array::create();
 
-    size_t size = m_coreFrame->tree()->childCount();
+    size_t size = m_coreFrame->tree().childCount();
     if (!size)
-        return ImmutableArray::create();
+        return API::Array::create();
 
-    Vector<RefPtr<APIObject> > vector;
+    Vector<RefPtr<API::Object>> vector;
     vector.reserveInitialCapacity(size);
 
-    for (Frame* child = m_coreFrame->tree()->firstChild(); child; child = child->tree()->nextSibling()) {
-        WebFrame* webFrame = static_cast<WebFrameLoaderClient*>(child->loader()->client())->webFrame();
+    for (Frame* child = m_coreFrame->tree().firstChild(); child; child = child->tree().nextSibling()) {
+        WebFrame* webFrame = WebFrame::fromCoreFrame(*child);
+        ASSERT(webFrame);
         vector.uncheckedAppend(webFrame);
     }
 
-    return ImmutableArray::adopt(vector);
+    return API::Array::create(WTF::move(vector));
 }
 
-unsigned WebFrame::numberOfActiveAnimations() const
+String WebFrame::layerTreeAsText() const
 {
     if (!m_coreFrame)
-        return 0;
-
-    AnimationController* controller = m_coreFrame->animation();
-    if (!controller)
-        return 0;
+        return "";
 
-    return controller->numberOfActiveAnimations(m_coreFrame->document());
+    return m_coreFrame->layerTreeAsText(0);
 }
 
-bool WebFrame::pauseAnimationOnElementWithId(const String& animationName, const String& elementID, double time)
+unsigned WebFrame::pendingUnloadCount() const
 {
     if (!m_coreFrame)
-        return false;
-
-    AnimationController* controller = m_coreFrame->animation();
-    if (!controller)
-        return false;
-
-    if (!m_coreFrame->document())
-        return false;
-
-    Node* coreNode = m_coreFrame->document()->getElementById(elementID);
-    if (!coreNode || !coreNode->renderer())
-        return false;
+        return 0;
 
-    return controller->pauseAnimationAtTime(coreNode->renderer(), animationName, time);
+    return m_coreFrame->document()->domWindow()->pendingUnloadEventListeners();
 }
 
-bool WebFrame::pauseTransitionOnElementWithId(const String& propertyName, const String& elementID, double time)
+bool WebFrame::allowsFollowingLink(const WebCore::URL& url) const
 {
     if (!m_coreFrame)
-        return false;
-
-    AnimationController* controller = m_coreFrame->animation();
-    if (!controller)
-        return false;
-
-    if (!m_coreFrame->document())
-        return false;
-
-    Node* coreNode = m_coreFrame->document()->getElementById(elementID);
-    if (!coreNode || !coreNode->renderer())
-        return false;
-
-    return controller->pauseTransitionAtTime(coreNode->renderer(), propertyName, time);
+        return true;
+        
+    return m_coreFrame->document()->securityOrigin()->canDisplay(url);
 }
 
-void WebFrame::suspendAnimations()
+JSGlobalContextRef WebFrame::jsContext()
 {
-    if (!m_coreFrame)
-        return;
-
-    AnimationController* controller = m_coreFrame->animation();
-    if (!controller)
-        return;
-
-    controller->suspendAnimations();
+    return toGlobalRef(m_coreFrame->script().globalObject(mainThreadNormalWorld())->globalExec());
 }
 
-void WebFrame::resumeAnimations()
+JSGlobalContextRef WebFrame::jsContextForWorld(InjectedBundleScriptWorld* world)
 {
-    if (!m_coreFrame)
-        return;
-
-    AnimationController* controller = m_coreFrame->animation();
-    if (!controller)
-        return;
-
-    controller->resumeAnimations();
+    return toGlobalRef(m_coreFrame->script().globalObject(world->coreWorld())->globalExec());
 }
 
-String WebFrame::layerTreeAsText() const
+bool WebFrame::handlesPageScaleGesture() const
 {
-    if (!m_coreFrame)
-        return "";
+    if (!m_coreFrame->document()->isPluginDocument())
+        return 0;
 
-    return m_coreFrame->layerTreeAsText();
+    PluginDocument* pluginDocument = static_cast<PluginDocument*>(m_coreFrame->document());
+    PluginView* pluginView = static_cast<PluginView*>(pluginDocument->pluginWidget());
+    return pluginView && pluginView->handlesPageScaleFactor();
 }
 
-unsigned WebFrame::pendingUnloadCount() const
+bool WebFrame::requiresUnifiedScaleFactor() const
 {
-    if (!m_coreFrame)
+    if (!m_coreFrame->document()->isPluginDocument())
         return 0;
 
-    return m_coreFrame->domWindow()->pendingUnloadEventListeners();
+    PluginDocument* pluginDocument = static_cast<PluginDocument*>(m_coreFrame->document());
+    PluginView* pluginView = static_cast<PluginView*>(pluginDocument->pluginWidget());
+    return pluginView && pluginView->requiresUnifiedScaleFactor();
 }
 
-bool WebFrame::allowsFollowingLink(const WebCore::KURL& url) const
+void WebFrame::setAccessibleName(const String& accessibleName)
 {
+    if (!AXObjectCache::accessibilityEnabled())
+        return;
+    
     if (!m_coreFrame)
-        return true;
-        
-    return m_coreFrame->document()->securityOrigin()->canDisplay(url);
-}
+        return;
 
-JSGlobalContextRef WebFrame::jsContext()
-{
-    return toGlobalRef(m_coreFrame->script()->globalObject(mainThreadNormalWorld())->globalExec());
-}
+    auto* document = m_coreFrame->document();
+    if (!document)
+        return;
+    
+    auto* rootObject = document->axObjectCache()->rootObject();
+    if (!rootObject)
+        return;
 
-JSGlobalContextRef WebFrame::jsContextForWorld(InjectedBundleScriptWorld* world)
-{
-    return toGlobalRef(m_coreFrame->script()->globalObject(world->coreWorld())->globalExec());
+    rootObject->setAccessibleName(accessibleName);
 }
 
 IntRect WebFrame::contentBounds() const
@@ -504,7 +564,7 @@ IntRect WebFrame::visibleContentBounds() const
     if (!view)
         return IntRect();
     
-    IntRect contentRect = view->visibleContentRect(true);
+    IntRect contentRect = view->visibleContentRectIncludingScrollbars();
     return IntRect(0, 0, contentRect.width(), contentRect.height());
 }
 
@@ -517,7 +577,7 @@ IntRect WebFrame::visibleContentBoundsExcludingScrollbars() const
     if (!view)
         return IntRect();
     
-    IntRect contentRect = view->visibleContentRect(false);
+    IntRect contentRect = view->visibleContentRect();
     return IntRect(0, 0, contentRect.width(), contentRect.height());
 }
 
@@ -557,11 +617,24 @@ bool WebFrame::hasVerticalScrollbar() const
     return view->verticalScrollbar();
 }
 
+PassRefPtr<InjectedBundleHitTestResult> WebFrame::hitTest(const IntPoint point) const
+{
+    if (!m_coreFrame)
+        return 0;
+
+    return InjectedBundleHitTestResult::create(m_coreFrame->eventHandler().hitTestResultAtPoint(point, HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::IgnoreClipping | HitTestRequest::DisallowShadowContent));
+}
+
 bool WebFrame::getDocumentBackgroundColor(double* red, double* green, double* blue, double* alpha)
 {
     if (!m_coreFrame)
         return false;
-    Color bgColor = m_coreFrame->getDocumentBackgroundColor();
+
+    FrameView* view = m_coreFrame->view();
+    if (!view)
+        return false;
+
+    Color bgColor = view->documentBackgroundColor();
     if (!bgColor.isValid())
         return false;
 
@@ -578,15 +651,41 @@ bool WebFrame::containsAnyFormElements() const
     if (!document)
         return false;
 
-    for (Node* node = document->documentElement(); node; node = node->traverseNextNode()) {
-        if (!node->isElementNode())
+    for (Node* node = document->documentElement(); node; node = NodeTraversal::next(*node)) {
+        if (!is<Element>(*node))
+            continue;
+        if (is<HTMLFormElement>(*node))
+            return true;
+    }
+    return false;
+}
+
+bool WebFrame::containsAnyFormControls() const
+{
+    if (!m_coreFrame)
+        return false;
+    
+    Document* document = m_coreFrame->document();
+    if (!document)
+        return false;
+
+    for (Node* node = document->documentElement(); node; node = NodeTraversal::next(*node)) {
+        if (!is<Element>(*node))
             continue;
-        if (static_cast<Element*>(node)->hasTagName(HTMLNames::formTag))
+        if (is<HTMLInputElement>(*node) || is<HTMLSelectElement>(*node) || is<HTMLTextAreaElement>(*node))
             return true;
     }
     return false;
 }
 
+void WebFrame::stopLoading()
+{
+    if (!m_coreFrame)
+        return;
+
+    m_coreFrame->loader().stopForUserCancel();
+}
+
 WebFrame* WebFrame::frameForContext(JSContextRef context)
 {
     JSObjectRef globalObjectRef = JSContextGetGlobalObject(context);
@@ -594,8 +693,8 @@ WebFrame* WebFrame::frameForContext(JSContextRef context)
     if (strcmp(globalObjectObj->classInfo()->className, "JSDOMWindowShell") != 0)
         return 0;
 
-    Frame* coreFrame = static_cast<JSDOMWindowShell*>(globalObjectObj)->window()->impl()->frame();
-    return static_cast<WebFrameLoaderClient*>(coreFrame->loader()->client())->webFrame();
+    Frame* frame = static_cast<JSDOMWindowShell*>(globalObjectObj)->window()->wrapped().frame();
+    return WebFrame::fromCoreFrame(*frame);
 }
 
 JSValueRef WebFrame::jsWrapperForWorld(InjectedBundleNodeHandle* nodeHandle, InjectedBundleScriptWorld* world)
@@ -603,10 +702,10 @@ JSValueRef WebFrame::jsWrapperForWorld(InjectedBundleNodeHandle* nodeHandle, Inj
     if (!m_coreFrame)
         return 0;
 
-    JSDOMWindow* globalObject = m_coreFrame->script()->globalObject(world->coreWorld());
+    JSDOMWindow* globalObject = m_coreFrame->script().globalObject(world->coreWorld());
     ExecState* exec = globalObject->globalExec();
 
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(exec);
     return toRef(exec, toJS(exec, globalObject, nodeHandle->coreNode()));
 }
 
@@ -615,44 +714,31 @@ JSValueRef WebFrame::jsWrapperForWorld(InjectedBundleRangeHandle* rangeHandle, I
     if (!m_coreFrame)
         return 0;
 
-    JSDOMWindow* globalObject = m_coreFrame->script()->globalObject(world->coreWorld());
+    JSDOMWindow* globalObject = m_coreFrame->script().globalObject(world->coreWorld());
     ExecState* exec = globalObject->globalExec();
 
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(exec);
     return toRef(exec, toJS(exec, globalObject, rangeHandle->coreRange()));
 }
 
-JSValueRef WebFrame::computedStyleIncludingVisitedInfo(JSObjectRef element)
+JSValueRef WebFrame::jsWrapperForWorld(InjectedBundleFileHandle* fileHandle, InjectedBundleScriptWorld* world)
 {
     if (!m_coreFrame)
-        return 0;
+        return nullptr;
 
-    JSDOMWindow* globalObject = m_coreFrame->script()->globalObject(mainThreadNormalWorld());
+    JSDOMWindow* globalObject = m_coreFrame->script().globalObject(world->coreWorld());
     ExecState* exec = globalObject->globalExec();
 
-    if (!toJS(element)->inherits(&JSElement::s_info))
-        return JSValueMakeUndefined(toRef(exec));
-
-    RefPtr<CSSComputedStyleDeclaration> style = computedStyle(static_cast<JSElement*>(toJS(element))->impl(), true);
-
-    JSLock lock(SilenceAssertionsOnly);
-    return toRef(exec, toJS(exec, globalObject, style.get()));
+    JSLockHolder lock(exec);
+    return toRef(exec, toJS(exec, globalObject, fileHandle->coreFile()));
 }
 
 String WebFrame::counterValue(JSObjectRef element)
 {
-    if (!toJS(element)->inherits(&JSElement::s_info))
+    if (!toJS(element)->inherits(JSElement::info()))
         return String();
 
-    return counterValueForElement(static_cast<JSElement*>(toJS(element))->impl());
-}
-
-String WebFrame::markerText(JSObjectRef element)
-{
-    if (!toJS(element)->inherits(&JSElement::s_info))
-        return String();
-
-    return markerTextForListItem(static_cast<JSElement*>(toJS(element))->impl());
+    return counterValueForElement(&jsCast<JSElement*>(toJS(element))->wrapped());
 }
 
 String WebFrame::provisionalURL() const
@@ -660,15 +746,19 @@ String WebFrame::provisionalURL() const
     if (!m_coreFrame)
         return String();
 
-    return m_coreFrame->loader()->provisionalDocumentLoader()->url().string();
+    DocumentLoader* provisionalDocumentLoader = m_coreFrame->loader().provisionalDocumentLoader();
+    if (!provisionalDocumentLoader)
+        return String();
+
+    return provisionalDocumentLoader->url().string();
 }
 
-String WebFrame::suggestedFilenameForResourceWithURL(const KURL& url) const
+String WebFrame::suggestedFilenameForResourceWithURL(const URL& url) const
 {
     if (!m_coreFrame)
         return String();
 
-    DocumentLoader* loader = m_coreFrame->loader()->documentLoader();
+    DocumentLoader* loader = m_coreFrame->loader().documentLoader();
     if (!loader)
         return String();
 
@@ -684,12 +774,12 @@ String WebFrame::suggestedFilenameForResourceWithURL(const KURL& url) const
     return page()->cachedSuggestedFilenameForURL(url);
 }
 
-String WebFrame::mimeTypeForResourceWithURL(const KURL& url) const
+String WebFrame::mimeTypeForResourceWithURL(const URL& url) const
 {
     if (!m_coreFrame)
         return String();
 
-    DocumentLoader* loader = m_coreFrame->loader()->documentLoader();
+    DocumentLoader* loader = m_coreFrame->loader().documentLoader();
     if (!loader)
         return String();
 
@@ -705,4 +795,62 @@ String WebFrame::mimeTypeForResourceWithURL(const KURL& url) const
     return page()->cachedResponseMIMETypeForURL(url);
 }
 
+void WebFrame::setTextDirection(const String& direction)
+{
+    if (!m_coreFrame)
+        return;
+
+    if (direction == "auto")
+        m_coreFrame->editor().setBaseWritingDirection(NaturalWritingDirection);
+    else if (direction == "ltr")
+        m_coreFrame->editor().setBaseWritingDirection(LeftToRightWritingDirection);
+    else if (direction == "rtl")
+        m_coreFrame->editor().setBaseWritingDirection(RightToLeftWritingDirection);
+}
+
+void WebFrame::documentLoaderDetached(uint64_t navigationID)
+{
+    page()->send(Messages::WebPageProxy::DidDestroyNavigation(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 {
+        if (!callback)
+            return true;
+
+        WebFrame* webFrame = WebFrame::fromCoreFrame(frame);
+        ASSERT(webFrame);
+
+        return callback(toAPI(this), toAPI(webFrame), context);
+    });
+
+    if (!archive)
+        return nullptr;
+
+    return archive->rawDataRepresentation();
+}
+#endif
+
+PassRefPtr<ShareableBitmap> WebFrame::createSelectionSnapshot() const
+{
+    std::unique_ptr<ImageBuffer> snapshot = snapshotSelection(*coreFrame(), WebCore::SnapshotOptionsForceBlackText);
+    if (!snapshot)
+        return nullptr;
+
+    RefPtr<ShareableBitmap> 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(FloatSize(deviceScaleFactor, deviceScaleFactor));
+    graphicsContext->drawImageBuffer(*snapshot, ColorSpaceDeviceRGB, FloatPoint());
+
+    return sharedSnapshot.release();
+}
+    
 } // namespace WebKit