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 "FeatureObserver.h" 25#include "FindOptions.h" 26#include "FrameLoaderTypes.h" 27#include "LayoutMilestones.h" 28#include "LayoutRect.h" 29#include "PageVisibilityState.h" 30#include "Pagination.h" 31#include "PlatformScreen.h" 32#include "Region.h" 33#include "Supplementable.h" 34#include "ViewportArguments.h" 35#include <wtf/Forward.h> 36#include <wtf/HashMap.h> 37#include <wtf/HashSet.h> 38#include <wtf/Noncopyable.h> 39#include <wtf/RefCounted.h> 40#include <wtf/text/WTFString.h> 41 42#if OS(SOLARIS) 43#include <sys/time.h> // For time_t structure. 44#endif 45 46#if PLATFORM(MAC) 47#include <wtf/SchedulePair.h> 48#endif 49 50namespace JSC { 51class Debugger; 52} 53 54namespace WebCore { 55 56class AlternativeTextClient; 57class BackForwardController; 58class BackForwardList; 59class Chrome; 60class ChromeClient; 61class ClientRectList; 62class ContextMenuClient; 63class ContextMenuController; 64class Document; 65class DragCaretController; 66class DragClient; 67class DragController; 68class EditorClient; 69class FocusController; 70class Frame; 71class FrameSelection; 72class HaltablePlugin; 73class HistoryItem; 74class InspectorClient; 75class InspectorController; 76class MediaCanStartListener; 77class Node; 78class PageActivityAssertionToken; 79class PageConsole; 80class PageGroup; 81class PageThrottler; 82class PlugInClient; 83class PluginData; 84class PluginViewBase; 85class PointerLockController; 86class ProgressTracker; 87class Range; 88class RenderObject; 89class RenderTheme; 90class VisibleSelection; 91class ScrollableArea; 92class ScrollingCoordinator; 93class Settings; 94class StorageNamespace; 95class ValidationMessageClient; 96 97typedef uint64_t LinkHash; 98 99enum FindDirection { FindDirectionForward, FindDirectionBackward }; 100 101float deviceScaleFactor(Frame*); 102 103struct ArenaSize { 104 ArenaSize(size_t treeSize, size_t allocated) 105 : treeSize(treeSize) 106 , allocated(allocated) 107 { 108 } 109 size_t treeSize; 110 size_t allocated; 111}; 112 113class Page : public Supplementable<Page> { 114 WTF_MAKE_NONCOPYABLE(Page); 115 friend class Settings; 116 friend class PageThrottler; 117 118public: 119 static void updateStyleForAllPagesAfterGlobalChangeInEnvironment(); 120 121 // It is up to the platform to ensure that non-null clients are provided where required. 122 struct PageClients { 123 WTF_MAKE_NONCOPYABLE(PageClients); WTF_MAKE_FAST_ALLOCATED; 124 public: 125 PageClients(); 126 ~PageClients(); 127 128 AlternativeTextClient* alternativeTextClient; 129 ChromeClient* chromeClient; 130#if ENABLE(CONTEXT_MENUS) 131 ContextMenuClient* contextMenuClient; 132#endif 133 EditorClient* editorClient; 134 DragClient* dragClient; 135 InspectorClient* inspectorClient; 136 PlugInClient* plugInClient; 137 RefPtr<BackForwardList> backForwardClient; 138 ValidationMessageClient* validationMessageClient; 139 }; 140 141 explicit Page(PageClients&); 142 ~Page(); 143 144 ArenaSize renderTreeSize() const; 145 146 void setNeedsRecalcStyleInAllFrames(); 147 148 RenderTheme* theme() const { return m_theme.get(); } 149 150 ViewportArguments viewportArguments() const; 151 152 static void refreshPlugins(bool reload); 153 PluginData* pluginData() const; 154 155 void setCanStartMedia(bool); 156 bool canStartMedia() const { return m_canStartMedia; } 157 158 EditorClient* editorClient() const { return m_editorClient; } 159 PlugInClient* plugInClient() const { return m_plugInClient; } 160 161 void setMainFrame(PassRefPtr<Frame>); 162 Frame* mainFrame() const { return m_mainFrame.get(); } 163 164 bool openedByDOM() const; 165 void setOpenedByDOM(); 166 167 // DEPRECATED. Use backForward() instead of the following 6 functions. 168 BackForwardList* backForwardList() const; 169 bool goBack(); 170 bool goForward(); 171 bool canGoBackOrForward(int distance) const; 172 void goBackOrForward(int distance); 173 int getHistoryLength(); 174 175 void goToItem(HistoryItem*, FrameLoadType); 176 177 void setGroupName(const String&); 178 const String& groupName() const; 179 180 PageGroup& group(); 181 PageGroup* groupPtr() { return m_group; } // can return 0 182 183 void incrementSubframeCount() { ++m_subframeCount; } 184 void decrementSubframeCount() { ASSERT(m_subframeCount); --m_subframeCount; } 185 int subframeCount() const { checkSubframeCountConsistency(); return m_subframeCount; } 186 187 Chrome& chrome() const { return *m_chrome; } 188 DragCaretController* dragCaretController() const { return m_dragCaretController.get(); } 189#if ENABLE(DRAG_SUPPORT) 190 DragController* dragController() const { return m_dragController.get(); } 191#endif 192 FocusController* focusController() const { return m_focusController.get(); } 193#if ENABLE(CONTEXT_MENUS) 194 ContextMenuController* contextMenuController() const { return m_contextMenuController.get(); } 195#endif 196#if ENABLE(INSPECTOR) 197 InspectorController* inspectorController() const { return m_inspectorController.get(); } 198#endif 199#if ENABLE(POINTER_LOCK) 200 PointerLockController* pointerLockController() const { return m_pointerLockController.get(); } 201#endif 202 ValidationMessageClient* validationMessageClient() const { return m_validationMessageClient; } 203 204 ScrollingCoordinator* scrollingCoordinator(); 205 206 String scrollingStateTreeAsText(); 207 String mainThreadScrollingReasonsAsText(); 208 PassRefPtr<ClientRectList> nonFastScrollableRects(const Frame*); 209 210 Settings* settings() const { return m_settings.get(); } 211 ProgressTracker* progress() const { return m_progress.get(); } 212 BackForwardController* backForward() const { return m_backForwardController.get(); } 213 214 FeatureObserver* featureObserver() { return &m_featureObserver; } 215 216#if ENABLE(VIEW_MODE_CSS_MEDIA) 217 enum ViewMode { 218 ViewModeInvalid, 219 ViewModeWindowed, 220 ViewModeFloating, 221 ViewModeFullscreen, 222 ViewModeMaximized, 223 ViewModeMinimized 224 }; 225 static ViewMode stringToViewMode(const String&); 226 227 ViewMode viewMode() const { return m_viewMode; } 228 void setViewMode(ViewMode); 229#endif // ENABLE(VIEW_MODE_CSS_MEDIA) 230 231 void setTabKeyCyclesThroughElements(bool b) { m_tabKeyCyclesThroughElements = b; } 232 bool tabKeyCyclesThroughElements() const { return m_tabKeyCyclesThroughElements; } 233 234 bool findString(const String&, FindOptions); 235 // FIXME: Switch callers over to the FindOptions version and retire this one. 236 bool findString(const String&, TextCaseSensitivity, FindDirection, bool shouldWrap); 237 238 PassRefPtr<Range> rangeOfString(const String&, Range*, FindOptions); 239 240 unsigned countFindMatches(const String&, FindOptions, unsigned maxMatchCount); 241 unsigned markAllMatchesForText(const String&, FindOptions, bool shouldHighlight, unsigned maxMatchCount); 242 243 void unmarkAllTextMatches(); 244 245 // find all the Ranges for the matching text. 246 // Upon return, indexForSelection will be one of the following: 247 // 0 if there is no user selection 248 // the index of the first range after the user selection 249 // NoMatchAfterUserSelection if there is no matching text after the user selection. 250 enum { NoMatchAfterUserSelection = -1 }; 251 void findStringMatchingRanges(const String&, FindOptions, int maxCount, Vector<RefPtr<Range> >*, int& indexForSelection); 252#if PLATFORM(MAC) 253 void addSchedulePair(PassRefPtr<SchedulePair>); 254 void removeSchedulePair(PassRefPtr<SchedulePair>); 255 SchedulePairHashSet* scheduledRunLoopPairs() { return m_scheduledRunLoopPairs.get(); } 256 257 OwnPtr<SchedulePairHashSet> m_scheduledRunLoopPairs; 258#endif 259 260 const VisibleSelection& selection() const; 261 262 void setDefersLoading(bool); 263 bool defersLoading() const { return m_defersLoading; } 264 265 void clearUndoRedoOperations(); 266 267 bool inLowQualityImageInterpolationMode() const; 268 void setInLowQualityImageInterpolationMode(bool = true); 269 270 float mediaVolume() const { return m_mediaVolume; } 271 void setMediaVolume(float); 272 273 void setPageScaleFactor(float scale, const IntPoint& origin); 274 float pageScaleFactor() const { return m_pageScaleFactor; } 275 276 float deviceScaleFactor() const { return m_deviceScaleFactor; } 277 void setDeviceScaleFactor(float); 278 279 bool shouldSuppressScrollbarAnimations() const { return m_suppressScrollbarAnimations; } 280 void setShouldSuppressScrollbarAnimations(bool suppressAnimations); 281 282 bool rubberBandsAtBottom(); 283 void setRubberBandsAtBottom(bool); 284 bool rubberBandsAtTop(); 285 void setRubberBandsAtTop(bool); 286 287 // Page and FrameView both store a Pagination value. Page::pagination() is set only by API, 288 // and FrameView::pagination() is set only by CSS. Page::pagination() will affect all 289 // FrameViews in the page cache, but FrameView::pagination() only affects the current 290 // FrameView. 291 const Pagination& pagination() const { return m_pagination; } 292 void setPagination(const Pagination&); 293 294 unsigned pageCount() const; 295 296 // Notifications when the Page starts and stops being presented via a native window. 297 void didMoveOnscreen(); 298 void willMoveOffscreen(); 299 bool isOnscreen() const { return m_isOnscreen; } 300 301 // Notification that this Page was moved into or out of a native window. 302 void setIsInWindow(bool); 303 bool isInWindow() const { return m_isInWindow; } 304 305 void windowScreenDidChange(PlatformDisplayID); 306 307 void suspendScriptedAnimations(); 308 void resumeScriptedAnimations(); 309 bool scriptedAnimationsSuspended() const { return m_scriptedAnimationsSuspended; } 310 void setThrottled(bool); 311 312 void userStyleSheetLocationChanged(); 313 const String& userStyleSheet() const; 314 315 void dnsPrefetchingStateChanged(); 316 void storageBlockingStateChanged(); 317 void privateBrowsingStateChanged(); 318 319 static void setDebuggerForAllPages(JSC::Debugger*); 320 void setDebugger(JSC::Debugger*); 321 JSC::Debugger* debugger() const { return m_debugger; } 322 323 static void removeAllVisitedLinks(); 324 325 static void allVisitedStateChanged(PageGroup*); 326 static void visitedStateChanged(PageGroup*, LinkHash visitedHash); 327 328 StorageNamespace* sessionStorage(bool optionalCreate = true); 329 void setSessionStorage(PassRefPtr<StorageNamespace>); 330 331 void setCustomHTMLTokenizerTimeDelay(double); 332 bool hasCustomHTMLTokenizerTimeDelay() const { return m_customHTMLTokenizerTimeDelay != -1; } 333 double customHTMLTokenizerTimeDelay() const { ASSERT(m_customHTMLTokenizerTimeDelay != -1); return m_customHTMLTokenizerTimeDelay; } 334 335 void setCustomHTMLTokenizerChunkSize(int); 336 bool hasCustomHTMLTokenizerChunkSize() const { return m_customHTMLTokenizerChunkSize != -1; } 337 int customHTMLTokenizerChunkSize() const { ASSERT(m_customHTMLTokenizerChunkSize != -1); return m_customHTMLTokenizerChunkSize; } 338 339 void setMemoryCacheClientCallsEnabled(bool); 340 bool areMemoryCacheClientCallsEnabled() const { return m_areMemoryCacheClientCallsEnabled; } 341 342 // Don't allow more than a certain number of frames in a page. 343 // This seems like a reasonable upper bound, and otherwise mutually 344 // recursive frameset pages can quickly bring the program to its knees 345 // with exponential growth in the number of frames. 346 static const int maxNumberOfFrames = 1000; 347 348 void setEditable(bool isEditable) { m_isEditable = isEditable; } 349 bool isEditable() { return m_isEditable; } 350 351#if ENABLE(PAGE_VISIBILITY_API) 352 PageVisibilityState visibilityState() const; 353#endif 354#if ENABLE(PAGE_VISIBILITY_API) || ENABLE(HIDDEN_PAGE_DOM_TIMER_THROTTLING) 355 void setVisibilityState(PageVisibilityState, bool); 356#endif 357 void resumeAnimatingImages(); 358 359 PlatformDisplayID displayID() const { return m_displayID; } 360 361 void addLayoutMilestones(LayoutMilestones); 362 void removeLayoutMilestones(LayoutMilestones); 363 LayoutMilestones requestedLayoutMilestones() const { return m_requestedLayoutMilestones; } 364 365#if ENABLE(RUBBER_BANDING) 366 void addHeaderWithHeight(int); 367 void addFooterWithHeight(int); 368#endif 369 370 int headerHeight() const { return m_headerHeight; } 371 int footerHeight() const { return m_footerHeight; } 372 373 bool isCountingRelevantRepaintedObjects() const; 374 void startCountingRelevantRepaintedObjects(); 375 void resetRelevantPaintedObjectCounter(); 376 void addRelevantRepaintedObject(RenderObject*, const LayoutRect& objectPaintRect); 377 void addRelevantUnpaintedObject(RenderObject*, const LayoutRect& objectPaintRect); 378 379 void suspendActiveDOMObjectsAndAnimations(); 380 void resumeActiveDOMObjectsAndAnimations(); 381#ifndef NDEBUG 382 void setIsPainting(bool painting) { m_isPainting = painting; } 383 bool isPainting() const { return m_isPainting; } 384#endif 385 386 AlternativeTextClient* alternativeTextClient() const { return m_alternativeTextClient; } 387 388 bool hasSeenPlugin(const String& serviceType) const; 389 bool hasSeenAnyPlugin() const; 390 void sawPlugin(const String& serviceType); 391 void resetSeenPlugins(); 392 393 bool hasSeenMediaEngine(const String& engineName) const; 394 bool hasSeenAnyMediaEngine() const; 395 void sawMediaEngine(const String& engineName); 396 void resetSeenMediaEngines(); 397 398 PageThrottler* pageThrottler() { return m_pageThrottler.get(); } 399 PassOwnPtr<PageActivityAssertionToken> createActivityToken(); 400 401 PageConsole* console() { return m_console.get(); } 402 403#if ENABLE(HIDDEN_PAGE_DOM_TIMER_THROTTLING) 404 void hiddenPageDOMTimerThrottlingStateChanged(); 405#endif 406#if ENABLE(PAGE_VISIBILITY_API) 407 void hiddenPageCSSAnimationSuspensionStateChanged(); 408#endif 409 410#if ENABLE(VIDEO_TRACK) 411 void captionPreferencesChanged(); 412#endif 413 414 void incrementFrameHandlingBeforeUnloadEventCount(); 415 void decrementFrameHandlingBeforeUnloadEventCount(); 416 bool isAnyFrameHandlingBeforeUnloadEvent(); 417 418private: 419 void initGroup(); 420 421#if ASSERT_DISABLED 422 void checkSubframeCountConsistency() const { } 423#else 424 void checkSubframeCountConsistency() const; 425#endif 426 427 enum ShouldHighlightMatches { DoNotHighlightMatches, HighlightMatches }; 428 enum ShouldMarkMatches { DoNotMarkMatches, MarkMatches }; 429 430 unsigned findMatchesForText(const String&, FindOptions, unsigned maxMatchCount, ShouldHighlightMatches, ShouldMarkMatches); 431 432 MediaCanStartListener* takeAnyMediaCanStartListener(); 433 434 void setMinimumTimerInterval(double); 435 double minimumTimerInterval() const; 436 437 void setTimerAlignmentInterval(double); 438 double timerAlignmentInterval() const; 439 440 void collectPluginViews(Vector<RefPtr<PluginViewBase>, 32>& pluginViewBases); 441 442 void throttleTimers(); 443 void unthrottleTimers(); 444 445 const OwnPtr<Chrome> m_chrome; 446 OwnPtr<DragCaretController> m_dragCaretController; 447 448#if ENABLE(DRAG_SUPPORT) 449 OwnPtr<DragController> m_dragController; 450#endif 451 OwnPtr<FocusController> m_focusController; 452#if ENABLE(CONTEXT_MENUS) 453 OwnPtr<ContextMenuController> m_contextMenuController; 454#endif 455#if ENABLE(INSPECTOR) 456 OwnPtr<InspectorController> m_inspectorController; 457#endif 458#if ENABLE(POINTER_LOCK) 459 OwnPtr<PointerLockController> m_pointerLockController; 460#endif 461 RefPtr<ScrollingCoordinator> m_scrollingCoordinator; 462 463 OwnPtr<Settings> m_settings; 464 OwnPtr<ProgressTracker> m_progress; 465 466 OwnPtr<BackForwardController> m_backForwardController; 467 RefPtr<Frame> m_mainFrame; 468 469 mutable RefPtr<PluginData> m_pluginData; 470 471 RefPtr<RenderTheme> m_theme; 472 473 EditorClient* m_editorClient; 474 PlugInClient* m_plugInClient; 475 ValidationMessageClient* m_validationMessageClient; 476 477 FeatureObserver m_featureObserver; 478 479 int m_subframeCount; 480 String m_groupName; 481 bool m_openedByDOM; 482 483 bool m_tabKeyCyclesThroughElements; 484 bool m_defersLoading; 485 unsigned m_defersLoadingCallCount; 486 487 bool m_inLowQualityInterpolationMode; 488 bool m_cookieEnabled; 489 bool m_areMemoryCacheClientCallsEnabled; 490 float m_mediaVolume; 491 492 float m_pageScaleFactor; 493 float m_deviceScaleFactor; 494 495 bool m_suppressScrollbarAnimations; 496 497 Pagination m_pagination; 498 499 String m_userStyleSheetPath; 500 mutable String m_userStyleSheet; 501 mutable bool m_didLoadUserStyleSheet; 502 mutable time_t m_userStyleSheetModificationTime; 503 504 OwnPtr<PageGroup> m_singlePageGroup; 505 PageGroup* m_group; 506 507 JSC::Debugger* m_debugger; 508 509 double m_customHTMLTokenizerTimeDelay; 510 int m_customHTMLTokenizerChunkSize; 511 512 bool m_canStartMedia; 513 514 RefPtr<StorageNamespace> m_sessionStorage; 515 516#if ENABLE(VIEW_MODE_CSS_MEDIA) 517 ViewMode m_viewMode; 518#endif // ENABLE(VIEW_MODE_CSS_MEDIA) 519 520 double m_minimumTimerInterval; 521 522 double m_timerAlignmentInterval; 523 524 bool m_isEditable; 525 bool m_isOnscreen; 526 bool m_isInWindow; 527 528#if ENABLE(PAGE_VISIBILITY_API) 529 PageVisibilityState m_visibilityState; 530#endif 531 PlatformDisplayID m_displayID; 532 533 LayoutMilestones m_requestedLayoutMilestones; 534 535 int m_headerHeight; 536 int m_footerHeight; 537 538 HashSet<RenderObject*> m_relevantUnpaintedRenderObjects; 539 Region m_topRelevantPaintedRegion; 540 Region m_bottomRelevantPaintedRegion; 541 Region m_relevantUnpaintedRegion; 542 bool m_isCountingRelevantRepaintedObjects; 543#ifndef NDEBUG 544 bool m_isPainting; 545#endif 546 AlternativeTextClient* m_alternativeTextClient; 547 548 bool m_scriptedAnimationsSuspended; 549 RefPtr<PageThrottler> m_pageThrottler; 550 551 OwnPtr<PageConsole> m_console; 552 553 HashSet<String> m_seenPlugins; 554 HashSet<String> m_seenMediaEngines; 555 556 unsigned m_framesHandlingBeforeUnloadEvent; 557}; 558 559inline PageGroup& Page::group() 560{ 561 if (!m_group) 562 initGroup(); 563 return *m_group; 564} 565 566} // namespace WebCore 567 568#endif // Page_h 569