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(); } }