Home | History | Annotate | Download | only in page
      1 /*
      2  * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All Rights Reserved.
      3  * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
      4  *
      5  * This library is free software; you can redistribute it and/or
      6  * modify it under the terms of the GNU Library General Public
      7  * License as published by the Free Software Foundation; either
      8  * version 2 of the License, or (at your option) any later version.
      9  * This library is distributed in the hope that it will be useful,
     10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     12  * Library General Public License for more details.
     13  *
     14  * You should have received a copy of the GNU Library General Public License
     15  * along with this library; see the file COPYING.LIB.  If not, write to
     16  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     17  * Boston, MA 02110-1301, USA.
     18  */
     19 
     20 #include "config.h"
     21 #include "core/page/Page.h"
     22 
     23 #include "core/dom/ClientRectList.h"
     24 #include "core/dom/DocumentMarkerController.h"
     25 #include "core/dom/StyleEngine.h"
     26 #include "core/dom/VisitedLinkState.h"
     27 #include "core/editing/Caret.h"
     28 #include "core/editing/UndoStack.h"
     29 #include "core/events/Event.h"
     30 #include "core/fetch/ResourceFetcher.h"
     31 #include "core/frame/DOMTimer.h"
     32 #include "core/frame/FrameConsole.h"
     33 #include "core/frame/FrameHost.h"
     34 #include "core/frame/FrameView.h"
     35 #include "core/frame/LocalDOMWindow.h"
     36 #include "core/frame/LocalFrame.h"
     37 #include "core/frame/RemoteFrame.h"
     38 #include "core/frame/RemoteFrameView.h"
     39 #include "core/frame/Settings.h"
     40 #include "core/inspector/InspectorController.h"
     41 #include "core/inspector/InspectorInstrumentation.h"
     42 #include "core/loader/FrameLoader.h"
     43 #include "core/loader/HistoryItem.h"
     44 #include "core/page/AutoscrollController.h"
     45 #include "core/page/Chrome.h"
     46 #include "core/page/ChromeClient.h"
     47 #include "core/page/ContextMenuController.h"
     48 #include "core/page/DragController.h"
     49 #include "core/page/FocusController.h"
     50 #include "core/page/FrameTree.h"
     51 #include "core/page/PageLifecycleNotifier.h"
     52 #include "core/page/PointerLockController.h"
     53 #include "core/page/StorageClient.h"
     54 #include "core/page/ValidationMessageClient.h"
     55 #include "core/page/scrolling/ScrollingCoordinator.h"
     56 #include "core/rendering/RenderView.h"
     57 #include "core/rendering/TextAutosizer.h"
     58 #include "core/storage/StorageNamespace.h"
     59 #include "platform/plugins/PluginData.h"
     60 #include "wtf/HashMap.h"
     61 #include "wtf/RefCountedLeakCounter.h"
     62 #include "wtf/StdLibExtras.h"
     63 #include "wtf/text/Base64.h"
     64 
     65 namespace blink {
     66 
     67 DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, pageCounter, ("Page"));
     68 
     69 // static
     70 HashSet<Page*>& Page::allPages()
     71 {
     72     DEFINE_STATIC_LOCAL(HashSet<Page*>, allPages, ());
     73     return allPages;
     74 }
     75 
     76 // static
     77 HashSet<Page*>& Page::ordinaryPages()
     78 {
     79     DEFINE_STATIC_LOCAL(HashSet<Page*>, ordinaryPages, ());
     80     return ordinaryPages;
     81 }
     82 
     83 
     84 void Page::networkStateChanged(bool online)
     85 {
     86     WillBeHeapVector<RefPtrWillBeMember<LocalFrame> > frames;
     87 
     88     // Get all the frames of all the pages in all the page groups
     89     HashSet<Page*>::iterator end = allPages().end();
     90     for (HashSet<Page*>::iterator it = allPages().begin(); it != end; ++it) {
     91         for (Frame* frame = (*it)->mainFrame(); frame; frame = frame->tree().traverseNext()) {
     92             // FIXME: There is currently no way to dispatch events to out-of-process frames.
     93             if (frame->isLocalFrame())
     94                 frames.append(toLocalFrame(frame));
     95         }
     96         InspectorInstrumentation::networkStateChanged(*it, online);
     97     }
     98 
     99     AtomicString eventName = online ? EventTypeNames::online : EventTypeNames::offline;
    100     for (unsigned i = 0; i < frames.size(); i++)
    101         frames[i]->domWindow()->dispatchEvent(Event::create(eventName));
    102 }
    103 
    104 float deviceScaleFactor(LocalFrame* frame)
    105 {
    106     if (!frame)
    107         return 1;
    108     Page* page = frame->page();
    109     if (!page)
    110         return 1;
    111     return page->deviceScaleFactor();
    112 }
    113 
    114 Page::Page(PageClients& pageClients)
    115     : SettingsDelegate(Settings::create())
    116     , m_animator(PageAnimator::create(*this))
    117     , m_autoscrollController(AutoscrollController::create(*this))
    118     , m_chrome(Chrome::create(this, pageClients.chromeClient))
    119     , m_dragCaretController(DragCaretController::create())
    120     , m_dragController(DragController::create(this, pageClients.dragClient))
    121     , m_focusController(FocusController::create(this))
    122     , m_contextMenuController(ContextMenuController::create(this, pageClients.contextMenuClient))
    123     , m_inspectorController(InspectorController::create(this, pageClients.inspectorClient))
    124     , m_pointerLockController(PointerLockController::create(this))
    125     , m_undoStack(UndoStack::create())
    126     , m_mainFrame(nullptr)
    127     , m_backForwardClient(pageClients.backForwardClient)
    128     , m_editorClient(pageClients.editorClient)
    129     , m_spellCheckerClient(pageClients.spellCheckerClient)
    130     , m_storageClient(pageClients.storageClient)
    131     , m_subframeCount(0)
    132     , m_openedByDOM(false)
    133     , m_tabKeyCyclesThroughElements(true)
    134     , m_defersLoading(false)
    135     , m_deviceScaleFactor(1)
    136     , m_timerAlignmentInterval(DOMTimer::visiblePageAlignmentInterval())
    137     , m_visibilityState(PageVisibilityStateVisible)
    138     , m_isCursorVisible(true)
    139 #if ENABLE(ASSERT)
    140     , m_isPainting(false)
    141 #endif
    142     , m_frameHost(FrameHost::create(*this))
    143 {
    144     ASSERT(m_editorClient);
    145 
    146     ASSERT(!allPages().contains(this));
    147     allPages().add(this);
    148 
    149 #ifndef NDEBUG
    150     pageCounter.increment();
    151 #endif
    152 }
    153 
    154 Page::~Page()
    155 {
    156     // willBeDestroyed() must be called before Page destruction.
    157     ASSERT(!m_mainFrame);
    158 }
    159 
    160 void Page::makeOrdinary()
    161 {
    162     ASSERT(!ordinaryPages().contains(this));
    163     ordinaryPages().add(this);
    164 }
    165 
    166 ViewportDescription Page::viewportDescription() const
    167 {
    168     return mainFrame() && mainFrame()->isLocalFrame() && deprecatedLocalMainFrame()->document() ? deprecatedLocalMainFrame()->document()->viewportDescription() : ViewportDescription();
    169 }
    170 
    171 ScrollingCoordinator* Page::scrollingCoordinator()
    172 {
    173     if (!m_scrollingCoordinator && m_settings->acceleratedCompositingEnabled())
    174         m_scrollingCoordinator = ScrollingCoordinator::create(this);
    175 
    176     return m_scrollingCoordinator.get();
    177 }
    178 
    179 String Page::mainThreadScrollingReasonsAsText()
    180 {
    181     if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
    182         return scrollingCoordinator->mainThreadScrollingReasonsAsText();
    183 
    184     return String();
    185 }
    186 
    187 PassRefPtrWillBeRawPtr<ClientRectList> Page::nonFastScrollableRects(const LocalFrame* frame)
    188 {
    189     if (m_mainFrame->isLocalFrame() && deprecatedLocalMainFrame()->document())
    190         deprecatedLocalMainFrame()->document()->updateLayout();
    191 
    192     Vector<IntRect> rects;
    193     if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
    194         rects = scrollingCoordinator->computeShouldHandleScrollGestureOnMainThreadRegion(frame, IntPoint()).rects();
    195 
    196     Vector<FloatQuad> quads(rects.size());
    197     for (size_t i = 0; i < rects.size(); ++i)
    198         quads[i] = FloatRect(rects[i]);
    199     return ClientRectList::create(quads);
    200 }
    201 
    202 void Page::setMainFrame(Frame* mainFrame)
    203 {
    204     // Should only be called during initialization or swaps between local and
    205     // remote frames.
    206     // FIXME: Unfortunately we can't assert on this at the moment, because this
    207     // is called in the base constructor for both LocalFrame and RemoteFrame,
    208     // when the vtables for the derived classes have not yet been setup.
    209     m_mainFrame = mainFrame;
    210 }
    211 
    212 void Page::documentDetached(Document* document)
    213 {
    214     m_multisamplingChangedObservers.clear();
    215     m_pointerLockController->documentDetached(document);
    216     m_contextMenuController->documentDetached(document);
    217     if (m_validationMessageClient)
    218         m_validationMessageClient->documentDetached(*document);
    219 }
    220 
    221 bool Page::openedByDOM() const
    222 {
    223     return m_openedByDOM;
    224 }
    225 
    226 void Page::setOpenedByDOM()
    227 {
    228     m_openedByDOM = true;
    229 }
    230 
    231 void Page::scheduleForcedStyleRecalcForAllPages()
    232 {
    233     HashSet<Page*>::iterator end = allPages().end();
    234     for (HashSet<Page*>::iterator it = allPages().begin(); it != end; ++it)
    235         for (Frame* frame = (*it)->mainFrame(); frame; frame = frame->tree().traverseNext()) {
    236             if (frame->isLocalFrame())
    237                 toLocalFrame(frame)->document()->setNeedsStyleRecalc(SubtreeStyleChange);
    238         }
    239 }
    240 
    241 void Page::setNeedsRecalcStyleInAllFrames()
    242 {
    243     for (Frame* frame = mainFrame(); frame; frame = frame->tree().traverseNext()) {
    244         if (frame->isLocalFrame())
    245             toLocalFrame(frame)->document()->styleResolverChanged();
    246     }
    247 }
    248 
    249 void Page::setNeedsLayoutInAllFrames()
    250 {
    251     for (Frame* frame = mainFrame(); frame; frame = frame->tree().traverseNext()) {
    252         if (!frame->isLocalFrame())
    253             continue;
    254         if (FrameView* view = toLocalFrame(frame)->view()) {
    255             view->setNeedsLayout();
    256             view->scheduleRelayout();
    257         }
    258     }
    259 }
    260 
    261 void Page::refreshPlugins(bool reload)
    262 {
    263     if (allPages().isEmpty())
    264         return;
    265 
    266     PluginData::refresh();
    267 
    268     WillBeHeapVector<RefPtrWillBeMember<LocalFrame> > framesNeedingReload;
    269 
    270     HashSet<Page*>::iterator end = allPages().end();
    271     for (HashSet<Page*>::iterator it = allPages().begin(); it != end; ++it) {
    272         Page* page = *it;
    273 
    274         // Clear out the page's plug-in data.
    275         if (page->m_pluginData)
    276             page->m_pluginData = nullptr;
    277 
    278         if (!reload)
    279             continue;
    280 
    281         for (Frame* frame = (*it)->mainFrame(); frame; frame = frame->tree().traverseNext()) {
    282             if (frame->isLocalFrame() && toLocalFrame(frame)->document()->containsPlugins())
    283                 framesNeedingReload.append(toLocalFrame(frame));
    284         }
    285     }
    286 
    287     for (size_t i = 0; i < framesNeedingReload.size(); ++i)
    288         framesNeedingReload[i]->loader().reload();
    289 }
    290 
    291 PluginData* Page::pluginData() const
    292 {
    293     if (!deprecatedLocalMainFrame()->loader().allowPlugins(NotAboutToInstantiatePlugin))
    294         return 0;
    295     if (!m_pluginData)
    296         m_pluginData = PluginData::create(this);
    297     return m_pluginData.get();
    298 }
    299 
    300 static Frame* incrementFrame(Frame* curr, bool forward, bool wrapFlag)
    301 {
    302     return forward
    303         ? curr->tree().traverseNextWithWrap(wrapFlag)
    304         : curr->tree().traversePreviousWithWrap(wrapFlag);
    305 }
    306 
    307 void Page::unmarkAllTextMatches()
    308 {
    309     if (!mainFrame())
    310         return;
    311 
    312     Frame* frame = mainFrame();
    313     do {
    314         if (frame->isLocalFrame())
    315             toLocalFrame(frame)->document()->markers().removeMarkers(DocumentMarker::TextMatch);
    316         frame = incrementFrame(frame, true, false);
    317     } while (frame);
    318 }
    319 
    320 void Page::setValidationMessageClient(PassOwnPtrWillBeRawPtr<ValidationMessageClient> client)
    321 {
    322     m_validationMessageClient = client;
    323 }
    324 
    325 void Page::setDefersLoading(bool defers)
    326 {
    327     if (defers == m_defersLoading)
    328         return;
    329 
    330     m_defersLoading = defers;
    331     for (Frame* frame = mainFrame(); frame; frame = frame->tree().traverseNext()) {
    332         if (frame->isLocalFrame())
    333             toLocalFrame(frame)->loader().setDefersLoading(defers);
    334     }
    335 }
    336 
    337 void Page::setPageScaleFactor(float scale, const IntPoint& origin)
    338 {
    339     if (!mainFrame()->isLocalFrame())
    340         return;
    341 
    342     FrameView* view = deprecatedLocalMainFrame()->view();
    343     PinchViewport& viewport = frameHost().pinchViewport();
    344 
    345     if (scale != viewport.scale()) {
    346         viewport.setScale(scale);
    347 
    348         if (view && !settings().pinchVirtualViewportEnabled())
    349             view->setVisibleContentScaleFactor(scale);
    350 
    351         deprecatedLocalMainFrame()->deviceOrPageScaleFactorChanged();
    352         m_chrome->client().deviceOrPageScaleFactorChanged();
    353 
    354         // FIXME: In virtual-viewport pinch mode, scale doesn't change the fixed-pos viewport;
    355         // remove once it's the only pinch mode in town.
    356         if (view)
    357             view->viewportConstrainedVisibleContentSizeChanged(true, true);
    358 
    359         deprecatedLocalMainFrame()->loader().saveScrollState();
    360     }
    361 
    362     if (view && view->scrollPosition() != origin)
    363         view->notifyScrollPositionChanged(origin);
    364 }
    365 
    366 float Page::pageScaleFactor() const
    367 {
    368     return frameHost().pinchViewport().scale();
    369 }
    370 
    371 void Page::setDeviceScaleFactor(float scaleFactor)
    372 {
    373     if (m_deviceScaleFactor == scaleFactor)
    374         return;
    375 
    376     m_deviceScaleFactor = scaleFactor;
    377     setNeedsRecalcStyleInAllFrames();
    378 
    379     if (mainFrame() && mainFrame()->isLocalFrame()) {
    380         deprecatedLocalMainFrame()->deviceOrPageScaleFactorChanged();
    381         m_chrome->client().deviceOrPageScaleFactorChanged();
    382     }
    383 }
    384 
    385 void Page::setDeviceColorProfile(const Vector<char>& profile)
    386 {
    387     // FIXME: implement.
    388 }
    389 
    390 void Page::resetDeviceColorProfile()
    391 {
    392     // FIXME: implement.
    393 }
    394 
    395 void Page::allVisitedStateChanged()
    396 {
    397     HashSet<Page*>::iterator pagesEnd = ordinaryPages().end();
    398     for (HashSet<Page*>::iterator it = ordinaryPages().begin(); it != pagesEnd; ++it) {
    399         Page* page = *it;
    400         for (Frame* frame = page->m_mainFrame; frame; frame = frame->tree().traverseNext()) {
    401             if (frame->isLocalFrame())
    402                 toLocalFrame(frame)->document()->visitedLinkState().invalidateStyleForAllLinks();
    403         }
    404     }
    405 }
    406 
    407 void Page::visitedStateChanged(LinkHash linkHash)
    408 {
    409     HashSet<Page*>::iterator pagesEnd = ordinaryPages().end();
    410     for (HashSet<Page*>::iterator it = ordinaryPages().begin(); it != pagesEnd; ++it) {
    411         Page* page = *it;
    412         for (Frame* frame = page->m_mainFrame; frame; frame = frame->tree().traverseNext()) {
    413             if (frame->isLocalFrame())
    414                 toLocalFrame(frame)->document()->visitedLinkState().invalidateStyleForLink(linkHash);
    415         }
    416     }
    417 }
    418 
    419 StorageNamespace* Page::sessionStorage(bool optionalCreate)
    420 {
    421     if (!m_sessionStorage && optionalCreate)
    422         m_sessionStorage = m_storageClient->createSessionStorageNamespace();
    423     return m_sessionStorage.get();
    424 }
    425 
    426 void Page::setTimerAlignmentInterval(double interval)
    427 {
    428     if (interval == m_timerAlignmentInterval)
    429         return;
    430 
    431     m_timerAlignmentInterval = interval;
    432     for (Frame* frame = mainFrame(); frame; frame = frame->tree().traverseNextWithWrap(false)) {
    433         if (frame->isLocalFrame() && toLocalFrame(frame)->document())
    434             toLocalFrame(frame)->document()->didChangeTimerAlignmentInterval();
    435     }
    436 }
    437 
    438 double Page::timerAlignmentInterval() const
    439 {
    440     return m_timerAlignmentInterval;
    441 }
    442 
    443 #if ENABLE(ASSERT)
    444 void Page::checkSubframeCountConsistency() const
    445 {
    446     ASSERT(m_subframeCount >= 0);
    447 
    448     int subframeCount = 0;
    449     for (Frame* frame = mainFrame(); frame; frame = frame->tree().traverseNext())
    450         ++subframeCount;
    451 
    452     ASSERT(m_subframeCount + 1 == subframeCount);
    453 }
    454 #endif
    455 
    456 void Page::setVisibilityState(PageVisibilityState visibilityState, bool isInitialState)
    457 {
    458     if (m_visibilityState == visibilityState)
    459         return;
    460     m_visibilityState = visibilityState;
    461 
    462     if (visibilityState == blink::PageVisibilityStateVisible)
    463         setTimerAlignmentInterval(DOMTimer::visiblePageAlignmentInterval());
    464     else
    465         setTimerAlignmentInterval(DOMTimer::hiddenPageAlignmentInterval());
    466 
    467     if (!isInitialState)
    468         lifecycleNotifier().notifyPageVisibilityChanged();
    469 
    470     if (!isInitialState && m_mainFrame && m_mainFrame->isLocalFrame())
    471         deprecatedLocalMainFrame()->didChangeVisibilityState();
    472 }
    473 
    474 PageVisibilityState Page::visibilityState() const
    475 {
    476     return m_visibilityState;
    477 }
    478 
    479 bool Page::isCursorVisible() const
    480 {
    481     return m_isCursorVisible && settings().deviceSupportsMouse();
    482 }
    483 
    484 void Page::addMultisamplingChangedObserver(MultisamplingChangedObserver* observer)
    485 {
    486     m_multisamplingChangedObservers.add(observer);
    487 }
    488 
    489 void Page::removeMultisamplingChangedObserver(MultisamplingChangedObserver* observer)
    490 {
    491     m_multisamplingChangedObservers.remove(observer);
    492 }
    493 
    494 void Page::settingsChanged(SettingsDelegate::ChangeType changeType)
    495 {
    496     switch (changeType) {
    497     case SettingsDelegate::StyleChange:
    498         setNeedsRecalcStyleInAllFrames();
    499         break;
    500     case SettingsDelegate::ViewportDescriptionChange:
    501         if (mainFrame() && mainFrame()->isLocalFrame())
    502             deprecatedLocalMainFrame()->document()->updateViewportDescription();
    503         break;
    504     case SettingsDelegate::MediaTypeChange:
    505         if (m_mainFrame->isLocalFrame()) {
    506             deprecatedLocalMainFrame()->view()->setMediaType(AtomicString(settings().mediaTypeOverride()));
    507             setNeedsRecalcStyleInAllFrames();
    508         }
    509         break;
    510     case SettingsDelegate::DNSPrefetchingChange:
    511         for (Frame* frame = mainFrame(); frame; frame = frame->tree().traverseNext()) {
    512             if (frame->isLocalFrame())
    513                 toLocalFrame(frame)->document()->initDNSPrefetch();
    514         }
    515         break;
    516     case SettingsDelegate::MultisamplingChange: {
    517         WillBeHeapHashSet<RawPtrWillBeWeakMember<MultisamplingChangedObserver> >::iterator stop = m_multisamplingChangedObservers.end();
    518         for (WillBeHeapHashSet<RawPtrWillBeWeakMember<MultisamplingChangedObserver> >::iterator it = m_multisamplingChangedObservers.begin(); it != stop; ++it)
    519             (*it)->multisamplingChanged(m_settings->openGLMultisamplingEnabled());
    520         break;
    521     }
    522     case SettingsDelegate::ImageLoadingChange:
    523         for (Frame* frame = mainFrame(); frame; frame = frame->tree().traverseNext()) {
    524             if (frame->isLocalFrame()) {
    525                 toLocalFrame(frame)->document()->fetcher()->setImagesEnabled(settings().imagesEnabled());
    526                 toLocalFrame(frame)->document()->fetcher()->setAutoLoadImages(settings().loadsImagesAutomatically());
    527             }
    528         }
    529         break;
    530     case SettingsDelegate::TextAutosizingChange:
    531         if (!mainFrame() || !mainFrame()->isLocalFrame())
    532             break;
    533         if (TextAutosizer* textAutosizer = deprecatedLocalMainFrame()->document()->textAutosizer())
    534             textAutosizer->updatePageInfoInAllFrames();
    535         break;
    536     case SettingsDelegate::ScriptEnableChange:
    537         m_inspectorController->scriptsEnabled(settings().scriptEnabled());
    538         break;
    539     case SettingsDelegate::FontFamilyChange:
    540         for (Frame* frame = mainFrame(); frame; frame = frame->tree().traverseNext()) {
    541             if (frame->isLocalFrame())
    542                 toLocalFrame(frame)->document()->styleEngine()->updateGenericFontFamilySettings();
    543         }
    544         setNeedsRecalcStyleInAllFrames();
    545         break;
    546     case SettingsDelegate::AcceleratedCompositingChange:
    547         updateAcceleratedCompositingSettings();
    548         break;
    549     case SettingsDelegate::MediaQueryChange:
    550         for (Frame* frame = mainFrame(); frame; frame = frame->tree().traverseNext()) {
    551             if (frame->isLocalFrame())
    552                 toLocalFrame(frame)->document()->mediaQueryAffectingValueChanged();
    553         }
    554         setNeedsRecalcStyleInAllFrames();
    555         break;
    556     }
    557 }
    558 
    559 void Page::updateAcceleratedCompositingSettings()
    560 {
    561     for (Frame* frame = mainFrame(); frame; frame = frame->tree().traverseNext()) {
    562         if (!frame->isLocalFrame())
    563             continue;
    564         if (FrameView* view = toLocalFrame(frame)->view())
    565             view->updateAcceleratedCompositingSettings();
    566     }
    567 }
    568 
    569 void Page::didCommitLoad(LocalFrame* frame)
    570 {
    571     lifecycleNotifier().notifyDidCommitLoad(frame);
    572     if (m_mainFrame == frame) {
    573         frame->console().clearMessages();
    574         useCounter().didCommitLoad();
    575         m_inspectorController->didCommitLoadForMainFrame();
    576         UserGestureIndicator::clearProcessedUserGestureSinceLoad();
    577     }
    578 }
    579 
    580 void Page::acceptLanguagesChanged()
    581 {
    582     WillBeHeapVector<RefPtrWillBeMember<LocalFrame> > frames;
    583 
    584     // Even though we don't fire an event from here, the LocalDOMWindow's will fire
    585     // an event so we keep the frames alive until we are done.
    586     for (Frame* frame = mainFrame(); frame; frame = frame->tree().traverseNext()) {
    587         if (frame->isLocalFrame())
    588             frames.append(toLocalFrame(frame));
    589     }
    590 
    591     for (unsigned i = 0; i < frames.size(); ++i)
    592         frames[i]->domWindow()->acceptLanguagesChanged();
    593 }
    594 
    595 PageLifecycleNotifier& Page::lifecycleNotifier()
    596 {
    597     return static_cast<PageLifecycleNotifier&>(LifecycleContext<Page>::lifecycleNotifier());
    598 }
    599 
    600 PassOwnPtr<LifecycleNotifier<Page> > Page::createLifecycleNotifier()
    601 {
    602     return PageLifecycleNotifier::create(this);
    603 }
    604 
    605 void Page::trace(Visitor* visitor)
    606 {
    607 #if ENABLE(OILPAN)
    608     visitor->trace(m_animator);
    609     visitor->trace(m_dragCaretController);
    610     visitor->trace(m_dragController);
    611     visitor->trace(m_focusController);
    612     visitor->trace(m_contextMenuController);
    613     visitor->trace(m_inspectorController);
    614     visitor->trace(m_pointerLockController);
    615     visitor->trace(m_undoStack);
    616     visitor->trace(m_mainFrame);
    617     visitor->trace(m_validationMessageClient);
    618     visitor->trace(m_multisamplingChangedObservers);
    619     visitor->trace(m_frameHost);
    620     HeapSupplementable<Page>::trace(visitor);
    621 #endif
    622     LifecycleContext<Page>::trace(visitor);
    623 }
    624 
    625 void Page::willBeDestroyed()
    626 {
    627     // Destroy inspector first, since it uses frame and view during destruction.
    628     m_inspectorController->willBeDestroyed();
    629 
    630     RefPtrWillBeRawPtr<Frame> mainFrame = m_mainFrame;
    631 
    632     mainFrame->detach();
    633 
    634     if (mainFrame->isLocalFrame()) {
    635         toLocalFrame(mainFrame.get())->setView(nullptr);
    636     } else {
    637         ASSERT(m_mainFrame->isRemoteFrame());
    638         toRemoteFrame(mainFrame.get())->setView(nullptr);
    639     }
    640 
    641     allPages().remove(this);
    642     if (ordinaryPages().contains(this))
    643         ordinaryPages().remove(this);
    644 
    645     if (m_scrollingCoordinator)
    646         m_scrollingCoordinator->willBeDestroyed();
    647 
    648 #ifndef NDEBUG
    649     pageCounter.decrement();
    650 #endif
    651 
    652     m_chrome->willBeDestroyed();
    653     if (m_validationMessageClient)
    654         m_validationMessageClient->willBeDestroyed();
    655     m_mainFrame = nullptr;
    656 }
    657 
    658 Page::PageClients::PageClients()
    659     : chromeClient(0)
    660     , contextMenuClient(0)
    661     , editorClient(0)
    662     , dragClient(0)
    663     , inspectorClient(0)
    664     , backForwardClient(0)
    665     , spellCheckerClient(0)
    666     , storageClient(0)
    667 {
    668 }
    669 
    670 Page::PageClients::~PageClients()
    671 {
    672 }
    673 
    674 } // namespace blink
    675