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