Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / page / Page.cpp
index ecb20aa..2b1a695 100644 (file)
 #include "core/events/Event.h"
 #include "core/fetch/ResourceFetcher.h"
 #include "core/frame/DOMTimer.h"
-#include "core/frame/DOMWindow.h"
+#include "core/frame/FrameConsole.h"
 #include "core/frame/FrameHost.h"
 #include "core/frame/FrameView.h"
+#include "core/frame/LocalDOMWindow.h"
 #include "core/frame/LocalFrame.h"
+#include "core/frame/RemoteFrame.h"
+#include "core/frame/RemoteFrameView.h"
 #include "core/frame/Settings.h"
 #include "core/inspector/InspectorController.h"
 #include "core/inspector/InspectorInstrumentation.h"
 #include "core/loader/FrameLoader.h"
 #include "core/loader/HistoryItem.h"
-#include "core/loader/ProgressTracker.h"
 #include "core/page/AutoscrollController.h"
 #include "core/page/Chrome.h"
 #include "core/page/ChromeClient.h"
@@ -60,7 +62,7 @@
 #include "wtf/StdLibExtras.h"
 #include "wtf/text/Base64.h"
 
-namespace WebCore {
+namespace blink {
 
 DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, pageCounter, ("Page"));
 
@@ -81,14 +83,16 @@ HashSet<Page*>& Page::ordinaryPages()
 
 void Page::networkStateChanged(bool online)
 {
-    Vector<RefPtr<LocalFrame> > frames;
+    WillBeHeapVector<RefPtrWillBeMember<LocalFrame>> frames;
 
     // Get all the frames of all the pages in all the page groups
-    HashSet<Page*>::iterator end = allPages().end();
-    for (HashSet<Page*>::iterator it = allPages().begin(); it != end; ++it) {
-        for (LocalFrame* frame = (*it)->mainFrame(); frame; frame = frame->tree().traverseNext())
-            frames.append(frame);
-        InspectorInstrumentation::networkStateChanged(*it, online);
+    for (Page* page : allPages()) {
+        for (Frame* frame = page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
+            // FIXME: There is currently no way to dispatch events to out-of-process frames.
+            if (frame->isLocalFrame())
+                frames.append(toLocalFrame(frame));
+        }
+        InspectorInstrumentation::networkStateChanged(page, online);
     }
 
     AtomicString eventName = online ? EventTypeNames::online : EventTypeNames::offline;
@@ -108,7 +112,7 @@ float deviceScaleFactor(LocalFrame* frame)
 
 Page::Page(PageClients& pageClients)
     : SettingsDelegate(Settings::create())
-    , m_animator(this)
+    , m_animator(PageAnimator::create(*this))
     , m_autoscrollController(AutoscrollController::create(*this))
     , m_chrome(Chrome::create(this, pageClients.chromeClient))
     , m_dragCaretController(DragCaretController::create())
@@ -117,24 +121,19 @@ Page::Page(PageClients& pageClients)
     , m_contextMenuController(ContextMenuController::create(this, pageClients.contextMenuClient))
     , m_inspectorController(InspectorController::create(this, pageClients.inspectorClient))
     , m_pointerLockController(PointerLockController::create(this))
-    , m_historyController(adoptPtr(new HistoryController(this)))
-    , m_progress(ProgressTracker::create())
     , m_undoStack(UndoStack::create())
-    , m_backForwardClient(pageClients.backForwardClient)
+    , m_mainFrame(nullptr)
     , m_editorClient(pageClients.editorClient)
-    , m_validationMessageClient(0)
     , m_spellCheckerClient(pageClients.spellCheckerClient)
     , m_storageClient(pageClients.storageClient)
-    , m_subframeCount(0)
     , m_openedByDOM(false)
     , m_tabKeyCyclesThroughElements(true)
     , m_defersLoading(false)
-    , m_pageScaleFactor(1)
     , m_deviceScaleFactor(1)
     , m_timerAlignmentInterval(DOMTimer::visiblePageAlignmentInterval())
     , m_visibilityState(PageVisibilityStateVisible)
     , m_isCursorVisible(true)
-#ifndef NDEBUG
+#if ENABLE(ASSERT)
     , m_isPainting(false)
 #endif
     , m_frameHost(FrameHost::create(*this))
@@ -151,25 +150,8 @@ Page::Page(PageClients& pageClients)
 
 Page::~Page()
 {
-    // Disable all agents prior to resetting the frame view.
-    m_inspectorController->inspectedPageDestroyed();
-
-    m_mainFrame->setView(nullptr);
-    allPages().remove(this);
-    if (ordinaryPages().contains(this))
-        ordinaryPages().remove(this);
-
-    for (LocalFrame* frame = mainFrame(); frame; frame = frame->tree().traverseNext()) {
-        frame->willDetachFrameHost();
-        frame->detachFromFrameHost();
-    }
-
-    if (m_scrollingCoordinator)
-        m_scrollingCoordinator->pageDestroyed();
-
-#ifndef NDEBUG
-    pageCounter.decrement();
-#endif
+    // willBeDestroyed() must be called before Page destruction.
+    ASSERT(!m_mainFrame);
 }
 
 void Page::makeOrdinary()
@@ -180,12 +162,12 @@ void Page::makeOrdinary()
 
 ViewportDescription Page::viewportDescription() const
 {
-    return mainFrame() && mainFrame()->document() ? mainFrame()->document()->viewportDescription() : ViewportDescription();
+    return mainFrame() && mainFrame()->isLocalFrame() && deprecatedLocalMainFrame()->document() ? deprecatedLocalMainFrame()->document()->viewportDescription() : ViewportDescription();
 }
 
 ScrollingCoordinator* Page::scrollingCoordinator()
 {
-    if (!m_scrollingCoordinator && m_settings->scrollingCoordinatorEnabled())
+    if (!m_scrollingCoordinator && m_settings->acceleratedCompositingEnabled())
         m_scrollingCoordinator = ScrollingCoordinator::create(this);
 
     return m_scrollingCoordinator.get();
@@ -199,10 +181,10 @@ String Page::mainThreadScrollingReasonsAsText()
     return String();
 }
 
-PassRefPtr<ClientRectList> Page::nonFastScrollableRects(const LocalFrame* frame)
+PassRefPtrWillBeRawPtr<ClientRectList> Page::nonFastScrollableRects(const LocalFrame* frame)
 {
-    if (Document* document = m_mainFrame->document())
-        document->updateLayout();
+    if (m_mainFrame->isLocalFrame() && deprecatedLocalMainFrame()->document())
+        deprecatedLocalMainFrame()->document()->updateLayout();
 
     Vector<IntRect> rects;
     if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
@@ -214,9 +196,13 @@ PassRefPtr<ClientRectList> Page::nonFastScrollableRects(const LocalFrame* frame)
     return ClientRectList::create(quads);
 }
 
-void Page::setMainFrame(PassRefPtr<LocalFrame> mainFrame)
+void Page::setMainFrame(Frame* mainFrame)
 {
-    ASSERT(!m_mainFrame); // Should only be called during initialization
+    // Should only be called during initialization or swaps between local and
+    // remote frames.
+    // FIXME: Unfortunately we can't assert on this at the moment, because this
+    // is called in the base constructor for both LocalFrame and RemoteFrame,
+    // when the vtables for the derived classes have not yet been setup.
     m_mainFrame = mainFrame;
 }
 
@@ -241,22 +227,27 @@ void Page::setOpenedByDOM()
 
 void Page::scheduleForcedStyleRecalcForAllPages()
 {
-    HashSet<Page*>::iterator end = allPages().end();
-    for (HashSet<Page*>::iterator it = allPages().begin(); it != end; ++it)
-        for (LocalFrame* frame = (*it)->mainFrame(); frame; frame = frame->tree().traverseNext())
-            frame->document()->setNeedsStyleRecalc(SubtreeStyleChange);
+    for (const Page* page : allPages())
+        for (Frame* frame = page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
+            if (frame->isLocalFrame())
+                toLocalFrame(frame)->document()->setNeedsStyleRecalc(SubtreeStyleChange, StyleChangeReasonForTracing::create(StyleChangeReason::PlatformColorChange));
+        }
 }
 
 void Page::setNeedsRecalcStyleInAllFrames()
 {
-    for (LocalFrame* frame = mainFrame(); frame; frame = frame->tree().traverseNext())
-        frame->document()->styleResolverChanged(RecalcStyleDeferred);
+    for (Frame* frame = mainFrame(); frame; frame = frame->tree().traverseNext()) {
+        if (frame->isLocalFrame())
+            toLocalFrame(frame)->document()->styleResolverChanged();
+    }
 }
 
 void Page::setNeedsLayoutInAllFrames()
 {
-    for (LocalFrame* frame = mainFrame(); frame; frame = frame->tree().traverseNext()) {
-        if (FrameView* view = frame->view()) {
+    for (Frame* frame = mainFrame(); frame; frame = frame->tree().traverseNext()) {
+        if (!frame->isLocalFrame())
+            continue;
+        if (FrameView* view = toLocalFrame(frame)->view()) {
             view->setNeedsLayout();
             view->scheduleRelayout();
         }
@@ -270,12 +261,9 @@ void Page::refreshPlugins(bool reload)
 
     PluginData::refresh();
 
-    Vector<RefPtr<LocalFrame> > framesNeedingReload;
-
-    HashSet<Page*>::iterator end = allPages().end();
-    for (HashSet<Page*>::iterator it = allPages().begin(); it != end; ++it) {
-        Page* page = *it;
+    WillBeHeapVector<RefPtrWillBeMember<LocalFrame>> framesNeedingReload;
 
+    for (const Page* page : allPages()) {
         // Clear out the page's plug-in data.
         if (page->m_pluginData)
             page->m_pluginData = nullptr;
@@ -283,26 +271,27 @@ void Page::refreshPlugins(bool reload)
         if (!reload)
             continue;
 
-        for (LocalFrame* frame = (*it)->mainFrame(); frame; frame = frame->tree().traverseNext()) {
-            if (frame->document()->containsPlugins())
-                framesNeedingReload.append(frame);
+        for (Frame* frame = page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
+            if (frame->isLocalFrame() && toLocalFrame(frame)->document()->containsPlugins())
+                framesNeedingReload.append(toLocalFrame(frame));
         }
     }
 
     for (size_t i = 0; i < framesNeedingReload.size(); ++i)
-        framesNeedingReload[i]->loader().reload();
+        framesNeedingReload[i]->loader().reload(NormalReload);
 }
 
 PluginData* Page::pluginData() const
 {
-    if (!mainFrame()->loader().allowPlugins(NotAboutToInstantiatePlugin))
-        return 0;
+    if (!mainFrame()->isLocalFrame()
+        || !deprecatedLocalMainFrame()->loader().allowPlugins(NotAboutToInstantiatePlugin))
+        return nullptr;
     if (!m_pluginData)
         m_pluginData = PluginData::create(this);
     return m_pluginData.get();
 }
 
-static LocalFrame* incrementFrame(LocalFrame* curr, bool forward, bool wrapFlag)
+static Frame* incrementFrame(Frame* curr, bool forward, bool wrapFlag)
 {
     return forward
         ? curr->tree().traverseNextWithWrap(wrapFlag)
@@ -314,46 +303,65 @@ void Page::unmarkAllTextMatches()
     if (!mainFrame())
         return;
 
-    LocalFrame* frame = mainFrame();
+    Frame* frame = mainFrame();
     do {
-        frame->document()->markers().removeMarkers(DocumentMarker::TextMatch);
+        if (frame->isLocalFrame())
+            toLocalFrame(frame)->document()->markers().removeMarkers(DocumentMarker::TextMatch);
         frame = incrementFrame(frame, true, false);
     } while (frame);
 }
 
+void Page::setValidationMessageClient(PassOwnPtrWillBeRawPtr<ValidationMessageClient> client)
+{
+    m_validationMessageClient = client;
+}
+
 void Page::setDefersLoading(bool defers)
 {
     if (defers == m_defersLoading)
         return;
 
     m_defersLoading = defers;
-    for (LocalFrame* frame = mainFrame(); frame; frame = frame->tree().traverseNext())
-        frame->loader().setDefersLoading(defers);
+    for (Frame* frame = mainFrame(); frame; frame = frame->tree().traverseNext()) {
+        if (frame->isLocalFrame())
+            toLocalFrame(frame)->loader().setDefersLoading(defers);
+    }
 }
 
 void Page::setPageScaleFactor(float scale, const IntPoint& origin)
 {
-    FrameView* view = mainFrame()->view();
+    if (!mainFrame()->isLocalFrame())
+        return;
 
-    if (scale != m_pageScaleFactor) {
-        m_pageScaleFactor = scale;
+    FrameView* view = deprecatedLocalMainFrame()->view();
+    PinchViewport& viewport = frameHost().pinchViewport();
 
-        if (view)
+    if (scale != viewport.scale()) {
+        viewport.setScale(scale);
+
+        if (view && !settings().pinchVirtualViewportEnabled())
             view->setVisibleContentScaleFactor(scale);
 
-        mainFrame()->deviceOrPageScaleFactorChanged();
+        deprecatedLocalMainFrame()->deviceOrPageScaleFactorChanged();
         m_chrome->client().deviceOrPageScaleFactorChanged();
 
+        // FIXME: In virtual-viewport pinch mode, scale doesn't change the fixed-pos viewport;
+        // remove once it's the only pinch mode in town.
         if (view)
             view->viewportConstrainedVisibleContentSizeChanged(true, true);
 
-        mainFrame()->loader().saveScrollState();
+        deprecatedLocalMainFrame()->loader().saveScrollState();
     }
 
     if (view && view->scrollPosition() != origin)
         view->notifyScrollPositionChanged(origin);
 }
 
+float Page::pageScaleFactor() const
+{
+    return frameHost().pinchViewport().scale();
+}
+
 void Page::setDeviceScaleFactor(float scaleFactor)
 {
     if (m_deviceScaleFactor == scaleFactor)
@@ -362,29 +370,39 @@ void Page::setDeviceScaleFactor(float scaleFactor)
     m_deviceScaleFactor = scaleFactor;
     setNeedsRecalcStyleInAllFrames();
 
-    if (mainFrame()) {
-        mainFrame()->deviceOrPageScaleFactorChanged();
+    if (mainFrame() && mainFrame()->isLocalFrame()) {
+        deprecatedLocalMainFrame()->deviceOrPageScaleFactorChanged();
         m_chrome->client().deviceOrPageScaleFactorChanged();
     }
 }
 
+void Page::setDeviceColorProfile(const Vector<char>& profile)
+{
+    // FIXME: implement.
+}
+
+void Page::resetDeviceColorProfile()
+{
+    // FIXME: implement.
+}
+
 void Page::allVisitedStateChanged()
 {
-    HashSet<Page*>::iterator pagesEnd = ordinaryPages().end();
-    for (HashSet<Page*>::iterator it = ordinaryPages().begin(); it != pagesEnd; ++it) {
-        Page* page = *it;
-        for (LocalFrame* frame = page->m_mainFrame.get(); frame; frame = frame->tree().traverseNext())
-            frame->document()->visitedLinkState().invalidateStyleForAllLinks();
+    for (const Page* page : ordinaryPages()) {
+        for (Frame* frame = page->m_mainFrame; frame; frame = frame->tree().traverseNext()) {
+            if (frame->isLocalFrame())
+                toLocalFrame(frame)->document()->visitedLinkState().invalidateStyleForAllLinks();
+        }
     }
 }
 
 void Page::visitedStateChanged(LinkHash linkHash)
 {
-    HashSet<Page*>::iterator pagesEnd = ordinaryPages().end();
-    for (HashSet<Page*>::iterator it = ordinaryPages().begin(); it != pagesEnd; ++it) {
-        Page* page = *it;
-        for (LocalFrame* frame = page->m_mainFrame.get(); frame; frame = frame->tree().traverseNext())
-            frame->document()->visitedLinkState().invalidateStyleForLink(linkHash);
+    for (const Page* page : ordinaryPages()) {
+        for (Frame* frame = page->m_mainFrame; frame; frame = frame->tree().traverseNext()) {
+            if (frame->isLocalFrame())
+                toLocalFrame(frame)->document()->visitedLinkState().invalidateStyleForLink(linkHash);
+        }
     }
 }
 
@@ -401,9 +419,9 @@ void Page::setTimerAlignmentInterval(double interval)
         return;
 
     m_timerAlignmentInterval = interval;
-    for (LocalFrame* frame = mainFrame(); frame; frame = frame->tree().traverseNextWithWrap(false)) {
-        if (frame->document())
-            frame->document()->didChangeTimerAlignmentInterval();
+    for (Frame* frame = mainFrame(); frame; frame = frame->tree().traverseNextWithWrap(false)) {
+        if (frame->isLocalFrame() && toLocalFrame(frame)->document())
+            toLocalFrame(frame)->document()->didChangeTimerAlignmentInterval();
     }
 }
 
@@ -412,35 +430,22 @@ double Page::timerAlignmentInterval() const
     return m_timerAlignmentInterval;
 }
 
-#if !ASSERT_DISABLED
-void Page::checkSubframeCountConsistency() const
-{
-    ASSERT(m_subframeCount >= 0);
-
-    int subframeCount = 0;
-    for (LocalFrame* frame = mainFrame(); frame; frame = frame->tree().traverseNext())
-        ++subframeCount;
-
-    ASSERT(m_subframeCount + 1 == subframeCount);
-}
-#endif
-
 void Page::setVisibilityState(PageVisibilityState visibilityState, bool isInitialState)
 {
     if (m_visibilityState == visibilityState)
         return;
     m_visibilityState = visibilityState;
 
-    if (visibilityState == WebCore::PageVisibilityStateHidden)
-        setTimerAlignmentInterval(DOMTimer::hiddenPageAlignmentInterval());
-    else
+    if (visibilityState == blink::PageVisibilityStateVisible)
         setTimerAlignmentInterval(DOMTimer::visiblePageAlignmentInterval());
+    else
+        setTimerAlignmentInterval(DOMTimer::hiddenPageAlignmentInterval());
 
     if (!isInitialState)
         lifecycleNotifier().notifyPageVisibilityChanged();
 
-    if (!isInitialState && m_mainFrame)
-        m_mainFrame->didChangeVisibilityState();
+    if (!isInitialState && m_mainFrame && m_mainFrame->isLocalFrame())
+        deprecatedLocalMainFrame()->didChangeVisibilityState();
 }
 
 PageVisibilityState Page::visibilityState() const
@@ -448,6 +453,11 @@ PageVisibilityState Page::visibilityState() const
     return m_visibilityState;
 }
 
+bool Page::isCursorVisible() const
+{
+    return m_isCursorVisible && settings().deviceSupportsMouse();
+}
+
 void Page::addMultisamplingChangedObserver(MultisamplingChangedObserver* observer)
 {
     m_multisamplingChangedObservers.add(observer);
@@ -465,53 +475,74 @@ void Page::settingsChanged(SettingsDelegate::ChangeType changeType)
         setNeedsRecalcStyleInAllFrames();
         break;
     case SettingsDelegate::ViewportDescriptionChange:
-        if (mainFrame())
-            mainFrame()->document()->updateViewportDescription();
+        if (mainFrame() && mainFrame()->isLocalFrame())
+            deprecatedLocalMainFrame()->document()->updateViewportDescription();
         break;
     case SettingsDelegate::MediaTypeChange:
-        m_mainFrame->view()->setMediaType(AtomicString(settings().mediaTypeOverride()));
-        setNeedsRecalcStyleInAllFrames();
+        if (m_mainFrame->isLocalFrame()) {
+            deprecatedLocalMainFrame()->view()->setMediaType(AtomicString(settings().mediaTypeOverride()));
+            setNeedsRecalcStyleInAllFrames();
+        }
         break;
     case SettingsDelegate::DNSPrefetchingChange:
-        for (LocalFrame* frame = mainFrame(); frame; frame = frame->tree().traverseNext())
-            frame->document()->initDNSPrefetch();
+        for (Frame* frame = mainFrame(); frame; frame = frame->tree().traverseNext()) {
+            if (frame->isLocalFrame())
+                toLocalFrame(frame)->document()->initDNSPrefetch();
+        }
         break;
     case SettingsDelegate::MultisamplingChange: {
-        HashSet<MultisamplingChangedObserver*>::iterator stop = m_multisamplingChangedObservers.end();
-        for (HashSet<MultisamplingChangedObserver*>::iterator it = m_multisamplingChangedObservers.begin(); it != stop; ++it)
-            (*it)->multisamplingChanged(m_settings->openGLMultisamplingEnabled());
+        for (MultisamplingChangedObserver* observer : m_multisamplingChangedObservers)
+            observer->multisamplingChanged(m_settings->openGLMultisamplingEnabled());
         break;
     }
     case SettingsDelegate::ImageLoadingChange:
-        for (LocalFrame* frame = mainFrame(); frame; frame = frame->tree().traverseNext()) {
-            frame->document()->fetcher()->setImagesEnabled(settings().imagesEnabled());
-            frame->document()->fetcher()->setAutoLoadImages(settings().loadsImagesAutomatically());
+        for (Frame* frame = mainFrame(); frame; frame = frame->tree().traverseNext()) {
+            if (frame->isLocalFrame()) {
+                toLocalFrame(frame)->document()->fetcher()->setImagesEnabled(settings().imagesEnabled());
+                toLocalFrame(frame)->document()->fetcher()->setAutoLoadImages(settings().loadsImagesAutomatically());
+            }
         }
         break;
     case SettingsDelegate::TextAutosizingChange:
-        // FTA needs both setNeedsRecalcStyle and setNeedsLayout after a setting change.
-        if (RuntimeEnabledFeatures::fastTextAutosizingEnabled()) {
-            setNeedsRecalcStyleInAllFrames();
-        } else {
-            // FIXME: I wonder if this needs to traverse frames like in WebViewImpl::resize, or whether there is only one document per Settings instance?
-            for (LocalFrame* frame = mainFrame(); frame; frame = frame->tree().traverseNext()) {
-                TextAutosizer* textAutosizer = frame->document()->textAutosizer();
-                if (textAutosizer)
-                    textAutosizer->recalculateMultipliers();
-            }
-        }
-        // TextAutosizing updates RenderStyle during layout phase (via TextAutosizer::processSubtree).
-        // We should invoke setNeedsLayout here.
-        setNeedsLayoutInAllFrames();
+        if (!mainFrame() || !mainFrame()->isLocalFrame())
+            break;
+        if (TextAutosizer* textAutosizer = deprecatedLocalMainFrame()->document()->textAutosizer())
+            textAutosizer->updatePageInfoInAllFrames();
         break;
     case SettingsDelegate::ScriptEnableChange:
         m_inspectorController->scriptsEnabled(settings().scriptEnabled());
         break;
     case SettingsDelegate::FontFamilyChange:
-        for (LocalFrame* frame = mainFrame(); frame; frame = frame->tree().traverseNext())
-            frame->document()->styleEngine()->updateGenericFontFamilySettings();
+        for (Frame* frame = mainFrame(); frame; frame = frame->tree().traverseNext()) {
+            if (frame->isLocalFrame())
+                toLocalFrame(frame)->document()->styleEngine()->updateGenericFontFamilySettings();
+        }
+        setNeedsRecalcStyleInAllFrames();
+        break;
+    case SettingsDelegate::AcceleratedCompositingChange:
+        updateAcceleratedCompositingSettings();
+        break;
+    case SettingsDelegate::MediaQueryChange:
+        for (Frame* frame = mainFrame(); frame; frame = frame->tree().traverseNext()) {
+            if (frame->isLocalFrame())
+                toLocalFrame(frame)->document()->mediaQueryAffectingValueChanged();
+        }
         setNeedsRecalcStyleInAllFrames();
         break;
+    case SettingsDelegate::AccessibilityStateChange:
+        if (!mainFrame() || !mainFrame()->isLocalFrame())
+            break;
+        deprecatedLocalMainFrame()->document()->axObjectCacheOwner().clearAXObjectCache();
+    }
+}
+
+void Page::updateAcceleratedCompositingSettings()
+{
+    for (Frame* frame = mainFrame(); frame; frame = frame->tree().traverseNext()) {
+        if (!frame->isLocalFrame())
+            continue;
+        if (FrameView* view = toLocalFrame(frame)->view())
+            view->updateAcceleratedCompositingSettings();
     }
 }
 
@@ -519,30 +550,99 @@ void Page::didCommitLoad(LocalFrame* frame)
 {
     lifecycleNotifier().notifyDidCommitLoad(frame);
     if (m_mainFrame == frame) {
+        frame->console().clearMessages();
         useCounter().didCommitLoad();
         m_inspectorController->didCommitLoadForMainFrame();
+        UserGestureIndicator::clearProcessedUserGestureSinceLoad();
     }
 }
 
+void Page::acceptLanguagesChanged()
+{
+    WillBeHeapVector<RefPtrWillBeMember<LocalFrame>> frames;
+
+    // Even though we don't fire an event from here, the LocalDOMWindow's will fire
+    // an event so we keep the frames alive until we are done.
+    for (Frame* frame = mainFrame(); frame; frame = frame->tree().traverseNext()) {
+        if (frame->isLocalFrame())
+            frames.append(toLocalFrame(frame));
+    }
+
+    for (unsigned i = 0; i < frames.size(); ++i)
+        frames[i]->domWindow()->acceptLanguagesChanged();
+}
+
 PageLifecycleNotifier& Page::lifecycleNotifier()
 {
     return static_cast<PageLifecycleNotifier&>(LifecycleContext<Page>::lifecycleNotifier());
 }
 
-PassOwnPtr<LifecycleNotifier<Page> > Page::createLifecycleNotifier()
+PassOwnPtr<LifecycleNotifier<Page>> Page::createLifecycleNotifier()
 {
     return PageLifecycleNotifier::create(this);
 }
 
+void Page::trace(Visitor* visitor)
+{
+#if ENABLE(OILPAN)
+    visitor->trace(m_animator);
+    visitor->trace(m_dragCaretController);
+    visitor->trace(m_dragController);
+    visitor->trace(m_focusController);
+    visitor->trace(m_contextMenuController);
+    visitor->trace(m_inspectorController);
+    visitor->trace(m_pointerLockController);
+    visitor->trace(m_undoStack);
+    visitor->trace(m_mainFrame);
+    visitor->trace(m_validationMessageClient);
+    visitor->trace(m_multisamplingChangedObservers);
+    visitor->trace(m_frameHost);
+    HeapSupplementable<Page>::trace(visitor);
+#endif
+    LifecycleContext<Page>::trace(visitor);
+}
+
+void Page::willBeDestroyed()
+{
+    // Destroy inspector first, since it uses frame and view during destruction.
+    m_inspectorController->willBeDestroyed();
+
+    RefPtrWillBeRawPtr<Frame> mainFrame = m_mainFrame;
+
+    mainFrame->detach();
+
+    if (mainFrame->isLocalFrame()) {
+        toLocalFrame(mainFrame.get())->setView(nullptr);
+    } else {
+        ASSERT(m_mainFrame->isRemoteFrame());
+        toRemoteFrame(mainFrame.get())->setView(nullptr);
+    }
+
+    allPages().remove(this);
+    if (ordinaryPages().contains(this))
+        ordinaryPages().remove(this);
+
+    if (m_scrollingCoordinator)
+        m_scrollingCoordinator->willBeDestroyed();
+
+#ifndef NDEBUG
+    pageCounter.decrement();
+#endif
+
+    m_chrome->willBeDestroyed();
+    if (m_validationMessageClient)
+        m_validationMessageClient->willBeDestroyed();
+    m_mainFrame = nullptr;
+}
+
 Page::PageClients::PageClients()
-    : chromeClient(0)
-    , contextMenuClient(0)
-    , editorClient(0)
-    , dragClient(0)
-    , inspectorClient(0)
-    , backForwardClient(0)
-    , spellCheckerClient(0)
-    , storageClient(0)
+    : chromeClient(nullptr)
+    , contextMenuClient(nullptr)
+    , editorClient(nullptr)
+    , dragClient(nullptr)
+    , inspectorClient(nullptr)
+    , spellCheckerClient(nullptr)
+    , storageClient(nullptr)
 {
 }
 
@@ -550,4 +650,4 @@ Page::PageClients::~PageClients()
 {
 }
 
-} // namespace WebCore
+} // namespace blink