void ApplicationCacheHost::maybeLoadMainResource(ResourceRequest& request, SubstituteData& substituteData) { // Check if this request should be loaded from the application cache if (!substituteData.isValid() && isApplicationCacheEnabled() && !isApplicationCacheBlockedForRequest(request)) { ASSERT(!m_mainResourceApplicationCache); m_mainResourceApplicationCache = ApplicationCacheGroup::cacheForMainRequest(request, &m_documentLoader); if (m_mainResourceApplicationCache) { // Get the resource from the application cache. By definition, cacheForMainRequest() returns a cache that contains the resource. ApplicationCacheResource* resource = m_mainResourceApplicationCache->resourceForRequest(request); // ApplicationCache resources have fragment identifiers stripped off of their URLs, // but we'll need to restore that for the SubstituteData. ResourceResponse responseToUse = resource->response(); if (request.url().hasFragmentIdentifier()) { URL url = responseToUse.url(); url.setFragmentIdentifier(request.url().fragmentIdentifier()); responseToUse.setURL(url); } substituteData = SubstituteData(&resource->data(), URL(), responseToUse, SubstituteData::SessionHistoryVisibility::Visible); } } }
void WebSharedWorkerImpl::initializeLoader(const WebURL& url) { // Create 'shadow page'. This page is never displayed, it is used to proxy the // loading requests from the worker context to the rest of WebKit and Chromium // infrastructure. ASSERT(!m_webView); m_webView = WebView::create(0); m_webView->settings()->setOfflineWebApplicationCacheEnabled(WebRuntimeFeatures::isApplicationCacheEnabled()); // FIXME: Settings information should be passed to the Worker process from Browser process when the worker // is created (similar to RenderThread::OnCreateNewView). m_mainFrame = WebFrame::create(this); m_webView->setMainFrame(m_mainFrame); WebFrameImpl* webFrame = toWebFrameImpl(m_webView->mainFrame()); // Construct substitute data source for the 'shadow page'. We only need it // to have same origin as the worker so the loading checks work correctly. CString content(""); int length = static_cast<int>(content.length()); RefPtr<SharedBuffer> buffer(SharedBuffer::create(content.data(), length)); webFrame->frame()->loader().load(FrameLoadRequest(0, ResourceRequest(url), SubstituteData(buffer, "text/html", "UTF-8", KURL()))); // This document will be used as 'loading context' for the worker. m_loadingDocument = webFrame->frame()->document(); }
void DocumentLoader::redirectReceived(Resource* resource, ResourceRequest& request, const ResourceResponse& redirectResponse) { ASSERT_UNUSED(resource, resource == m_mainResource); ASSERT(!redirectResponse.isNull()); m_request = request; // If the redirecting url is not allowed to display content from the target origin, // then block the redirect. const KURL& requestURL = m_request.url(); RefPtr<SecurityOrigin> redirectingOrigin = SecurityOrigin::create(redirectResponse.url()); if (!redirectingOrigin->canDisplay(requestURL)) { FrameLoader::reportLocalLoadFailed(m_frame, requestURL.getString()); m_fetcher->stopFetching(); return; } if (!frameLoader()->shouldContinueForNavigationPolicy(m_request, SubstituteData(), this, CheckContentSecurityPolicy, m_navigationType, NavigationPolicyCurrentTab, replacesCurrentHistoryItem(), isClientRedirect())) { m_fetcher->stopFetching(); return; } ASSERT(timing().fetchStart()); timing().addRedirect(redirectResponse.url(), requestURL); appendRedirect(requestURL); frameLoader()->receivedMainResourceRedirect(requestURL); }
bool DocumentLoader::redirectReceived( Resource* resource, const ResourceRequest& request, const ResourceResponse& redirectResponse) { DCHECK_EQ(resource, m_mainResource); DCHECK(!redirectResponse.isNull()); m_request = request; // If the redirecting url is not allowed to display content from the target // origin, then block the redirect. const KURL& requestURL = m_request.url(); RefPtr<SecurityOrigin> redirectingOrigin = SecurityOrigin::create(redirectResponse.url()); if (!redirectingOrigin->canDisplay(requestURL)) { FrameLoader::reportLocalLoadFailed(m_frame, requestURL.getString()); m_fetcher->stopFetching(); return false; } if (!frameLoader()->shouldContinueForNavigationPolicy( m_request, SubstituteData(), this, CheckContentSecurityPolicy, m_navigationType, NavigationPolicyCurrentTab, replacesCurrentHistoryItem(), isClientRedirect(), nullptr)) { m_fetcher->stopFetching(); return false; } DCHECK(timing().fetchStart()); appendRedirect(requestURL); didRedirect(redirectResponse.url(), requestURL); frameLoader()->client()->dispatchDidReceiveServerRedirectForProvisionalLoad(); return true; }
void WebSharedWorkerImpl::loadShadowPage() { // Construct substitute data source for the 'shadow page'. We only need it // to have same origin as the worker so the loading checks work correctly. CString content(""); RefPtr<SharedBuffer> buffer(SharedBuffer::create(content.data(), content.length())); m_mainFrame->frame()->loader().load(FrameLoadRequest(0, ResourceRequest(m_url), SubstituteData(buffer, "text/html", "UTF-8", KURL()))); }
FrameLoadRequest::FrameLoadRequest( Document* originDocument, const ResourceRequest& resourceRequest, const AtomicString& frameName, ContentSecurityPolicyDisposition shouldCheckMainWorldContentSecurityPolicy) : FrameLoadRequest(originDocument, resourceRequest, frameName, SubstituteData(), shouldCheckMainWorldContentSecurityPolicy) {}
bool MockPagePopup::initialize() { const char scriptToSetUpPagePopupController[] = "<script>window.pagePopupController = parent.internals.pagePopupController;</script>"; RefPtr<SharedBuffer> data = SharedBuffer::create(scriptToSetUpPagePopupController, sizeof(scriptToSetUpPagePopupController)); m_popupClient->writeDocument(data.get()); LocalFrame* localFrame = toLocalFrame(m_iframe->contentFrame()); if (!localFrame) return false; localFrame->loader().load(FrameLoadRequest(0, blankURL(), SubstituteData(data, "text/html", "UTF-8", KURL(), ForceSynchronousLoad))); return true; }
void createChildFrame() { m_childFrame = LocalFrame::create( MockCrossOriginFrameLoaderClient::create(document().frame()), document().frame()->host(), m_dummyFrameOwner.get()); m_childFrame->setView(FrameView::create(*m_childFrame, IntSize(500, 500))); m_childFrame->init(); m_childDocumentLoader = DocumentLoader::create( m_childFrame.get(), ResourceRequest("https://www.example.com"), SubstituteData(), ClientRedirectPolicy::NotClientRedirect); childDocument().updateSecurityOrigin( SecurityOrigin::create("https", "cross-origin.com", 80)); }
bool MainResourceLoader::load(const ResourceRequest& r, const SubstituteData& substituteData) { ASSERT(!m_handle); m_substituteData = substituteData; #if ENABLE(OFFLINE_WEB_APPLICATIONS) // Check if this request should be loaded from the application cache if (!m_substituteData.isValid() && frameLoader()->frame()->settings() && frameLoader()->frame()->settings()->offlineWebApplicationCacheEnabled()) { ASSERT(!m_applicationCache); if (Page* page = frameLoader()->frame()->page()) { if (frameLoader()->frame() == page->mainFrame()) m_applicationCache = ApplicationCacheGroup::cacheForMainRequest(r, m_documentLoader.get()); else m_applicationCache = frameLoader()->documentLoader()->topLevelApplicationCache(); } if (m_applicationCache) { // Get the resource from the application cache. // FIXME: If the resource does not exist, the load should fail. if (ApplicationCacheResource* resource = m_applicationCache->resourceForRequest(r)) { m_substituteData = SubstituteData(resource->data(), resource->response().mimeType(), resource->response().textEncodingName(), KURL()); } } } #endif ResourceRequest request(r); bool defer = defersLoading(); if (defer) { bool shouldLoadEmpty = shouldLoadAsEmptyDocument(r.url()); if (shouldLoadEmpty) defer = false; } if (!defer) { if (loadNow(request)) { // Started as an empty document, but was redirected to something non-empty. ASSERT(defersLoading()); defer = true; } } if (defer) m_initialRequest = request; return true; }
bool WebPagePopupImpl::initializePage() { Page::PageClients pageClients; fillWithEmptyClients(pageClients); m_chromeClient = PagePopupChromeClient::create(this); pageClients.chromeClient = m_chromeClient.get(); Settings& mainSettings = m_webView->page()->settings(); m_page = Page::create(pageClients); m_page->settings().setScriptEnabled(true); m_page->settings().setAllowScriptsToCloseWindows(true); m_page->settings().setDeviceSupportsTouch(mainSettings.deviceSupportsTouch()); m_page->settings().setMinimumFontSize(mainSettings.minimumFontSize()); m_page->settings().setMinimumLogicalFontSize( mainSettings.minimumLogicalFontSize()); // FIXME: Should we support enabling a11y while a popup is shown? m_page->settings().setAccessibilityEnabled( mainSettings.accessibilityEnabled()); m_page->settings().setScrollAnimatorEnabled( mainSettings.scrollAnimatorEnabled()); provideContextFeaturesTo(*m_page, WTF::makeUnique<PagePopupFeaturesClient>()); DEFINE_STATIC_LOCAL(FrameLoaderClient, emptyFrameLoaderClient, (EmptyFrameLoaderClient::create())); LocalFrame* frame = LocalFrame::create(&emptyFrameLoaderClient, &m_page->frameHost(), 0); frame->setPagePopupOwner(m_popupClient->ownerElement()); frame->setView(FrameView::create(*frame)); frame->init(); frame->view()->setParentVisible(true); frame->view()->setSelfVisible(true); frame->view()->setTransparent(false); if (AXObjectCache* cache = m_popupClient->ownerElement().document().existingAXObjectCache()) cache->childrenChanged(&m_popupClient->ownerElement()); DCHECK(frame->domWindow()); PagePopupSupplement::install(*frame, *this, m_popupClient); DCHECK_EQ(m_popupClient->ownerElement().document().existingAXObjectCache(), frame->document()->existingAXObjectCache()); RefPtr<SharedBuffer> data = SharedBuffer::create(); m_popupClient->writeDocument(data.get()); frame->loader().load(FrameLoadRequest( 0, blankURL(), SubstituteData(data, "text/html", "UTF-8", KURL(), ForceSynchronousLoad))); frame->setPageZoomFactor(m_popupClient->zoomFactor()); return true; }
bool SVGImage::dataChanged(bool allDataReceived) { TRACE_EVENT0("webkit", "SVGImage::dataChanged"); // Don't do anything if is an empty image. if (!data()->size()) return true; if (allDataReceived) { static FrameLoaderClient* dummyFrameLoaderClient = new EmptyFrameLoaderClient; Page::PageClients pageClients; fillWithEmptyClients(pageClients); m_chromeClient = adoptPtr(new SVGImageChromeClient(this)); pageClients.chromeClient = m_chromeClient.get(); // FIXME: If this SVG ends up loading itself, we might leak the world. // The Cache code does not know about ImageResources holding Frames and // won't know to break the cycle. // This will become an issue when SVGImage will be able to load other // SVGImage objects, but we're safe now, because SVGImage can only be // loaded by a top-level document. OwnPtr<Page> page = adoptPtr(new Page(pageClients)); page->settings().setScriptEnabled(false); page->settings().setPluginsEnabled(false); page->settings().setAcceleratedCompositingEnabled(false); RefPtr<LocalFrame> frame = LocalFrame::create(dummyFrameLoaderClient, &page->frameHost(), 0); frame->setView(FrameView::create(frame.get())); frame->init(); FrameLoader& loader = frame->loader(); loader.forceSandboxFlags(SandboxAll); frame->view()->setScrollbarsSuppressed(true); frame->view()->setCanHaveScrollbars(false); // SVG Images will always synthesize a viewBox, if it's not available, and thus never see scrollbars. frame->view()->setTransparent(true); // SVG Images are transparent. m_page = page.release(); loader.load(FrameLoadRequest(0, blankURL(), SubstituteData(data(), "image/svg+xml", "UTF-8", KURL(), ForceSynchronousLoad))); // Set the intrinsic size before a container size is available. m_intrinsicSize = containerSize(); } return m_page; }
void ApplicationCacheHost::maybeLoadMainResource(ResourceRequest& request, SubstituteData& substituteData) { // Check if this request should be loaded from the application cache if (!substituteData.isValid() && isApplicationCacheEnabled()) { ASSERT(!m_mainResourceApplicationCache); m_mainResourceApplicationCache = ApplicationCacheGroup::cacheForMainRequest(request, m_documentLoader); if (m_mainResourceApplicationCache) { // Get the resource from the application cache. By definition, cacheForMainRequest() returns a cache that contains the resource. ApplicationCacheResource* resource = m_mainResourceApplicationCache->resourceForRequest(request); substituteData = SubstituteData(resource->data(), resource->response().mimeType(), resource->response().textEncodingName(), KURL()); } } }
void DocumentLoader::prepareSubframeArchiveLoadIfNeeded() { if (!m_frame->tree().parent() || !m_frame->tree().parent()->isLocalFrame()) return; ArchiveResourceCollection* parentCollection = toLocalFrame(m_frame->tree().parent())->loader().documentLoader()->m_archiveResourceCollection.get(); if (!parentCollection) return; m_archive = parentCollection->popSubframeArchive(m_frame->tree().uniqueName(), m_request.url()); if (!m_archive) return; addAllArchiveResources(m_archive.get()); ArchiveResource* mainResource = m_archive->mainResource(); m_substituteData = SubstituteData(mainResource->data(), mainResource->mimeType(), mainResource->textEncoding(), KURL()); }
bool WebPagePopupImpl::initializePage() { Page::PageClients pageClients; fillWithEmptyClients(pageClients); m_chromeClient = PagePopupChromeClient::create(this); pageClients.chromeClient = m_chromeClient.get(); m_page = adoptPtrWillBeNoop(new Page(pageClients)); m_page->settings().setScriptEnabled(true); m_page->settings().setAllowScriptsToCloseWindows(true); m_page->setDeviceScaleFactor(m_webView->deviceScaleFactor()); m_page->settings().setDeviceSupportsTouch(m_webView->page()->settings().deviceSupportsTouch()); // FIXME: Should we support enabling a11y while a popup is shown? m_page->settings().setAccessibilityEnabled(m_webView->page()->settings().accessibilityEnabled()); m_page->settings().setScrollAnimatorEnabled(m_webView->page()->settings().scrollAnimatorEnabled()); provideContextFeaturesTo(*m_page, adoptPtr(new PagePopupFeaturesClient())); DEFINE_STATIC_LOCAL(OwnPtrWillBePersistent<FrameLoaderClient>, emptyFrameLoaderClient, (EmptyFrameLoaderClient::create())); RefPtrWillBeRawPtr<LocalFrame> frame = LocalFrame::create(emptyFrameLoaderClient.get(), &m_page->frameHost(), 0); frame->setPagePopupOwner(m_popupClient->ownerElement()); frame->setView(FrameView::create(frame.get())); frame->init(); frame->view()->resize(m_popupClient->contentSize()); frame->view()->setTransparent(false); if (AXObjectCache* cache = m_popupClient->ownerElement().document().existingAXObjectCache()) cache->childrenChanged(&m_popupClient->ownerElement()); ASSERT(frame->localDOMWindow()); DOMWindowPagePopup::install(*frame->localDOMWindow(), *this, m_popupClient); ASSERT(m_popupClient->ownerElement().document().existingAXObjectCache() == frame->document()->existingAXObjectCache()); RefPtr<SharedBuffer> data = SharedBuffer::create(); m_popupClient->writeDocument(data.get()); frame->loader().load(FrameLoadRequest(0, blankURL(), SubstituteData(data, "text/html", "UTF-8", KURL(), ForceSynchronousLoad))); return true; }
void SetUp() override { url = KURL(KURL(), "https://example.test/foo"); securityInfo = "security info"; mainResourceUrl = KURL(KURL(), "https://www.example.test"); MockFrameLoaderClient* client = new MockFrameLoaderClient; EXPECT_CALL(*client, didDisplayContentWithCertificateErrors(url, securityInfo)); dummyPageHolder = DummyPageHolder::create(IntSize(500, 500), nullptr, client); dummyPageHolder->page().setDeviceScaleFactor(1.0); documentLoader = DocumentLoader::create(&dummyPageHolder->frame(), ResourceRequest(mainResourceUrl), SubstituteData()); document = toHTMLDocument(&dummyPageHolder->document()); document->setURL(mainResourceUrl); fetchContext = static_cast<FrameFetchContext*>(&documentLoader->fetcher()->context()); owner = DummyFrameOwner::create(); FrameFetchContext::provideDocumentToContext(*fetchContext, document.get()); }
bool SVGImage::dataChanged(bool allDataReceived) { TRACE_EVENT0("blink", "SVGImage::dataChanged"); // Don't do anything if is an empty image. if (!data()->size()) return true; if (allDataReceived) { // SVGImage will fire events (and the default C++ handlers run) but doesn't // actually allow script to run so it's fine to call into it. We allow this // since it means an SVG data url can synchronously load like other image // types. EventDispatchForbiddenScope::AllowUserAgentEvents allowUserAgentEvents; DEFINE_STATIC_LOCAL(OwnPtrWillBePersistent<FrameLoaderClient>, dummyFrameLoaderClient, (EmptyFrameLoaderClient::create())); if (m_page) { toLocalFrame(m_page->mainFrame())->loader().load(FrameLoadRequest(0, blankURL(), SubstituteData(data(), AtomicString("image/svg+xml", AtomicString::ConstructFromLiteral), AtomicString("UTF-8", AtomicString::ConstructFromLiteral), KURL(), ForceSynchronousLoad))); return true; } Page::PageClients pageClients; fillWithEmptyClients(pageClients); m_chromeClient = SVGImageChromeClient::create(this); pageClients.chromeClient = m_chromeClient.get(); // FIXME: If this SVG ends up loading itself, we might leak the world. // The Cache code does not know about ImageResources holding Frames and // won't know to break the cycle. // This will become an issue when SVGImage will be able to load other // SVGImage objects, but we're safe now, because SVGImage can only be // loaded by a top-level document. OwnPtrWillBeRawPtr<Page> page; { TRACE_EVENT0("blink", "SVGImage::dataChanged::createPage"); page = Page::create(pageClients); page->settings().setScriptEnabled(false); page->settings().setPluginsEnabled(false); page->settings().setAcceleratedCompositingEnabled(false); // Because this page is detached, it can't get default font settings // from the embedder. Copy over font settings so we have sensible // defaults. These settings are fixed and will not update if changed. if (!Page::ordinaryPages().isEmpty()) { Settings& defaultSettings = (*Page::ordinaryPages().begin())->settings(); page->settings().genericFontFamilySettings() = defaultSettings.genericFontFamilySettings(); page->settings().setMinimumFontSize(defaultSettings.minimumFontSize()); page->settings().setMinimumLogicalFontSize(defaultSettings.minimumLogicalFontSize()); page->settings().setDefaultFontSize(defaultSettings.defaultFontSize()); page->settings().setDefaultFixedFontSize(defaultSettings.defaultFixedFontSize()); } } RefPtrWillBeRawPtr<LocalFrame> frame = nullptr; { TRACE_EVENT0("blink", "SVGImage::dataChanged::createFrame"); frame = LocalFrame::create(dummyFrameLoaderClient.get(), &page->frameHost(), 0); frame->setView(FrameView::create(frame.get())); frame->init(); } FrameLoader& loader = frame->loader(); loader.forceSandboxFlags(SandboxAll); frame->view()->setScrollbarsSuppressed(true); frame->view()->setCanHaveScrollbars(false); // SVG Images will always synthesize a viewBox, if it's not available, and thus never see scrollbars. frame->view()->setTransparent(true); // SVG Images are transparent. m_page = page.release(); TRACE_EVENT0("blink", "SVGImage::dataChanged::load"); loader.load(FrameLoadRequest(0, blankURL(), SubstituteData(data(), AtomicString("image/svg+xml", AtomicString::ConstructFromLiteral), AtomicString("UTF-8", AtomicString::ConstructFromLiteral), KURL(), ForceSynchronousLoad))); // Set the intrinsic size before a container size is available. m_intrinsicSize = containerSize(); } return m_page; }
FrameFetchContext* createChildFrame() { childClient = StubFrameLoaderClientWithParent::create(document->frame()); childFrame = LocalFrame::create(childClient.get(), document->frame()->host(), owner.get()); childFrame->setView(FrameView::create(childFrame.get(), IntSize(500, 500))); childFrame->init(); childDocumentLoader = DocumentLoader::create(childFrame.get(), ResourceRequest("http://www.example.com"), SubstituteData()); childDocument = childFrame->document(); FrameFetchContext* childFetchContext = static_cast<FrameFetchContext*>(&childDocumentLoader->fetcher()->context()); FrameFetchContext::provideDocumentToContext(*childFetchContext, childDocument.get()); return childFetchContext; }
Page* InspectorOverlay::overlayPage() { if (m_overlayPage) return m_overlayPage.get(); ScriptForbiddenScope::AllowUserAgentScript allowScript; DEFINE_STATIC_LOCAL(FrameLoaderClient, dummyFrameLoaderClient, (EmptyFrameLoaderClient::create())); Page::PageClients pageClients; fillWithEmptyClients(pageClients); DCHECK(!m_overlayChromeClient); m_overlayChromeClient = InspectorOverlayChromeClient::create( m_frameImpl->frame()->host()->chromeClient(), *this); pageClients.chromeClient = m_overlayChromeClient.get(); m_overlayPage = Page::create(pageClients); Settings& settings = m_frameImpl->frame()->host()->settings(); Settings& overlaySettings = m_overlayPage->settings(); overlaySettings.genericFontFamilySettings().updateStandard( settings.genericFontFamilySettings().standard()); overlaySettings.genericFontFamilySettings().updateSerif( settings.genericFontFamilySettings().serif()); overlaySettings.genericFontFamilySettings().updateSansSerif( settings.genericFontFamilySettings().sansSerif()); overlaySettings.genericFontFamilySettings().updateCursive( settings.genericFontFamilySettings().cursive()); overlaySettings.genericFontFamilySettings().updateFantasy( settings.genericFontFamilySettings().fantasy()); overlaySettings.genericFontFamilySettings().updatePictograph( settings.genericFontFamilySettings().pictograph()); overlaySettings.setMinimumFontSize(settings.minimumFontSize()); overlaySettings.setMinimumLogicalFontSize(settings.minimumLogicalFontSize()); overlaySettings.setScriptEnabled(true); overlaySettings.setPluginsEnabled(false); overlaySettings.setLoadsImagesAutomatically(true); // FIXME: http://crbug.com/363843. Inspector should probably create its // own graphics layers and attach them to the tree rather than going // through some non-composited paint function. overlaySettings.setAcceleratedCompositingEnabled(false); LocalFrame* frame = LocalFrame::create(&dummyFrameLoaderClient, &m_overlayPage->frameHost(), 0); frame->setView(FrameView::create(*frame)); frame->init(); FrameLoader& loader = frame->loader(); frame->view()->setCanHaveScrollbars(false); frame->view()->setTransparent(true); const WebData& overlayPageHTMLResource = Platform::current()->loadResource("InspectorOverlayPage.html"); RefPtr<SharedBuffer> data = SharedBuffer::create( overlayPageHTMLResource.data(), overlayPageHTMLResource.size()); loader.load(FrameLoadRequest( 0, blankURL(), SubstituteData(data, "text/html", "UTF-8", KURL(), ForceSynchronousLoad))); v8::Isolate* isolate = toIsolate(frame); ScriptState* scriptState = ScriptState::forMainWorld(frame); DCHECK(scriptState); ScriptState::Scope scope(scriptState); v8::Local<v8::Object> global = scriptState->context()->Global(); v8::Local<v8::Value> overlayHostObj = toV8(m_overlayHost.get(), global, isolate); DCHECK(!overlayHostObj.IsEmpty()); global ->Set(scriptState->context(), v8AtomicString(isolate, "InspectorOverlayHost"), overlayHostObj) .ToChecked(); #if OS(WIN) evaluateInOverlay("setPlatform", "windows"); #elif OS(MACOSX) evaluateInOverlay("setPlatform", "mac"); #elif OS(POSIX) evaluateInOverlay("setPlatform", "linux"); #endif return m_overlayPage.get(); }
void SetUp() override { dummyPageHolder = DummyPageHolder::create(IntSize(500, 500)); dummyPageHolder->page().setDeviceScaleFactor(1.0); documentLoader = DocumentLoader::create(&dummyPageHolder->frame(), ResourceRequest("http://www.example.com"), SubstituteData()); document = toHTMLDocument(&dummyPageHolder->document()); fetchContext = static_cast<FrameFetchContext*>(&documentLoader->fetcher()->context()); owner = DummyFrameOwner::create(); FrameFetchContext::provideDocumentToContext(*fetchContext, document.get()); }