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
allPages()70 HashSet<Page*>& Page::allPages()
71 {
72 DEFINE_STATIC_LOCAL(HashSet<Page*>, allPages, ());
73 return allPages;
74 }
75
76 // static
ordinaryPages()77 HashSet<Page*>& Page::ordinaryPages()
78 {
79 DEFINE_STATIC_LOCAL(HashSet<Page*>, ordinaryPages, ());
80 return ordinaryPages;
81 }
82
83
networkStateChanged(bool online)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
deviceScaleFactor(LocalFrame * frame)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
Page(PageClients & pageClients)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
~Page()154 Page::~Page()
155 {
156 // willBeDestroyed() must be called before Page destruction.
157 ASSERT(!m_mainFrame);
158 }
159
makeOrdinary()160 void Page::makeOrdinary()
161 {
162 ASSERT(!ordinaryPages().contains(this));
163 ordinaryPages().add(this);
164 }
165
viewportDescription() const166 ViewportDescription Page::viewportDescription() const
167 {
168 return mainFrame() && mainFrame()->isLocalFrame() && deprecatedLocalMainFrame()->document() ? deprecatedLocalMainFrame()->document()->viewportDescription() : ViewportDescription();
169 }
170
scrollingCoordinator()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
mainThreadScrollingReasonsAsText()179 String Page::mainThreadScrollingReasonsAsText()
180 {
181 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
182 return scrollingCoordinator->mainThreadScrollingReasonsAsText();
183
184 return String();
185 }
186
nonFastScrollableRects(const LocalFrame * frame)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
setMainFrame(Frame * mainFrame)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
documentDetached(Document * document)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
openedByDOM() const221 bool Page::openedByDOM() const
222 {
223 return m_openedByDOM;
224 }
225
setOpenedByDOM()226 void Page::setOpenedByDOM()
227 {
228 m_openedByDOM = true;
229 }
230
scheduleForcedStyleRecalcForAllPages()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
setNeedsRecalcStyleInAllFrames()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
setNeedsLayoutInAllFrames()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
refreshPlugins(bool reload)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
pluginData() const291 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
incrementFrame(Frame * curr,bool forward,bool wrapFlag)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
unmarkAllTextMatches()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
setValidationMessageClient(PassOwnPtrWillBeRawPtr<ValidationMessageClient> client)320 void Page::setValidationMessageClient(PassOwnPtrWillBeRawPtr<ValidationMessageClient> client)
321 {
322 m_validationMessageClient = client;
323 }
324
setDefersLoading(bool defers)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
setPageScaleFactor(float scale,const IntPoint & origin)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
pageScaleFactor() const366 float Page::pageScaleFactor() const
367 {
368 return frameHost().pinchViewport().scale();
369 }
370
setDeviceScaleFactor(float scaleFactor)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
setDeviceColorProfile(const Vector<char> & profile)385 void Page::setDeviceColorProfile(const Vector<char>& profile)
386 {
387 // FIXME: implement.
388 }
389
resetDeviceColorProfile()390 void Page::resetDeviceColorProfile()
391 {
392 // FIXME: implement.
393 }
394
allVisitedStateChanged()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
visitedStateChanged(LinkHash linkHash)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
sessionStorage(bool optionalCreate)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
setTimerAlignmentInterval(double interval)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
timerAlignmentInterval() const438 double Page::timerAlignmentInterval() const
439 {
440 return m_timerAlignmentInterval;
441 }
442
443 #if ENABLE(ASSERT)
checkSubframeCountConsistency() const444 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
setVisibilityState(PageVisibilityState visibilityState,bool isInitialState)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
visibilityState() const474 PageVisibilityState Page::visibilityState() const
475 {
476 return m_visibilityState;
477 }
478
isCursorVisible() const479 bool Page::isCursorVisible() const
480 {
481 return m_isCursorVisible && settings().deviceSupportsMouse();
482 }
483
addMultisamplingChangedObserver(MultisamplingChangedObserver * observer)484 void Page::addMultisamplingChangedObserver(MultisamplingChangedObserver* observer)
485 {
486 m_multisamplingChangedObservers.add(observer);
487 }
488
removeMultisamplingChangedObserver(MultisamplingChangedObserver * observer)489 void Page::removeMultisamplingChangedObserver(MultisamplingChangedObserver* observer)
490 {
491 m_multisamplingChangedObservers.remove(observer);
492 }
493
settingsChanged(SettingsDelegate::ChangeType changeType)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
updateAcceleratedCompositingSettings()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
didCommitLoad(LocalFrame * frame)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
acceptLanguagesChanged()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
lifecycleNotifier()595 PageLifecycleNotifier& Page::lifecycleNotifier()
596 {
597 return static_cast<PageLifecycleNotifier&>(LifecycleContext<Page>::lifecycleNotifier());
598 }
599
createLifecycleNotifier()600 PassOwnPtr<LifecycleNotifier<Page> > Page::createLifecycleNotifier()
601 {
602 return PageLifecycleNotifier::create(this);
603 }
604
trace(Visitor * visitor)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
willBeDestroyed()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
PageClients()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
~PageClients()670 Page::PageClients::~PageClients()
671 {
672 }
673
674 } // namespace blink
675