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/LocalDOMWindow.h"
     33 #include "core/frame/EventHandlerRegistry.h"
     34 #include "core/frame/FrameHost.h"
     35 #include "core/frame/FrameView.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/FastTextAutosizer.h"
     57 #include "core/rendering/RenderView.h"
     58 #include "core/rendering/TextAutosizer.h"
     59 #include "core/storage/StorageNamespace.h"
     60 #include "platform/plugins/PluginData.h"
     61 #include "wtf/HashMap.h"
     62 #include "wtf/RefCountedLeakCounter.h"
     63 #include "wtf/StdLibExtras.h"
     64 #include "wtf/text/Base64.h"
     65 
     66 namespace WebCore {
     67 
     68 DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, pageCounter, ("Page"));
     69 
     70 // static
     71 HashSet<Page*>& Page::allPages()
     72 {
     73     DEFINE_STATIC_LOCAL(HashSet<Page*>, allPages, ());
     74     return allPages;
     75 }
     76 
     77 // static
     78 HashSet<Page*>& Page::ordinaryPages()
     79 {
     80     DEFINE_STATIC_LOCAL(HashSet<Page*>, ordinaryPages, ());
     81     return ordinaryPages;
     82 }
     83 
     84 
     85 void Page::networkStateChanged(bool online)
     86 {
     87     Vector<RefPtr<LocalFrame> > frames;
     88 
     89     // Get all the frames of all the pages in all the page groups
     90     HashSet<Page*>::iterator end = allPages().end();
     91     for (HashSet<Page*>::iterator it = allPages().begin(); it != end; ++it) {
     92         for (Frame* frame = (*it)->mainFrame(); frame; frame = frame->tree().traverseNext()) {
     93             // FIXME: There is currently no way to dispatch events to out-of-process frames.
     94             if (frame->isLocalFrame())
     95                 frames.append(toLocalFrame(frame));
     96         }
     97         InspectorInstrumentation::networkStateChanged(*it, online);
     98     }
     99 
    100     AtomicString eventName = online ? EventTypeNames::online : EventTypeNames::offline;
    101     for (unsigned i = 0; i < frames.size(); i++)
    102         frames[i]->domWindow()->dispatchEvent(Event::create(eventName));
    103 }
    104 
    105 float deviceScaleFactor(LocalFrame* frame)
    106 {
    107     if (!frame)
    108         return 1;
    109     Page* page = frame->page();
    110     if (!page)
    111         return 1;
    112     return page->deviceScaleFactor();
    113 }
    114 
    115 Page::Page(PageClients& pageClients)
    116     : SettingsDelegate(Settings::create())
    117     , m_animator(this)
    118     , m_autoscrollController(AutoscrollController::create(*this))
    119     , m_chrome(Chrome::create(this, pageClients.chromeClient))
    120     , m_dragCaretController(DragCaretController::create())
    121     , m_dragController(DragController::create(this, pageClients.dragClient))
    122     , m_focusController(FocusController::create(this))
    123     , m_contextMenuController(ContextMenuController::create(this, pageClients.contextMenuClient))
    124     , m_inspectorController(InspectorController::create(this, pageClients.inspectorClient))
    125     , m_pointerLockController(PointerLockController::create(this))
    126     , m_undoStack(UndoStack::create())
    127     , m_mainFrame(0)
    128     , m_backForwardClient(pageClients.backForwardClient)
    129     , m_editorClient(pageClients.editorClient)
    130     , m_spellCheckerClient(pageClients.spellCheckerClient)
    131     , m_storageClient(pageClients.storageClient)
    132     , m_subframeCount(0)
    133     , m_openedByDOM(false)
    134     , m_tabKeyCyclesThroughElements(true)
    135     , m_defersLoading(false)
    136     , m_deviceScaleFactor(1)
    137     , m_timerAlignmentInterval(DOMTimer::visiblePageAlignmentInterval())
    138     , m_visibilityState(PageVisibilityStateVisible)
    139     , m_isCursorVisible(true)
    140 #ifndef NDEBUG
    141     , m_isPainting(false)
    142 #endif
    143     , m_frameHost(FrameHost::create(*this))
    144 {
    145     ASSERT(m_editorClient);
    146 
    147     ASSERT(!allPages().contains(this));
    148     allPages().add(this);
    149 
    150 #ifndef NDEBUG
    151     pageCounter.increment();
    152 #endif
    153 }
    154 
    155 Page::~Page()
    156 {
    157     // willBeDestroyed() must be called before Page destruction.
    158     ASSERT(!m_mainFrame);
    159 }
    160 
    161 void Page::makeOrdinary()
    162 {
    163     ASSERT(!ordinaryPages().contains(this));
    164     ordinaryPages().add(this);
    165 }
    166 
    167 ViewportDescription Page::viewportDescription() const
    168 {
    169     return mainFrame() && mainFrame()->isLocalFrame() && deprecatedLocalMainFrame()->document() ? deprecatedLocalMainFrame()->document()->viewportDescription() : ViewportDescription();
    170 }
    171 
    172 ScrollingCoordinator* Page::scrollingCoordinator()
    173 {
    174     if (!m_scrollingCoordinator && m_settings->acceleratedCompositingEnabled())
    175         m_scrollingCoordinator = ScrollingCoordinator::create(this);
    176 
    177     return m_scrollingCoordinator.get();
    178 }
    179 
    180 String Page::mainThreadScrollingReasonsAsText()
    181 {
    182     if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
    183         return scrollingCoordinator->mainThreadScrollingReasonsAsText();
    184 
    185     return String();
    186 }
    187 
    188 PassRefPtrWillBeRawPtr<ClientRectList> Page::nonFastScrollableRects(const LocalFrame* frame)
    189 {
    190     if (m_mainFrame->isLocalFrame() && deprecatedLocalMainFrame()->document())
    191         deprecatedLocalMainFrame()->document()->updateLayout();
    192 
    193     Vector<IntRect> rects;
    194     if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
    195         rects = scrollingCoordinator->computeShouldHandleScrollGestureOnMainThreadRegion(frame, IntPoint()).rects();
    196 
    197     Vector<FloatQuad> quads(rects.size());
    198     for (size_t i = 0; i < rects.size(); ++i)
    199         quads[i] = FloatRect(rects[i]);
    200     return ClientRectList::create(quads);
    201 }
    202 
    203 void Page::setMainFrame(Frame* mainFrame)
    204 {
    205     ASSERT(!m_mainFrame); // Should only be called during initialization
    206     m_mainFrame = mainFrame;
    207 }
    208 
    209 void Page::documentDetached(Document* document)
    210 {
    211     m_multisamplingChangedObservers.clear();
    212     m_pointerLockController->documentDetached(document);
    213     m_contextMenuController->documentDetached(document);
    214     if (m_validationMessageClient)
    215         m_validationMessageClient->documentDetached(*document);
    216     m_frameHost->eventHandlerRegistry().documentDetached(*document);
    217 }
    218 
    219 bool Page::openedByDOM() const
    220 {
    221     return m_openedByDOM;
    222 }
    223 
    224 void Page::setOpenedByDOM()
    225 {
    226     m_openedByDOM = true;
    227 }
    228 
    229 void Page::scheduleForcedStyleRecalcForAllPages()
    230 {
    231     HashSet<Page*>::iterator end = allPages().end();
    232     for (HashSet<Page*>::iterator it = allPages().begin(); it != end; ++it)
    233         for (Frame* frame = (*it)->mainFrame(); frame; frame = frame->tree().traverseNext()) {
    234             if (frame->isLocalFrame())
    235                 toLocalFrame(frame)->document()->setNeedsStyleRecalc(SubtreeStyleChange);
    236         }
    237 }
    238 
    239 void Page::setNeedsRecalcStyleInAllFrames()
    240 {
    241     for (Frame* frame = mainFrame(); frame; frame = frame->tree().traverseNext()) {
    242         if (frame->isLocalFrame())
    243             toLocalFrame(frame)->document()->styleResolverChanged();
    244     }
    245 }
    246 
    247 void Page::setNeedsLayoutInAllFrames()
    248 {
    249     for (Frame* frame = mainFrame(); frame; frame = frame->tree().traverseNext()) {
    250         if (!frame->isLocalFrame())
    251             continue;
    252         if (FrameView* view = toLocalFrame(frame)->view()) {
    253             view->setNeedsLayout();
    254             view->scheduleRelayout();
    255         }
    256     }
    257 }
    258 
    259 void Page::refreshPlugins(bool reload)
    260 {
    261     if (allPages().isEmpty())
    262         return;
    263 
    264     PluginData::refresh();
    265 
    266     Vector<RefPtr<LocalFrame> > framesNeedingReload;
    267 
    268     HashSet<Page*>::iterator end = allPages().end();
    269     for (HashSet<Page*>::iterator it = allPages().begin(); it != end; ++it) {
    270         Page* page = *it;
    271 
    272         // Clear out the page's plug-in data.
    273         if (page->m_pluginData)
    274             page->m_pluginData = nullptr;
    275 
    276         if (!reload)
    277             continue;
    278 
    279         for (Frame* frame = (*it)->mainFrame(); frame; frame = frame->tree().traverseNext()) {
    280             if (frame->isLocalFrame() && toLocalFrame(frame)->document()->containsPlugins())
    281                 framesNeedingReload.append(toLocalFrame(frame));
    282         }
    283     }
    284 
    285     for (size_t i = 0; i < framesNeedingReload.size(); ++i)
    286         framesNeedingReload[i]->loader().reload();
    287 }
    288 
    289 PluginData* Page::pluginData() const
    290 {
    291     if (!deprecatedLocalMainFrame()->loader().allowPlugins(NotAboutToInstantiatePlugin))
    292         return 0;
    293     if (!m_pluginData)
    294         m_pluginData = PluginData::create(this);
    295     return m_pluginData.get();
    296 }
    297 
    298 static Frame* incrementFrame(Frame* curr, bool forward, bool wrapFlag)
    299 {
    300     return forward
    301         ? curr->tree().traverseNextWithWrap(wrapFlag)
    302         : curr->tree().traversePreviousWithWrap(wrapFlag);
    303 }
    304 
    305 void Page::unmarkAllTextMatches()
    306 {
    307     if (!mainFrame())
    308         return;
    309 
    310     Frame* frame = mainFrame();
    311     do {
    312         if (frame->isLocalFrame())
    313             toLocalFrame(frame)->document()->markers().removeMarkers(DocumentMarker::TextMatch);
    314         frame = incrementFrame(frame, true, false);
    315     } while (frame);
    316 }
    317 
    318 void Page::setValidationMessageClient(PassOwnPtrWillBeRawPtr<ValidationMessageClient> client)
    319 {
    320     m_validationMessageClient = client;
    321 }
    322 
    323 void Page::setDefersLoading(bool defers)
    324 {
    325     if (defers == m_defersLoading)
    326         return;
    327 
    328     m_defersLoading = defers;
    329     for (Frame* frame = mainFrame(); frame; frame = frame->tree().traverseNext()) {
    330         if (frame->isLocalFrame())
    331             toLocalFrame(frame)->loader().setDefersLoading(defers);
    332     }
    333 }
    334 
    335 void Page::setPageScaleFactor(float scale, const IntPoint& origin)
    336 {
    337     if (!mainFrame()->isLocalFrame())
    338         return;
    339 
    340     FrameView* view = deprecatedLocalMainFrame()->view();
    341     PinchViewport& viewport = frameHost().pinchViewport();
    342 
    343     if (scale != viewport.scale()) {
    344         viewport.setScale(scale);
    345 
    346         if (view && !settings().pinchVirtualViewportEnabled())
    347             view->setVisibleContentScaleFactor(scale);
    348 
    349         deprecatedLocalMainFrame()->deviceOrPageScaleFactorChanged();
    350         m_chrome->client().deviceOrPageScaleFactorChanged();
    351 
    352         // FIXME: In virtual-viewport pinch mode, scale doesn't change the fixed-pos viewport;
    353         // remove once it's the only pinch mode in town.
    354         if (view)
    355             view->viewportConstrainedVisibleContentSizeChanged(true, true);
    356 
    357         deprecatedLocalMainFrame()->loader().saveScrollState();
    358     }
    359 
    360     if (view && view->scrollPosition() != origin)
    361         view->notifyScrollPositionChanged(origin);
    362 }
    363 
    364 float Page::pageScaleFactor() const
    365 {
    366     return frameHost().pinchViewport().scale();
    367 }
    368 
    369 void Page::setDeviceScaleFactor(float scaleFactor)
    370 {
    371     if (m_deviceScaleFactor == scaleFactor)
    372         return;
    373 
    374     m_deviceScaleFactor = scaleFactor;
    375     setNeedsRecalcStyleInAllFrames();
    376 
    377     if (mainFrame() && mainFrame()->isLocalFrame()) {
    378         deprecatedLocalMainFrame()->deviceOrPageScaleFactorChanged();
    379         m_chrome->client().deviceOrPageScaleFactorChanged();
    380     }
    381 }
    382 
    383 void Page::allVisitedStateChanged()
    384 {
    385     HashSet<Page*>::iterator pagesEnd = ordinaryPages().end();
    386     for (HashSet<Page*>::iterator it = ordinaryPages().begin(); it != pagesEnd; ++it) {
    387         Page* page = *it;
    388         for (Frame* frame = page->m_mainFrame; frame; frame = frame->tree().traverseNext()) {
    389             if (frame->isLocalFrame())
    390                 toLocalFrame(frame)->document()->visitedLinkState().invalidateStyleForAllLinks();
    391         }
    392     }
    393 }
    394 
    395 void Page::visitedStateChanged(LinkHash linkHash)
    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().invalidateStyleForLink(linkHash);
    403         }
    404     }
    405 }
    406 
    407 StorageNamespace* Page::sessionStorage(bool optionalCreate)
    408 {
    409     if (!m_sessionStorage && optionalCreate)
    410         m_sessionStorage = m_storageClient->createSessionStorageNamespace();
    411     return m_sessionStorage.get();
    412 }
    413 
    414 void Page::setTimerAlignmentInterval(double interval)
    415 {
    416     if (interval == m_timerAlignmentInterval)
    417         return;
    418 
    419     m_timerAlignmentInterval = interval;
    420     for (Frame* frame = mainFrame(); frame; frame = frame->tree().traverseNextWithWrap(false)) {
    421         if (frame->isLocalFrame() && toLocalFrame(frame)->document())
    422             toLocalFrame(frame)->document()->didChangeTimerAlignmentInterval();
    423     }
    424 }
    425 
    426 double Page::timerAlignmentInterval() const
    427 {
    428     return m_timerAlignmentInterval;
    429 }
    430 
    431 #if ASSERT_ENABLED
    432 void Page::checkSubframeCountConsistency() const
    433 {
    434     ASSERT(m_subframeCount >= 0);
    435 
    436     int subframeCount = 0;
    437     for (Frame* frame = mainFrame(); frame; frame = frame->tree().traverseNext())
    438         ++subframeCount;
    439 
    440     ASSERT(m_subframeCount + 1 == subframeCount);
    441 }
    442 #endif
    443 
    444 void Page::setVisibilityState(PageVisibilityState visibilityState, bool isInitialState)
    445 {
    446     if (m_visibilityState == visibilityState)
    447         return;
    448     m_visibilityState = visibilityState;
    449 
    450     if (visibilityState == WebCore::PageVisibilityStateHidden)
    451         setTimerAlignmentInterval(DOMTimer::hiddenPageAlignmentInterval());
    452     else
    453         setTimerAlignmentInterval(DOMTimer::visiblePageAlignmentInterval());
    454 
    455     if (!isInitialState)
    456         lifecycleNotifier().notifyPageVisibilityChanged();
    457 
    458     if (!isInitialState && m_mainFrame && m_mainFrame->isLocalFrame())
    459         deprecatedLocalMainFrame()->didChangeVisibilityState();
    460 }
    461 
    462 PageVisibilityState Page::visibilityState() const
    463 {
    464     return m_visibilityState;
    465 }
    466 
    467 bool Page::isCursorVisible() const
    468 {
    469     return m_isCursorVisible && settings().deviceSupportsMouse();
    470 }
    471 
    472 void Page::addMultisamplingChangedObserver(MultisamplingChangedObserver* observer)
    473 {
    474     m_multisamplingChangedObservers.add(observer);
    475 }
    476 
    477 void Page::removeMultisamplingChangedObserver(MultisamplingChangedObserver* observer)
    478 {
    479     m_multisamplingChangedObservers.remove(observer);
    480 }
    481 
    482 void Page::settingsChanged(SettingsDelegate::ChangeType changeType)
    483 {
    484     switch (changeType) {
    485     case SettingsDelegate::StyleChange:
    486         setNeedsRecalcStyleInAllFrames();
    487         break;
    488     case SettingsDelegate::ViewportDescriptionChange:
    489         if (mainFrame() && mainFrame()->isLocalFrame())
    490             deprecatedLocalMainFrame()->document()->updateViewportDescription();
    491         break;
    492     case SettingsDelegate::MediaTypeChange:
    493         if (m_mainFrame->isLocalFrame()) {
    494             deprecatedLocalMainFrame()->view()->setMediaType(AtomicString(settings().mediaTypeOverride()));
    495             setNeedsRecalcStyleInAllFrames();
    496         }
    497         break;
    498     case SettingsDelegate::DNSPrefetchingChange:
    499         for (Frame* frame = mainFrame(); frame; frame = frame->tree().traverseNext()) {
    500             if (frame->isLocalFrame())
    501                 toLocalFrame(frame)->document()->initDNSPrefetch();
    502         }
    503         break;
    504     case SettingsDelegate::MultisamplingChange: {
    505         WillBeHeapHashSet<RawPtrWillBeWeakMember<MultisamplingChangedObserver> >::iterator stop = m_multisamplingChangedObservers.end();
    506         for (WillBeHeapHashSet<RawPtrWillBeWeakMember<MultisamplingChangedObserver> >::iterator it = m_multisamplingChangedObservers.begin(); it != stop; ++it)
    507             (*it)->multisamplingChanged(m_settings->openGLMultisamplingEnabled());
    508         break;
    509     }
    510     case SettingsDelegate::ImageLoadingChange:
    511         for (Frame* frame = mainFrame(); frame; frame = frame->tree().traverseNext()) {
    512             if (frame->isLocalFrame()) {
    513                 toLocalFrame(frame)->document()->fetcher()->setImagesEnabled(settings().imagesEnabled());
    514                 toLocalFrame(frame)->document()->fetcher()->setAutoLoadImages(settings().loadsImagesAutomatically());
    515             }
    516         }
    517         break;
    518     case SettingsDelegate::TextAutosizingChange:
    519         if (!mainFrame() || !mainFrame()->isLocalFrame())
    520             break;
    521         if (FastTextAutosizer* textAutosizer = deprecatedLocalMainFrame()->document()->fastTextAutosizer()) {
    522             textAutosizer->updatePageInfoInAllFrames();
    523         } else {
    524             for (Frame* frame = mainFrame(); frame; frame = frame->tree().traverseNext()) {
    525                 if (!frame->isLocalFrame())
    526                     continue;
    527                 if (TextAutosizer* textAutosizer = toLocalFrame(frame)->document()->textAutosizer())
    528                     textAutosizer->recalculateMultipliers();
    529             }
    530             // TextAutosizing updates RenderStyle during layout phase (via TextAutosizer::processSubtree).
    531             // We should invoke setNeedsLayout here.
    532             setNeedsLayoutInAllFrames();
    533         }
    534         break;
    535     case SettingsDelegate::ScriptEnableChange:
    536         m_inspectorController->scriptsEnabled(settings().scriptEnabled());
    537         break;
    538     case SettingsDelegate::FontFamilyChange:
    539         for (Frame* frame = mainFrame(); frame; frame = frame->tree().traverseNext()) {
    540             if (frame->isLocalFrame())
    541                 toLocalFrame(frame)->document()->styleEngine()->updateGenericFontFamilySettings();
    542         }
    543         setNeedsRecalcStyleInAllFrames();
    544         break;
    545     case SettingsDelegate::AcceleratedCompositingChange:
    546         updateAcceleratedCompositingSettings();
    547         break;
    548     }
    549 }
    550 
    551 void Page::updateAcceleratedCompositingSettings()
    552 {
    553     for (Frame* frame = mainFrame(); frame; frame = frame->tree().traverseNext()) {
    554         if (!frame->isLocalFrame())
    555             continue;
    556         if (FrameView* view = toLocalFrame(frame)->view())
    557             view->updateAcceleratedCompositingSettings();
    558     }
    559 }
    560 
    561 void Page::didCommitLoad(LocalFrame* frame)
    562 {
    563     lifecycleNotifier().notifyDidCommitLoad(frame);
    564     if (m_mainFrame == frame) {
    565         useCounter().didCommitLoad();
    566         m_inspectorController->didCommitLoadForMainFrame();
    567     }
    568 }
    569 
    570 void Page::acceptLanguagesChanged()
    571 {
    572     Vector< RefPtr<LocalFrame> > frames;
    573 
    574     // Even though we don't fire an event from here, the LocalDOMWindow's will fire
    575     // an event so we keep the frames alive until we are done.
    576     for (Frame* frame = mainFrame(); frame; frame = frame->tree().traverseNext()) {
    577         if (frame->isLocalFrame())
    578             frames.append(toLocalFrame(frame));
    579     }
    580 
    581     for (unsigned i = 0; i < frames.size(); ++i)
    582         frames[i]->domWindow()->acceptLanguagesChanged();
    583 }
    584 
    585 PageLifecycleNotifier& Page::lifecycleNotifier()
    586 {
    587     return static_cast<PageLifecycleNotifier&>(LifecycleContext<Page>::lifecycleNotifier());
    588 }
    589 
    590 PassOwnPtr<LifecycleNotifier<Page> > Page::createLifecycleNotifier()
    591 {
    592     return PageLifecycleNotifier::create(this);
    593 }
    594 
    595 void Page::trace(Visitor* visitor)
    596 {
    597     visitor->trace(m_dragCaretController);
    598     visitor->trace(m_dragController);
    599     visitor->trace(m_pointerLockController);
    600     visitor->trace(m_undoStack);
    601     visitor->trace(m_validationMessageClient);
    602     visitor->trace(m_multisamplingChangedObservers);
    603     visitor->trace(m_frameHost);
    604     WillBeHeapSupplementable<Page>::trace(visitor);
    605 }
    606 
    607 void Page::willBeDestroyed()
    608 {
    609     RefPtr<Frame> mainFrame = m_mainFrame;
    610 
    611     if (mainFrame->isLocalFrame())
    612         toLocalFrame(mainFrame.get())->loader().frameDetached();
    613 
    614     // Disable all agents prior to resetting the frame view.
    615     m_inspectorController->willBeDestroyed();
    616 
    617     if (mainFrame->isLocalFrame()) {
    618         toLocalFrame(mainFrame.get())->setView(nullptr);
    619     } else {
    620         ASSERT(m_mainFrame->isRemoteFrame());
    621         toRemoteFrame(mainFrame.get())->setView(nullptr);
    622     }
    623 
    624     allPages().remove(this);
    625     if (ordinaryPages().contains(this))
    626         ordinaryPages().remove(this);
    627 
    628     if (m_scrollingCoordinator)
    629         m_scrollingCoordinator->willBeDestroyed();
    630 
    631 #ifndef NDEBUG
    632     pageCounter.decrement();
    633 #endif
    634 
    635     m_chrome->willBeDestroyed();
    636     m_mainFrame = 0;
    637     if (m_validationMessageClient)
    638         m_validationMessageClient->willBeDestroyed();
    639     WillBeHeapSupplementable<Page>::willBeDestroyed();
    640 }
    641 
    642 Page::PageClients::PageClients()
    643     : chromeClient(0)
    644     , contextMenuClient(0)
    645     , editorClient(0)
    646     , dragClient(0)
    647     , inspectorClient(0)
    648     , backForwardClient(0)
    649     , spellCheckerClient(0)
    650     , storageClient(0)
    651 {
    652 }
    653 
    654 Page::PageClients::~PageClients()
    655 {
    656 }
    657 
    658 } // namespace WebCore
    659