IntRect BackingStoreClient::absoluteRect() const { IntRect rect = IntRect(IntPoint::zero(), viewportSize()); if (!isMainFrame()) { // It is possible that the owner HTML element has been removed at this point, // especially when the frame is loading a JavaScript URL. if (Element* elt = m_frame->ownerElement()) { if (RenderBox* obj = elt->renderBox()) rect.move(obj->borderLeft() + obj->paddingLeft(), obj->borderTop() + obj->paddingTop()); } } Frame* frame = m_frame; while (frame) { if (Element* element = static_cast<Element*>(frame->ownerElement())) { do { rect.move(element->offsetLeft(), element->offsetTop()); } while ((element = element->offsetParent())); } if ((frame = frame->tree()->parent())) rect.move((-frame->view()->scrollOffset())); } return rect; }
void FrameLoaderClientBlackBerry::dispatchDidStartProvisionalLoad() { if (isMainFrame()) m_webPagePrivate->setLoadState(WebPagePrivate::Provisional); if (m_webPagePrivate->m_dumpRenderTree) m_webPagePrivate->m_dumpRenderTree->didStartProvisionalLoadForFrame(m_frame); }
void FrameLoaderClientBlackBerry::dispatchDidReceiveTitle(const StringWithDirection& title) { if (isMainFrame()) m_webPagePrivate->m_client->setPageTitle(title.string().characters(), title.string().length()); if (m_webPagePrivate->m_dumpRenderTree) m_webPagePrivate->m_dumpRenderTree->didReceiveTitleForFrame(title.string(), m_frame); }
void FrameLoaderClientBlackBerry::provisionalLoadStarted() { // We would like to hide the virtual keyboard before it navigates to another page // so that the scroll offset without keyboard shown will be saved in the history item. // Then when the user navigates back, it will scroll to the right position. if (isMainFrame()) m_webPagePrivate->showVirtualKeyboard(false); }
IntSize BackingStoreClient::transformedViewportSize() const { ASSERT(m_frame); if (!m_frame->view()) return IntSize(); ASSERT(isMainFrame()); return m_webPage->d->transformedViewportSize(); }
void FrameLoaderClientBlackBerry::dispatchDecidePolicyForNavigationAction(FramePolicyFunction function, const NavigationAction& action, const ResourceRequest& request, PassRefPtr<FormState>) { PolicyAction decision = PolicyIgnore; const KURL& url = request.url(); if (!url.isNull()) { // Fragment scrolls on the same page should always be handled internally. // (Only count as a fragment scroll if we are scrolling to a #fragment url, not back to the top, and reloading // the same url is not a fragment scroll even if it has a #fragment.) const KURL& currentUrl = m_frame->document()->url(); bool isFragmentScroll = url.hasFragmentIdentifier() && url != currentUrl && equalIgnoringFragmentIdentifier(currentUrl, url); decision = decidePolicyForExternalLoad(request, isFragmentScroll); // Let the client have a chance to say whether this navigation should // be ignored or not. NetworkRequest platformRequest; request.initializePlatformRequest(platformRequest, cookiesEnabled()); if (platformRequest.getTargetType() == NetworkRequest::TargetIsUnknown) platformRequest.setTargetType(isMainFrame() ? NetworkRequest::TargetIsMainFrame : NetworkRequest::TargetIsSubframe); if (isMainFrame() && !m_webPagePrivate->m_client->acceptNavigationRequest( platformRequest, BlackBerry::Platform::NavigationType(action.type()))) { if (action.type() == NavigationTypeFormSubmitted || action.type() == NavigationTypeFormResubmitted) m_frame->loader()->resetMultipleFormSubmissionProtection(); if (action.type() == NavigationTypeLinkClicked && url.hasFragmentIdentifier()) { ResourceRequest emptyRequest; m_frame->loader()->activeDocumentLoader()->setLastCheckedRequest(emptyRequest); } decision = PolicyIgnore; } } // If we abort here, dispatchDidCancelClientRedirect will not be called. // So call it by hand. if (decision == PolicyIgnore) dispatchDidCancelClientRedirect(); (m_frame->loader()->policyChecker()->*function)(decision); if (m_webPagePrivate->m_dumpRenderTree) m_webPagePrivate->m_dumpRenderTree->didDecidePolicyForNavigationAction(action, request); }
IntRect BackingStoreClient::visibleContentsRect() const { ASSERT(m_frame); if (!m_frame->view()) return IntRect(); IntRect visibleContentRect = m_frame->view()->visibleContentRect(); ASSERT(isMainFrame()); return visibleContentRect; }
void FrameLoaderClientBlackBerry::dispatchDidChangeLocationWithinPage() { if (!isMainFrame()) return; String url = m_frame->document()->url().string(); String token = m_frame->loader()->documentLoader()->request().token(); m_webPagePrivate->m_client->notifyLoadToAnchor(url.characters(), url.length(), token.characters(), token.length()); }
void FrameLoaderClientBlackBerry::postProgressStartedNotification() { if (!isMainFrame()) return; // New load started, so clear the error. m_loadError = ResourceError(); m_sentReadyToRender = false; m_webPagePrivate->m_client->notifyLoadStarted(); }
MHTMLArchive* FrameFetchContext::archive() const { ASSERT(!isMainFrame()); // TODO(nasko): How should this work with OOPIF? // The MHTMLArchive is parsed as a whole, but can be constructed from // frames in mutliple processes. In that case, which process should parse // it and how should the output be spread back across multiple processes? if (!frame()->tree().parent()->isLocalFrame()) return nullptr; return toLocalFrame(frame()->tree().parent())->loader().documentLoader()->fetcher()->archive(); }
IntSize BackingStoreClient::viewportSize() const { ASSERT(m_frame); if (!m_frame->view()) return IntSize(); if (isMainFrame()) return m_webPage->d->viewportSize(); return m_frame->view()->visibleContentRect().size(); }
// This information doesn't appear to be incorporated into CompositingReasons. bool CompositingReasonFinder::requiresCompositingForScrollableFrame() const { // Need this done first to determine overflow. DCHECK(!m_layoutView.needsLayout()); if (isMainFrame()) return false; if (!(m_compositingTriggers & ScrollableInnerFrameTrigger)) return false; return m_layoutView.frameView()->isScrollable(); }
void BackingStoreClient::checkOriginOfCurrentScrollOperation() { // This is called via ChromeClientBlackBerry::scroll in order to check the origin // of the current scroll operation to decide whether to notify the client. // If the current scroll operation was initiated internally by WebCore itself // either via JavaScript, back/forward or otherwise then we need to go ahead // and notify the client of this change. if (isScrollNotificationSuppressed()) return; ASSERT(isMainFrame()); m_webPage->d->notifyTransformedScrollChanged(); }
IntSize BackingStoreClient::transformedViewportSize() const { ASSERT(m_frame); if (!m_frame->view()) return IntSize(); if (isMainFrame()) return m_webPage->d->transformedViewportSize(); const IntSize untransformedViewportSize = m_frame->view()->visibleContentRect().size(); const FloatPoint transformedBottomRight = m_webPage->d->m_transformationMatrix->mapPoint( FloatPoint(untransformedViewportSize.width(), untransformedViewportSize.height())); return IntSize(floorf(transformedBottomRight.x()), floorf(transformedBottomRight.y())); }
void FrameLoaderClientBlackBerry::delayPolicyCheckUntilFragmentExists(const String& fragment, FramePolicyFunction function) { ASSERT(isMainFrame()); if (m_webPagePrivate->loadState() < WebPagePrivate::Finished && !m_frame->document()->findAnchor(fragment)) { // Tell the client we need more data, in case the fragment exists but is being held back. m_webPagePrivate->m_client->needMoreData(); m_pendingFragmentScrollPolicyFunction = function; m_pendingFragmentScroll = fragment; return; } (m_frame->loader()->policyChecker()->*function)(PolicyUse); }
WebCachePolicy FrameFetchContext::resourceRequestCachePolicy(const ResourceRequest& request, Resource::Type type, FetchRequest::DeferOption defer) const { ASSERT(frame()); if (type == Resource::MainResource) { FrameLoadType frameLoadType = frame()->loader().loadType(); if (request.httpMethod() == "POST" && frameLoadType == FrameLoadTypeBackForward) return WebCachePolicy::ReturnCacheDataDontLoad; if (!frame()->host()->overrideEncoding().isEmpty()) return WebCachePolicy::ReturnCacheDataElseLoad; if (frameLoadType == FrameLoadTypeReloadMainResource || request.isConditional() || request.httpMethod() == "POST") return WebCachePolicy::ValidatingCacheData; for (Frame* f = frame(); f; f = f->tree().parent()) { if (!f->isLocalFrame()) continue; frameLoadType = toLocalFrame(f)->loader().loadType(); if (frameLoadType == FrameLoadTypeBackForward) return WebCachePolicy::ReturnCacheDataElseLoad; if (frameLoadType == FrameLoadTypeReloadBypassingCache) return WebCachePolicy::BypassingCache; if (frameLoadType == FrameLoadTypeReload) return WebCachePolicy::ValidatingCacheData; } return WebCachePolicy::UseProtocolCachePolicy; } // For users on slow connections, we want to avoid blocking the parser in // the main frame on script loads inserted via document.write, since it can // add significant delays before page content is displayed on the screen. if (type == Resource::Script && isMainFrame() && m_document && shouldDisallowFetchForMainFrameScript(request, defer, *m_document)) return WebCachePolicy::ReturnCacheDataDontLoad; if (request.isConditional()) return WebCachePolicy::ValidatingCacheData; if (m_documentLoader && m_document && !m_document->loadEventFinished()) { // For POST requests, we mutate the main resource's cache policy to avoid form resubmission. // This policy should not be inherited by subresources. WebCachePolicy mainResourceCachePolicy = m_documentLoader->request().getCachePolicy(); if (m_documentLoader->request().httpMethod() == "POST") { if (mainResourceCachePolicy == WebCachePolicy::ReturnCacheDataDontLoad) return WebCachePolicy::ReturnCacheDataElseLoad; return WebCachePolicy::UseProtocolCachePolicy; } return memoryCachePolicyToResourceRequestCachePolicy(getCachePolicy()); } return WebCachePolicy::UseProtocolCachePolicy; }
bool WebFrameProxy::canShowMIMEType(const String& mimeType) const { if (!m_page) return false; if (m_page->canShowMIMEType(mimeType)) return true; #if PLATFORM(MAC) // On Mac, we can show PDFs in the main frame. if (isMainFrame() && !mimeType.isEmpty()) return WebContext::pdfAndPostScriptMIMETypes().contains(mimeType); #endif return false; }
IntRect BackingStoreClient::transformedVisibleContentsRect() const { // Usually this would be mapToTransformed(visibleContentsRect()), but // that results in rounding errors because we already set the WebCore // viewport size from our original transformedViewportSize(). // Instead, we only transform the scroll position and take the // viewport size as it is, which ensures that e.g. blitting operations // always cover the whole widget/screen. IntRect visibleContentsRect = IntRect(transformedScrollPosition(), transformedViewportSize()); if (isMainFrame()) return visibleContentsRect; IntPoint offset = transformedAbsoluteLocation(); visibleContentsRect.move(offset.x(), offset.y()); return visibleContentsRect; }
void FrameLoaderClientBlackBerry::saveViewStateToItem(HistoryItem* item) { if (!isMainFrame()) return; ASSERT(item); HistoryItemViewState& viewState = item->viewState(); if (viewState.shouldSaveViewState) { viewState.orientation = m_webPagePrivate->mainFrame()->orientation(); viewState.isZoomToFitScale = m_webPagePrivate->currentScale() == m_webPagePrivate->zoomToFitScale(); viewState.scale = m_webPagePrivate->currentScale(); viewState.shouldReflowBlock = m_webPagePrivate->m_shouldReflowBlock; viewState.minimumScale = m_webPagePrivate->m_minimumScale; viewState.maximumScale = m_webPagePrivate->m_maximumScale; viewState.isUserScalable = m_webPagePrivate->m_userScalable; } }
void FrameLoaderClientBlackBerry::postProgressFinishedNotification() { if (!isMainFrame()) return; // Empty pages will never have called // dispatchDidFirstVisuallyNonEmptyLayout, since they're visually empty, so // we may need to call readyToRender now. readyToRender(false); // FIXME: Send up a real status code. m_webPagePrivate->m_client->notifyLoadFinished(m_loadError.isNull() ? 0 : -1); // Notify plugins that are waiting for the page to fully load before starting that // the load has completed. m_webPagePrivate->notifyPageOnLoad(); }
IntRect BackingStoreClient::visibleContentsRect() const { ASSERT(m_frame); if (!m_frame->view()) return IntRect(); IntRect visibleContentRect = m_frame->view()->visibleContentRect(); if (isMainFrame()) return visibleContentRect; IntPoint offset = absoluteLocation(); visibleContentRect.move(offset.x(), offset.y()); if (m_parent) visibleContentRect.intersect(m_parent->visibleContentsRect()); return visibleContentRect; }
void FrameLoaderClientBlackBerry::dispatchDidFirstVisuallyNonEmptyLayout() { if (!isMainFrame()) return; BlackBerry::Platform::log(BlackBerry::Platform::LogLevelInfo, "dispatchDidFirstVisuallyNonEmptyLayout"); readyToRender(true); // FIXME: We shouldn't be getting here if we are not in the Committed state but we are // so we can not assert on that right now. But we only want to do this on load. // RIM Bug #555 if (m_webPagePrivate->loadState() == WebPagePrivate::Committed) { m_webPagePrivate->zoomToInitialScaleOnLoad(); // Set the proper zoom level first. m_webPagePrivate->m_backingStore->d->clearVisibleZoom(); // Clear the visible zoom since we're explicitly rendering+blitting below. m_webPagePrivate->m_backingStore->d->renderVisibleContents(); } m_webPagePrivate->m_client->notifyFirstVisuallyNonEmptyLayout(); }
void FrameLoaderClientBlackBerry::didFinishOrFailLoading(const ResourceError& error) { // FIXME: Do we need to find a replacement for m_frame->document()->setExtraLayoutDelay(0);? // If we have finished loading a page through history navigation, any // attempt to go back to that page through an automatic redirect should be // denied to avoid redirect loops. So save the history navigation urls to // check later. (If this was not a history navigation, // m_historyNavigationSourceURLs will be empty, and we should save that // too.) m_redirectURLsToSkipDueToHistoryNavigation.swap(m_historyNavigationSourceURLs); // History navigation is finished so clear the history navigation url. m_historyNavigationSourceURLs.clear(); if (isMainFrame()) { m_loadError = error; m_webPagePrivate->setLoadState(error.isNull() ? WebPagePrivate::Finished : WebPagePrivate::Failed); } }
void FrameLoaderClientBlackBerry::transitionToCommittedForNewPage() { m_cancelLoadOnNextData = false; // In Frame::createView, Frame's FrameView object is set to 0 and recreated. // This operation is not atomic, and an attempt to blit contents might happen // in the backing store from another thread (see BackingStorePrivate::blitContents method), // so we suspend and resume screen update to make sure we do not get a invalid FrameView // state. BackingStoreClient* backingStoreClientForFrame = m_webPagePrivate->backingStoreClientForFrame(m_frame); if (backingStoreClientForFrame) backingStoreClientForFrame->backingStore()->d->suspendScreenAndBackingStoreUpdates(); // We are navigating away from this document, so clean up any footprint we might have. if (m_frame->document()) m_webPagePrivate->clearDocumentData(m_frame->document()); Color backgroundColor(m_webPagePrivate->m_webSettings->backgroundColor()); m_frame->createView(m_webPagePrivate->viewportSize(), /* viewport */ backgroundColor, /* background color */ backgroundColor.hasAlpha(), /* is transparent */ m_webPagePrivate->actualVisibleSize(), /* fixed reported size */ m_webPagePrivate->fixedLayoutSize(), /* fixed layout size */ m_webPagePrivate->useFixedLayout(), /* use fixed layout */ ScrollbarAlwaysOff, /* hor mode */ true, /* lock the mode */ ScrollbarAlwaysOff, /* ver mode */ true); /* lock the mode */ if (backingStoreClientForFrame) backingStoreClientForFrame->backingStore()->d->resumeScreenAndBackingStoreUpdates(BackingStore::None); m_frame->view()->updateCanHaveScrollbars(); if (isMainFrame()) { // Since the mainframe has a tiled backingstore request to receive all update // rects instead of the default which just sends update rects for currently // visible viewport. m_frame->view()->setPaintsEntireContents(true); } }
void FrameLoaderClientBlackBerry::dispatchDidFinishLoad() { didFinishOrFailLoading(ResourceError()); if (m_webPagePrivate->m_dumpRenderTree) m_webPagePrivate->m_dumpRenderTree->didFinishLoadForFrame(m_frame); if (!isMainFrame() || m_webPagePrivate->m_webSettings->isEmailMode() || !m_frame->document() || !m_frame->document()->head()) return; HTMLHeadElement* headElement = m_frame->document()->head(); // FIXME: Handle NOSCRIPT special case? // Process document metadata. RefPtr<NodeList> nodeList = headElement->getElementsByTagName(HTMLNames::metaTag.localName()); unsigned int size = nodeList->length(); ScopeArray<WebString> headers; // This may allocate more space than needed since not all meta elements will be http-equiv. headers.reset(new WebString[2 * size]); unsigned headersLength = 0; for (unsigned i = 0; i < size; ++i) { HTMLMetaElement* metaElement = static_cast<HTMLMetaElement*>(nodeList->item(i)); if (WTF::equalIgnoringCase(metaElement->name(), "apple-mobile-web-app-capable") && WTF::equalIgnoringCase(metaElement->content().stripWhiteSpace(), "yes")) m_webPagePrivate->m_client->setWebAppCapable(); else { String httpEquiv = metaElement->httpEquiv().stripWhiteSpace(); String content = metaElement->content().stripWhiteSpace(); if (!httpEquiv.isNull() && !content.isNull()) { headers[headersLength++] = httpEquiv; headers[headersLength++] = content; } } } if (headersLength > 0) m_webPagePrivate->m_client->setMetaHeaders(headers, headersLength); nodeList = headElement->getElementsByTagName(HTMLNames::linkTag.localName()); size = nodeList->length(); for (unsigned i = 0; i < size; ++i) { HTMLLinkElement* linkElement = static_cast<HTMLLinkElement*>(nodeList->item(i)); String href = linkElement->href().string(); if (!href.isEmpty()) { String title = linkElement->title(); if (WTF::equalIgnoringCase(linkElement->rel(), "apple-touch-icon")) m_webPagePrivate->m_client->setLargeIcon(href.latin1().data()); else if (WTF::equalIgnoringCase(linkElement->rel(), "search")) { if (WTF::equalIgnoringCase(linkElement->type(), "application/opensearchdescription+xml")) m_webPagePrivate->m_client->setSearchProviderDetails(title.utf8().data(), href.utf8().data()); } else if (WTF::equalIgnoringCase(linkElement->rel(), "alternate") && (WTF::equalIgnoringCase(linkElement->type(), "application/rss+xml") || WTF::equalIgnoringCase(linkElement->type(), "application/atom+xml"))) m_webPagePrivate->m_client->setAlternateFeedDetails(title.utf8().data(), href.utf8().data()); } } #if ENABLE(BLACKBERRY_CREDENTIAL_PERSIST) if (!m_webPagePrivate->m_webSettings->isPrivateBrowsingEnabled()) credentialManager().autofillPasswordForms(m_frame->document()->forms()); #endif }
IntSize BackingStoreClient::transformedActualVisibleSize() const { ASSERT(isMainFrame()); return m_webPage->webkitThreadViewportAccessor()->pixelViewportSize(); }
void FrameLoaderClientBlackBerry::restoreViewState() { if (!isMainFrame()) return; HistoryItem* currentItem = m_frame->loader()->history()->currentItem(); ASSERT(currentItem); if (!currentItem) return; // WebPagePrivate is messing up FrameView::wasScrolledByUser() by sending // scroll events that look like they were user generated all the time. // // Even if the user did not scroll, FrameView is gonna think they did. // So we use our own bookkeeping code to keep track of whether we were // actually scrolled by the user during load. // // If the user did scroll though, all are going to be in agreement about // that, and the worst thing that could happen is that // HistoryController::restoreScrollPositionAndViewState calls // setScrollPosition with the the same point, which is a NOOP. IntSize contentsSize = currentItem->contentsSize(); IntPoint scrollPosition = currentItem->scrollPoint(); if (m_webPagePrivate->m_userPerformedManualScroll) scrollPosition = m_webPagePrivate->scrollPosition(); // We need to reset this variable after the view state has been restored. m_webPagePrivate->m_didRestoreFromPageCache = false; HistoryItemViewState& viewState = currentItem->viewState(); // Restore the meta first. m_webPagePrivate->m_minimumScale = viewState.minimumScale; m_webPagePrivate->m_maximumScale = viewState.maximumScale; m_webPagePrivate->m_userScalable = viewState.isUserScalable; // Also, try to keep the users zoom if any. double scale = viewState.scale; bool shouldReflowBlock = viewState.shouldReflowBlock; if (m_webPagePrivate->m_userPerformedManualZoom) { scale = m_webPagePrivate->currentScale(); shouldReflowBlock = m_webPagePrivate->m_shouldReflowBlock; } bool scrollChanged = scrollPosition != m_webPagePrivate->scrollPosition(); bool scaleChanged = scale != m_webPagePrivate->currentScale(); bool reflowChanged = shouldReflowBlock != m_webPagePrivate->m_shouldReflowBlock; bool orientationChanged = viewState.orientation % 180 != m_webPagePrivate->mainFrame()->orientation() % 180; if (!scrollChanged && !scaleChanged && !reflowChanged && !orientationChanged) return; // When rotate happens, only zoom when previous page was zoomToFitScale, otherwise keep old scale. if (orientationChanged && viewState.isZoomToFitScale) scale = BlackBerry::Platform::Graphics::Screen::primaryScreen()->width() * scale / static_cast<double>(BlackBerry::Platform::Graphics::Screen::primaryScreen()->height()); m_webPagePrivate->m_backingStore->d->suspendScreenAndBackingStoreUpdates(); // don't flash checkerboard for the setScrollPosition call m_frame->view()->setContentsSizeFromHistory(contentsSize); // Here we need to set scroll position what we asked for. // So we use ScrollView::setCanOverscroll(true). bool oldCanOverscroll = m_frame->view()->canOverScroll(); m_frame->view()->setCanOverscroll(true); m_webPagePrivate->setScrollPosition(scrollPosition); m_frame->view()->setCanOverscroll(oldCanOverscroll); m_webPagePrivate->m_shouldReflowBlock = viewState.shouldReflowBlock; // Will restore updates to backingstore guaranteed! if (!m_webPagePrivate->zoomAboutPoint(scale, m_frame->view()->scrollPosition(), true /* enforceScaleClamping */, true /*forceRendering*/, true /*isRestoringZoomLevel*/)) { // If we're already at that scale, then we should still force rendering since // our scroll position changed. m_webPagePrivate->m_backingStore->d->renderVisibleContents(); // We need to notify the client of the scroll position and content size change(s) above even if we didn't scale. m_webPagePrivate->notifyTransformedContentsSizeChanged(); m_webPagePrivate->notifyTransformedScrollChanged(); } }