Upstream version 11.39.250.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / page / Page.cpp
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