Beispiel #1
0
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();
}
Beispiel #11
0
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();
}
Beispiel #14
0
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;
}
Beispiel #17
0
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;
}
Beispiel #18
0
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();
}
Beispiel #21
0
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();
    }
}