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
allPages()71 HashSet<Page*>& Page::allPages()
72 {
73 DEFINE_STATIC_LOCAL(HashSet<Page*>, allPages, ());
74 return allPages;
75 }
76
77 // static
ordinaryPages()78 HashSet<Page*>& Page::ordinaryPages()
79 {
80 DEFINE_STATIC_LOCAL(HashSet<Page*>, ordinaryPages, ());
81 return ordinaryPages;
82 }
83
84
networkStateChanged(bool online)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
deviceScaleFactor(LocalFrame * frame)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
Page(PageClients & pageClients)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
~Page()155 Page::~Page()
156 {
157 // willBeDestroyed() must be called before Page destruction.
158 ASSERT(!m_mainFrame);
159 }
160
makeOrdinary()161 void Page::makeOrdinary()
162 {
163 ASSERT(!ordinaryPages().contains(this));
164 ordinaryPages().add(this);
165 }
166
viewportDescription() const167 ViewportDescription Page::viewportDescription() const
168 {
169 return mainFrame() && mainFrame()->isLocalFrame() && deprecatedLocalMainFrame()->document() ? deprecatedLocalMainFrame()->document()->viewportDescription() : ViewportDescription();
170 }
171
scrollingCoordinator()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
mainThreadScrollingReasonsAsText()180 String Page::mainThreadScrollingReasonsAsText()
181 {
182 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
183 return scrollingCoordinator->mainThreadScrollingReasonsAsText();
184
185 return String();
186 }
187
nonFastScrollableRects(const LocalFrame * frame)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
setMainFrame(Frame * mainFrame)203 void Page::setMainFrame(Frame* mainFrame)
204 {
205 ASSERT(!m_mainFrame); // Should only be called during initialization
206 m_mainFrame = mainFrame;
207 }
208
documentDetached(Document * document)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
openedByDOM() const219 bool Page::openedByDOM() const
220 {
221 return m_openedByDOM;
222 }
223
setOpenedByDOM()224 void Page::setOpenedByDOM()
225 {
226 m_openedByDOM = true;
227 }
228
scheduleForcedStyleRecalcForAllPages()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
setNeedsRecalcStyleInAllFrames()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
setNeedsLayoutInAllFrames()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
refreshPlugins(bool reload)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
pluginData() const289 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
incrementFrame(Frame * curr,bool forward,bool wrapFlag)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
unmarkAllTextMatches()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
setValidationMessageClient(PassOwnPtrWillBeRawPtr<ValidationMessageClient> client)318 void Page::setValidationMessageClient(PassOwnPtrWillBeRawPtr<ValidationMessageClient> client)
319 {
320 m_validationMessageClient = client;
321 }
322
setDefersLoading(bool defers)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
setPageScaleFactor(float scale,const IntPoint & origin)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
pageScaleFactor() const364 float Page::pageScaleFactor() const
365 {
366 return frameHost().pinchViewport().scale();
367 }
368
setDeviceScaleFactor(float scaleFactor)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
allVisitedStateChanged()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
visitedStateChanged(LinkHash linkHash)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
sessionStorage(bool optionalCreate)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
setTimerAlignmentInterval(double interval)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
timerAlignmentInterval() const426 double Page::timerAlignmentInterval() const
427 {
428 return m_timerAlignmentInterval;
429 }
430
431 #if ASSERT_ENABLED
checkSubframeCountConsistency() const432 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
setVisibilityState(PageVisibilityState visibilityState,bool isInitialState)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
visibilityState() const462 PageVisibilityState Page::visibilityState() const
463 {
464 return m_visibilityState;
465 }
466
isCursorVisible() const467 bool Page::isCursorVisible() const
468 {
469 return m_isCursorVisible && settings().deviceSupportsMouse();
470 }
471
addMultisamplingChangedObserver(MultisamplingChangedObserver * observer)472 void Page::addMultisamplingChangedObserver(MultisamplingChangedObserver* observer)
473 {
474 m_multisamplingChangedObservers.add(observer);
475 }
476
removeMultisamplingChangedObserver(MultisamplingChangedObserver * observer)477 void Page::removeMultisamplingChangedObserver(MultisamplingChangedObserver* observer)
478 {
479 m_multisamplingChangedObservers.remove(observer);
480 }
481
settingsChanged(SettingsDelegate::ChangeType changeType)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
updateAcceleratedCompositingSettings()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
didCommitLoad(LocalFrame * frame)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
acceptLanguagesChanged()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
lifecycleNotifier()585 PageLifecycleNotifier& Page::lifecycleNotifier()
586 {
587 return static_cast<PageLifecycleNotifier&>(LifecycleContext<Page>::lifecycleNotifier());
588 }
589
createLifecycleNotifier()590 PassOwnPtr<LifecycleNotifier<Page> > Page::createLifecycleNotifier()
591 {
592 return PageLifecycleNotifier::create(this);
593 }
594
trace(Visitor * visitor)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
willBeDestroyed()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
PageClients()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
~PageClients()654 Page::PageClients::~PageClients()
655 {
656 }
657
658 } // namespace WebCore
659