1/* 2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 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 * 10 * This library is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * Library General Public License for more details. 14 * 15 * You should have received a copy of the GNU Library General Public License 16 * along with this library; see the file COPYING.LIB. If not, write to 17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 18 * Boston, MA 02110-1301, USA. 19 */ 20 21#ifndef Page_h 22#define Page_h 23 24#include "FindOptions.h" 25#include "FrameLoaderTypes.h" 26#include "LayoutMilestones.h" 27#include "LayoutRect.h" 28#include "PageThrottler.h" 29#include "PageVisibilityState.h" 30#include "Pagination.h" 31#include "PlatformScreen.h" 32#include "Region.h" 33#include "ScrollTypes.h" 34#include "SessionID.h" 35#include "Supplementable.h" 36#include "ViewState.h" 37#include "ViewportArguments.h" 38#include <memory> 39#include <wtf/Forward.h> 40#include <wtf/HashMap.h> 41#include <wtf/HashSet.h> 42#include <wtf/Noncopyable.h> 43#include <wtf/Ref.h> 44#include <wtf/RefCounted.h> 45#include <wtf/text/WTFString.h> 46 47#if OS(SOLARIS) 48#include <sys/time.h> // For time_t structure. 49#endif 50 51#if PLATFORM(COCOA) 52#include <wtf/SchedulePair.h> 53#endif 54 55namespace JSC { 56class Debugger; 57} 58 59namespace WebCore { 60 61class AlternativeTextClient; 62class BackForwardController; 63class BackForwardClient; 64class Chrome; 65class ChromeClient; 66class ClientRectList; 67class Color; 68class ContextMenuClient; 69class ContextMenuController; 70class DragCaretController; 71class DragClient; 72class DragController; 73class EditorClient; 74class FocusController; 75class Frame; 76class FrameLoaderClient; 77class HistoryItem; 78class UserInputBridge; 79class InspectorClient; 80class InspectorController; 81class MainFrame; 82class MediaCanStartListener; 83class PageActivityAssertionToken; 84class PageConsole; 85class PageDebuggable; 86class PageGroup; 87class PageThrottler; 88class PlugInClient; 89class PluginData; 90class PluginViewBase; 91class PointerLockController; 92class ProgressTracker; 93class ProgressTrackerClient; 94class Range; 95class RenderObject; 96class RenderTheme; 97class ReplayController; 98class VisibleSelection; 99class ScrollableArea; 100class ScrollingCoordinator; 101class Settings; 102class StorageNamespace; 103class UserContentController; 104class ValidationMessageClient; 105class ViewStateChangeObserver; 106class VisitedLinkStore; 107 108typedef uint64_t LinkHash; 109 110enum FindDirection { FindDirectionForward, FindDirectionBackward }; 111 112class Page : public Supplementable<Page> { 113 WTF_MAKE_NONCOPYABLE(Page); 114 WTF_MAKE_FAST_ALLOCATED; 115 friend class Settings; 116 friend class PageThrottler; 117 118public: 119 static void updateStyleForAllPagesAfterGlobalChangeInEnvironment(); 120 static void clearPreviousItemFromAllPages(HistoryItem*); 121 122 // It is up to the platform to ensure that non-null clients are provided where required. 123 // FIXME: Rename this to PageConfiguration and move it to its own class. 124 struct PageClients { 125 WTF_MAKE_NONCOPYABLE(PageClients); WTF_MAKE_FAST_ALLOCATED; 126 public: 127 PageClients(); 128 ~PageClients(); 129 130 AlternativeTextClient* alternativeTextClient; 131 ChromeClient* chromeClient; 132#if ENABLE(CONTEXT_MENUS) 133 ContextMenuClient* contextMenuClient; 134#endif 135 EditorClient* editorClient; 136 DragClient* dragClient; 137 InspectorClient* inspectorClient; 138 PlugInClient* plugInClient; 139 ProgressTrackerClient* progressTrackerClient; 140 RefPtr<BackForwardClient> backForwardClient; 141 ValidationMessageClient* validationMessageClient; 142 FrameLoaderClient* loaderClientForMainFrame; 143 144 RefPtr<UserContentController> userContentController; 145 RefPtr<VisitedLinkStore> visitedLinkStore; 146 }; 147 148 explicit Page(PageClients&); 149 ~Page(); 150 151 uint64_t renderTreeSize() const; 152 153 void setNeedsRecalcStyleInAllFrames(); 154 155 RenderTheme& theme() const { return *m_theme; } 156 157 ViewportArguments viewportArguments() const; 158 159 static void refreshPlugins(bool reload); 160 PluginData& pluginData() const; 161 162 void setCanStartMedia(bool); 163 bool canStartMedia() const { return m_canStartMedia; } 164 165 EditorClient* editorClient() const { return m_editorClient; } 166 PlugInClient* plugInClient() const { return m_plugInClient; } 167 168 MainFrame& mainFrame() { ASSERT(m_mainFrame); return *m_mainFrame; } 169 const MainFrame& mainFrame() const { ASSERT(m_mainFrame); return *m_mainFrame; } 170 171 bool openedByDOM() const; 172 void setOpenedByDOM(); 173 174 void goToItem(HistoryItem*, FrameLoadType); 175 176 void setGroupName(const String&); 177 const String& groupName() const; 178 179 PageGroup& group(); 180 PageGroup* groupPtr() { return m_group; } // can return 0 181 182 void incrementSubframeCount() { ++m_subframeCount; } 183 void decrementSubframeCount() { ASSERT(m_subframeCount); --m_subframeCount; } 184 int subframeCount() const { checkSubframeCountConsistency(); return m_subframeCount; } 185 186#if ENABLE(REMOTE_INSPECTOR) 187 bool remoteInspectionAllowed() const; 188 void setRemoteInspectionAllowed(bool); 189 void remoteInspectorInformationDidChange() const; 190#endif 191 192 Chrome& chrome() const { return *m_chrome; } 193 DragCaretController& dragCaretController() const { return *m_dragCaretController; } 194#if ENABLE(DRAG_SUPPORT) 195 DragController& dragController() const { return *m_dragController; } 196#endif 197 FocusController& focusController() const { return *m_focusController; } 198#if ENABLE(CONTEXT_MENUS) 199 ContextMenuController& contextMenuController() const { return *m_contextMenuController; } 200#endif 201 UserInputBridge& userInputBridge() const { return *m_userInputBridge; } 202#if ENABLE(WEB_REPLAY) 203 ReplayController& replayController() const { return *m_replayController; } 204#endif 205#if ENABLE(INSPECTOR) 206 InspectorController& inspectorController() const { return *m_inspectorController; } 207#endif 208#if ENABLE(POINTER_LOCK) 209 PointerLockController& pointerLockController() const { return *m_pointerLockController; } 210#endif 211 ValidationMessageClient* validationMessageClient() const { return m_validationMessageClient; } 212 213 ScrollingCoordinator* scrollingCoordinator(); 214 215 String scrollingStateTreeAsText(); 216 String synchronousScrollingReasonsAsText(); 217 PassRefPtr<ClientRectList> nonFastScrollableRects(const Frame*); 218 219 Settings& settings() const { return *m_settings; } 220 ProgressTracker& progress() const { return *m_progress; } 221 BackForwardController& backForward() const { return *m_backForwardController; } 222 223#if ENABLE(VIEW_MODE_CSS_MEDIA) 224 enum ViewMode { 225 ViewModeInvalid, 226 ViewModeWindowed, 227 ViewModeFloating, 228 ViewModeFullscreen, 229 ViewModeMaximized, 230 ViewModeMinimized 231 }; 232 static ViewMode stringToViewMode(const String&); 233 234 ViewMode viewMode() const { return m_viewMode; } 235 void setViewMode(ViewMode); 236#endif // ENABLE(VIEW_MODE_CSS_MEDIA) 237 238 void setTabKeyCyclesThroughElements(bool b) { m_tabKeyCyclesThroughElements = b; } 239 bool tabKeyCyclesThroughElements() const { return m_tabKeyCyclesThroughElements; } 240 241 bool findString(const String&, FindOptions); 242 243 PassRefPtr<Range> rangeOfString(const String&, Range*, FindOptions); 244 245 unsigned countFindMatches(const String&, FindOptions, unsigned maxMatchCount); 246 unsigned markAllMatchesForText(const String&, FindOptions, bool shouldHighlight, unsigned maxMatchCount); 247 248 void unmarkAllTextMatches(); 249 250 // find all the Ranges for the matching text. 251 // Upon return, indexForSelection will be one of the following: 252 // 0 if there is no user selection 253 // the index of the first range after the user selection 254 // NoMatchAfterUserSelection if there is no matching text after the user selection. 255 enum { NoMatchAfterUserSelection = -1 }; 256 void findStringMatchingRanges(const String&, FindOptions, int maxCount, Vector<RefPtr<Range>>&, int& indexForSelection); 257#if PLATFORM(COCOA) 258 void addSchedulePair(PassRefPtr<SchedulePair>); 259 void removeSchedulePair(PassRefPtr<SchedulePair>); 260 SchedulePairHashSet* scheduledRunLoopPairs() { return m_scheduledRunLoopPairs.get(); } 261 262 std::unique_ptr<SchedulePairHashSet> m_scheduledRunLoopPairs; 263#endif 264 265 const VisibleSelection& selection() const; 266 267 void setDefersLoading(bool); 268 bool defersLoading() const { return m_defersLoading; } 269 270 void clearUndoRedoOperations(); 271 272 bool inLowQualityImageInterpolationMode() const; 273 void setInLowQualityImageInterpolationMode(bool = true); 274 275 float mediaVolume() const { return m_mediaVolume; } 276 void setMediaVolume(float); 277 278 void setPageScaleFactor(float scale, const IntPoint& origin, bool inStableState = true); 279 float pageScaleFactor() const { return m_pageScaleFactor; } 280 281 void setZoomedOutPageScaleFactor(float); 282 float zoomedOutPageScaleFactor() const { return m_zoomedOutPageScaleFactor; } 283 284 float deviceScaleFactor() const { return m_deviceScaleFactor; } 285 void setDeviceScaleFactor(float); 286 287 float topContentInset() const { return m_topContentInset; } 288 void setTopContentInset(float); 289 290#if ENABLE(IOS_TEXT_AUTOSIZING) 291 float textAutosizingWidth() const { return m_textAutosizingWidth; } 292 void setTextAutosizingWidth(float textAutosizingWidth) { m_textAutosizingWidth = textAutosizingWidth; } 293#endif 294 295 bool shouldSuppressScrollbarAnimations() const { return m_suppressScrollbarAnimations; } 296 void setShouldSuppressScrollbarAnimations(bool suppressAnimations); 297 void lockAllOverlayScrollbarsToHidden(bool lockOverlayScrollbars); 298 299 void setVerticalScrollElasticity(ScrollElasticity); 300 ScrollElasticity verticalScrollElasticity() const { return static_cast<ScrollElasticity>(m_verticalScrollElasticity); } 301 302 void setHorizontalScrollElasticity(ScrollElasticity); 303 ScrollElasticity horizontalScrollElasticity() const { return static_cast<ScrollElasticity>(m_horizontalScrollElasticity); } 304 305 // Page and FrameView both store a Pagination value. Page::pagination() is set only by API, 306 // and FrameView::pagination() is set only by CSS. Page::pagination() will affect all 307 // FrameViews in the page cache, but FrameView::pagination() only affects the current 308 // FrameView. 309 const Pagination& pagination() const { return m_pagination; } 310 void setPagination(const Pagination&); 311 312 unsigned pageCount() const; 313 314 // Notifications when the Page starts and stops being presented via a native window. 315 void setViewState(ViewState::Flags); 316 void setIsVisible(bool); 317 void setIsPrerender(); 318 bool isVisible() const { return m_viewState & ViewState::IsVisible; } 319 320 // Notification that this Page was moved into or out of a native window. 321 void setIsInWindow(bool); 322 bool isInWindow() const { return m_viewState & ViewState::IsInWindow; } 323 324 void setIsClosing() { m_isClosing = true; } 325 bool isClosing() const { return m_isClosing; } 326 327 void addViewStateChangeObserver(ViewStateChangeObserver&); 328 void removeViewStateChangeObserver(ViewStateChangeObserver&); 329 330 void suspendScriptedAnimations(); 331 void resumeScriptedAnimations(); 332 bool scriptedAnimationsSuspended() const { return m_scriptedAnimationsSuspended; } 333 334 void userStyleSheetLocationChanged(); 335 const String& userStyleSheet() const; 336 337 void dnsPrefetchingStateChanged(); 338 void storageBlockingStateChanged(); 339 340 void setDebugger(JSC::Debugger*); 341 JSC::Debugger* debugger() const { return m_debugger; } 342 343 static void removeAllVisitedLinks(); 344 345 void invalidateStylesForAllLinks(); 346 void invalidateStylesForLink(LinkHash); 347 348 StorageNamespace* sessionStorage(bool optionalCreate = true); 349 void setSessionStorage(PassRefPtr<StorageNamespace>); 350 351 bool hasCustomHTMLTokenizerTimeDelay() const; 352 double customHTMLTokenizerTimeDelay() const; 353 354 void setMemoryCacheClientCallsEnabled(bool); 355 bool areMemoryCacheClientCallsEnabled() const { return m_areMemoryCacheClientCallsEnabled; } 356 357 // Don't allow more than a certain number of frames in a page. 358 // This seems like a reasonable upper bound, and otherwise mutually 359 // recursive frameset pages can quickly bring the program to its knees 360 // with exponential growth in the number of frames. 361 static const int maxNumberOfFrames = 1000; 362 363 void setEditable(bool isEditable) { m_isEditable = isEditable; } 364 bool isEditable() { return m_isEditable; } 365 366 PageVisibilityState visibilityState() const; 367 void resumeAnimatingImages(); 368 369 void addLayoutMilestones(LayoutMilestones); 370 void removeLayoutMilestones(LayoutMilestones); 371 LayoutMilestones requestedLayoutMilestones() const { return m_requestedLayoutMilestones; } 372 373#if ENABLE(RUBBER_BANDING) 374 void addHeaderWithHeight(int); 375 void addFooterWithHeight(int); 376#endif 377 378 int headerHeight() const { return m_headerHeight; } 379 int footerHeight() const { return m_footerHeight; } 380 381 Color pageExtendedBackgroundColor() const; 382 383 bool isCountingRelevantRepaintedObjects() const; 384 void startCountingRelevantRepaintedObjects(); 385 void resetRelevantPaintedObjectCounter(); 386 void addRelevantRepaintedObject(RenderObject*, const LayoutRect& objectPaintRect); 387 void addRelevantUnpaintedObject(RenderObject*, const LayoutRect& objectPaintRect); 388 389 void suspendActiveDOMObjectsAndAnimations(); 390 void resumeActiveDOMObjectsAndAnimations(); 391#ifndef NDEBUG 392 void setIsPainting(bool painting) { m_isPainting = painting; } 393 bool isPainting() const { return m_isPainting; } 394#endif 395 396 AlternativeTextClient* alternativeTextClient() const { return m_alternativeTextClient; } 397 398 bool hasSeenPlugin(const String& serviceType) const; 399 bool hasSeenAnyPlugin() const; 400 void sawPlugin(const String& serviceType); 401 void resetSeenPlugins(); 402 403 bool hasSeenMediaEngine(const String& engineName) const; 404 bool hasSeenAnyMediaEngine() const; 405 void sawMediaEngine(const String& engineName); 406 void resetSeenMediaEngines(); 407 408 PageThrottler* pageThrottler() { return m_pageThrottler.get(); } 409 void createPageThrottler(); 410 411 PageConsole& console() { return *m_console; } 412 413 void hiddenPageCSSAnimationSuspensionStateChanged(); 414 415#if ENABLE(VIDEO_TRACK) 416 void captionPreferencesChanged(); 417#endif 418 419 void incrementFrameHandlingBeforeUnloadEventCount(); 420 void decrementFrameHandlingBeforeUnloadEventCount(); 421 bool isAnyFrameHandlingBeforeUnloadEvent(); 422 void setLastSpatialNavigationCandidateCount(unsigned count) { m_lastSpatialNavigationCandidatesCount = count; } 423 unsigned lastSpatialNavigationCandidateCount() const { return m_lastSpatialNavigationCandidatesCount; } 424 425 void setUserContentController(UserContentController*); 426 UserContentController* userContentController() { return m_userContentController.get(); } 427 428 VisitedLinkStore& visitedLinkStore(); 429 430 SessionID sessionID() const; 431 void setSessionID(SessionID); 432 void enableLegacyPrivateBrowsing(bool privateBrowsingEnabled); 433 bool usesEphemeralSession() const { return m_sessionID.isEphemeral(); } 434 435private: 436 void initGroup(); 437 438 void setIsInWindowInternal(bool); 439 void setIsVisibleInternal(bool); 440 void setIsVisuallyIdleInternal(bool); 441 442#if ASSERT_DISABLED 443 void checkSubframeCountConsistency() const { } 444#else 445 void checkSubframeCountConsistency() const; 446#endif 447 448 enum ShouldHighlightMatches { DoNotHighlightMatches, HighlightMatches }; 449 enum ShouldMarkMatches { DoNotMarkMatches, MarkMatches }; 450 451 unsigned findMatchesForText(const String&, FindOptions, unsigned maxMatchCount, ShouldHighlightMatches, ShouldMarkMatches); 452 453 MediaCanStartListener* takeAnyMediaCanStartListener(); 454 455 void setMinimumTimerInterval(double); 456 double minimumTimerInterval() const; 457 458 double timerAlignmentInterval() const { return m_timerAlignmentInterval; } 459 460 Vector<Ref<PluginViewBase>> pluginViews(); 461 462 void hiddenPageDOMTimerThrottlingStateChanged(); 463 void setTimerThrottlingEnabled(bool); 464 465 const std::unique_ptr<Chrome> m_chrome; 466 const std::unique_ptr<DragCaretController> m_dragCaretController; 467 468#if ENABLE(DRAG_SUPPORT) 469 const std::unique_ptr<DragController> m_dragController; 470#endif 471 const std::unique_ptr<FocusController> m_focusController; 472#if ENABLE(CONTEXT_MENUS) 473 const std::unique_ptr<ContextMenuController> m_contextMenuController; 474#endif 475 const std::unique_ptr<UserInputBridge> m_userInputBridge; 476#if ENABLE(WEB_REPLAY) 477 const std::unique_ptr<ReplayController> m_replayController; 478#endif 479#if ENABLE(INSPECTOR) 480 const std::unique_ptr<InspectorController> m_inspectorController; 481#endif 482#if ENABLE(POINTER_LOCK) 483 const std::unique_ptr<PointerLockController> m_pointerLockController; 484#endif 485 RefPtr<ScrollingCoordinator> m_scrollingCoordinator; 486 487 const RefPtr<Settings> m_settings; 488 const std::unique_ptr<ProgressTracker> m_progress; 489 490 const std::unique_ptr<BackForwardController> m_backForwardController; 491 const RefPtr<MainFrame> m_mainFrame; 492 493 mutable RefPtr<PluginData> m_pluginData; 494 495 RefPtr<RenderTheme> m_theme; 496 497 EditorClient* m_editorClient; 498 PlugInClient* m_plugInClient; 499 ValidationMessageClient* m_validationMessageClient; 500 501 int m_subframeCount; 502 String m_groupName; 503 bool m_openedByDOM; 504 505 bool m_tabKeyCyclesThroughElements; 506 bool m_defersLoading; 507 unsigned m_defersLoadingCallCount; 508 509 bool m_inLowQualityInterpolationMode; 510 bool m_areMemoryCacheClientCallsEnabled; 511 float m_mediaVolume; 512 513 float m_pageScaleFactor; 514 float m_zoomedOutPageScaleFactor; 515 float m_deviceScaleFactor; 516 517 float m_topContentInset; 518 519#if ENABLE(IOS_TEXT_AUTOSIZING) 520 float m_textAutosizingWidth; 521#endif 522 523 bool m_suppressScrollbarAnimations; 524 525 unsigned m_verticalScrollElasticity : 2; // ScrollElasticity 526 unsigned m_horizontalScrollElasticity : 2; // ScrollElasticity 527 528 Pagination m_pagination; 529 530 String m_userStyleSheetPath; 531 mutable String m_userStyleSheet; 532 mutable bool m_didLoadUserStyleSheet; 533 mutable time_t m_userStyleSheetModificationTime; 534 535 std::unique_ptr<PageGroup> m_singlePageGroup; 536 PageGroup* m_group; 537 538 JSC::Debugger* m_debugger; 539 540 bool m_canStartMedia; 541 542 RefPtr<StorageNamespace> m_sessionStorage; 543 544#if ENABLE(VIEW_MODE_CSS_MEDIA) 545 ViewMode m_viewMode; 546#endif // ENABLE(VIEW_MODE_CSS_MEDIA) 547 548 double m_minimumTimerInterval; 549 550 bool m_timerThrottlingEnabled; 551 double m_timerAlignmentInterval; 552 553 bool m_isEditable; 554 bool m_isPrerender; 555 ViewState::Flags m_viewState; 556 557 LayoutMilestones m_requestedLayoutMilestones; 558 559 int m_headerHeight; 560 int m_footerHeight; 561 562 HashSet<RenderObject*> m_relevantUnpaintedRenderObjects; 563 Region m_topRelevantPaintedRegion; 564 Region m_bottomRelevantPaintedRegion; 565 Region m_relevantUnpaintedRegion; 566 bool m_isCountingRelevantRepaintedObjects; 567#ifndef NDEBUG 568 bool m_isPainting; 569#endif 570 AlternativeTextClient* m_alternativeTextClient; 571 572 bool m_scriptedAnimationsSuspended; 573 std::unique_ptr<PageThrottler> m_pageThrottler; 574 const std::unique_ptr<PageConsole> m_console; 575 576#if ENABLE(REMOTE_INSPECTOR) 577 const std::unique_ptr<PageDebuggable> m_inspectorDebuggable; 578#endif 579 580 HashSet<String> m_seenPlugins; 581 HashSet<String> m_seenMediaEngines; 582 583 unsigned m_lastSpatialNavigationCandidatesCount; 584 unsigned m_framesHandlingBeforeUnloadEvent; 585 586 RefPtr<UserContentController> m_userContentController; 587 RefPtr<VisitedLinkStore> m_visitedLinkStore; 588 589 HashSet<ViewStateChangeObserver*> m_viewStateChangeObservers; 590 591 SessionID m_sessionID; 592 593 bool m_isClosing; 594}; 595 596inline PageGroup& Page::group() 597{ 598 if (!m_group) 599 initGroup(); 600 return *m_group; 601} 602 603} // namespace WebCore 604 605#endif // Page_h 606