void ProgressTracker::incrementProgress(unsigned long identifier, unsigned bytesReceived) { ProgressItem* item = m_progressItems.get(identifier); // FIXME: Can this ever happen? if (!item) return; RefPtr<Frame> frame = m_originatingProgressFrame; m_client.willChangeEstimatedProgress(); double increment, percentOfRemainingBytes; long long remainingBytes, estimatedBytesForPendingRequests; item->bytesReceived += bytesReceived; if (item->bytesReceived > item->estimatedLength) { m_totalPageAndResourceBytesToLoad += ((item->bytesReceived * 2) - item->estimatedLength); item->estimatedLength = item->bytesReceived * 2; } int numPendingOrLoadingRequests = frame->loader().numPendingOrLoadingRequests(true); estimatedBytesForPendingRequests = static_cast<long long>(progressItemDefaultEstimatedLength) * numPendingOrLoadingRequests; remainingBytes = ((m_totalPageAndResourceBytesToLoad + estimatedBytesForPendingRequests) - m_totalBytesReceived); if (remainingBytes > 0) // Prevent divide by 0. percentOfRemainingBytes = (double)bytesReceived / (double)remainingBytes; else percentOfRemainingBytes = 1.0; // For documents that use WebCore's layout system, treat first layout as the half-way point. // FIXME: The hasHTMLView function is a sort of roundabout way of asking "do you use WebCore's layout system". bool useClampedMaxProgress = frame->loader().client().hasHTMLView() && !frame->loader().stateMachine().firstLayoutDone(); double maxProgressValue = useClampedMaxProgress ? 0.5 : finalProgressValue; increment = (maxProgressValue - m_progressValue) * percentOfRemainingBytes; m_progressValue += increment; m_progressValue = std::min(m_progressValue, maxProgressValue); ASSERT(m_progressValue >= initialProgressValue); m_totalBytesReceived += bytesReceived; auto now = std::chrono::steady_clock::now(); auto notifiedProgressTimeDelta = now - m_lastNotifiedProgressTime; LOG(Progress, "Progress incremented (%p) - value %f, tracked frames %d", this, m_progressValue, m_numProgressTrackedFrames); if ((notifiedProgressTimeDelta >= progressNotificationTimeInterval || m_progressValue == 1) && m_numProgressTrackedFrames > 0) { if (!m_finalProgressChangedSent) { if (m_progressValue == 1) m_finalProgressChangedSent = true; m_client.progressEstimateChanged(*frame); m_lastNotifiedProgressValue = m_progressValue; m_lastNotifiedProgressTime = now; } } m_client.didChangeEstimatedProgress(); }
Frame* SubframeLoader::loadSubframe(HTMLFrameOwnerElement& ownerElement, const URL& url, const String& name, const String& referrer) { Ref<Frame> protect(m_frame); bool allowsScrolling = true; int marginWidth = -1; int marginHeight = -1; if (is<HTMLFrameElementBase>(ownerElement)) { HTMLFrameElementBase& frameElementBase = downcast<HTMLFrameElementBase>(ownerElement); allowsScrolling = frameElementBase.scrollingMode() != ScrollbarAlwaysOff; marginWidth = frameElementBase.marginWidth(); marginHeight = frameElementBase.marginHeight(); } if (!ownerElement.document().securityOrigin()->canDisplay(url)) { FrameLoader::reportLocalLoadFailed(&m_frame, url.string()); return nullptr; } if (!SubframeLoadingDisabler::canLoadFrame(ownerElement)) return nullptr; String referrerToUse = SecurityPolicy::generateReferrerHeader(ownerElement.document().referrerPolicy(), url, referrer); RefPtr<Frame> frame = m_frame.loader().client().createFrame(url, name, &ownerElement, referrerToUse, allowsScrolling, marginWidth, marginHeight); if (!frame) { m_frame.loader().checkCallImplicitClose(); return nullptr; } // All new frames will have m_isComplete set to true at this point due to synchronously loading // an empty document in FrameLoader::init(). But many frames will now be starting an // asynchronous load of url, so we set m_isComplete to false and then check if the load is // actually completed below. (Note that we set m_isComplete to false even for synchronous // loads, so that checkCompleted() below won't bail early.) // FIXME: Can we remove this entirely? m_isComplete normally gets set to false when a load is committed. frame->loader().started(); auto* renderer = ownerElement.renderer(); FrameView* view = frame->view(); if (is<RenderWidget>(renderer) && view) downcast<RenderWidget>(*renderer).setWidget(view); m_frame.loader().checkCallImplicitClose(); // Some loads are performed synchronously (e.g., about:blank and loads // cancelled by returning a null ResourceRequest from requestFromDelegate). // In these cases, the synchronous load would have finished // before we could connect the signals, so make sure to send the // completed() signal for the child by hand and mark the load as being // complete. // FIXME: In this case the Frame will have finished loading before // it's being added to the child list. It would be a good idea to // create the child first, then invoke the loader separately. if (frame->loader().state() == FrameStateComplete && !frame->loader().policyDocumentLoader()) frame->loader().checkCompleted(); return frame.get(); }
void ProgressTracker::incrementProgress(unsigned long identifier, const char*, int length) { ProgressItem* item = m_progressItems.get(identifier); // FIXME: Can this ever happen? if (!item) return; RefPtr<Frame> frame = m_originatingProgressFrame; unsigned bytesReceived = length; double increment, percentOfRemainingBytes; long long remainingBytes, estimatedBytesForPendingRequests; item->bytesReceived += bytesReceived; if (item->bytesReceived > item->estimatedLength) { m_totalPageAndResourceBytesToLoad += ((item->bytesReceived * 2) - item->estimatedLength); item->estimatedLength = item->bytesReceived * 2; } int numPendingOrLoadingRequests = frame->loader()->numPendingOrLoadingRequests(true); estimatedBytesForPendingRequests = progressItemDefaultEstimatedLength * numPendingOrLoadingRequests; remainingBytes = ((m_totalPageAndResourceBytesToLoad + estimatedBytesForPendingRequests) - m_totalBytesReceived); if (remainingBytes > 0) // Prevent divide by 0. percentOfRemainingBytes = (double)bytesReceived / (double)remainingBytes; else percentOfRemainingBytes = 1.0; // For documents that use WebCore's layout system, treat first layout as the half-way point. bool useClampedMaxProgress = !frame->view()->didFirstLayout(); double maxProgressValue = useClampedMaxProgress ? 0.5 : finalProgressValue; increment = (maxProgressValue - m_progressValue) * percentOfRemainingBytes; m_progressValue += increment; m_progressValue = min(m_progressValue, maxProgressValue); ASSERT(m_progressValue >= initialProgressValue); m_totalBytesReceived += bytesReceived; double now = currentTime(); double notifiedProgressTimeDelta = now - m_lastNotifiedProgressTime; LOG(Progress, "Progress incremented (%p) - value %f, tracked frames %d", this, m_progressValue, m_numProgressTrackedFrames); double notificationProgressDelta = m_progressValue - m_lastNotifiedProgressValue; if ((notificationProgressDelta >= m_progressNotificationInterval || notifiedProgressTimeDelta >= m_progressNotificationTimeInterval) && m_numProgressTrackedFrames > 0) { if (!m_finalProgressChangedSent) { if (m_progressValue == 1) m_finalProgressChangedSent = true; frame->loader()->client()->postProgressEstimateChangedNotification(); m_lastNotifiedProgressValue = m_progressValue; m_lastNotifiedProgressTime = now; } } }
Frame* SubframeLoader::loadSubframe(HTMLFrameOwnerElement* ownerElement, const KURL& url, const String& name, const String& referrer) { bool allowsScrolling = true; int marginWidth = -1; int marginHeight = -1; if (ownerElement->hasTagName(frameTag) || ownerElement->hasTagName(iframeTag)) { HTMLFrameElementBase* o = static_cast<HTMLFrameElementBase*>(ownerElement); allowsScrolling = o->scrollingMode() != ScrollbarAlwaysOff; marginWidth = o->marginWidth(); marginHeight = o->marginHeight(); } if (!ownerElement->document()->securityOrigin()->canDisplay(url)) { FrameLoader::reportLocalLoadFailed(m_frame, url.string()); return 0; } if (!ownerElement->document()->contentSecurityPolicy()->allowChildFrameFromSource(url)) return 0; bool hideReferrer = SecurityOrigin::shouldHideReferrer(url, referrer); RefPtr<Frame> frame = m_frame->loader()->client()->createFrame(url, name, ownerElement, hideReferrer ? String() : referrer, allowsScrolling, marginWidth, marginHeight); if (!frame) { m_frame->loader()->checkCallImplicitClose(); return 0; } // All new frames will have m_isComplete set to true at this point due to synchronously loading // an empty document in FrameLoader::init(). But many frames will now be starting an // asynchronous load of url, so we set m_isComplete to false and then check if the load is // actually completed below. (Note that we set m_isComplete to false even for synchronous // loads, so that checkCompleted() below won't bail early.) // FIXME: Can we remove this entirely? m_isComplete normally gets set to false when a load is committed. frame->loader()->started(); RenderObject* renderer = ownerElement->renderer(); FrameView* view = frame->view(); if (renderer && renderer->isWidget() && view) toRenderWidget(renderer)->setWidget(view); m_frame->loader()->checkCallImplicitClose(); // Some loads are performed synchronously (e.g., about:blank and loads // cancelled by returning a null ResourceRequest from requestFromDelegate). // In these cases, the synchronous load would have finished // before we could connect the signals, so make sure to send the // completed() signal for the child by hand and mark the load as being // complete. // FIXME: In this case the Frame will have finished loading before // it's being added to the child list. It would be a good idea to // create the child first, then invoke the loader separately. if (frame->loader()->state() == FrameStateComplete && !frame->loader()->policyDocumentLoader()) frame->loader()->checkCompleted(); return frame.get(); }
PassRefPtr<Frame> FrameLoaderClientHl::createFrame(const KURL& url, const String& name, HTMLFrameOwnerElement* ownerElement, const String& referrer, bool allowsScrolling, int marginWidth, int marginHeight) { // Create separate frame loader for a new frame FrameLoaderClientHl* newLoaderClient = new FrameLoaderClientHl(); newLoaderClient->setUserAgent(m_userAgent); // And a new frame, inheriting current page RefPtr<Frame> childFrame = Frame::create(m_frame->page(), ownerElement, newLoaderClient); newLoaderClient->setFrame(m_webFrame, childFrame.get()); childFrame->tree()->setName(name); m_frame->tree()->appendChild(childFrame); childFrame->init(); if (!childFrame->page()) return 0; childFrame->loader()->loadURLIntoChildFrame(url, referrer, childFrame.get()); if (!childFrame->tree()->parent()) return 0; return childFrame.release(); }
PassRefPtr<Frame> FrameLoaderClientQt::createFrame(const KURL& url, const String& name, HTMLFrameOwnerElement* ownerElement, const String& referrer, bool allowsScrolling, int marginWidth, int marginHeight) { if (!m_webFrame) return 0; QWebFrameData frameData; frameData.url = url; frameData.name = name; frameData.ownerElement = ownerElement; frameData.referrer = referrer; frameData.allowsScrolling = allowsScrolling; frameData.marginWidth = marginWidth; frameData.marginHeight = marginHeight; QWebFrame* webFrame = new QWebFrame(m_webFrame, &frameData); emit m_webFrame->page()->frameCreated(webFrame); RefPtr<Frame> childFrame = adoptRef(webFrame->d->frame); // ### set override encoding if we have one FrameLoadType loadType = m_frame->loader()->loadType(); FrameLoadType childLoadType = FrameLoadTypeRedirectWithLockedHistory; childFrame->loader()->loadURL(frameData.url, frameData.referrer, String(), childLoadType, 0, 0); // The frame's onload handler may have removed it from the document. if (!childFrame->tree()->parent()) return 0; return childFrame.release(); }
PassRefPtr<Frame> WebFrameLoaderClient::createFrame(const KURL& url, const String& name, HTMLFrameOwnerElement* ownerElement, const String& referrer) { if (url.string().isEmpty()) return 0; Frame* coreFrame = core(m_webFrame); ASSERT(coreFrame); WebFrame* webFrame = WebFrame::createInstance(); //webFrame->ref(); RefPtr<Frame> childFrame = webFrame->init(m_webFrame->webView(), coreFrame->page(), ownerElement); childFrame->ref(); coreFrame->tree()->appendChild(childFrame); childFrame->tree()->setName(name); childFrame->init(); // The creation of the frame may have run arbitrary JavaScript that removed it from the page already. if (!childFrame->page()) { delete webFrame; return 0; } childFrame->loader()->loadURLIntoChildFrame(url, referrer, childFrame.get()); // The frame's onload handler may have removed it from the document. if (!childFrame->tree()->parent()) { delete webFrame; return 0; } return childFrame.release(); }
PassRefPtr<Frame> FrameLoaderClientWx::createFrame(const KURL& url, const String& name, HTMLFrameOwnerElement* ownerElement, const String& referrer, bool allowsScrolling, int marginWidth, int marginHeight) { WebViewFrameData* data = new WebViewFrameData(); data->name = name; data->ownerElement = ownerElement; data->url = url; data->referrer = referrer; data->allowsScrolling = allowsScrolling; data->marginWidth = marginWidth; data->marginHeight = marginHeight; wxWebFrame* newFrame = new wxWebFrame(m_webView, m_webFrame, data); RefPtr<Frame> childFrame = adoptRef(newFrame->m_impl->frame); // The creation of the frame may have run arbitrary JavaScript that removed it from the page already. if (!childFrame->page()) return 0; childFrame->loader()->loadURLIntoChildFrame(url, referrer, childFrame.get()); // The frame's onload handler may have removed it from the document. if (!childFrame->tree()->parent()) return 0; return childFrame.release(); }
PassRefPtr<Frame> FrameLoaderClientHaiku::createFrame(const KURL& url, const String& name, HTMLFrameOwnerElement* ownerElement, const String& referrer, bool allowsScrolling, int marginWidth, int marginHeight) { // FIXME: We should apply the right property to the frameView. (scrollbar,margins) RefPtr<Frame> childFrame = Frame::create(m_frame->page(), ownerElement, this); setFrame(childFrame.get()); RefPtr<FrameView> frameView = FrameView::create(childFrame.get()); frameView->setAllowsScrolling(allowsScrolling); frameView->deref(); childFrame->setView(frameView.get()); childFrame->init(); childFrame->tree()->setName(name); m_frame->tree()->appendChild(childFrame); childFrame->loader()->loadURLIntoChildFrame(url, referrer, childFrame.get()); // The frame's onload handler may have removed it from the document. if (!childFrame->tree()->parent()) return 0; return childFrame.release(); notImplemented(); return 0; }
PassRefPtr<Frame> FrameLoaderClient::createFrame(const KURL& url, const String& name, HTMLFrameOwnerElement* ownerElement, const String& referrer, bool allowsScrolling, int marginWidth, int marginHeight) { Frame* coreFrame = core(m_frame); ASSERT(core(getViewFromFrame(m_frame)) == coreFrame->page()); RefPtr<Frame> childFrame = webkit_web_frame_init_with_web_view(getViewFromFrame(m_frame), ownerElement); coreFrame->tree()->appendChild(childFrame); childFrame->tree()->setName(name); childFrame->init(); // The creation of the frame may have run arbitrary JavaScript that removed it from the page already. if (!childFrame->page()) return 0; childFrame->loader()->loadURLIntoChildFrame(url, referrer, childFrame.get()); // The frame's onload handler may have removed it from the document. if (!childFrame->tree()->parent()) return 0; return childFrame.release(); }
Page* InspectorOverlay::overlayPage() { if (m_overlayPage) return m_overlayPage.get(); static FrameLoaderClient* dummyFrameLoaderClient = new EmptyFrameLoaderClient; Page::PageClients pageClients; fillWithEmptyClients(pageClients); ASSERT(!m_overlayChromeClient); m_overlayChromeClient = adoptPtr(new InspectorOverlayChromeClient(m_page->chrome().client(), this)); pageClients.chromeClient = m_overlayChromeClient.get(); m_overlayPage = adoptPtr(new Page(pageClients)); m_overlayPage->setGroupType(Page::InspectorPageGroup); Settings* settings = m_page->settings(); Settings* overlaySettings = m_overlayPage->settings(); overlaySettings->setStandardFontFamily(settings->standardFontFamily()); overlaySettings->setSerifFontFamily(settings->serifFontFamily()); overlaySettings->setSansSerifFontFamily(settings->sansSerifFontFamily()); overlaySettings->setCursiveFontFamily(settings->cursiveFontFamily()); overlaySettings->setFantasyFontFamily(settings->fantasyFontFamily()); overlaySettings->setPictographFontFamily(settings->pictographFontFamily()); overlaySettings->setMinimumFontSize(settings->minimumFontSize()); overlaySettings->setMinimumLogicalFontSize(settings->minimumLogicalFontSize()); overlaySettings->setMediaEnabled(false); overlaySettings->setScriptEnabled(true); overlaySettings->setPluginsEnabled(false); overlaySettings->setLoadsImagesAutomatically(true); RefPtr<Frame> frame = Frame::create(m_overlayPage.get(), 0, dummyFrameLoaderClient); frame->setView(FrameView::create(frame.get())); frame->init(); FrameLoader* loader = frame->loader(); frame->view()->setCanHaveScrollbars(false); frame->view()->setTransparent(true); ASSERT(loader->activeDocumentLoader()); loader->activeDocumentLoader()->writer()->setMIMEType("text/html"); loader->activeDocumentLoader()->writer()->begin(); loader->activeDocumentLoader()->writer()->addData(reinterpret_cast<const char*>(InspectorOverlayPage_html), sizeof(InspectorOverlayPage_html)); loader->activeDocumentLoader()->writer()->end(); v8::HandleScope handleScope; v8::Handle<v8::Context> frameContext = frame->script()->currentWorldContext(); v8::Context::Scope contextScope(frameContext); v8::Handle<v8::Value> overlayHostObj = toV8(m_overlayHost.get(), v8::Handle<v8::Object>(), frameContext->GetIsolate()); v8::Handle<v8::Object> global = frameContext->Global(); global->Set(v8::String::New("InspectorOverlayHost"), overlayHostObj); #if OS(WINDOWS) evaluateInOverlay("setPlatform", "windows"); #elif OS(DARWIN) evaluateInOverlay("setPlatform", "mac"); #elif OS(UNIX) evaluateInOverlay("setPlatform", "linux"); #endif return m_overlayPage.get(); }
void ProgressTracker::finalProgressComplete() { LOG(Progress, "Final progress complete (%p)", this); RefPtr<Frame> frame = m_originatingProgressFrame.release(); // Before resetting progress value be sure to send client a least one notification // with final progress value. if (!m_finalProgressChangedSent) { m_progressValue = 1; frame->loader()->client()->postProgressEstimateChangedNotification(); } reset(); frame->loader()->client()->postProgressFinishedNotification(); InspectorInstrumentation::frameStoppedLoading(frame.get()); }
bool SVGImage::dataChanged(bool allDataReceived) { // Don't do anything if is an empty image. if (!data()->size()) return true; if (allDataReceived) { static FrameLoaderClient* dummyFrameLoaderClient = new EmptyFrameLoaderClient; Page::PageClients pageClients; m_chromeClient = adoptPtr(new SVGImageChromeClient(this)); pageClients.chromeClient = m_chromeClient.get(); #if ENABLE(CONTEXT_MENUS) static ContextMenuClient* dummyContextMenuClient = new EmptyContextMenuClient; pageClients.contextMenuClient = dummyContextMenuClient; #endif static EditorClient* dummyEditorClient = new EmptyEditorClient; pageClients.editorClient = dummyEditorClient; #if ENABLE(DRAG_SUPPORT) static DragClient* dummyDragClient = new EmptyDragClient; pageClients.dragClient = dummyDragClient; #endif static InspectorClient* dummyInspectorClient = new EmptyInspectorClient; pageClients.inspectorClient = dummyInspectorClient; #if ENABLE(DEVICE_ORIENTATION) static DeviceMotionClient* dummyDeviceMotionClient = new EmptyDeviceMotionClient; pageClients.deviceMotionClient = dummyDeviceMotionClient; static DeviceOrientationClient* dummyDeviceOrientationClient = new EmptyDeviceOrientationClient; pageClients.deviceOrientationClient = dummyDeviceOrientationClient; #endif // FIXME: If this SVG ends up loading itself, we might leak the world. // The comment said that the Cache code does not know about CachedImages // holding Frames and won't know to break the cycle. But m_page.set(new Page(pageClients)); m_page->settings()->setMediaEnabled(false); m_page->settings()->setJavaScriptEnabled(false); m_page->settings()->setPluginsEnabled(false); RefPtr<Frame> frame = Frame::create(m_page.get(), 0, dummyFrameLoaderClient); frame->setView(FrameView::create(frame.get())); frame->init(); ResourceRequest fakeRequest(KURL(ParsedURLString, "")); FrameLoader* loader = frame->loader(); loader->setForcedSandboxFlags(SandboxAll); loader->load(fakeRequest, false); // Make sure the DocumentLoader is created loader->policyChecker()->cancelCheck(); // cancel any policy checks loader->commitProvisionalLoad(); loader->writer()->setMIMEType("image/svg+xml"); loader->writer()->begin(KURL()); // create the empty document loader->writer()->addData(data()->data(), data()->size()); loader->writer()->end(); frame->view()->setTransparent(true); // SVG Images are transparent. } return m_page; }
void InspectorFrontendClientLocal::openInNewTab(const String& url) { UserGestureIndicator indicator(DefinitelyProcessingUserGesture); Frame& mainFrame = m_inspectorController->inspectedPage().mainFrame(); FrameLoadRequest request(mainFrame.document()->securityOrigin(), ResourceRequest(), "_blank"); bool created; WindowFeatures windowFeatures; RefPtr<Frame> frame = WebCore::createWindow(&mainFrame, &mainFrame, request, windowFeatures, created); if (!frame) return; frame->loader().setOpener(&mainFrame); frame->page()->setOpenedByDOM(); // FIXME: Why does one use mainFrame and the other frame? frame->loader().changeLocation(mainFrame.document()->securityOrigin(), frame->document()->completeURL(url), "", LockHistory::No, LockBackForwardList::No); }
bool SVGImage::dataChanged(bool allDataReceived) { // Don't do anything if is an empty image. if (!data()->size()) return true; if (allDataReceived) { static FrameLoaderClient* dummyFrameLoaderClient = new EmptyFrameLoaderClient; Page::PageClients pageClients; m_chromeClient = adoptPtr(new SVGImageChromeClient(this)); pageClients.chromeClient = m_chromeClient.get(); #if ENABLE(CONTEXT_MENUS) static ContextMenuClient* dummyContextMenuClient = new EmptyContextMenuClient; pageClients.contextMenuClient = dummyContextMenuClient; #endif static EditorClient* dummyEditorClient = new EmptyEditorClient; pageClients.editorClient = dummyEditorClient; #if ENABLE(DRAG_SUPPORT) static DragClient* dummyDragClient = new EmptyDragClient; pageClients.dragClient = dummyDragClient; #endif static InspectorClient* dummyInspectorClient = new EmptyInspectorClient; pageClients.inspectorClient = dummyInspectorClient; #if ENABLE(DEVICE_ORIENTATION) static DeviceMotionClient* dummyDeviceMotionClient = new EmptyDeviceMotionClient; pageClients.deviceMotionClient = dummyDeviceMotionClient; static DeviceOrientationClient* dummyDeviceOrientationClient = new EmptyDeviceOrientationClient; pageClients.deviceOrientationClient = dummyDeviceOrientationClient; #endif // FIXME: If this SVG ends up loading itself, we might leak the world. // The Cache code does not know about CachedImages 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. m_page.set(new Page(pageClients)); m_page->settings()->setMediaEnabled(false); m_page->settings()->setJavaScriptEnabled(false); m_page->settings()->setPluginsEnabled(false); RefPtr<Frame> frame = Frame::create(m_page.get(), 0, dummyFrameLoaderClient); frame->setView(FrameView::create(frame.get())); frame->init(); FrameLoader* loader = frame->loader(); loader->setForcedSandboxFlags(SandboxAll); ASSERT(loader->activeDocumentLoader()); // DocumentLoader should have been created by frame->init(). loader->activeDocumentLoader()->writer()->setMIMEType("image/svg+xml"); loader->activeDocumentLoader()->writer()->begin(KURL()); // create the empty document loader->activeDocumentLoader()->writer()->addData(data()->data(), data()->size()); loader->activeDocumentLoader()->writer()->end(); frame->view()->setTransparent(true); // SVG Images are transparent. } return m_page; }
void ProgressTracker::finalProgressComplete() { // LOG (Progress, ""); RefPtr<Frame> frame = m_originatingProgressFrame.release(); // Before resetting progress value be sure to send client a least one notification // with final progress value. if (!m_finalProgressChangedSent) { m_progressValue = 1; frame->loader()->client()->postProgressEstimateChangedNotification(); } reset(); frame->loader()->client()->setMainFrameDocumentReady(true); frame->loader()->client()->postProgressFinishedNotification(); }
void InspectorFrontendClientLocal::openInNewTab(const String& url) { UserGestureIndicator indicator(DefinitelyProcessingUserGesture); Frame& mainFrame = m_inspectedPageController->inspectedPage().mainFrame(); FrameLoadRequest request(mainFrame.document()->securityOrigin(), ResourceRequest(), "_blank", LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, ReplaceDocumentIfJavaScriptURL, ShouldOpenExternalURLsPolicy::ShouldNotAllow); bool created; WindowFeatures windowFeatures; RefPtr<Frame> frame = WebCore::createWindow(mainFrame, mainFrame, request, windowFeatures, created); if (!frame) return; frame->loader().setOpener(&mainFrame); frame->page()->setOpenedByDOM(); // FIXME: Why does one use mainFrame and the other frame? ResourceRequest resourceRequest(frame->document()->completeURL(url)); FrameLoadRequest frameRequest(mainFrame.document()->securityOrigin(), resourceRequest, "_self", LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, ReplaceDocumentIfJavaScriptURL, ShouldOpenExternalURLsPolicy::ShouldNotAllow); frame->loader().changeLocation(frameRequest); }
void Page::setMemoryCacheClientCallsEnabled(bool enabled) { if (m_areMemoryCacheClientCallsEnabled == enabled) return; m_areMemoryCacheClientCallsEnabled = enabled; if (!enabled) return; for (RefPtr<Frame> frame = mainFrame(); frame; frame = frame->tree()->traverseNext()) frame->loader()->tellClientAboutPastMemoryCacheLoads(); }
void ProgressTracker::finalProgressComplete() { LOG(Progress, "Final progress complete (%p)", this); RefPtr<Frame> frame = m_originatingProgressFrame.release(); // Before resetting progress value be sure to send client a least one notification // with final progress value. if (!m_finalProgressChangedSent) { m_progressValue = 1; m_client.progressEstimateChanged(*frame); } reset(); frame->loader().client().setMainFrameDocumentReady(true); m_client.progressFinished(*frame); frame->loader().loadProgressingStatusChanged(); InspectorInstrumentation::frameStoppedLoading(*frame); }
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. m_page = adoptPtr(new Page(pageClients)); m_page->settings().setMediaEnabled(false); m_page->settings().setScriptEnabled(false); m_page->settings().setPluginsEnabled(false); m_page->settings().setAcceleratedCompositingEnabled(false); RefPtr<Frame> frame = Frame::create(FrameInit::create(0, m_page.get(), dummyFrameLoaderClient)); 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. ASSERT(loader.activeDocumentLoader()); // DocumentLoader should have been created by frame->init(). DocumentWriter* writer = loader.activeDocumentLoader()->beginWriting("image/svg+xml", "UTF-8"); writer->addData(data()->data(), data()->size()); loader.activeDocumentLoader()->endWriting(writer); // Set the intrinsic size before a container size is available. m_intrinsicSize = containerSize(); } return m_page; }
Page* InspectorOverlay::overlayPage() { if (m_overlayPage) return m_overlayPage.get(); static FrameLoaderClient* dummyFrameLoaderClient = new EmptyFrameLoaderClient; Page::PageClients pageClients; fillWithEmptyClients(pageClients); m_overlayPage = adoptPtr(new Page(pageClients)); Settings* settings = m_page->settings(); Settings* overlaySettings = m_overlayPage->settings(); overlaySettings->setStandardFontFamily(settings->standardFontFamily()); overlaySettings->setSerifFontFamily(settings->serifFontFamily()); overlaySettings->setSansSerifFontFamily(settings->sansSerifFontFamily()); overlaySettings->setCursiveFontFamily(settings->cursiveFontFamily()); overlaySettings->setFantasyFontFamily(settings->fantasyFontFamily()); overlaySettings->setPictographFontFamily(settings->pictographFontFamily()); overlaySettings->setMinimumFontSize(settings->minimumFontSize()); overlaySettings->setMinimumLogicalFontSize(settings->minimumLogicalFontSize()); overlaySettings->setMediaEnabled(false); overlaySettings->setScriptEnabled(true); overlaySettings->setPluginsEnabled(false); RefPtr<Frame> frame = Frame::create(m_overlayPage.get(), 0, dummyFrameLoaderClient); frame->setView(FrameView::create(frame.get())); frame->init(); FrameLoader* loader = frame->loader(); frame->view()->setCanHaveScrollbars(false); frame->view()->setTransparent(true); ASSERT(loader->activeDocumentLoader()); loader->activeDocumentLoader()->writer()->setMIMEType("text/html"); loader->activeDocumentLoader()->writer()->begin(); loader->activeDocumentLoader()->writer()->addData(reinterpret_cast<const char*>(InspectorOverlayPage_html), sizeof(InspectorOverlayPage_html)); loader->activeDocumentLoader()->writer()->end(); #if OS(WINDOWS) evaluateInOverlay("setPlatform", "windows"); #elif OS(MAC_OS_X) evaluateInOverlay("setPlatform", "mac"); #elif OS(UNIX) evaluateInOverlay("setPlatform", "linux"); #endif return m_overlayPage.get(); }
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; }
bool SVGImage::dataChanged(bool allDataReceived) { // 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 CachedImages 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. m_page = adoptPtr(new Page(pageClients)); m_page->settings()->setMediaEnabled(false); m_page->settings()->setScriptEnabled(false); m_page->settings()->setPluginsEnabled(false); RefPtr<Frame> frame = Frame::create(m_page.get(), 0, dummyFrameLoaderClient); frame->setView(FrameView::create(frame.get())); frame->init(); FrameLoader* loader = frame->loader(); loader->forceSandboxFlags(SandboxAll); 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. ASSERT(loader->activeDocumentLoader()); // DocumentLoader should have been created by frame->init(). loader->activeDocumentLoader()->writer()->setMIMEType("image/svg+xml"); loader->activeDocumentLoader()->writer()->begin(KURL()); // create the empty document loader->activeDocumentLoader()->writer()->addData(data()->data(), data()->size()); loader->activeDocumentLoader()->writer()->end(); } return m_page; }
bool HTMLFrameOwnerElement::loadOrRedirectSubframe(const KURL& url, const AtomicString& frameName, bool lockBackForwardList) { RefPtr<Frame> parentFrame = document().frame(); if (contentFrame()) { contentFrame()->navigationScheduler().scheduleLocationChange(document().securityOrigin(), url.string(), parentFrame->loader().outgoingReferrer(), lockBackForwardList); return true; } if (!document().securityOrigin()->canDisplay(url)) { FrameLoader::reportLocalLoadFailed(parentFrame.get(), url.string()); return false; } if (!SubframeLoadingDisabler::canLoadFrame(*this)) return false; String referrer = SecurityPolicy::generateReferrerHeader(document().referrerPolicy(), url, parentFrame->loader().outgoingReferrer()); RefPtr<Frame> childFrame = parentFrame->loader().client()->createFrame(url, frameName, referrer, this); if (!childFrame) { parentFrame->loader().checkCompleted(); return false; } // All new frames will have m_isComplete set to true at this point due to synchronously loading // an empty document in FrameLoader::init(). But many frames will now be starting an // asynchronous load of url, so we set m_isComplete to false and then check if the load is // actually completed below. (Note that we set m_isComplete to false even for synchronous // loads, so that checkCompleted() below won't bail early.) // FIXME: Can we remove this entirely? m_isComplete normally gets set to false when a load is committed. childFrame->loader().started(); RenderObject* renderObject = renderer(); FrameView* view = childFrame->view(); if (renderObject && renderObject->isWidget() && view) toRenderWidget(renderObject)->setWidget(view); // Some loads are performed synchronously (e.g., about:blank and loads // cancelled by returning a null ResourceRequest from requestFromDelegate). // In these cases, the synchronous load would have finished // before we could connect the signals, so make sure to send the // completed() signal for the child by hand and mark the load as being // complete. // FIXME: In this case the Frame will have finished loading before // it's being added to the child list. It would be a good idea to // create the child first, then invoke the loader separately. if (childFrame->loader().state() == FrameStateComplete && !childFrame->loader().policyDocumentLoader()) childFrame->loader().checkCompleted(); return true; }
void ScheduledAction::execute(Document* document) { JSDOMWindow* window = toJSDOMWindow(document->frame()); if (!window) return; RefPtr<Frame> frame = window->impl()->frame(); if (!frame || !frame->script()->isEnabled()) return; frame->script()->setProcessingTimerCallback(true); if (m_function) { executeFunctionInContext(window, window->shell()); Document::updateStyleForAllDocuments(); } else frame->loader()->executeScript(m_code); frame->script()->setProcessingTimerCallback(false); }
DragOperation DragController::tryDHTMLDrag(DragData* dragData) { ASSERT(dragData); ASSERT(m_document); DragOperation op = DragOperationNone; RefPtr<Frame> frame = m_page->mainFrame(); RefPtr<FrameView> viewProtector = frame->view(); if (!viewProtector) return DragOperationNone; ClipboardAccessPolicy policy = frame->loader()->baseURL().isLocalFile() ? ClipboardReadable : ClipboardTypesReadable; RefPtr<Clipboard> clipboard = dragData->createClipboard(policy); DragOperation srcOp = dragData->draggingSourceOperationMask(); clipboard->setSourceOperation(srcOp); PlatformMouseEvent event = createMouseEvent(dragData); if (frame->eventHandler()->updateDragAndDrop(event, clipboard.get())) { // *op unchanged if no source op was set if (!clipboard->destinationOperation(op)) { // The element accepted but they didn't pick an operation, so we pick one for them // (as does WinIE). if (srcOp & DragOperationCopy) op = DragOperationCopy; else if (srcOp & DragOperationMove || srcOp & DragOperationGeneric) op = DragOperationMove; else if (srcOp & DragOperationLink) op = DragOperationLink; else op = DragOperationGeneric; } else if (!(op & srcOp)) { op = DragOperationNone; } clipboard->setAccessPolicy(ClipboardNumb); // invalidate clipboard here for security return op; } return op; }
void ProgressTracker::incrementProgress(unsigned long identifier, const char*, int length) { ProgressItem* item = m_progressItems.get(identifier); // FIXME: Can this ever happen? if (!item) return; RefPtr<Frame> frame = m_originatingProgressFrame; frame->loader()->client()->willChangeEstimatedProgress(); unsigned bytesReceived = length; double increment, percentOfRemainingBytes; long long remainingBytes, estimatedBytesForPendingRequests; item->bytesReceived += bytesReceived; if (item->bytesReceived > item->estimatedLength) { m_totalPageAndResourceBytesToLoad += ((item->bytesReceived * 2) - item->estimatedLength); item->estimatedLength = item->bytesReceived * 2; } int numPendingOrLoadingRequests = frame->loader()->numPendingOrLoadingRequests(true); estimatedBytesForPendingRequests = progressItemDefaultEstimatedLength * numPendingOrLoadingRequests; remainingBytes = ((m_totalPageAndResourceBytesToLoad + estimatedBytesForPendingRequests) - m_totalBytesReceived); if (remainingBytes > 0) // Prevent divide by 0. percentOfRemainingBytes = (double)bytesReceived / (double)remainingBytes; else percentOfRemainingBytes = 1.0; // For documents that use WebCore's layout system, treat first layout as the half-way point. // FIXME: The hasHTMLView function is a sort of roundabout way of asking "do you use WebCore's layout system". bool useClampedMaxProgress = frame->loader()->client()->hasHTMLView() && !frame->loader()->firstLayoutDone(); double maxProgressValue = useClampedMaxProgress ? 0.5 : finalProgressValue; increment = (maxProgressValue - m_progressValue) * percentOfRemainingBytes; m_progressValue += increment; m_progressValue = min(m_progressValue, maxProgressValue); ASSERT(m_progressValue >= initialProgressValue); m_totalBytesReceived += bytesReceived; double now = currentTime(); double notifiedProgressTimeDelta = now - m_lastNotifiedProgressTime; // LOG (Progress, "_private->progressValue %g, _private->numProgressTrackedFrames %d", _private->progressValue, _private->numProgressTrackedFrames); double notificationProgressDelta = m_progressValue - m_lastNotifiedProgressValue; #ifdef OMAP_ENHANCEMENT if( (m_progressValue < slowfasttransitionProgressValue) && (m_progressNotificationInterval != slowProgressNotificationInterval)) { m_progressNotificationInterval = slowProgressNotificationInterval; m_progressNotificationTimeInterval = slowProgressNotificationTimeInterval; } else if (m_progressNotificationInterval != fastProgressNotificationInterval){ m_progressNotificationInterval = fastProgressNotificationInterval; m_progressNotificationTimeInterval = fastProgressNotificationTimeInterval; } #endif #ifdef OMAP_ENHANCEMENT if (((notificationProgressDelta >= m_progressNotificationInterval || notifiedProgressTimeDelta >= m_progressNotificationTimeInterval) && m_numProgressTrackedFrames > 0) || (m_progressValue >= finalProgressValue)) { #else if ((notificationProgressDelta >= m_progressNotificationInterval || notifiedProgressTimeDelta >= m_progressNotificationTimeInterval) && m_numProgressTrackedFrames > 0) { #endif if (!m_finalProgressChangedSent) { if (m_progressValue == 1) m_finalProgressChangedSent = true; frame->loader()->client()->postProgressEstimateChangedNotification(); m_lastNotifiedProgressValue = m_progressValue; m_lastNotifiedProgressTime = now; } } frame->loader()->client()->didChangeEstimatedProgress(); } void ProgressTracker::completeProgress(unsigned long identifier) { ProgressItem* item = m_progressItems.get(identifier); // FIXME: Can this happen? if (!item) return; // Adjust the total expected bytes to account for any overage/underage. long long delta = item->bytesReceived - item->estimatedLength; m_totalPageAndResourceBytesToLoad += delta; item->estimatedLength = item->bytesReceived; m_progressItems.remove(identifier); delete item; }
// WebFramePolicyListener ---------------------------------------------------------------- void WebFramePolicyListener::receivedPolicyDecision(PolicyAction action) { RefPtr<Frame> frame = m_frame.release(); if (frame) static_cast<WebFrame*>(frame->loader()->client())->receivedPolicyDecision(action); }
DragOperation DragController::tryDHTMLDrag(DragData* dragData) { ASSERT(dragData); ASSERT(m_document); DragOperation op = DragOperationNone; RefPtr<Frame> frame = m_page->mainFrame(); RefPtr<FrameView> viewProtector = frame->view(); if (!viewProtector) return DragOperationNone; ClipboardAccessPolicy policy = frame->loader()->baseURL().isLocalFile() ? ClipboardReadable : ClipboardTypesReadable; RefPtr<Clipboard> clipboard = dragData->createClipboard(policy); DragOperation srcOp = dragData->draggingSourceOperationMask(); clipboard->setSourceOperation(srcOp); #ifdef __OWB__ if (frame->eventHandler()->updateDragAndDrop(createMouseEvent(dragData), clipboard.get())) { #else PlatformMouseEvent event = createMouseEvent(dragData); if (frame->eventHandler()->updateDragAndDrop(event, clipboard.get())) { #endif // *op unchanged if no source op was set if (!clipboard->destinationOperation(op)) { // The element accepted but they didn't pick an operation, so we pick one for them // (as does WinIE). if (srcOp & DragOperationCopy) op = DragOperationCopy; else if (srcOp & DragOperationMove || srcOp & DragOperationGeneric) op = DragOperationMove; else if (srcOp & DragOperationLink) op = DragOperationLink; else op = DragOperationGeneric; } else if (!(op & srcOp)) { op = DragOperationNone; } clipboard->setAccessPolicy(ClipboardNumb); // invalidate clipboard here for security return op; } return op; } bool DragController::mayStartDragAtEventLocation(const Frame* frame, const IntPoint& framePos) { ASSERT(frame); if (!frame->view() || !frame->renderer()) return false; HitTestResult mouseDownTarget = HitTestResult(framePos); mouseDownTarget = frame->eventHandler()->hitTestResultAtPoint(framePos, true); if (mouseDownTarget.image() && !mouseDownTarget.absoluteImageURL().isEmpty() && frame->settings()->loadsImagesAutomatically() && m_dragSourceAction & DragSourceActionImage) return true; if (!mouseDownTarget.absoluteLinkURL().isEmpty() && m_dragSourceAction & DragSourceActionLink && mouseDownTarget.isLiveLink()) return true; if (mouseDownTarget.isSelected() && m_dragSourceAction & DragSourceActionSelection) return true; return false; }
EXPORT void benchmark(const char* url, int reloadCount, int width, int height) { ScriptController::initializeThreading(); // Setting this allows data: urls to load from a local file. SecurityOrigin::setLocalLoadPolicy(SecurityOrigin::AllowLocalLoadsForAll); // Create the fake JNIEnv and JavaVM InitializeJavaVM(); // The real function is private to libwebcore but we know what it does. notifyHistoryItemChanged = historyItemChanged; // Implement the shared timer callback MyJavaSharedClient client; JavaSharedClient::SetTimerClient(&client); JavaSharedClient::SetCookieClient(&client); // Create the page with all the various clients ChromeClientAndroid* chrome = new ChromeClientAndroid; EditorClientAndroid* editor = new EditorClientAndroid; Page* page = new Page(chrome, new ContextMenuClientAndroid, editor, new DragClientAndroid, new InspectorClientAndroid, 0, // PluginHalterClient 0); // GeolocationControllerClient editor->setPage(page); // Create MyWebFrame that intercepts network requests MyWebFrame* webFrame = new MyWebFrame(page); webFrame->setUserAgent("Performance testing"); // needs to be non-empty chrome->setWebFrame(webFrame); // ChromeClientAndroid maintains the reference. Release(webFrame); // Create the Frame and the FrameLoaderClient FrameLoaderClientAndroid* loader = new FrameLoaderClientAndroid(webFrame); RefPtr<Frame> frame = Frame::create(page, NULL, loader); loader->setFrame(frame.get()); // Build our View system, resize it to the given dimensions and release our // references. Note: We keep a referenec to frameView so we can layout and // draw later without risk of it being deleted. WebViewCore* webViewCore = new WebViewCore(JSC::Bindings::getJNIEnv(), MY_JOBJECT, frame.get()); RefPtr<FrameView> frameView = FrameView::create(frame.get()); WebFrameView* webFrameView = new WebFrameView(frameView.get(), webViewCore); frame->setView(frameView); frameView->resize(width, height); Release(webViewCore); Release(webFrameView); // Initialize the frame and turn of low-bandwidth display (it fails an // assertion in the Cache code) frame->init(); frame->selection()->setFocused(true); // Set all the default settings the Browser normally uses. Settings* s = frame->settings(); s->setLayoutAlgorithm(Settings::kLayoutNormal); // Normal layout for now s->setStandardFontFamily("sans-serif"); s->setFixedFontFamily("monospace"); s->setSansSerifFontFamily("sans-serif"); s->setSerifFontFamily("serif"); s->setCursiveFontFamily("cursive"); s->setFantasyFontFamily("fantasy"); s->setMinimumFontSize(8); s->setMinimumLogicalFontSize(8); s->setDefaultFontSize(16); s->setDefaultFixedFontSize(13); s->setLoadsImagesAutomatically(true); s->setJavaScriptEnabled(true); s->setDefaultTextEncodingName("latin1"); s->setPluginsEnabled(false); s->setShrinksStandaloneImagesToFit(false); s->setUseWideViewport(false); // Finally, load the actual data ResourceRequest req(url); frame->loader()->load(req, false); do { // Layout the page and service the timer frame->view()->layout(); while (client.m_hasTimer) { client.m_func(); JavaSharedClient::ServiceFunctionPtrQueue(); } JavaSharedClient::ServiceFunctionPtrQueue(); // Layout more if needed. while (frame->view()->needsLayout()) frame->view()->layout(); JavaSharedClient::ServiceFunctionPtrQueue(); if (reloadCount) frame->loader()->reload(true); } while (reloadCount--); // Draw into an offscreen bitmap SkBitmap bmp; bmp.setConfig(SkBitmap::kARGB_8888_Config, width, height); bmp.allocPixels(); SkCanvas canvas(bmp); PlatformGraphicsContext ctx(&canvas, NULL); GraphicsContext gc(&ctx); frame->view()->paintContents(&gc, IntRect(0, 0, width, height)); // Write the bitmap to the sdcard SkImageEncoder* enc = SkImageEncoder::Create(SkImageEncoder::kPNG_Type); enc->encodeFile("/sdcard/webcore_test.png", bmp, 100); delete enc; // Tear down the world. frame->loader()->detachFromParent(); delete page; }