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