summaryrefslogtreecommitdiff
path: root/Source/WebCore/page
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/page')
-rw-r--r--Source/WebCore/page/AbstractView.idl6
-rw-r--r--Source/WebCore/page/AlternativeTextClient.h10
-rw-r--r--Source/WebCore/page/AutoscrollController.cpp18
-rw-r--r--Source/WebCore/page/AutoscrollController.h8
-rw-r--r--Source/WebCore/page/BarProp.cpp2
-rw-r--r--Source/WebCore/page/BarProp.h6
-rw-r--r--Source/WebCore/page/BarProp.idl2
-rw-r--r--Source/WebCore/page/CaptionUserPreferences.cpp110
-rw-r--r--Source/WebCore/page/CaptionUserPreferences.h22
-rw-r--r--Source/WebCore/page/CaptionUserPreferencesMediaAF.cpp956
-rw-r--r--Source/WebCore/page/CaptionUserPreferencesMediaAF.h99
-rw-r--r--Source/WebCore/page/Chrome.cpp173
-rw-r--r--Source/WebCore/page/Chrome.h56
-rw-r--r--Source/WebCore/page/ChromeClient.h181
-rw-r--r--Source/WebCore/page/Console.cpp266
-rw-r--r--Source/WebCore/page/Console.h85
-rw-r--r--Source/WebCore/page/Console.idl61
-rw-r--r--Source/WebCore/page/ConsoleTypes.h (renamed from Source/WebCore/page/LayerFlushThrottleState.h)32
-rw-r--r--Source/WebCore/page/ContentSecurityPolicy.cpp1919
-rw-r--r--Source/WebCore/page/ContentSecurityPolicy.h151
-rw-r--r--Source/WebCore/page/ContextMenuClient.h18
-rw-r--r--Source/WebCore/page/ContextMenuContext.h65
-rw-r--r--Source/WebCore/page/ContextMenuController.cpp369
-rw-r--r--Source/WebCore/page/ContextMenuController.h102
-rw-r--r--Source/WebCore/page/ContextMenuProvider.h3
-rw-r--r--Source/WebCore/page/Crypto.cpp13
-rw-r--r--Source/WebCore/page/Crypto.h2
-rw-r--r--Source/WebCore/page/DOMSecurityPolicy.cpp177
-rw-r--r--Source/WebCore/page/DOMSecurityPolicy.h (renamed from Source/WebCore/page/csp/ContentSecurityPolicyDirective.h)49
-rw-r--r--Source/WebCore/page/DOMSecurityPolicy.idl46
-rw-r--r--Source/WebCore/page/DOMSelection.cpp97
-rw-r--r--Source/WebCore/page/DOMSelection.h4
-rw-r--r--Source/WebCore/page/DOMSelection.idl2
-rw-r--r--Source/WebCore/page/DOMTimer.cpp362
-rw-r--r--Source/WebCore/page/DOMTimer.h63
-rw-r--r--Source/WebCore/page/DOMWindow.cpp699
-rw-r--r--Source/WebCore/page/DOMWindow.h198
-rw-r--r--Source/WebCore/page/DOMWindow.idl227
-rw-r--r--Source/WebCore/page/DOMWindowExtension.cpp12
-rw-r--r--Source/WebCore/page/DOMWindowExtension.h11
-rw-r--r--Source/WebCore/page/DOMWindowProperty.cpp20
-rw-r--r--Source/WebCore/page/DOMWindowProperty.h4
-rw-r--r--Source/WebCore/page/DatabaseProvider.cpp35
-rw-r--r--Source/WebCore/page/DatabaseProvider.h52
-rw-r--r--Source/WebCore/page/DebugPageOverlays.cpp305
-rw-r--r--Source/WebCore/page/DebugPageOverlays.h105
-rw-r--r--Source/WebCore/page/DeviceClient.h1
-rw-r--r--Source/WebCore/page/DeviceController.cpp28
-rw-r--r--Source/WebCore/page/DeviceController.h11
-rw-r--r--Source/WebCore/page/DiagnosticLoggingClient.h62
-rw-r--r--Source/WebCore/page/DiagnosticLoggingKeys.cpp523
-rw-r--r--Source/WebCore/page/DiagnosticLoggingKeys.h119
-rw-r--r--Source/WebCore/page/DragActions.h7
-rw-r--r--Source/WebCore/page/DragClient.h17
-rw-r--r--Source/WebCore/page/DragController.cpp437
-rw-r--r--Source/WebCore/page/DragController.h51
-rw-r--r--Source/WebCore/page/DragSession.h (renamed from Source/WebCore/page/PageConfiguration.cpp)32
-rw-r--r--Source/WebCore/page/DragState.h8
-rw-r--r--Source/WebCore/page/EditorClient.h25
-rw-r--r--Source/WebCore/page/EventHandler.cpp1620
-rw-r--r--Source/WebCore/page/EventHandler.h303
-rw-r--r--Source/WebCore/page/EventSource.cpp82
-rw-r--r--Source/WebCore/page/EventSource.h16
-rw-r--r--Source/WebCore/page/EventSource.idl20
-rw-r--r--Source/WebCore/page/FeatureObserver.cpp (renamed from Source/WebCore/page/csp/ContentSecurityPolicySourceListDirective.cpp)58
-rw-r--r--Source/WebCore/page/FeatureObserver.h139
-rw-r--r--Source/WebCore/page/FocusController.cpp274
-rw-r--r--Source/WebCore/page/FocusController.h51
-rw-r--r--Source/WebCore/page/FocusDirection.h6
-rw-r--r--Source/WebCore/page/Frame.cpp356
-rw-r--r--Source/WebCore/page/Frame.h212
-rw-r--r--Source/WebCore/page/FrameDestructionObserver.cpp6
-rw-r--r--Source/WebCore/page/FrameDestructionObserver.h10
-rw-r--r--Source/WebCore/page/FrameSnapshotting.cpp27
-rw-r--r--Source/WebCore/page/FrameSnapshotting.h5
-rw-r--r--Source/WebCore/page/FrameTree.cpp112
-rw-r--r--Source/WebCore/page/FrameTree.h40
-rw-r--r--Source/WebCore/page/FrameView.cpp2457
-rw-r--r--Source/WebCore/page/FrameView.h451
-rw-r--r--Source/WebCore/page/GestureTapHighlighter.cpp272
-rw-r--r--Source/WebCore/page/GestureTapHighlighter.h (renamed from Source/WebCore/page/WheelEventTestTrigger.h)49
-rw-r--r--Source/WebCore/page/GroupSettings.cpp53
-rw-r--r--Source/WebCore/page/GroupSettings.h57
-rw-r--r--Source/WebCore/page/History.cpp103
-rw-r--r--Source/WebCore/page/History.h19
-rw-r--r--Source/WebCore/page/History.idl14
-rw-r--r--Source/WebCore/page/LayoutMilestones.h3
-rw-r--r--Source/WebCore/page/Location.cpp49
-rw-r--r--Source/WebCore/page/Location.h26
-rw-r--r--Source/WebCore/page/Location.idl32
-rw-r--r--Source/WebCore/page/MainFrame.cpp143
-rw-r--r--Source/WebCore/page/MainFrame.h97
-rw-r--r--Source/WebCore/page/MediaProducer.h58
-rw-r--r--Source/WebCore/page/MouseEventWithHitTestResults.cpp2
-rw-r--r--Source/WebCore/page/MouseEventWithHitTestResults.h2
-rw-r--r--Source/WebCore/page/Navigator.cpp28
-rw-r--r--Source/WebCore/page/Navigator.h6
-rw-r--r--Source/WebCore/page/Navigator.idl28
-rw-r--r--Source/WebCore/page/NavigatorBase.cpp12
-rw-r--r--Source/WebCore/page/NavigatorBase.h4
-rw-r--r--Source/WebCore/page/OriginAccessEntry.cpp8
-rw-r--r--Source/WebCore/page/OriginAccessEntry.h2
-rw-r--r--Source/WebCore/page/Page.cpp1072
-rw-r--r--Source/WebCore/page/Page.h438
-rw-r--r--Source/WebCore/page/PageActivityAssertionToken.cpp (renamed from Source/WebCore/page/scrolling/coordinatedgraphics/ScrollingStateNodeCoordinatedGraphics.cpp)27
-rw-r--r--Source/WebCore/page/PageActivityAssertionToken.h (renamed from Source/WebCore/page/DiagnosticLoggingResultType.h)27
-rw-r--r--Source/WebCore/page/PageConfiguration.h93
-rw-r--r--Source/WebCore/page/PageConsole.cpp225
-rw-r--r--Source/WebCore/page/PageConsole.h (renamed from Source/WebCore/page/PageConsoleClient.h)49
-rw-r--r--Source/WebCore/page/PageConsoleClient.cpp219
-rw-r--r--Source/WebCore/page/PageDebuggable.cpp44
-rw-r--r--Source/WebCore/page/PageDebuggable.h23
-rw-r--r--Source/WebCore/page/PageGroup.cpp224
-rw-r--r--Source/WebCore/page/PageGroup.h73
-rw-r--r--Source/WebCore/page/PageGroupLoadDeferrer.cpp16
-rw-r--r--Source/WebCore/page/PageOverlay.cpp292
-rw-r--r--Source/WebCore/page/PageOverlay.h157
-rw-r--r--Source/WebCore/page/PageOverlayController.cpp365
-rw-r--r--Source/WebCore/page/PageOverlayController.h105
-rw-r--r--Source/WebCore/page/PageSerializer.cpp96
-rw-r--r--Source/WebCore/page/PageSerializer.h2
-rw-r--r--Source/WebCore/page/PageThrottler.cpp145
-rw-r--r--Source/WebCore/page/PageThrottler.h64
-rw-r--r--Source/WebCore/page/PageVisibilityState.cpp10
-rw-r--r--Source/WebCore/page/PageVisibilityState.h2
-rw-r--r--Source/WebCore/page/Performance.cpp54
-rw-r--r--Source/WebCore/page/Performance.h10
-rw-r--r--Source/WebCore/page/Performance.idl9
-rw-r--r--Source/WebCore/page/PerformanceEntry.idl4
-rw-r--r--Source/WebCore/page/PerformanceEntryList.h2
-rw-r--r--Source/WebCore/page/PerformanceMark.h2
-rw-r--r--Source/WebCore/page/PerformanceMeasure.h2
-rw-r--r--Source/WebCore/page/PerformanceNavigation.cpp10
-rw-r--r--Source/WebCore/page/PerformanceNavigation.h2
-rw-r--r--Source/WebCore/page/PerformanceResourceTiming.cpp60
-rw-r--r--Source/WebCore/page/PerformanceResourceTiming.h9
-rw-r--r--Source/WebCore/page/PerformanceResourceTiming.idl21
-rw-r--r--Source/WebCore/page/PerformanceTiming.cpp117
-rw-r--r--Source/WebCore/page/PerformanceTiming.h5
-rw-r--r--Source/WebCore/page/PerformanceTiming.idl2
-rw-r--r--Source/WebCore/page/PerformanceUserTiming.cpp76
-rw-r--r--Source/WebCore/page/PerformanceUserTiming.h3
-rw-r--r--Source/WebCore/page/PlugInClient.h3
-rw-r--r--Source/WebCore/page/PointerLockController.cpp40
-rw-r--r--Source/WebCore/page/PointerLockController.h6
-rw-r--r--Source/WebCore/page/PrintContext.cpp68
-rw-r--r--Source/WebCore/page/PrintContext.h31
-rw-r--r--Source/WebCore/page/ResourceUsageData.cpp59
-rw-r--r--Source/WebCore/page/ResourceUsageData.h76
-rw-r--r--Source/WebCore/page/ResourceUsageOverlay.cpp130
-rw-r--r--Source/WebCore/page/ResourceUsageOverlay.h93
-rw-r--r--Source/WebCore/page/ResourceUsageThread.cpp130
-rw-r--r--Source/WebCore/page/ResourceUsageThread.h92
-rw-r--r--Source/WebCore/page/Screen.cpp6
-rw-r--r--Source/WebCore/page/Screen.h32
-rw-r--r--Source/WebCore/page/Screen.idl18
-rw-r--r--Source/WebCore/page/SecurityOrigin.cpp133
-rw-r--r--Source/WebCore/page/SecurityOrigin.h51
-rw-r--r--Source/WebCore/page/SecurityOriginData.cpp98
-rw-r--r--Source/WebCore/page/SecurityOriginData.h83
-rw-r--r--Source/WebCore/page/SecurityOriginHash.h2
-rw-r--r--Source/WebCore/page/SecurityPolicy.cpp32
-rw-r--r--Source/WebCore/page/SecurityPolicy.h12
-rw-r--r--Source/WebCore/page/SessionID.h76
-rw-r--r--Source/WebCore/page/Settings.cpp303
-rw-r--r--Source/WebCore/page/Settings.h314
-rw-r--r--Source/WebCore/page/Settings.in87
-rw-r--r--Source/WebCore/page/SpatialNavigation.cpp70
-rw-r--r--Source/WebCore/page/SpatialNavigation.h6
-rw-r--r--Source/WebCore/page/SpeechInput.cpp132
-rw-r--r--Source/WebCore/page/SpeechInput.h91
-rw-r--r--Source/WebCore/page/SpeechInputClient.h76
-rw-r--r--Source/WebCore/page/SpeechInputEvent.cpp72
-rw-r--r--Source/WebCore/page/SpeechInputEvent.h61
-rw-r--r--Source/WebCore/page/SpeechInputEvent.idl (renamed from Source/WebCore/page/ContextMenuContext.cpp)37
-rw-r--r--Source/WebCore/page/SpeechInputListener.h67
-rw-r--r--Source/WebCore/page/SpeechInputResult.cpp61
-rw-r--r--Source/WebCore/page/SpeechInputResult.h60
-rw-r--r--Source/WebCore/page/SpeechInputResult.idl34
-rw-r--r--Source/WebCore/page/SpeechInputResultList.cpp55
-rw-r--r--Source/WebCore/page/SpeechInputResultList.h (renamed from Source/WebCore/page/csp/ContentSecurityPolicyMediaListDirective.h)43
-rw-r--r--Source/WebCore/page/SpeechInputResultList.idl34
-rw-r--r--Source/WebCore/page/SuspendableTimer.cpp8
-rw-r--r--Source/WebCore/page/SuspendableTimer.h18
-rw-r--r--Source/WebCore/page/TextIndicator.cpp244
-rw-r--r--Source/WebCore/page/TextIndicator.h133
-rw-r--r--Source/WebCore/page/UserContentController.cpp104
-rw-r--r--Source/WebCore/page/UserContentController.h62
-rw-r--r--Source/WebCore/page/UserContentTypes.h4
-rw-r--r--Source/WebCore/page/UserContentURLPattern.cpp31
-rw-r--r--Source/WebCore/page/UserContentURLPattern.h8
-rw-r--r--Source/WebCore/page/UserMessageHandler.cpp71
-rw-r--r--Source/WebCore/page/UserMessageHandler.h62
-rw-r--r--Source/WebCore/page/UserMessageHandler.idl30
-rw-r--r--Source/WebCore/page/UserMessageHandlerDescriptor.cpp58
-rw-r--r--Source/WebCore/page/UserMessageHandlerDescriptor.h74
-rw-r--r--Source/WebCore/page/UserMessageHandlerDescriptorTypes.h46
-rw-r--r--Source/WebCore/page/UserMessageHandlersNamespace.cpp88
-rw-r--r--Source/WebCore/page/UserMessageHandlersNamespace.h64
-rw-r--r--Source/WebCore/page/UserMessageHandlersNamespace.idl30
-rw-r--r--Source/WebCore/page/UserScript.h10
-rw-r--r--Source/WebCore/page/UserScriptTypes.h4
-rw-r--r--Source/WebCore/page/UserStyleSheet.h10
-rw-r--r--Source/WebCore/page/UserStyleSheetTypes.h4
-rw-r--r--Source/WebCore/page/ViewState.h7
-rw-r--r--Source/WebCore/page/ViewportConfiguration.cpp480
-rw-r--r--Source/WebCore/page/ViewportConfiguration.h131
-rw-r--r--Source/WebCore/page/VisitedLinkProvider.cpp (renamed from Source/WebCore/page/WebKitNamespace.idl)18
-rw-r--r--Source/WebCore/page/VisitedLinkProvider.h (renamed from Source/WebCore/page/ViewStateChangeObserver.h)27
-rw-r--r--Source/WebCore/page/VisitedLinkStore.cpp68
-rw-r--r--Source/WebCore/page/VisitedLinkStore.h60
-rw-r--r--Source/WebCore/page/WebCoreKeyboardUIMode.h6
-rw-r--r--Source/WebCore/page/WebKitNamespace.cpp53
-rw-r--r--Source/WebCore/page/WebKitNamespace.h60
-rw-r--r--Source/WebCore/page/WebKitPoint.h12
-rw-r--r--Source/WebCore/page/WebKitPoint.idl10
-rw-r--r--Source/WebCore/page/WheelEventDeltaFilter.cpp128
-rw-r--r--Source/WebCore/page/WheelEventDeltaFilter.h74
-rw-r--r--Source/WebCore/page/WheelEventTestTrigger.cpp133
-rw-r--r--Source/WebCore/page/WindowBase64.idl4
-rw-r--r--Source/WebCore/page/WindowEventHandlers.idl52
-rw-r--r--Source/WebCore/page/WindowFeatures.cpp290
-rw-r--r--Source/WebCore/page/WindowFeatures.h66
-rw-r--r--Source/WebCore/page/WindowFocusAllowedIndicator.cpp2
-rw-r--r--Source/WebCore/page/WindowFocusAllowedIndicator.h2
-rw-r--r--Source/WebCore/page/WindowTimers.idl4
-rw-r--r--Source/WebCore/page/WorkerNavigator.cpp4
-rw-r--r--Source/WebCore/page/WorkerNavigator.h6
-rw-r--r--Source/WebCore/page/WorkerNavigator.idl3
-rw-r--r--Source/WebCore/page/animation/AnimationBase.cpp528
-rw-r--r--Source/WebCore/page/animation/AnimationBase.h188
-rw-r--r--Source/WebCore/page/animation/AnimationController.cpp345
-rw-r--r--Source/WebCore/page/animation/AnimationController.h46
-rw-r--r--Source/WebCore/page/animation/AnimationControllerPrivate.h52
-rw-r--r--Source/WebCore/page/animation/CSSPropertyAnimation.cpp482
-rw-r--r--Source/WebCore/page/animation/CSSPropertyAnimation.h4
-rw-r--r--Source/WebCore/page/animation/CompositeAnimation.cpp375
-rw-r--r--Source/WebCore/page/animation/CompositeAnimation.h27
-rw-r--r--Source/WebCore/page/animation/ImplicitAnimation.cpp136
-rw-r--r--Source/WebCore/page/animation/ImplicitAnimation.h26
-rw-r--r--Source/WebCore/page/animation/KeyframeAnimation.cpp269
-rw-r--r--Source/WebCore/page/animation/KeyframeAnimation.h30
-rw-r--r--Source/WebCore/page/csp/ContentSecurityPolicy.cpp525
-rw-r--r--Source/WebCore/page/csp/ContentSecurityPolicy.h159
-rw-r--r--Source/WebCore/page/csp/ContentSecurityPolicyDirectiveList.cpp624
-rw-r--r--Source/WebCore/page/csp/ContentSecurityPolicyDirectiveList.h136
-rw-r--r--Source/WebCore/page/csp/ContentSecurityPolicyMediaListDirective.cpp117
-rw-r--r--Source/WebCore/page/csp/ContentSecurityPolicyResponseHeaders.cpp62
-rw-r--r--Source/WebCore/page/csp/ContentSecurityPolicyResponseHeaders.h60
-rw-r--r--Source/WebCore/page/csp/ContentSecurityPolicySource.cpp108
-rw-r--r--Source/WebCore/page/csp/ContentSecurityPolicySource.h62
-rw-r--r--Source/WebCore/page/csp/ContentSecurityPolicySourceList.cpp388
-rw-r--r--Source/WebCore/page/csp/ContentSecurityPolicySourceList.h71
-rw-r--r--Source/WebCore/page/csp/ContentSecurityPolicySourceListDirective.h51
-rw-r--r--Source/WebCore/page/gtk/DragControllerGtk.cpp25
-rw-r--r--Source/WebCore/page/gtk/EventHandlerGtk.cpp35
-rwxr-xr-xSource/WebCore/page/make_settings.pl15
-rw-r--r--Source/WebCore/page/scrolling/AsyncScrollingCoordinator.cpp631
-rw-r--r--Source/WebCore/page/scrolling/AsyncScrollingCoordinator.h172
-rw-r--r--Source/WebCore/page/scrolling/AxisScrollSnapOffsets.cpp205
-rw-r--r--Source/WebCore/page/scrolling/AxisScrollSnapOffsets.h89
-rw-r--r--Source/WebCore/page/scrolling/ScrollLatchingState.cpp73
-rw-r--r--Source/WebCore/page/scrolling/ScrollLatchingState.h73
-rw-r--r--Source/WebCore/page/scrolling/ScrollingConstraints.cpp18
-rw-r--r--Source/WebCore/page/scrolling/ScrollingConstraints.h12
-rw-r--r--Source/WebCore/page/scrolling/ScrollingCoordinator.cpp326
-rw-r--r--Source/WebCore/page/scrolling/ScrollingCoordinator.h126
-rw-r--r--Source/WebCore/page/scrolling/ScrollingStateFixedNode.cpp9
-rw-r--r--Source/WebCore/page/scrolling/ScrollingStateFixedNode.h10
-rw-r--r--Source/WebCore/page/scrolling/ScrollingStateFrameScrollingNode.cpp259
-rw-r--r--Source/WebCore/page/scrolling/ScrollingStateFrameScrollingNode.h158
-rw-r--r--Source/WebCore/page/scrolling/ScrollingStateNode.cpp56
-rw-r--r--Source/WebCore/page/scrolling/ScrollingStateNode.h87
-rw-r--r--Source/WebCore/page/scrolling/ScrollingStateOverflowScrollingNode.cpp85
-rw-r--r--Source/WebCore/page/scrolling/ScrollingStateOverflowScrollingNode.h66
-rw-r--r--Source/WebCore/page/scrolling/ScrollingStateScrollingNode.cpp221
-rw-r--r--Source/WebCore/page/scrolling/ScrollingStateScrollingNode.h156
-rw-r--r--Source/WebCore/page/scrolling/ScrollingStateStickyNode.cpp134
-rw-r--r--Source/WebCore/page/scrolling/ScrollingStateStickyNode.h72
-rw-r--r--Source/WebCore/page/scrolling/ScrollingStateTree.cpp168
-rw-r--r--Source/WebCore/page/scrolling/ScrollingStateTree.h52
-rw-r--r--Source/WebCore/page/scrolling/ScrollingThread.cpp120
-rw-r--r--Source/WebCore/page/scrolling/ScrollingThread.h95
-rw-r--r--Source/WebCore/page/scrolling/ScrollingTree.cpp376
-rw-r--r--Source/WebCore/page/scrolling/ScrollingTree.h196
-rw-r--r--Source/WebCore/page/scrolling/ScrollingTreeFrameScrollingNode.cpp96
-rw-r--r--Source/WebCore/page/scrolling/ScrollingTreeFrameScrollingNode.h93
-rw-r--r--Source/WebCore/page/scrolling/ScrollingTreeNode.cpp77
-rw-r--r--Source/WebCore/page/scrolling/ScrollingTreeNode.h94
-rw-r--r--Source/WebCore/page/scrolling/ScrollingTreeOverflowScrollingNode.cpp47
-rw-r--r--Source/WebCore/page/scrolling/ScrollingTreeOverflowScrollingNode.h50
-rw-r--r--Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.cpp130
-rw-r--r--Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.h118
-rw-r--r--Source/WebCore/page/scrolling/ThreadedScrollingTree.cpp174
-rw-r--r--Source/WebCore/page/scrolling/ThreadedScrollingTree.h83
-rw-r--r--Source/WebCore/page/scrolling/coordinatedgraphics/ScrollingCoordinatorCoordinatedGraphics.cpp126
-rw-r--r--Source/WebCore/page/scrolling/coordinatedgraphics/ScrollingCoordinatorCoordinatedGraphics.h63
297 files changed, 12414 insertions, 23457 deletions
diff --git a/Source/WebCore/page/AbstractView.idl b/Source/WebCore/page/AbstractView.idl
index 2d2ec15bf..4c39566ea 100644
--- a/Source/WebCore/page/AbstractView.idl
+++ b/Source/WebCore/page/AbstractView.idl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006 Apple Inc. All rights reserved.
+ * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
* Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
*
* Redistribution and use in source and binary forms, with or without
@@ -11,10 +11,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
diff --git a/Source/WebCore/page/AlternativeTextClient.h b/Source/WebCore/page/AlternativeTextClient.h
index 3a1c3e93a..a7e991d03 100644
--- a/Source/WebCore/page/AlternativeTextClient.h
+++ b/Source/WebCore/page/AlternativeTextClient.h
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -31,10 +31,10 @@
#include <wtf/Vector.h>
#include <wtf/text/WTFString.h>
-#if PLATFORM(MAC)
+#if !PLATFORM(IOS) && PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1080
// Some platforms provide UI for suggesting alternative dictation text.
-#define USE_DICTATION_ALTERNATIVES 1
-#endif // PLATFORM(MAC)
+#define WTF_USE_DICTATION_ALTERNATIVES 1
+#endif // !PLATFORM(IOS) && PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1080
namespace WebCore {
diff --git a/Source/WebCore/page/AutoscrollController.cpp b/Source/WebCore/page/AutoscrollController.cpp
index b5896700b..aec9affe5 100644
--- a/Source/WebCore/page/AutoscrollController.cpp
+++ b/Source/WebCore/page/AutoscrollController.cpp
@@ -12,10 +12,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -42,7 +42,7 @@
namespace WebCore {
// Delay time in second for start autoscroll if pointer is in border edge of scrollable element.
-static const double autoscrollDelay = 0.2;
+static double autoscrollDelay = 0.2;
// When the autoscroll or the panScroll is triggered when do the scroll every 0.05s to make it smooth
static const double autoscrollInterval = 0.05;
@@ -56,8 +56,8 @@ static Frame* getMainFrame(Frame* frame)
#endif
AutoscrollController::AutoscrollController()
- : m_autoscrollTimer(*this, &AutoscrollController::autoscrollTimerFired)
- , m_autoscrollRenderer(nullptr)
+ : m_autoscrollTimer(this, &AutoscrollController::autoscrollTimerFired)
+ , m_autoscrollRenderer(0)
, m_autoscrollType(NoAutoscroll)
, m_dragAndDropAutoscrollStartTime(0)
{
@@ -90,7 +90,7 @@ void AutoscrollController::stopAutoscrollTimer(bool rendererIsBeingDestroyed)
{
RenderBox* scrollable = m_autoscrollRenderer;
m_autoscrollTimer.stop();
- m_autoscrollRenderer = nullptr;
+ m_autoscrollRenderer = 0;
if (!scrollable)
return;
@@ -135,9 +135,9 @@ void AutoscrollController::updateAutoscrollRenderer()
renderer = nodeAtPoint->renderer();
#endif
- while (renderer && !(is<RenderBox>(*renderer) && downcast<RenderBox>(*renderer).canAutoscroll()))
+ while (renderer && !(renderer->isBox() && toRenderBox(renderer)->canAutoscroll()))
renderer = renderer->parent();
- m_autoscrollRenderer = is<RenderBox>(renderer) ? downcast<RenderBox>(renderer) : nullptr;
+ m_autoscrollRenderer = renderer && renderer->isBox() ? toRenderBox(renderer) : 0;
}
void AutoscrollController::updateDragAndDrop(Node* dropTargetNode, const IntPoint& eventPosition, double eventTime)
@@ -231,7 +231,7 @@ bool AutoscrollController::panScrollInProgress() const
}
#endif
-void AutoscrollController::autoscrollTimerFired()
+void AutoscrollController::autoscrollTimerFired(Timer<AutoscrollController>&)
{
if (!m_autoscrollRenderer) {
stopAutoscrollTimer();
diff --git a/Source/WebCore/page/AutoscrollController.h b/Source/WebCore/page/AutoscrollController.h
index 20e709cc0..2c34cb62a 100644
--- a/Source/WebCore/page/AutoscrollController.h
+++ b/Source/WebCore/page/AutoscrollController.h
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -69,13 +69,13 @@ public:
#endif
private:
- void autoscrollTimerFired();
+ void autoscrollTimerFired(Timer<AutoscrollController>&);
void startAutoscrollTimer();
#if ENABLE(PAN_SCROLLING)
void updatePanScrollState(FrameView*, const IntPoint&);
#endif
- Timer m_autoscrollTimer;
+ Timer<AutoscrollController> m_autoscrollTimer;
RenderBox* m_autoscrollRenderer;
AutoscrollType m_autoscrollType;
IntPoint m_dragAndDropAutoscrollReferencePosition;
diff --git a/Source/WebCore/page/BarProp.cpp b/Source/WebCore/page/BarProp.cpp
index 9446634e3..3be4fb397 100644
--- a/Source/WebCore/page/BarProp.cpp
+++ b/Source/WebCore/page/BarProp.cpp
@@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Inc. ("Apple") nor the names of
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
diff --git a/Source/WebCore/page/BarProp.h b/Source/WebCore/page/BarProp.h
index 03d71bf41..36830ea6a 100644
--- a/Source/WebCore/page/BarProp.h
+++ b/Source/WebCore/page/BarProp.h
@@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Inc. ("Apple") nor the names of
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
@@ -31,7 +31,7 @@
#include "DOMWindowProperty.h"
#include "ScriptWrappable.h"
-#include <wtf/Ref.h>
+#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
namespace WebCore {
@@ -42,7 +42,7 @@ class BarProp : public ScriptWrappable, public RefCounted<BarProp>, public DOMWi
public:
enum Type { Locationbar, Menubar, Personalbar, Scrollbars, Statusbar, Toolbar };
- static Ref<BarProp> create(Frame* frame, Type type) { return adoptRef(*new BarProp(frame, type)); }
+ static PassRefPtr<BarProp> create(Frame* frame, Type type) { return adoptRef(new BarProp(frame, type)); }
Type type() const;
bool visible() const;
diff --git a/Source/WebCore/page/BarProp.idl b/Source/WebCore/page/BarProp.idl
index d7ae23932..188a24f70 100644
--- a/Source/WebCore/page/BarProp.idl
+++ b/Source/WebCore/page/BarProp.idl
@@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Inc. ("Apple") nor the names of
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
diff --git a/Source/WebCore/page/CaptionUserPreferences.cpp b/Source/WebCore/page/CaptionUserPreferences.cpp
index fd754e76d..adb570ea7 100644
--- a/Source/WebCore/page/CaptionUserPreferences.cpp
+++ b/Source/WebCore/page/CaptionUserPreferences.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -24,30 +24,23 @@
*/
#include "config.h"
-#include "CaptionUserPreferences.h"
#if ENABLE(VIDEO_TRACK)
-#include "AudioTrackList.h"
+#include "CaptionUserPreferences.h"
#include "DOMWrapperWorld.h"
#include "Page.h"
#include "PageGroup.h"
#include "Settings.h"
#include "TextTrackList.h"
-#include "UserContentController.h"
-#include "UserContentTypes.h"
-#include "UserStyleSheet.h"
#include "UserStyleSheetTypes.h"
-#include <runtime/JSCellInlines.h>
-#include <runtime/StructureInlines.h>
-#include <wtf/NeverDestroyed.h>
namespace WebCore {
CaptionUserPreferences::CaptionUserPreferences(PageGroup& group)
: m_pageGroup(group)
, m_displayMode(ForcedOnly)
- , m_timer(*this, &CaptionUserPreferences::timerFired)
+ , m_timer(this, &CaptionUserPreferences::timerFired)
, m_testingMode(false)
, m_havePreferences(false)
{
@@ -57,27 +50,13 @@ CaptionUserPreferences::~CaptionUserPreferences()
{
}
-void CaptionUserPreferences::timerFired()
+void CaptionUserPreferences::timerFired(Timer<CaptionUserPreferences>&)
{
captionPreferencesChanged();
}
-void CaptionUserPreferences::beginBlockingNotifications()
-{
- ++m_blockNotificationsCounter;
-}
-
-void CaptionUserPreferences::endBlockingNotifications()
-{
- ASSERT(m_blockNotificationsCounter);
- --m_blockNotificationsCounter;
-}
-
void CaptionUserPreferences::notify()
{
- if (m_blockNotificationsCounter)
- return;
-
m_havePreferences = true;
if (!m_timer.isActive())
m_timer.startOneShot(0);
@@ -175,20 +154,6 @@ void CaptionUserPreferences::setPreferredLanguage(const String& language)
notify();
}
-void CaptionUserPreferences::setPreferredAudioCharacteristic(const String& characteristic)
-{
- m_userPreferredAudioCharacteristic = characteristic;
- notify();
-}
-
-Vector<String> CaptionUserPreferences::preferredAudioCharacteristics() const
-{
- Vector<String> characteristics;
- if (!m_userPreferredAudioCharacteristic.isEmpty())
- characteristics.append(m_userPreferredAudioCharacteristic);
- return characteristics;
-}
-
static String trackDisplayName(TextTrack* track)
{
if (track == TextTrack::captionMenuOffItem())
@@ -231,47 +196,22 @@ Vector<RefPtr<TextTrack>> CaptionUserPreferences::sortedTrackListForMenu(TextTra
return tracksForMenu;
}
-static String trackDisplayName(AudioTrack* track)
-{
- if (track->label().isEmpty() && track->language().isEmpty())
- return audioTrackNoLabelText();
- if (!track->label().isEmpty())
- return track->label();
- return track->language();
-}
-
-String CaptionUserPreferences::displayNameForTrack(AudioTrack* track) const
-{
- return trackDisplayName(track);
-}
-
-Vector<RefPtr<AudioTrack>> CaptionUserPreferences::sortedTrackListForMenu(AudioTrackList* trackList)
-{
- ASSERT(trackList);
-
- Vector<RefPtr<AudioTrack>> tracksForMenu;
-
- for (unsigned i = 0, length = trackList->length(); i < length; ++i) {
- AudioTrack* track = trackList->item(i);
- tracksForMenu.append(track);
- }
-
- std::sort(tracksForMenu.begin(), tracksForMenu.end(), [](const RefPtr<AudioTrack>& a, const RefPtr<AudioTrack>& b) {
- return codePointCompare(trackDisplayName(a.get()), trackDisplayName(b.get())) < 0;
- });
-
- return tracksForMenu;
-}
-
int CaptionUserPreferences::textTrackSelectionScore(TextTrack* track, HTMLMediaElement*) const
{
+ int trackScore = 0;
+
if (track->kind() != TextTrack::captionsKeyword() && track->kind() != TextTrack::subtitlesKeyword())
- return 0;
+ return trackScore;
if (!userPrefersSubtitles() && !userPrefersCaptions())
- return 0;
+ return trackScore;
+
+ if (track->kind() == TextTrack::subtitlesKeyword() && userPrefersSubtitles())
+ trackScore = 1;
+ else if (track->kind() == TextTrack::captionsKeyword() && userPrefersCaptions())
+ trackScore = 1;
- return textTrackLanguageSelectionScore(track, preferredLanguages()) + 1;
+ return trackScore + textTrackLanguageSelectionScore(track, preferredLanguages());
}
int CaptionUserPreferences::textTrackLanguageSelectionScore(TextTrack* track, const Vector<String>& preferredLanguages) const
@@ -279,15 +219,13 @@ int CaptionUserPreferences::textTrackLanguageSelectionScore(TextTrack* track, co
if (track->language().isEmpty())
return 0;
- bool exactMatch;
- size_t languageMatchIndex = indexOfBestMatchingLanguageInList(track->language(), preferredLanguages, exactMatch);
+ size_t languageMatchIndex = indexOfBestMatchingLanguageInList(track->language(), preferredLanguages);
if (languageMatchIndex >= preferredLanguages.size())
return 0;
// Matching a track language is more important than matching track type, so this multiplier must be
// greater than the maximum value returned by textTrackSelectionScore.
- int bonus = exactMatch ? 1 : 0;
- return (preferredLanguages.size() + bonus - languageMatchIndex) * 10;
+ return (preferredLanguages.size() - languageMatchIndex) * 10;
}
void CaptionUserPreferences::setCaptionsStyleSheetOverride(const String& override)
@@ -299,24 +237,16 @@ void CaptionUserPreferences::setCaptionsStyleSheetOverride(const String& overrid
void CaptionUserPreferences::updateCaptionStyleSheetOveride()
{
// Identify our override style sheet with a unique URL - a new scheme and a UUID.
- static NeverDestroyed<URL> captionsStyleSheetURL(ParsedURLString, "user-captions-override:01F6AF12-C3B0-4F70-AF5E-A3E00234DC23");
+ DEFINE_STATIC_LOCAL(URL, captionsStyleSheetURL, (ParsedURLString, "user-captions-override:01F6AF12-C3B0-4F70-AF5E-A3E00234DC23"));
- auto& pages = m_pageGroup.pages();
- for (auto& page : pages) {
- if (auto* pageUserContentController = page->userContentController())
- pageUserContentController->removeUserStyleSheet(mainThreadNormalWorld(), captionsStyleSheetURL);
- }
+ m_pageGroup.removeUserStyleSheetFromWorld(mainThreadNormalWorld(), captionsStyleSheetURL);
String captionsOverrideStyleSheet = captionsStyleSheetOverride();
if (captionsOverrideStyleSheet.isEmpty())
return;
- for (auto& page : pages) {
- if (auto* pageUserContentController = page->userContentController()) {
- auto userStyleSheet = std::make_unique<UserStyleSheet>(captionsOverrideStyleSheet, captionsStyleSheetURL, Vector<String>(), Vector<String>(), InjectInAllFrames, UserStyleAuthorLevel);
- pageUserContentController->addUserStyleSheet(mainThreadNormalWorld(), WTFMove(userStyleSheet), InjectInExistingDocuments);
- }
- }
+ m_pageGroup.addUserStyleSheetToWorld(mainThreadNormalWorld(), captionsOverrideStyleSheet, captionsStyleSheetURL, Vector<String>(),
+ Vector<String>(), InjectInAllFrames, UserStyleAuthorLevel, InjectInExistingDocuments);
}
String CaptionUserPreferences::primaryAudioTrackLanguageOverride() const
diff --git a/Source/WebCore/page/CaptionUserPreferences.h b/Source/WebCore/page/CaptionUserPreferences.h
index 8b08bbb41..3e5a3b9c4 100644
--- a/Source/WebCore/page/CaptionUserPreferences.h
+++ b/Source/WebCore/page/CaptionUserPreferences.h
@@ -28,18 +28,17 @@
#if ENABLE(VIDEO_TRACK)
-#include "AudioTrack.h"
#include "Language.h"
#include "LocalizedStrings.h"
#include "TextTrack.h"
#include "Timer.h"
+#include <wtf/PassOwnPtr.h>
#include <wtf/text/AtomicString.h>
namespace WebCore {
class HTMLMediaElement;
class PageGroup;
-class AudioTrackList;
class TextTrackList;
class CaptionUserPreferences {
@@ -50,8 +49,7 @@ public:
enum CaptionDisplayMode {
Automatic,
ForcedOnly,
- AlwaysOn,
- Manual,
+ AlwaysOn
};
virtual CaptionDisplayMode captionDisplayMode() const;
virtual void setCaptionDisplayMode(CaptionDisplayMode);
@@ -80,15 +78,9 @@ public:
virtual void setPreferredLanguage(const String&);
virtual Vector<String> preferredLanguages() const;
- virtual void setPreferredAudioCharacteristic(const String&);
- virtual Vector<String> preferredAudioCharacteristics() const;
-
virtual String displayNameForTrack(TextTrack*) const;
virtual Vector<RefPtr<TextTrack>> sortedTrackListForMenu(TextTrackList*);
- virtual String displayNameForTrack(AudioTrack*) const;
- virtual Vector<RefPtr<AudioTrack>> sortedTrackListForMenu(AudioTrackList*);
-
void setPrimaryAudioTrackLanguageOverride(const String& language) { m_primaryAudioTrackLanguageOverride = language; }
String primaryAudioTrackLanguageOverride() const;
@@ -99,21 +91,17 @@ public:
protected:
void updateCaptionStyleSheetOveride();
- void beginBlockingNotifications();
- void endBlockingNotifications();
private:
- void timerFired();
+ void timerFired(Timer<CaptionUserPreferences>&);
void notify();
PageGroup& m_pageGroup;
- mutable CaptionDisplayMode m_displayMode;
- Timer m_timer;
+ CaptionDisplayMode m_displayMode;
+ Timer<CaptionUserPreferences> m_timer;
String m_userPreferredLanguage;
- String m_userPreferredAudioCharacteristic;
String m_captionsStyleSheetOverride;
String m_primaryAudioTrackLanguageOverride;
- unsigned m_blockNotificationsCounter { 0 };
bool m_testingMode;
bool m_havePreferences;
};
diff --git a/Source/WebCore/page/CaptionUserPreferencesMediaAF.cpp b/Source/WebCore/page/CaptionUserPreferencesMediaAF.cpp
deleted file mode 100644
index 54fde9870..000000000
--- a/Source/WebCore/page/CaptionUserPreferencesMediaAF.cpp
+++ /dev/null
@@ -1,956 +0,0 @@
-/*
- * Copyright (C) 2012-2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#if ENABLE(VIDEO_TRACK)
-
-#include "CaptionUserPreferencesMediaAF.h"
-
-#include "AudioTrackList.h"
-#include "FloatConversion.h"
-#include "HTMLMediaElement.h"
-#include "URL.h"
-#include "Language.h"
-#include "LocalizedStrings.h"
-#include "Logging.h"
-#include "MediaControlElements.h"
-#include "SoftLinking.h"
-#include "TextTrackList.h"
-#include "UserStyleSheetTypes.h"
-#include "VTTCue.h"
-#include <wtf/NeverDestroyed.h>
-#include <wtf/RetainPtr.h>
-#include <wtf/text/CString.h>
-#include <wtf/text/StringBuilder.h>
-
-#if PLATFORM(IOS)
-#import "WebCoreThreadRun.h"
-#endif
-
-#if HAVE(MEDIA_ACCESSIBILITY_FRAMEWORK)
-#include <CoreText/CoreText.h>
-#include <MediaAccessibility/MediaAccessibility.h>
-
-#include "MediaAccessibilitySoftLink.h"
-
-#if PLATFORM(WIN)
-
-#ifdef DEBUG_ALL
-#define SOFT_LINK_AVF_FRAMEWORK(Lib) SOFT_LINK_DEBUG_LIBRARY(Lib)
-#else
-#define SOFT_LINK_AVF_FRAMEWORK(Lib) SOFT_LINK_LIBRARY(Lib)
-#endif
-
-#define SOFT_LINK_AVF(Lib, Name, Type) SOFT_LINK_DLL_IMPORT(Lib, Name, Type)
-#define SOFT_LINK_AVF_POINTER(Lib, Name, Type) SOFT_LINK_VARIABLE_DLL_IMPORT_OPTIONAL(Lib, Name, Type)
-#define SOFT_LINK_AVF_FRAMEWORK_IMPORT(Lib, Fun, ReturnType, Arguments, Signature) SOFT_LINK_DLL_IMPORT(Lib, Fun, ReturnType, __cdecl, Arguments, Signature)
-#define SOFT_LINK_AVF_FRAMEWORK_IMPORT_OPTIONAL(Lib, Fun, ReturnType, Arguments) SOFT_LINK_DLL_IMPORT_OPTIONAL(Lib, Fun, ReturnType, __cdecl, Arguments)
-
-// CoreText only needs to be soft-linked on Windows.
-SOFT_LINK_AVF_FRAMEWORK(CoreText)
-SOFT_LINK_AVF_FRAMEWORK_IMPORT(CoreText, CTFontDescriptorCopyAttribute, CFTypeRef, (CTFontDescriptorRef descriptor, CFStringRef attribute), (descriptor, attribute));
-SOFT_LINK_AVF_POINTER(CoreText, kCTFontNameAttribute, CFStringRef)
-#define kCTFontNameAttribute getkCTFontNameAttribute()
-
-#define CTFontDescriptorCopyAttribute softLink_CTFontDescriptorCopyAttribute
-
-SOFT_LINK_AVF_FRAMEWORK(CoreMedia)
-SOFT_LINK_AVF_FRAMEWORK_IMPORT_OPTIONAL(CoreMedia, MTEnableCaption2015Behavior, Boolean, ())
-
-#else
-
-SOFT_LINK_FRAMEWORK(MediaToolbox)
-SOFT_LINK_OPTIONAL(MediaToolbox, MTEnableCaption2015Behavior, Boolean, (), ())
-
-#endif // PLATFORM(WIN)
-
-#endif // HAVE(MEDIA_ACCESSIBILITY_FRAMEWORK)
-
-namespace WebCore {
-
-#if HAVE(MEDIA_ACCESSIBILITY_FRAMEWORK)
-static void userCaptionPreferencesChangedNotificationCallback(CFNotificationCenterRef, void* observer, CFStringRef, const void *, CFDictionaryRef)
-{
-#if !PLATFORM(IOS)
- static_cast<CaptionUserPreferencesMediaAF*>(observer)->captionPreferencesChanged();
-#else
- WebThreadRun(^{
- static_cast<CaptionUserPreferencesMediaAF*>(observer)->captionPreferencesChanged();
- });
-#endif
-}
-#endif
-
-CaptionUserPreferencesMediaAF::CaptionUserPreferencesMediaAF(PageGroup& group)
- : CaptionUserPreferences(group)
-#if HAVE(MEDIA_ACCESSIBILITY_FRAMEWORK)
- , m_updateStyleSheetTimer(*this, &CaptionUserPreferencesMediaAF::updateTimerFired)
- , m_listeningForPreferenceChanges(false)
-#endif
-{
- static bool initialized;
- if (!initialized) {
- initialized = true;
-
- MTEnableCaption2015BehaviorPtrType function = MTEnableCaption2015BehaviorPtr();
- if (!function || !function())
- return;
-
- beginBlockingNotifications();
- CaptionUserPreferences::setCaptionDisplayMode(Manual);
- setUserPrefersCaptions(false);
- setUserPrefersSubtitles(false);
- setUserPrefersTextDescriptions(false);
- endBlockingNotifications();
- }
-}
-
-CaptionUserPreferencesMediaAF::~CaptionUserPreferencesMediaAF()
-{
-#if HAVE(MEDIA_ACCESSIBILITY_FRAMEWORK)
- if (kMAXCaptionAppearanceSettingsChangedNotification)
- CFNotificationCenterRemoveObserver(CFNotificationCenterGetLocalCenter(), this, kMAXCaptionAppearanceSettingsChangedNotification, 0);
- if (kMAAudibleMediaSettingsChangedNotification)
- CFNotificationCenterRemoveObserver(CFNotificationCenterGetLocalCenter(), this, kMAAudibleMediaSettingsChangedNotification, 0);
-#endif
-}
-
-#if HAVE(MEDIA_ACCESSIBILITY_FRAMEWORK)
-
-CaptionUserPreferences::CaptionDisplayMode CaptionUserPreferencesMediaAF::captionDisplayMode() const
-{
- CaptionDisplayMode internalMode = CaptionUserPreferences::captionDisplayMode();
- if (internalMode == Manual || testingMode() || !MediaAccessibilityLibrary())
- return internalMode;
-
- MACaptionAppearanceDisplayType displayType = MACaptionAppearanceGetDisplayType(kMACaptionAppearanceDomainUser);
- switch (displayType) {
- case kMACaptionAppearanceDisplayTypeForcedOnly:
- return ForcedOnly;
-
- case kMACaptionAppearanceDisplayTypeAutomatic:
- return Automatic;
-
- case kMACaptionAppearanceDisplayTypeAlwaysOn:
- return AlwaysOn;
- }
-
- ASSERT_NOT_REACHED();
- return ForcedOnly;
-}
-
-void CaptionUserPreferencesMediaAF::setCaptionDisplayMode(CaptionUserPreferences::CaptionDisplayMode mode)
-{
- if (testingMode() || !MediaAccessibilityLibrary()) {
- CaptionUserPreferences::setCaptionDisplayMode(mode);
- return;
- }
-
- if (captionDisplayMode() == Manual)
- return;
-
- MACaptionAppearanceDisplayType displayType = kMACaptionAppearanceDisplayTypeForcedOnly;
- switch (mode) {
- case Automatic:
- displayType = kMACaptionAppearanceDisplayTypeAutomatic;
- break;
- case ForcedOnly:
- displayType = kMACaptionAppearanceDisplayTypeForcedOnly;
- break;
- case AlwaysOn:
- displayType = kMACaptionAppearanceDisplayTypeAlwaysOn;
- break;
- default:
- ASSERT_NOT_REACHED();
- break;
- }
-
- MACaptionAppearanceSetDisplayType(kMACaptionAppearanceDomainUser, displayType);
-}
-
-bool CaptionUserPreferencesMediaAF::userPrefersCaptions() const
-{
- bool captionSetting = CaptionUserPreferences::userPrefersCaptions();
- if (captionSetting || testingMode() || !MediaAccessibilityLibrary())
- return captionSetting;
-
- RetainPtr<CFArrayRef> captioningMediaCharacteristics = adoptCF(MACaptionAppearanceCopyPreferredCaptioningMediaCharacteristics(kMACaptionAppearanceDomainUser));
- return captioningMediaCharacteristics && CFArrayGetCount(captioningMediaCharacteristics.get());
-}
-
-bool CaptionUserPreferencesMediaAF::userPrefersSubtitles() const
-{
- bool subtitlesSetting = CaptionUserPreferences::userPrefersSubtitles();
- if (subtitlesSetting || testingMode() || !MediaAccessibilityLibrary())
- return subtitlesSetting;
-
- RetainPtr<CFArrayRef> captioningMediaCharacteristics = adoptCF(MACaptionAppearanceCopyPreferredCaptioningMediaCharacteristics(kMACaptionAppearanceDomainUser));
- return !(captioningMediaCharacteristics && CFArrayGetCount(captioningMediaCharacteristics.get()));
-}
-
-void CaptionUserPreferencesMediaAF::updateTimerFired()
-{
- updateCaptionStyleSheetOveride();
-}
-
-void CaptionUserPreferencesMediaAF::setInterestedInCaptionPreferenceChanges()
-{
- if (m_listeningForPreferenceChanges)
- return;
-
- if (!MediaAccessibilityLibrary())
- return;
-
- if (!kMAXCaptionAppearanceSettingsChangedNotification && !canLoad_MediaAccessibility_kMAAudibleMediaSettingsChangedNotification())
- return;
-
- m_listeningForPreferenceChanges = true;
- m_registeringForNotification = true;
-
- if (kMAXCaptionAppearanceSettingsChangedNotification)
- CFNotificationCenterAddObserver(CFNotificationCenterGetLocalCenter(), this, userCaptionPreferencesChangedNotificationCallback, kMAXCaptionAppearanceSettingsChangedNotification, 0, CFNotificationSuspensionBehaviorCoalesce);
- if (canLoad_MediaAccessibility_kMAAudibleMediaSettingsChangedNotification())
- CFNotificationCenterAddObserver(CFNotificationCenterGetLocalCenter(), this, userCaptionPreferencesChangedNotificationCallback, kMAAudibleMediaSettingsChangedNotification, 0, CFNotificationSuspensionBehaviorCoalesce);
- m_registeringForNotification = false;
-
- // Generating and registering the caption stylesheet can be expensive and this method is called indirectly when the parser creates an audio or
- // video element, so do it after a brief pause.
- m_updateStyleSheetTimer.startOneShot(0);
-}
-
-void CaptionUserPreferencesMediaAF::captionPreferencesChanged()
-{
- if (m_registeringForNotification)
- return;
-
- if (m_listeningForPreferenceChanges)
- updateCaptionStyleSheetOveride();
-
- CaptionUserPreferences::captionPreferencesChanged();
-}
-
-String CaptionUserPreferencesMediaAF::captionsWindowCSS() const
-{
- MACaptionAppearanceBehavior behavior;
- RetainPtr<CGColorRef> color = adoptCF(MACaptionAppearanceCopyWindowColor(kMACaptionAppearanceDomainUser, &behavior));
-
- Color windowColor(color.get());
- if (!windowColor.isValid())
- windowColor = Color::transparent;
-
- bool important = behavior == kMACaptionAppearanceBehaviorUseValue;
- CGFloat opacity = MACaptionAppearanceGetWindowOpacity(kMACaptionAppearanceDomainUser, &behavior);
- if (!important)
- important = behavior == kMACaptionAppearanceBehaviorUseValue;
- String windowStyle = colorPropertyCSS(CSSPropertyBackgroundColor, Color(windowColor.red(), windowColor.green(), windowColor.blue(), static_cast<int>(opacity * 255)), important);
-
- if (!opacity)
- return windowStyle;
-
- return makeString(windowStyle, getPropertyNameString(CSSPropertyPadding), ": .4em !important;");
-}
-
-String CaptionUserPreferencesMediaAF::captionsBackgroundCSS() const
-{
- // This default value must be the same as the one specified in mediaControls.css for -webkit-media-text-track-past-nodes
- // and webkit-media-text-track-future-nodes.
- static NeverDestroyed<Color> defaultBackgroundColor(0, 0, 0, 0.8 * 255);
-
- MACaptionAppearanceBehavior behavior;
-
- RetainPtr<CGColorRef> color = adoptCF(MACaptionAppearanceCopyBackgroundColor(kMACaptionAppearanceDomainUser, &behavior));
- Color backgroundColor(color.get());
- if (!backgroundColor.isValid())
- backgroundColor = defaultBackgroundColor;
-
- bool important = behavior == kMACaptionAppearanceBehaviorUseValue;
- CGFloat opacity = MACaptionAppearanceGetBackgroundOpacity(kMACaptionAppearanceDomainUser, &behavior);
- if (!important)
- important = behavior == kMACaptionAppearanceBehaviorUseValue;
- return colorPropertyCSS(CSSPropertyBackgroundColor, Color(backgroundColor.red(), backgroundColor.green(), backgroundColor.blue(), static_cast<int>(opacity * 255)), important);
-}
-
-Color CaptionUserPreferencesMediaAF::captionsTextColor(bool& important) const
-{
- MACaptionAppearanceBehavior behavior;
- RetainPtr<CGColorRef> color = adoptCF(MACaptionAppearanceCopyForegroundColor(kMACaptionAppearanceDomainUser, &behavior));
- Color textColor(color.get());
- if (!textColor.isValid())
- // This default value must be the same as the one specified in mediaControls.css for -webkit-media-text-track-container.
- textColor = Color::white;
-
- important = behavior == kMACaptionAppearanceBehaviorUseValue;
- CGFloat opacity = MACaptionAppearanceGetForegroundOpacity(kMACaptionAppearanceDomainUser, &behavior);
- if (!important)
- important = behavior == kMACaptionAppearanceBehaviorUseValue;
- return Color(textColor.red(), textColor.green(), textColor.blue(), static_cast<int>(opacity * 255));
-}
-
-String CaptionUserPreferencesMediaAF::captionsTextColorCSS() const
-{
- bool important;
- Color textColor = captionsTextColor(important);
-
- if (!textColor.isValid())
- return emptyString();
-
- return colorPropertyCSS(CSSPropertyColor, textColor, important);
-}
-
-String CaptionUserPreferencesMediaAF::windowRoundedCornerRadiusCSS() const
-{
- MACaptionAppearanceBehavior behavior;
- CGFloat radius = MACaptionAppearanceGetWindowRoundedCornerRadius(kMACaptionAppearanceDomainUser, &behavior);
- if (!radius)
- return emptyString();
-
- StringBuilder builder;
- builder.append(getPropertyNameString(CSSPropertyBorderRadius));
- builder.append(String::format(":%.02fpx", radius));
- if (behavior == kMACaptionAppearanceBehaviorUseValue)
- builder.appendLiteral(" !important");
- builder.append(';');
-
- return builder.toString();
-}
-
-Color CaptionUserPreferencesMediaAF::captionsEdgeColorForTextColor(const Color& textColor) const
-{
- int distanceFromWhite = differenceSquared(textColor, Color::white);
- int distanceFromBlack = differenceSquared(textColor, Color::black);
-
- if (distanceFromWhite < distanceFromBlack)
- return textColor.dark();
-
- return textColor.light();
-}
-
-String CaptionUserPreferencesMediaAF::cssPropertyWithTextEdgeColor(CSSPropertyID id, const String& value, const Color& textColor, bool important) const
-{
- StringBuilder builder;
-
- builder.append(getPropertyNameString(id));
- builder.append(':');
- builder.append(value);
- builder.append(' ');
- builder.append(captionsEdgeColorForTextColor(textColor).serialized());
- if (important)
- builder.appendLiteral(" !important");
- builder.append(';');
-
- return builder.toString();
-}
-
-String CaptionUserPreferencesMediaAF::colorPropertyCSS(CSSPropertyID id, const Color& color, bool important) const
-{
- StringBuilder builder;
-
- builder.append(getPropertyNameString(id));
- builder.append(':');
- builder.append(color.serialized());
- if (important)
- builder.appendLiteral(" !important");
- builder.append(';');
-
- return builder.toString();
-}
-
-String CaptionUserPreferencesMediaAF::captionsTextEdgeCSS() const
-{
- static NeverDestroyed<const String> edgeStyleRaised(ASCIILiteral(" -.05em -.05em 0 "));
- static NeverDestroyed<const String> edgeStyleDepressed(ASCIILiteral(" .05em .05em 0 "));
- static NeverDestroyed<const String> edgeStyleDropShadow(ASCIILiteral(" .075em .075em 0 "));
- static NeverDestroyed<const String> edgeStyleUniform(ASCIILiteral(" .03em "));
-
- bool unused;
- Color color = captionsTextColor(unused);
- if (!color.isValid())
- color.setNamedColor("black");
- color = captionsEdgeColorForTextColor(color);
-
- MACaptionAppearanceBehavior behavior;
- MACaptionAppearanceTextEdgeStyle textEdgeStyle = MACaptionAppearanceGetTextEdgeStyle(kMACaptionAppearanceDomainUser, &behavior);
- switch (textEdgeStyle) {
- case kMACaptionAppearanceTextEdgeStyleUndefined:
- case kMACaptionAppearanceTextEdgeStyleNone:
- return emptyString();
-
- case kMACaptionAppearanceTextEdgeStyleRaised:
- return cssPropertyWithTextEdgeColor(CSSPropertyTextShadow, edgeStyleRaised, color, behavior == kMACaptionAppearanceBehaviorUseValue);
- case kMACaptionAppearanceTextEdgeStyleDepressed:
- return cssPropertyWithTextEdgeColor(CSSPropertyTextShadow, edgeStyleDepressed, color, behavior == kMACaptionAppearanceBehaviorUseValue);
- case kMACaptionAppearanceTextEdgeStyleDropShadow:
- return cssPropertyWithTextEdgeColor(CSSPropertyTextShadow, edgeStyleDropShadow, color, behavior == kMACaptionAppearanceBehaviorUseValue);
- case kMACaptionAppearanceTextEdgeStyleUniform:
- return cssPropertyWithTextEdgeColor(CSSPropertyWebkitTextStroke, edgeStyleUniform, color, behavior == kMACaptionAppearanceBehaviorUseValue);
-
- default:
- ASSERT_NOT_REACHED();
- break;
- }
-
- return emptyString();
-}
-
-String CaptionUserPreferencesMediaAF::captionsDefaultFontCSS() const
-{
- MACaptionAppearanceBehavior behavior;
-
- RetainPtr<CTFontDescriptorRef> font = adoptCF(MACaptionAppearanceCopyFontDescriptorForStyle(kMACaptionAppearanceDomainUser, &behavior, kMACaptionAppearanceFontStyleDefault));
- if (!font)
- return emptyString();
-
- RetainPtr<CFTypeRef> name = adoptCF(CTFontDescriptorCopyAttribute(font.get(), kCTFontNameAttribute));
- if (!name)
- return emptyString();
-
- StringBuilder builder;
-
- builder.append(getPropertyNameString(CSSPropertyFontFamily));
- builder.appendLiteral(": \"");
- builder.append(static_cast<CFStringRef>(name.get()));
- builder.append('"');
- if (behavior == kMACaptionAppearanceBehaviorUseValue)
- builder.appendLiteral(" !important");
- builder.append(';');
-
- return builder.toString();
-}
-
-float CaptionUserPreferencesMediaAF::captionFontSizeScaleAndImportance(bool& important) const
-{
- if (testingMode() || !MediaAccessibilityLibrary())
- return CaptionUserPreferences::captionFontSizeScaleAndImportance(important);
-
- MACaptionAppearanceBehavior behavior;
- CGFloat characterScale = CaptionUserPreferences::captionFontSizeScaleAndImportance(important);
- CGFloat scaleAdjustment = MACaptionAppearanceGetRelativeCharacterSize(kMACaptionAppearanceDomainUser, &behavior);
-
- if (!scaleAdjustment)
- return characterScale;
-
- important = behavior == kMACaptionAppearanceBehaviorUseValue;
-#if defined(__LP64__) && __LP64__
- return narrowPrecisionToFloat(scaleAdjustment * characterScale);
-#else
- return scaleAdjustment * characterScale;
-#endif
-}
-
-void CaptionUserPreferencesMediaAF::setPreferredLanguage(const String& language)
-{
- if (CaptionUserPreferences::captionDisplayMode() == Manual)
- return;
-
- if (testingMode() || !MediaAccessibilityLibrary()) {
- CaptionUserPreferences::setPreferredLanguage(language);
- return;
- }
-
- MACaptionAppearanceAddSelectedLanguage(kMACaptionAppearanceDomainUser, language.createCFString().get());
-}
-
-Vector<String> CaptionUserPreferencesMediaAF::preferredLanguages() const
-{
- if (testingMode() || !MediaAccessibilityLibrary())
- return CaptionUserPreferences::preferredLanguages();
-
- Vector<String> platformLanguages = platformUserPreferredLanguages();
- Vector<String> override = userPreferredLanguagesOverride();
- if (!override.isEmpty()) {
- if (platformLanguages.size() != override.size())
- return override;
- for (size_t i = 0; i < override.size(); i++) {
- if (override[i] != platformLanguages[i])
- return override;
- }
- }
-
- CFIndex languageCount = 0;
- RetainPtr<CFArrayRef> languages = adoptCF(MACaptionAppearanceCopySelectedLanguages(kMACaptionAppearanceDomainUser));
- if (languages)
- languageCount = CFArrayGetCount(languages.get());
-
- if (!languageCount)
- return CaptionUserPreferences::preferredLanguages();
-
- Vector<String> userPreferredLanguages;
- userPreferredLanguages.reserveCapacity(languageCount + platformLanguages.size());
- for (CFIndex i = 0; i < languageCount; i++)
- userPreferredLanguages.append(static_cast<CFStringRef>(CFArrayGetValueAtIndex(languages.get(), i)));
-
- userPreferredLanguages.appendVector(platformLanguages);
-
- return userPreferredLanguages;
-}
-
-void CaptionUserPreferencesMediaAF::setPreferredAudioCharacteristic(const String& characteristic)
-{
- if (testingMode() || !MediaAccessibilityLibrary())
- CaptionUserPreferences::setPreferredAudioCharacteristic(characteristic);
-}
-
-Vector<String> CaptionUserPreferencesMediaAF::preferredAudioCharacteristics() const
-{
- if (testingMode() || !MediaAccessibilityLibrary() || !canLoad_MediaAccessibility_MAAudibleMediaCopyPreferredCharacteristics())
- return CaptionUserPreferences::preferredAudioCharacteristics();
-
- CFIndex characteristicCount = 0;
- RetainPtr<CFArrayRef> characteristics = adoptCF(MAAudibleMediaCopyPreferredCharacteristics());
- if (characteristics)
- characteristicCount = CFArrayGetCount(characteristics.get());
-
- if (!characteristicCount)
- return CaptionUserPreferences::preferredAudioCharacteristics();
-
- Vector<String> userPreferredAudioCharacteristics;
- userPreferredAudioCharacteristics.reserveCapacity(characteristicCount);
- for (CFIndex i = 0; i < characteristicCount; i++)
- userPreferredAudioCharacteristics.append(static_cast<CFStringRef>(CFArrayGetValueAtIndex(characteristics.get(), i)));
-
- return userPreferredAudioCharacteristics;
-}
-#endif // HAVE(MEDIA_ACCESSIBILITY_FRAMEWORK)
-
-String CaptionUserPreferencesMediaAF::captionsStyleSheetOverride() const
-{
- if (testingMode())
- return CaptionUserPreferences::captionsStyleSheetOverride();
-
- StringBuilder captionsOverrideStyleSheet;
-
-#if HAVE(MEDIA_ACCESSIBILITY_FRAMEWORK)
- if (!MediaAccessibilityLibrary())
- return CaptionUserPreferences::captionsStyleSheetOverride();
-
- String captionsColor = captionsTextColorCSS();
- String edgeStyle = captionsTextEdgeCSS();
- String fontName = captionsDefaultFontCSS();
- String background = captionsBackgroundCSS();
- if (!background.isEmpty() || !captionsColor.isEmpty() || !edgeStyle.isEmpty() || !fontName.isEmpty()) {
- captionsOverrideStyleSheet.appendLiteral(" video::");
- captionsOverrideStyleSheet.append(TextTrackCue::cueShadowPseudoId());
- captionsOverrideStyleSheet.append('{');
-
- if (!background.isEmpty())
- captionsOverrideStyleSheet.append(background);
- if (!captionsColor.isEmpty())
- captionsOverrideStyleSheet.append(captionsColor);
- if (!edgeStyle.isEmpty())
- captionsOverrideStyleSheet.append(edgeStyle);
- if (!fontName.isEmpty())
- captionsOverrideStyleSheet.append(fontName);
-
- captionsOverrideStyleSheet.append('}');
- }
-
- String windowColor = captionsWindowCSS();
- String windowCornerRadius = windowRoundedCornerRadiusCSS();
- if (!windowColor.isEmpty() || !windowCornerRadius.isEmpty()) {
- captionsOverrideStyleSheet.appendLiteral(" video::");
- captionsOverrideStyleSheet.append(VTTCue::cueBackdropShadowPseudoId());
- captionsOverrideStyleSheet.append('{');
-
- if (!windowColor.isEmpty())
- captionsOverrideStyleSheet.append(windowColor);
- if (!windowCornerRadius.isEmpty()) {
- captionsOverrideStyleSheet.append(windowCornerRadius);
- }
-
- captionsOverrideStyleSheet.append('}');
- }
-#endif // HAVE(MEDIA_ACCESSIBILITY_FRAMEWORK)
-
- LOG(Media, "CaptionUserPreferencesMediaAF::captionsStyleSheetOverrideSetting sytle to:\n%s", captionsOverrideStyleSheet.toString().utf8().data());
-
- return captionsOverrideStyleSheet.toString();
-}
-
-static String languageIdentifier(const String& languageCode)
-{
- if (languageCode.isEmpty())
- return languageCode;
-
- String lowercaseLanguageCode = languageCode.convertToASCIILowercase();
-
- // Need 2U here to disambiguate String::operator[] from operator(NSString*, int)[] in a production build.
- if (lowercaseLanguageCode.length() >= 3 && (lowercaseLanguageCode[2U] == '_' || lowercaseLanguageCode[2U] == '-'))
- lowercaseLanguageCode.truncate(2);
-
- return lowercaseLanguageCode;
-}
-
-static void buildDisplayStringForTrackBase(StringBuilder& displayName, const TrackBase& track)
-{
- String label = track.label();
- String trackLanguageIdentifier = track.language();
-
- RetainPtr<CFLocaleRef> currentLocale = adoptCF(CFLocaleCreate(kCFAllocatorDefault, defaultLanguage().createCFString().get()));
- RetainPtr<CFStringRef> localeIdentifier = adoptCF(CFLocaleCreateCanonicalLocaleIdentifierFromString(kCFAllocatorDefault, trackLanguageIdentifier.createCFString().get()));
- RetainPtr<CFStringRef> languageCF = adoptCF(CFLocaleCopyDisplayNameForPropertyValue(currentLocale.get(), kCFLocaleLanguageCode, localeIdentifier.get()));
- String language = languageCF.get();
-
- if (!label.isEmpty()) {
- if (language.isEmpty() || label.contains(language))
- displayName.append(label);
- else {
- RetainPtr<CFDictionaryRef> localeDict = adoptCF(CFLocaleCreateComponentsFromLocaleIdentifier(kCFAllocatorDefault, localeIdentifier.get()));
- if (localeDict) {
- CFStringRef countryCode = 0;
- String countryName;
-
- CFDictionaryGetValueIfPresent(localeDict.get(), kCFLocaleCountryCode, (const void **)&countryCode);
- if (countryCode) {
- RetainPtr<CFStringRef> countryNameCF = adoptCF(CFLocaleCopyDisplayNameForPropertyValue(currentLocale.get(), kCFLocaleCountryCode, countryCode));
- countryName = countryNameCF.get();
- }
-
- if (!countryName.isEmpty())
- displayName.append(textTrackCountryAndLanguageMenuItemText(label, countryName, language));
- else
- displayName.append(textTrackLanguageMenuItemText(label, language));
- }
- }
- } else {
- String languageAndLocale = adoptCF(CFLocaleCopyDisplayNameForPropertyValue(currentLocale.get(), kCFLocaleIdentifier, trackLanguageIdentifier.createCFString().get())).get();
- if (!languageAndLocale.isEmpty())
- displayName.append(languageAndLocale);
- else if (!language.isEmpty())
- displayName.append(language);
- else
- displayName.append(localeIdentifier.get());
- }
-}
-
-static String trackDisplayName(AudioTrack* track)
-{
- StringBuilder displayName;
- buildDisplayStringForTrackBase(displayName, *track);
-
- if (displayName.isEmpty())
- displayName.append(audioTrackNoLabelText());
-
- return displayName.toString();
-}
-
-String CaptionUserPreferencesMediaAF::displayNameForTrack(AudioTrack* track) const
-{
- return trackDisplayName(track);
-}
-
-static String trackDisplayName(TextTrack* track)
-{
- if (track == TextTrack::captionMenuOffItem())
- return textTrackOffMenuItemText();
- if (track == TextTrack::captionMenuAutomaticItem())
- return textTrackAutomaticMenuItemText();
-
- StringBuilder displayNameBuilder;
- buildDisplayStringForTrackBase(displayNameBuilder, *track);
-
- if (displayNameBuilder.isEmpty())
- displayNameBuilder.append(textTrackNoLabelText());
-
- String displayName = displayNameBuilder.toString();
-
- if (track->isClosedCaptions()) {
- displayName = closedCaptionTrackMenuItemText(displayName);
- if (track->isEasyToRead())
- displayName = easyReaderTrackMenuItemText(displayName);
-
- return displayName;
- }
-
- if (track->isSDH())
- displayName = sdhTrackMenuItemText(displayName);
-
- if (track->containsOnlyForcedSubtitles())
- displayName = forcedTrackMenuItemText(displayName);
-
- if (track->isEasyToRead())
- displayName = easyReaderTrackMenuItemText(displayName);
-
- return displayName;
-}
-
-String CaptionUserPreferencesMediaAF::displayNameForTrack(TextTrack* track) const
-{
- return trackDisplayName(track);
-}
-
-int CaptionUserPreferencesMediaAF::textTrackSelectionScore(TextTrack* track, HTMLMediaElement* mediaElement) const
-{
- CaptionDisplayMode displayMode = captionDisplayMode();
- if (displayMode == Manual)
- return 0;
-
- bool legacyOverride = mediaElement->webkitClosedCaptionsVisible();
- if (displayMode == AlwaysOn && (!userPrefersSubtitles() && !userPrefersCaptions() && !legacyOverride))
- return 0;
- if (track->kind() != TextTrack::captionsKeyword() && track->kind() != TextTrack::subtitlesKeyword() && track->kind() != TextTrack::forcedKeyword())
- return 0;
- if (!track->isMainProgramContent())
- return 0;
-
- bool trackHasOnlyForcedSubtitles = track->containsOnlyForcedSubtitles();
- if (!legacyOverride && ((trackHasOnlyForcedSubtitles && displayMode != ForcedOnly) || (!trackHasOnlyForcedSubtitles && displayMode == ForcedOnly)))
- return 0;
-
- Vector<String> userPreferredCaptionLanguages = preferredLanguages();
-
- if ((displayMode == Automatic && !legacyOverride) || trackHasOnlyForcedSubtitles) {
-
- if (!mediaElement || !mediaElement->player())
- return 0;
-
- String textTrackLanguage = track->language();
- if (textTrackLanguage.isEmpty())
- return 0;
-
- Vector<String> languageList;
- languageList.reserveCapacity(1);
-
- String audioTrackLanguage;
- if (testingMode())
- audioTrackLanguage = primaryAudioTrackLanguageOverride();
- else
- audioTrackLanguage = mediaElement->player()->languageOfPrimaryAudioTrack();
-
- if (audioTrackLanguage.isEmpty())
- return 0;
-
- bool exactMatch;
- if (trackHasOnlyForcedSubtitles) {
- languageList.append(audioTrackLanguage);
- size_t offset = indexOfBestMatchingLanguageInList(textTrackLanguage, languageList, exactMatch);
-
- // Only consider a forced-only track if it IS in the same language as the primary audio track.
- if (offset)
- return 0;
- } else {
- languageList.append(defaultLanguage());
-
- // Only enable a text track if the current audio track is NOT in the user's preferred language ...
- size_t offset = indexOfBestMatchingLanguageInList(audioTrackLanguage, languageList, exactMatch);
- if (!offset)
- return 0;
-
- // and the text track matches the user's preferred language.
- offset = indexOfBestMatchingLanguageInList(textTrackLanguage, languageList, exactMatch);
- if (offset)
- return 0;
- }
-
- userPreferredCaptionLanguages = languageList;
- }
-
- int trackScore = 0;
-
- if (userPrefersCaptions()) {
- // When the user prefers accessibility tracks, rank is SDH, then CC, then subtitles.
- if (track->kind() == track->subtitlesKeyword())
- trackScore = 1;
- else if (track->isClosedCaptions())
- trackScore = 2;
- else
- trackScore = 3;
- } else {
- // When the user prefers translation tracks, rank is subtitles, then SDH, then CC tracks.
- if (track->kind() == track->subtitlesKeyword())
- trackScore = 3;
- else if (!track->isClosedCaptions())
- trackScore = 2;
- else
- trackScore = 1;
- }
-
- return trackScore + textTrackLanguageSelectionScore(track, userPreferredCaptionLanguages);
-}
-
-static bool textTrackCompare(const RefPtr<TextTrack>& a, const RefPtr<TextTrack>& b)
-{
- String preferredLanguageDisplayName = displayNameForLanguageLocale(languageIdentifier(defaultLanguage()));
- String aLanguageDisplayName = displayNameForLanguageLocale(languageIdentifier(a->language()));
- String bLanguageDisplayName = displayNameForLanguageLocale(languageIdentifier(b->language()));
-
- // Tracks in the user's preferred language are always at the top of the menu.
- bool aIsPreferredLanguage = !codePointCompare(aLanguageDisplayName, preferredLanguageDisplayName);
- bool bIsPreferredLanguage = !codePointCompare(bLanguageDisplayName, preferredLanguageDisplayName);
- if ((aIsPreferredLanguage || bIsPreferredLanguage) && (aIsPreferredLanguage != bIsPreferredLanguage))
- return aIsPreferredLanguage;
-
- // Tracks not in the user's preferred language sort first by language ...
- if (codePointCompare(aLanguageDisplayName, bLanguageDisplayName))
- return codePointCompare(aLanguageDisplayName, bLanguageDisplayName) < 0;
-
- // ... but when tracks have the same language, main program content sorts next highest ...
- bool aIsMainContent = a->isMainProgramContent();
- bool bIsMainContent = b->isMainProgramContent();
- if ((aIsMainContent || bIsMainContent) && (aIsMainContent != bIsMainContent))
- return aIsMainContent;
-
- // ... and main program trakcs sort higher than CC tracks ...
- bool aIsCC = a->isClosedCaptions();
- bool bIsCC = b->isClosedCaptions();
- if ((aIsCC || bIsCC) && (aIsCC != bIsCC)) {
- if (aIsCC)
- return aIsMainContent;
- return bIsMainContent;
- }
-
- // ... and tracks of the same type and language sort by the menu item text.
- return codePointCompare(trackDisplayName(a.get()), trackDisplayName(b.get())) < 0;
-}
-
-Vector<RefPtr<AudioTrack>> CaptionUserPreferencesMediaAF::sortedTrackListForMenu(AudioTrackList* trackList)
-{
- ASSERT(trackList);
-
- Vector<RefPtr<AudioTrack>> tracksForMenu;
-
- for (unsigned i = 0, length = trackList->length(); i < length; ++i) {
- AudioTrack* track = trackList->item(i);
- String language = displayNameForLanguageLocale(track->language());
- tracksForMenu.append(track);
- }
-
- std::sort(tracksForMenu.begin(), tracksForMenu.end(), [](const RefPtr<AudioTrack>& a, const RefPtr<AudioTrack>& b) {
- return codePointCompare(trackDisplayName(a.get()), trackDisplayName(b.get())) < 0;
- });
-
- return tracksForMenu;
-}
-
-Vector<RefPtr<TextTrack>> CaptionUserPreferencesMediaAF::sortedTrackListForMenu(TextTrackList* trackList)
-{
- ASSERT(trackList);
-
- Vector<RefPtr<TextTrack>> tracksForMenu;
- HashSet<String> languagesIncluded;
- CaptionDisplayMode displayMode = captionDisplayMode();
- bool prefersAccessibilityTracks = userPrefersCaptions();
- bool filterTrackList = shouldFilterTrackMenu();
-
- for (unsigned i = 0, length = trackList->length(); i < length; ++i) {
- TextTrack* track = trackList->item(i);
- String language = displayNameForLanguageLocale(track->language());
-
- if (displayMode == Manual) {
- LOG(Media, "CaptionUserPreferencesMediaAF::sortedTrackListForMenu - adding '%s' track with language '%s' because selection mode is 'manual'", track->kind().string().utf8().data(), language.utf8().data());
- tracksForMenu.append(track);
- continue;
- }
-
- const AtomicString& kind = track->kind();
- if (kind != TextTrack::captionsKeyword() && kind != TextTrack::descriptionsKeyword() && kind != TextTrack::subtitlesKeyword())
- continue;
-
- if (track->containsOnlyForcedSubtitles()) {
- LOG(Media, "CaptionUserPreferencesMediaAF::sortedTrackListForMenu - skipping '%s' track with language '%s' because it contains only forced subtitles", track->kind().string().utf8().data(), language.utf8().data());
- continue;
- }
-
- if (track->isEasyToRead()) {
- LOG(Media, "CaptionUserPreferencesMediaAF::sortedTrackListForMenu - adding '%s' track with language '%s' because it is 'easy to read'", track->kind().string().utf8().data(), language.utf8().data());
- if (!language.isEmpty())
- languagesIncluded.add(language);
- tracksForMenu.append(track);
- continue;
- }
-
- if (track->mode() == TextTrack::showingKeyword()) {
- LOG(Media, "CaptionUserPreferencesMediaAF::sortedTrackListForMenu - adding '%s' track with language '%s' because it is already visible", track->kind().string().utf8().data(), language.utf8().data());
- if (!language.isEmpty())
- languagesIncluded.add(language);
- tracksForMenu.append(track);
- continue;
- }
-
- if (!language.isEmpty() && track->isMainProgramContent()) {
- bool isAccessibilityTrack = track->kind() == track->captionsKeyword();
- if (prefersAccessibilityTracks) {
- // In the first pass, include only caption tracks if the user prefers accessibility tracks.
- if (!isAccessibilityTrack && filterTrackList) {
- LOG(Media, "CaptionUserPreferencesMediaAF::sortedTrackListForMenu - skipping '%s' track with language '%s' because it is NOT an accessibility track", track->kind().string().utf8().data(), language.utf8().data());
- continue;
- }
- } else {
- // In the first pass, only include the first non-CC or SDH track with each language if the user prefers translation tracks.
- if (isAccessibilityTrack && filterTrackList) {
- LOG(Media, "CaptionUserPreferencesMediaAF::sortedTrackListForMenu - skipping '%s' track with language '%s' because it is an accessibility track", track->kind().string().utf8().data(), language.utf8().data());
- continue;
- }
- if (languagesIncluded.contains(language) && filterTrackList) {
- LOG(Media, "CaptionUserPreferencesMediaAF::sortedTrackListForMenu - skipping '%s' track with language '%s' because it is not the first with this language", track->kind().string().utf8().data(), language.utf8().data());
- continue;
- }
- }
- }
-
- if (!language.isEmpty())
- languagesIncluded.add(language);
- tracksForMenu.append(track);
-
- LOG(Media, "CaptionUserPreferencesMediaAF::sortedTrackListForMenu - adding '%s' track with language '%s', is%s main program content", track->kind().string().utf8().data(), language.utf8().data(), track->isMainProgramContent() ? "" : " NOT");
- }
-
- // Now that we have filtered for the user's accessibility/translation preference, add all tracks with a unique language without regard to track type.
- for (unsigned i = 0, length = trackList->length(); i < length; ++i) {
- TextTrack* track = trackList->item(i);
- String language = displayNameForLanguageLocale(track->language());
-
- if (tracksForMenu.contains(track))
- continue;
-
- const AtomicString& kind = track->kind();
- if (kind != TextTrack::captionsKeyword() && kind != TextTrack::descriptionsKeyword() && kind != TextTrack::subtitlesKeyword())
- continue;
-
- // All candidates with no languge were added the first time through.
- if (language.isEmpty())
- continue;
-
- if (track->containsOnlyForcedSubtitles())
- continue;
-
- if (!languagesIncluded.contains(language) && track->isMainProgramContent()) {
- languagesIncluded.add(language);
- tracksForMenu.append(track);
- LOG(Media, "CaptionUserPreferencesMediaAF::sortedTrackListForMenu - adding '%s' track with language '%s' because it is the only track with this language", track->kind().string().utf8().data(), language.utf8().data());
- }
- }
-
- std::sort(tracksForMenu.begin(), tracksForMenu.end(), textTrackCompare);
-
- tracksForMenu.insert(0, TextTrack::captionMenuOffItem());
- tracksForMenu.insert(1, TextTrack::captionMenuAutomaticItem());
-
- return tracksForMenu;
-}
-
-}
-
-#endif // ENABLE(VIDEO_TRACK)
diff --git a/Source/WebCore/page/CaptionUserPreferencesMediaAF.h b/Source/WebCore/page/CaptionUserPreferencesMediaAF.h
deleted file mode 100644
index c334cb130..000000000
--- a/Source/WebCore/page/CaptionUserPreferencesMediaAF.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (C) 2012-2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef CaptionUserPreferencesMediaAF_h
-#define CaptionUserPreferencesMediaAF_h
-
-#if ENABLE(VIDEO_TRACK)
-
-#include "CSSPropertyNames.h"
-#include "CaptionUserPreferences.h"
-#include "Color.h"
-#include <wtf/HashSet.h>
-
-namespace WebCore {
-
-class CaptionUserPreferencesMediaAF : public CaptionUserPreferences {
- WTF_MAKE_FAST_ALLOCATED;
-public:
- CaptionUserPreferencesMediaAF(PageGroup&);
- virtual ~CaptionUserPreferencesMediaAF();
-
-#if HAVE(MEDIA_ACCESSIBILITY_FRAMEWORK)
- virtual CaptionDisplayMode captionDisplayMode() const override;
- virtual void setCaptionDisplayMode(CaptionDisplayMode) override;
-
- virtual bool userPrefersCaptions() const override;
- virtual bool userPrefersSubtitles() const override;
-
- virtual float captionFontSizeScaleAndImportance(bool&) const override;
-
- virtual void setInterestedInCaptionPreferenceChanges() override;
-
- virtual void setPreferredLanguage(const String&) override;
- virtual Vector<String> preferredLanguages() const override;
-
- virtual void setPreferredAudioCharacteristic(const String&) override;
- virtual Vector<String> preferredAudioCharacteristics() const override;
-
- virtual void captionPreferencesChanged() override;
-
- bool shouldFilterTrackMenu() const { return true; }
-#else
- bool shouldFilterTrackMenu() const { return false; }
-#endif
-
- virtual String captionsStyleSheetOverride() const override;
- virtual int textTrackSelectionScore(TextTrack*, HTMLMediaElement*) const override;
- Vector<RefPtr<AudioTrack>> sortedTrackListForMenu(AudioTrackList*) override;
- Vector<RefPtr<TextTrack>> sortedTrackListForMenu(TextTrackList*) override;
- String displayNameForTrack(AudioTrack*) const override;
- String displayNameForTrack(TextTrack*) const override;
-
-private:
-#if HAVE(MEDIA_ACCESSIBILITY_FRAMEWORK)
- void updateTimerFired();
-
- String captionsWindowCSS() const;
- String captionsBackgroundCSS() const;
- String captionsTextColorCSS() const;
- Color captionsTextColor(bool&) const;
- String captionsDefaultFontCSS() const;
- Color captionsEdgeColorForTextColor(const Color&) const;
- String windowRoundedCornerRadiusCSS() const;
- String captionsTextEdgeCSS() const;
- String cssPropertyWithTextEdgeColor(CSSPropertyID, const String&, const Color&, bool) const;
- String colorPropertyCSS(CSSPropertyID, const Color&, bool) const;
- Timer m_updateStyleSheetTimer;
-
- bool m_listeningForPreferenceChanges;
- bool m_registeringForNotification { false };
-#endif
-};
-
-}
-#endif
-
-#endif
diff --git a/Source/WebCore/page/Chrome.cpp b/Source/WebCore/page/Chrome.cpp
index 58f6c58ec..85cfd4d65 100644
--- a/Source/WebCore/page/Chrome.cpp
+++ b/Source/WebCore/page/Chrome.cpp
@@ -23,13 +23,14 @@
#include "Chrome.h"
#include "ChromeClient.h"
+#include "DNS.h"
+#include "DateTimeChooser.h"
#include "Document.h"
#include "DocumentType.h"
#include "FileIconLoader.h"
#include "FileChooser.h"
#include "FileList.h"
#include "FloatRect.h"
-#include "FrameLoaderClient.h"
#include "FrameTree.h"
#include "Geolocation.h"
#include "HTMLFormElement.h"
@@ -48,10 +49,8 @@
#include "Settings.h"
#include "StorageNamespace.h"
#include "WindowFeatures.h"
-#include <runtime/VM.h>
#include <wtf/PassRefPtr.h>
#include <wtf/RefPtr.h>
-#include <wtf/TemporaryChange.h>
#include <wtf/Vector.h>
#include <wtf/text/StringBuilder.h>
@@ -78,28 +77,28 @@ Chrome::~Chrome()
m_client.chromeDestroyed();
}
-void Chrome::invalidateRootView(const IntRect& updateRect)
+void Chrome::invalidateRootView(const IntRect& updateRect, bool immediate)
{
- m_client.invalidateRootView(updateRect);
+ m_client.invalidateRootView(updateRect, immediate);
}
-void Chrome::invalidateContentsAndRootView(const IntRect& updateRect)
+void Chrome::invalidateContentsAndRootView(const IntRect& updateRect, bool immediate)
{
- m_client.invalidateContentsAndRootView(updateRect);
+ m_client.invalidateContentsAndRootView(updateRect, immediate);
}
-void Chrome::invalidateContentsForSlowScroll(const IntRect& updateRect)
+void Chrome::invalidateContentsForSlowScroll(const IntRect& updateRect, bool immediate)
{
- m_client.invalidateContentsForSlowScroll(updateRect);
+ m_client.invalidateContentsForSlowScroll(updateRect, immediate);
}
void Chrome::scroll(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect)
{
m_client.scroll(scrollDelta, rectToScroll, clipRect);
- InspectorInstrumentation::didScroll(m_page);
+ InspectorInstrumentation::didScroll(&m_page);
}
-#if USE(COORDINATED_GRAPHICS)
+#if USE(TILED_BACKING_STORE)
void Chrome::delegatedScrollRequested(const IntPoint& scrollPoint)
{
m_client.delegatedScrollRequested(scrollPoint);
@@ -115,18 +114,6 @@ IntRect Chrome::rootViewToScreen(const IntRect& rect) const
{
return m_client.rootViewToScreen(rect);
}
-
-#if PLATFORM(IOS)
-IntPoint Chrome::accessibilityScreenToRootView(const IntPoint& point) const
-{
- return m_client.accessibilityScreenToRootView(point);
-}
-
-IntRect Chrome::rootViewToAccessibilityScreen(const IntRect& rect) const
-{
- return m_client.rootViewToAccessibilityScreen(rect);
-}
-#endif
PlatformPageClient Chrome::platformPageClient() const
{
@@ -138,6 +125,11 @@ void Chrome::contentsSizeChanged(Frame* frame, const IntSize& size) const
m_client.contentsSizeChanged(frame, size);
}
+void Chrome::layoutUpdated(Frame* frame) const
+{
+ m_client.layoutUpdated(frame);
+}
+
void Chrome::scrollRectIntoView(const IntRect& rect) const
{
m_client.scrollRectIntoView(rect);
@@ -215,16 +207,30 @@ bool Chrome::canRunModal() const
return m_client.canRunModal();
}
+static bool canRunModalIfDuringPageDismissal(Page& page, ChromeClient::DialogType dialog, const String& message)
+{
+ for (Frame* frame = &page.mainFrame(); frame; frame = frame->tree().traverseNext()) {
+ FrameLoader::PageDismissalType dismissal = frame->loader().pageDismissalEventBeingDispatched();
+ if (dismissal != FrameLoader::NoDismissal)
+ return page.chrome().client().shouldRunModalDialogDuringPageDismissal(dialog, message, dismissal);
+ }
+ return true;
+}
+
+bool Chrome::canRunModalNow() const
+{
+ // If loads are blocked, we can't run modal because the contents
+ // of the modal dialog will never show up!
+ return canRunModal() && !ResourceHandle::loadsBlocked()
+ && canRunModalIfDuringPageDismissal(m_page, ChromeClient::HTMLDialog, String());
+}
+
void Chrome::runModal() const
{
// Defer callbacks in all the other pages in this group, so we don't try to run JavaScript
// in a way that could interact with this view.
PageGroupLoadDeferrer deferrer(m_page, false);
- // JavaScript that runs within the nested event loop must not be run in the context of the
- // script that called showModalDialog. Null out entryScope to break the connection.
- TemporaryChange<JSC::VMEntryScope*> entryScopeNullifier { m_page.mainFrame().document()->vm().entryScope, nullptr };
-
TimerBase::fireTimersInNestedEventLoop();
m_client.runModal();
}
@@ -285,7 +291,7 @@ bool Chrome::runBeforeUnloadConfirmPanel(const String& message, Frame* frame)
// otherwise cause the load to continue while we're in the middle of executing JavaScript.
PageGroupLoadDeferrer deferrer(m_page, true);
- InspectorInstrumentationCookie cookie = InspectorInstrumentation::willRunJavaScriptDialog(m_page, message);
+ InspectorInstrumentationCookie cookie = InspectorInstrumentation::willRunJavaScriptDialog(&m_page, message);
bool ok = m_client.runBeforeUnloadConfirmPanel(message, frame);
InspectorInstrumentation::didRunJavaScriptDialog(cookie);
return ok;
@@ -298,6 +304,9 @@ void Chrome::closeWindowSoon()
void Chrome::runJavaScriptAlert(Frame* frame, const String& message)
{
+ if (!canRunModalIfDuringPageDismissal(m_page, ChromeClient::AlertDialog, message))
+ return;
+
// Defer loads in case the client method runs a new event loop that would
// otherwise cause the load to continue while we're in the middle of executing JavaScript.
PageGroupLoadDeferrer deferrer(m_page, true);
@@ -306,13 +315,16 @@ void Chrome::runJavaScriptAlert(Frame* frame, const String& message)
notifyPopupOpeningObservers();
String displayMessage = frame->displayStringModifiedByEncoding(message);
- InspectorInstrumentationCookie cookie = InspectorInstrumentation::willRunJavaScriptDialog(m_page, displayMessage);
+ InspectorInstrumentationCookie cookie = InspectorInstrumentation::willRunJavaScriptDialog(&m_page, displayMessage);
m_client.runJavaScriptAlert(frame, displayMessage);
InspectorInstrumentation::didRunJavaScriptDialog(cookie);
}
bool Chrome::runJavaScriptConfirm(Frame* frame, const String& message)
{
+ if (!canRunModalIfDuringPageDismissal(m_page, ChromeClient::ConfirmDialog, message))
+ return false;
+
// Defer loads in case the client method runs a new event loop that would
// otherwise cause the load to continue while we're in the middle of executing JavaScript.
PageGroupLoadDeferrer deferrer(m_page, true);
@@ -321,7 +333,7 @@ bool Chrome::runJavaScriptConfirm(Frame* frame, const String& message)
notifyPopupOpeningObservers();
String displayMessage = frame->displayStringModifiedByEncoding(message);
- InspectorInstrumentationCookie cookie = InspectorInstrumentation::willRunJavaScriptDialog(m_page, displayMessage);
+ InspectorInstrumentationCookie cookie = InspectorInstrumentation::willRunJavaScriptDialog(&m_page, displayMessage);
bool ok = m_client.runJavaScriptConfirm(frame, displayMessage);
InspectorInstrumentation::didRunJavaScriptDialog(cookie);
return ok;
@@ -329,6 +341,9 @@ bool Chrome::runJavaScriptConfirm(Frame* frame, const String& message)
bool Chrome::runJavaScriptPrompt(Frame* frame, const String& prompt, const String& defaultValue, String& result)
{
+ if (!canRunModalIfDuringPageDismissal(m_page, ChromeClient::PromptDialog, prompt))
+ return false;
+
// Defer loads in case the client method runs a new event loop that would
// otherwise cause the load to continue while we're in the middle of executing JavaScript.
PageGroupLoadDeferrer deferrer(m_page, true);
@@ -337,7 +352,7 @@ bool Chrome::runJavaScriptPrompt(Frame* frame, const String& prompt, const Strin
notifyPopupOpeningObservers();
String displayPrompt = frame->displayStringModifiedByEncoding(prompt);
- InspectorInstrumentationCookie cookie = InspectorInstrumentation::willRunJavaScriptDialog(m_page, displayPrompt);
+ InspectorInstrumentationCookie cookie = InspectorInstrumentation::willRunJavaScriptDialog(&m_page, displayPrompt);
bool ok = m_client.runJavaScriptPrompt(frame, displayPrompt, frame->displayStringModifiedByEncoding(defaultValue), result);
InspectorInstrumentation::didRunJavaScriptDialog(cookie);
@@ -353,13 +368,27 @@ void Chrome::setStatusbarText(Frame* frame, const String& status)
m_client.setStatusbarText(frame->displayStringModifiedByEncoding(status));
}
+bool Chrome::shouldInterruptJavaScript()
+{
+ // Defer loads in case the client method runs a new event loop that would
+ // otherwise cause the load to continue while we're in the middle of executing JavaScript.
+ PageGroupLoadDeferrer deferrer(m_page, true);
+
+ return m_client.shouldInterruptJavaScript();
+}
+
+IntRect Chrome::windowResizerRect() const
+{
+ return m_client.windowResizerRect();
+}
+
void Chrome::mouseDidMoveOverElement(const HitTestResult& result, unsigned modifierFlags)
{
if (result.innerNode() && result.innerNode()->document().isDNSPrefetchEnabled())
- m_page.mainFrame().loader().client().prefetchDNS(result.absoluteLinkURL().host());
+ prefetchDNS(result.absoluteLinkURL().host());
m_client.mouseDidMoveOverElement(result, modifierFlags);
- InspectorInstrumentation::mouseDidMoveOverElement(m_page, result, modifierFlags);
+ InspectorInstrumentation::mouseDidMoveOverElement(&m_page, result, modifierFlags);
}
void Chrome::setToolTip(const HitTestResult& result)
@@ -372,10 +401,10 @@ void Chrome::setToolTip(const HitTestResult& result)
if (toolTip.isEmpty() && m_page.settings().showsURLsInToolTips()) {
if (Element* element = result.innerNonSharedElement()) {
// Get tooltip representing form action, if relevant
- if (is<HTMLInputElement>(*element)) {
- HTMLInputElement& input = downcast<HTMLInputElement>(*element);
- if (input.isSubmitButton()) {
- if (HTMLFormElement* form = input.form()) {
+ if (isHTMLInputElement(element)) {
+ HTMLInputElement* input = toHTMLInputElement(element);
+ if (input->isSubmitButton()) {
+ if (HTMLFormElement* form = input->form()) {
toolTip = form->action();
if (form->renderer())
toolTipDirection = form->renderer()->style().direction();
@@ -405,8 +434,8 @@ void Chrome::setToolTip(const HitTestResult& result)
// Lastly, for <input type="file"> that allow multiple files, we'll consider a tooltip for the selected filenames
if (toolTip.isEmpty()) {
if (Element* element = result.innerNonSharedElement()) {
- if (is<HTMLInputElement>(*element)) {
- toolTip = downcast<HTMLInputElement>(*element).defaultToolTip();
+ if (isHTMLInputElement(element)) {
+ toolTip = toHTMLInputElement(element)->defaultToolTip();
// FIXME: We should obtain text direction of tooltip from
// ChromeClient or platform. As of October 2011, all client
@@ -437,14 +466,29 @@ void Chrome::disableSuddenTermination()
m_client.disableSuddenTermination();
}
+#if ENABLE(DIRECTORY_UPLOAD)
+void Chrome::enumerateChosenDirectory(FileChooser* fileChooser)
+{
+ m_client.enumerateChosenDirectory(fileChooser);
+}
+#endif
+
#if ENABLE(INPUT_TYPE_COLOR)
-std::unique_ptr<ColorChooser> Chrome::createColorChooser(ColorChooserClient* client, const Color& initialColor)
+PassOwnPtr<ColorChooser> Chrome::createColorChooser(ColorChooserClient* client, const Color& initialColor)
{
notifyPopupOpeningObservers();
return m_client.createColorChooser(client, initialColor);
}
#endif
+#if ENABLE(DATE_AND_TIME_INPUT_TYPES) && !PLATFORM(IOS)
+PassRefPtr<DateTimeChooser> Chrome::openDateTimeChooser(DateTimeChooserClient* client, const DateTimeChooserParameters& parameters)
+{
+ notifyPopupOpeningObservers();
+ return m_client.openDateTimeChooser(client, parameters);
+}
+#endif
+
void Chrome::runOpenPanel(Frame* frame, PassRefPtr<FileChooser> fileChooser)
{
notifyPopupOpeningObservers();
@@ -456,16 +500,6 @@ void Chrome::loadIconForFiles(const Vector<String>& filenames, FileIconLoader* l
m_client.loadIconForFiles(filenames, loader);
}
-FloatSize Chrome::screenSize() const
-{
- return m_client.screenSize();
-}
-
-FloatSize Chrome::availableScreenSize() const
-{
- return m_client.availableScreenSize();
-}
-
void Chrome::dispatchViewportPropertiesDidChange(const ViewportArguments& arguments) const
{
#if PLATFORM(IOS)
@@ -528,6 +562,19 @@ void ChromeClient::annotatedRegionsChanged()
}
#endif
+void ChromeClient::populateVisitedLinks()
+{
+}
+
+FloatRect ChromeClient::customHighlightRect(Node*, const AtomicString&, const FloatRect&)
+{
+ return FloatRect();
+}
+
+void ChromeClient::paintCustomHighlight(Node*, const AtomicString&, const FloatRect&, const FloatRect&, bool, bool)
+{
+}
+
bool ChromeClient::shouldReplaceWithGeneratedFileForUpload(const String&, String&)
{
return false;
@@ -554,13 +601,13 @@ bool Chrome::hasOpenedPopup() const
return m_client.hasOpenedPopup();
}
-RefPtr<PopupMenu> Chrome::createPopupMenu(PopupMenuClient* client) const
+PassRefPtr<PopupMenu> Chrome::createPopupMenu(PopupMenuClient* client) const
{
notifyPopupOpeningObservers();
return m_client.createPopupMenu(client);
}
-RefPtr<SearchPopupMenu> Chrome::createSearchPopupMenu(PopupMenuClient* client) const
+PassRefPtr<SearchPopupMenu> Chrome::createSearchPopupMenu(PopupMenuClient* client) const
{
notifyPopupOpeningObservers();
return m_client.createSearchPopupMenu(client);
@@ -579,10 +626,15 @@ void Chrome::didReceiveDocType(Frame* frame)
if (!frame->isMainFrame())
return;
- bool hasMobileDocType = false;
- if (DocumentType* documentType = frame->document()->doctype())
- hasMobileDocType = documentType->publicId().contains("xhtml mobile", false);
- m_client.didReceiveMobileDocType(hasMobileDocType);
+ DocumentType* documentType = frame->document()->doctype();
+ if (!documentType) {
+ // FIXME: We should notify the client when <!DOCTYPE> is removed so that
+ // it can adjust the viewport accordingly. See <rdar://problem/15417894>.
+ return;
+ }
+
+ if (documentType->publicId().contains("xhtml mobile", false))
+ m_client.didReceiveMobileDocType();
}
#endif
@@ -594,15 +646,16 @@ void Chrome::registerPopupOpeningObserver(PopupOpeningObserver* observer)
void Chrome::unregisterPopupOpeningObserver(PopupOpeningObserver* observer)
{
- bool removed = m_popupOpeningObservers.removeFirst(observer);
- ASSERT_UNUSED(removed, removed);
+ size_t index = m_popupOpeningObservers.find(observer);
+ ASSERT(index != notFound);
+ m_popupOpeningObservers.remove(index);
}
void Chrome::notifyPopupOpeningObservers() const
{
const Vector<PopupOpeningObserver*> observers(m_popupOpeningObservers);
- for (auto& observer : observers)
- observer->willOpenPopup();
+ for (size_t i = 0; i < observers.size(); ++i)
+ observers[i]->willOpenPopup();
}
} // namespace WebCore
diff --git a/Source/WebCore/page/Chrome.h b/Source/WebCore/page/Chrome.h
index 6272dbc17..71852cdda 100644
--- a/Source/WebCore/page/Chrome.h
+++ b/Source/WebCore/page/Chrome.h
@@ -28,7 +28,7 @@
#include <wtf/Forward.h>
#include <wtf/RefPtr.h>
-#if PLATFORM(COCOA)
+#if PLATFORM(MAC)
#ifndef __OBJC__
class NSView;
#endif
@@ -48,7 +48,6 @@ class Element;
class Frame;
class Geolocation;
class HitTestResult;
-class IntPoint;
class IntRect;
class NavigationAction;
class Page;
@@ -70,19 +69,15 @@ public:
ChromeClient& client() { return m_client; }
// HostWindow methods.
- virtual void invalidateRootView(const IntRect&) override;
- virtual void invalidateContentsAndRootView(const IntRect&) override;
- virtual void invalidateContentsForSlowScroll(const IntRect&) override;
+ virtual void invalidateRootView(const IntRect&, bool) override;
+ virtual void invalidateContentsAndRootView(const IntRect&, bool) override;
+ virtual void invalidateContentsForSlowScroll(const IntRect&, bool) override;
virtual void scroll(const IntSize&, const IntRect&, const IntRect&) override;
-#if USE(COORDINATED_GRAPHICS)
+#if USE(TILED_BACKING_STORE)
virtual void delegatedScrollRequested(const IntPoint& scrollPoint) override;
#endif
virtual IntPoint screenToRootView(const IntPoint&) const override;
virtual IntRect rootViewToScreen(const IntRect&) const override;
-#if PLATFORM(IOS)
- virtual IntPoint accessibilityScreenToRootView(const IntPoint&) const override;
- virtual IntRect rootViewToAccessibilityScreen(const IntRect&) const override;
-#endif
virtual PlatformPageClient platformPageClient() const override;
virtual void scrollbarsModeDidChange() const override;
virtual void setCursor(const Cursor&) override;
@@ -95,15 +90,13 @@ public:
virtual PlatformDisplayID displayID() const override;
virtual void windowScreenDidChange(PlatformDisplayID) override;
- FloatSize screenSize() const override;
- FloatSize availableScreenSize() const override;
-
void scrollRectIntoView(const IntRect&) const;
void contentsSizeChanged(Frame*, const IntSize&) const;
+ void layoutUpdated(Frame*) const;
- WEBCORE_EXPORT void setWindowRect(const FloatRect&) const;
- WEBCORE_EXPORT FloatRect windowRect() const;
+ void setWindowRect(const FloatRect&) const;
+ FloatRect windowRect() const;
FloatRect pageRect() const;
@@ -116,10 +109,11 @@ public:
void focusedElementChanged(Element*) const;
void focusedFrameChanged(Frame*) const;
- WEBCORE_EXPORT Page* createWindow(Frame*, const FrameLoadRequest&, const WindowFeatures&, const NavigationAction&) const;
- WEBCORE_EXPORT void show() const;
+ Page* createWindow(Frame*, const FrameLoadRequest&, const WindowFeatures&, const NavigationAction&) const;
+ void show() const;
bool canRunModal() const;
+ bool canRunModalNow() const;
void runModal() const;
void setToolbarsVisible(bool) const;
@@ -144,37 +138,47 @@ public:
void runJavaScriptAlert(Frame*, const String&);
bool runJavaScriptConfirm(Frame*, const String&);
bool runJavaScriptPrompt(Frame*, const String& message, const String& defaultValue, String& result);
- WEBCORE_EXPORT void setStatusbarText(Frame*, const String&);
+ void setStatusbarText(Frame*, const String&);
+ bool shouldInterruptJavaScript();
+
+ IntRect windowResizerRect() const;
void mouseDidMoveOverElement(const HitTestResult&, unsigned modifierFlags);
void setToolTip(const HitTestResult&);
- WEBCORE_EXPORT void print(Frame*);
+ void print(Frame*);
- WEBCORE_EXPORT void enableSuddenTermination();
- WEBCORE_EXPORT void disableSuddenTermination();
+ void enableSuddenTermination();
+ void disableSuddenTermination();
#if ENABLE(INPUT_TYPE_COLOR)
- std::unique_ptr<ColorChooser> createColorChooser(ColorChooserClient*, const Color& initialColor);
+ PassOwnPtr<ColorChooser> createColorChooser(ColorChooserClient*, const Color& initialColor);
+#endif
+
+#if ENABLE(DATE_AND_TIME_INPUT_TYPES) && !PLATFORM(IOS)
+ PassRefPtr<DateTimeChooser> openDateTimeChooser(DateTimeChooserClient*, const DateTimeChooserParameters&)
#endif
void runOpenPanel(Frame*, PassRefPtr<FileChooser>);
void loadIconForFiles(const Vector<String>&, FileIconLoader*);
+#if ENABLE(DIRECTORY_UPLOAD)
+ void enumerateChosenDirectory(FileChooser*);
+#endif
void dispatchViewportPropertiesDidChange(const ViewportArguments&) const;
bool requiresFullscreenForVideoPlayback();
-#if PLATFORM(COCOA)
- WEBCORE_EXPORT void focusNSView(NSView*);
+#if PLATFORM(MAC)
+ void focusNSView(NSView*);
#endif
bool selectItemWritingDirectionIsNatural();
bool selectItemAlignmentFollowsMenuWritingDirection();
bool hasOpenedPopup() const;
- RefPtr<PopupMenu> createPopupMenu(PopupMenuClient*) const;
- RefPtr<SearchPopupMenu> createSearchPopupMenu(PopupMenuClient*) const;
+ PassRefPtr<PopupMenu> createPopupMenu(PopupMenuClient*) const;
+ PassRefPtr<SearchPopupMenu> createSearchPopupMenu(PopupMenuClient*) const;
#if PLATFORM(IOS)
// FIXME: Can we come up with a better name for this setter?
diff --git a/Source/WebCore/page/ChromeClient.h b/Source/WebCore/page/ChromeClient.h
index 720cf0912..d7fe0f88b 100644
--- a/Source/WebCore/page/ChromeClient.h
+++ b/Source/WebCore/page/ChromeClient.h
@@ -23,17 +23,13 @@
#define ChromeClient_h
#include "AXObjectCache.h"
+#include "ConsoleAPITypes.h"
+#include "ConsoleTypes.h"
#include "Cursor.h"
-#include "DatabaseDetails.h"
-#include "DisplayRefreshMonitor.h"
#include "FocusDirection.h"
#include "FrameLoader.h"
#include "GraphicsContext.h"
-#include "HTMLMediaElementEnums.h"
#include "HostWindow.h"
-#include "LayerFlushThrottleState.h"
-#include "MediaProducer.h"
-#include "PageThrottler.h"
#include "PopupMenu.h"
#include "PopupMenuClient.h"
#include "RenderEmbeddedObject.h"
@@ -41,20 +37,10 @@
#include "ScrollingCoordinator.h"
#include "SearchPopupMenu.h"
#include "WebCoreKeyboardUIMode.h"
-#include <runtime/ConsoleTypes.h>
#include <wtf/Forward.h>
+#include <wtf/PassOwnPtr.h>
#include <wtf/Vector.h>
-#if ENABLE(MEDIA_SESSION)
-namespace WebCore {
-class MediaSessionMetadata;
-}
-#endif
-
-#if ENABLE(WIRELESS_PLAYBACK_TARGET)
-#include "MediaPlaybackTargetContext.h"
-#endif
-
#if PLATFORM(IOS)
#include "PlatformLayer.h"
#define NSResponder WAKResponder
@@ -65,6 +51,10 @@ class WAKResponder;
#endif
#endif
+#if ENABLE(SQL_DATABASE)
+#include "DatabaseDetails.h"
+#endif
+
OBJC_CLASS NSResponder;
namespace WebCore {
@@ -84,8 +74,6 @@ class GraphicsContext3D;
class GraphicsLayer;
class GraphicsLayerFactory;
class HTMLInputElement;
-class HTMLMediaElement;
-class HTMLVideoElement;
class HitTestResult;
class IntRect;
class NavigationAction;
@@ -96,17 +84,13 @@ class SecurityOrigin;
class ViewportConstraints;
class Widget;
-#if ENABLE(VIDEO) && USE(GSTREAMER)
-class MediaPlayerRequestInstallMissingPluginsCallback;
-#endif
-
struct DateTimeChooserParameters;
struct FrameLoadRequest;
struct GraphicsDeviceAdapter;
struct ViewportArguments;
struct WindowFeatures;
-class WEBCORE_EXPORT ChromeClient {
+class ChromeClient {
public:
virtual void chromeDestroyed() = 0;
@@ -151,6 +135,11 @@ public:
virtual void setResizable(bool) = 0;
virtual void addMessageToConsole(MessageSource, MessageLevel, const String& message, unsigned lineNumber, unsigned columnNumber, const String& sourceID) = 0;
+ // FIXME: Remove this MessageType variant once all the clients are updated.
+ virtual void addMessageToConsole(MessageSource source, MessageType, MessageLevel level, const String& message, unsigned lineNumber, unsigned columnNumber, const String& sourceID)
+ {
+ addMessageToConsole(source, level, message, lineNumber, columnNumber, sourceID);
+ }
virtual bool canRunBeforeUnloadConfirmPanel() = 0;
virtual bool runBeforeUnloadConfirmPanel(const String& message, Frame*) = 0;
@@ -161,23 +150,22 @@ public:
virtual bool runJavaScriptConfirm(Frame*, const String&) = 0;
virtual bool runJavaScriptPrompt(Frame*, const String& message, const String& defaultValue, String& result) = 0;
virtual void setStatusbarText(const String&) = 0;
+ virtual bool shouldInterruptJavaScript() = 0;
virtual KeyboardUIMode keyboardUIMode() = 0;
+ virtual IntRect windowResizerRect() const = 0;
+
// Methods used by HostWindow.
virtual bool supportsImmediateInvalidation() { return false; }
- virtual void invalidateRootView(const IntRect&) = 0;
- virtual void invalidateContentsAndRootView(const IntRect&) = 0;
- virtual void invalidateContentsForSlowScroll(const IntRect&) = 0;
+ virtual void invalidateRootView(const IntRect&, bool immediate) = 0;
+ virtual void invalidateContentsAndRootView(const IntRect&, bool immediate) = 0;
+ virtual void invalidateContentsForSlowScroll(const IntRect&, bool immediate) = 0;
virtual void scroll(const IntSize&, const IntRect&, const IntRect&) = 0;
-#if USE(COORDINATED_GRAPHICS)
+#if USE(TILED_BACKING_STORE)
virtual void delegatedScrollRequested(const IntPoint&) = 0;
#endif
virtual IntPoint screenToRootView(const IntPoint&) const = 0;
virtual IntRect rootViewToScreen(const IntRect&) const = 0;
-#if PLATFORM(IOS)
- virtual IntPoint accessibilityScreenToRootView(const IntPoint&) const = 0;
- virtual IntRect rootViewToAccessibilityScreen(const IntRect&) const = 0;
-#endif
virtual PlatformPageClient platformPageClient() const = 0;
virtual void scrollbarsModeDidChange() const = 0;
#if ENABLE(CURSOR_SUPPORT)
@@ -189,12 +177,10 @@ public:
#endif
// End methods used by HostWindow.
- virtual FloatSize screenSize() const { return const_cast<ChromeClient*>(this)->windowRect().size(); }
- virtual FloatSize availableScreenSize() const { return const_cast<ChromeClient*>(this)->windowRect().size(); }
-
virtual void dispatchViewportPropertiesDidChange(const ViewportArguments&) const { }
virtual void contentsSizeChanged(Frame*, const IntSize&) const = 0;
+ virtual void layoutUpdated(Frame*) const { }
virtual void scrollRectIntoView(const IntRect&) const { }; // Currently only Mac has a non empty implementation.
virtual bool shouldUnavailablePluginMessageBeButton(RenderEmbeddedObject::PluginUnavailabilityReason) const { return false; }
@@ -207,9 +193,9 @@ public:
virtual Color underlayColor() const { return Color(); }
- virtual void pageExtendedBackgroundColorDidChange(Color) const { }
-
+#if ENABLE(SQL_DATABASE)
virtual void exceededDatabaseQuota(Frame*, const String& databaseName, DatabaseDetails) = 0;
+#endif
// Callback invoked when the application cache fails to save a cache object
// because storing it would grow the database file past its defined maximum
@@ -232,6 +218,11 @@ public:
virtual void annotatedRegionsChanged();
#endif
+ virtual void populateVisitedLinks();
+
+ virtual FloatRect customHighlightRect(Node*, const AtomicString& type, const FloatRect& lineRect);
+ virtual void paintCustomHighlight(Node*, const AtomicString& type, const FloatRect& boxRect, const FloatRect& lineRect, bool behindText, bool entireLine);
+
virtual bool shouldReplaceWithGeneratedFileForUpload(const String& path, String& generatedFilename);
virtual String generateReplacementFile(const String& path);
@@ -239,10 +230,8 @@ public:
virtual void didPreventDefaultForEvent() = 0;
#endif
- virtual std::chrono::milliseconds eventThrottlingDelay() { return std::chrono::milliseconds::zero(); };
-
#if PLATFORM(IOS)
- virtual void didReceiveMobileDocType(bool) = 0;
+ virtual void didReceiveMobileDocType() = 0;
virtual void setNeedsScrollNotifications(Frame*, bool) = 0;
virtual void observedContentChange(Frame*) = 0;
virtual void clearContentChangeObservers(Frame*) = 0;
@@ -263,44 +252,47 @@ public:
virtual bool fetchCustomFixedPositionLayoutRect(IntRect&) { return false; }
- virtual void updateViewportConstrainedLayers(HashMap<PlatformLayer*, std::unique_ptr<ViewportConstraints>>&, HashMap<PlatformLayer*, PlatformLayer*>&) { }
+ // FIXME: Use std::unique_ptr instead of OwnPtr.
+ virtual void updateViewportConstrainedLayers(HashMap<PlatformLayer*, OwnPtr<ViewportConstraints>>&, HashMap<PlatformLayer*, PlatformLayer*>&) { }
virtual void addOrUpdateScrollingLayer(Node*, PlatformLayer* scrollingLayer, PlatformLayer* contentsLayer, const IntSize& scrollSize, bool allowHorizontalScrollbar, bool allowVerticalScrollbar) = 0;
virtual void removeScrollingLayer(Node*, PlatformLayer* scrollingLayer, PlatformLayer* contentsLayer) = 0;
virtual void webAppOrientationsUpdated() = 0;
- virtual void showPlaybackTargetPicker(bool hasVideo) = 0;
#endif
-#if ENABLE(ORIENTATION_EVENTS)
- virtual int deviceOrientation() const = 0;
+#if ENABLE(INPUT_TYPE_COLOR)
+ virtual PassOwnPtr<ColorChooser> createColorChooser(ColorChooserClient*, const Color&) = 0;
#endif
-#if ENABLE(INPUT_TYPE_COLOR)
- virtual std::unique_ptr<ColorChooser> createColorChooser(ColorChooserClient*, const Color&) = 0;
+#if ENABLE(DATE_AND_TIME_INPUT_TYPES) && !PLATFORM(IOS)
+ virtual PassRefPtr<DateTimeChooser> openDateTimeChooser(DateTimeChooserClient*, const DateTimeChooserParameters&) = 0;
#endif
virtual void runOpenPanel(Frame*, PassRefPtr<FileChooser>) = 0;
// Asynchronous request to load an icon for specified filenames.
virtual void loadIconForFiles(const Vector<String>&, FileIconLoader*) = 0;
+
+#if ENABLE(DIRECTORY_UPLOAD)
+ // Asychronous request to enumerate all files in a directory chosen by the user.
+ virtual void enumerateChosenDirectory(FileChooser*) = 0;
+#endif
+
+ // Notification that the given form element has changed. This function
+ // will be called frequently, so handling should be very fast.
+ virtual void formStateDidChange(const Node*) = 0;
virtual void elementDidFocus(const Node*) { };
virtual void elementDidBlur(const Node*) { };
- virtual void elementDidRefocus(const Node*) { };
virtual bool shouldPaintEntireContents() const { return false; }
- virtual bool hasStablePageScaleFactor() const { return true; }
+#if USE(ACCELERATED_COMPOSITING)
// Allows ports to customize the type of graphics layers created by this page.
- virtual GraphicsLayerFactory* graphicsLayerFactory() const { return nullptr; }
-
-#if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)
- virtual RefPtr<DisplayRefreshMonitor> createDisplayRefreshMonitor(PlatformDisplayID) const { return nullptr; }
-#endif
+ virtual GraphicsLayerFactory* graphicsLayerFactory() const { return 0; }
// Pass 0 as the GraphicsLayer to detatch the root layer.
virtual void attachRootGraphicsLayer(Frame*, GraphicsLayer*) = 0;
- virtual void attachViewOverlayGraphicsLayer(Frame*, GraphicsLayer*) = 0;
// Sets a flag to specify that the next time content is drawn to the window,
// the changes appear on the screen in synchrony with updates to GraphicsLayers.
virtual void setNeedsOneShotDrawingSynchronization() = 0;
@@ -329,8 +321,7 @@ public:
// Returns true if layer tree updates are disabled.
virtual bool layerTreeStateIsFrozen() const { return false; }
-
- virtual bool adjustLayerFlushThrottling(LayerFlushThrottleState::Flags) { return false; }
+#endif
virtual PassRefPtr<ScrollingCoordinator> createScrollingCoordinator(Page*) const { return nullptr; }
@@ -338,11 +329,9 @@ public:
virtual GraphicsDeviceAdapter* graphicsDeviceAdapter() const { return 0; }
#endif
- virtual bool supportsVideoFullscreen(HTMLMediaElementEnums::VideoFullscreenMode) { return false; }
-#if ENABLE(VIDEO)
- virtual void enterVideoFullscreenForVideoElement(HTMLVideoElement&, HTMLMediaElementEnums::VideoFullscreenMode) { }
-#endif
- virtual void exitVideoFullscreenForVideoElement(WebCore::HTMLVideoElement&) { }
+ virtual bool supportsFullscreenForNode(const Node*) { return false; }
+ virtual void enterFullscreenForNode(Node*) { }
+ virtual void exitFullscreenForNode(Node*) { }
virtual bool requiresFullscreenForVideoPlayback() { return false; }
#if ENABLE(FULLSCREEN_API)
@@ -352,11 +341,11 @@ public:
virtual void setRootFullScreenLayer(GraphicsLayer*) { }
#endif
-#if USE(COORDINATED_GRAPHICS)
+#if USE(TILED_BACKING_STORE)
virtual IntRect visibleRectForTiledBackingStore() const { return IntRect(); }
#endif
-#if PLATFORM(COCOA)
+#if PLATFORM(MAC)
virtual NSResponder *firstResponder() { return 0; }
virtual void makeFirstResponder(NSResponder *) { }
// Focuses on the containing view associated with this page.
@@ -385,17 +374,23 @@ public:
virtual bool selectItemAlignmentFollowsMenuWritingDirection() = 0;
// Checks if there is an opened popup, called by RenderMenuList::showPopup().
virtual bool hasOpenedPopup() const = 0;
- virtual RefPtr<PopupMenu> createPopupMenu(PopupMenuClient*) const = 0;
- virtual RefPtr<SearchPopupMenu> createSearchPopupMenu(PopupMenuClient*) const = 0;
+ virtual PassRefPtr<PopupMenu> createPopupMenu(PopupMenuClient*) const = 0;
+ virtual PassRefPtr<SearchPopupMenu> createSearchPopupMenu(PopupMenuClient*) const = 0;
virtual void postAccessibilityNotification(AccessibilityObject*, AXObjectCache::AXNotification) { }
virtual void notifyScrollerThumbIsVisibleInRect(const IntRect&) { }
- virtual void recommendedScrollbarStyleDidChange(ScrollbarStyle) { }
+ virtual void recommendedScrollbarStyleDidChange(int /*newStyle*/) { }
- virtual WTF::Optional<ScrollbarOverlayStyle> preferredScrollbarOverlayStyle() { return ScrollbarOverlayStyleDefault; }
+ enum DialogType {
+ AlertDialog = 0,
+ ConfirmDialog = 1,
+ PromptDialog = 2,
+ HTMLDialog = 3
+ };
+ virtual bool shouldRunModalDialogDuringPageDismissal(const DialogType&, const String& dialogMessage, FrameLoader::PageDismissalType) const { UNUSED_PARAM(dialogMessage); return true; }
- virtual void wheelEventHandlersChanged(bool hasHandlers) = 0;
+ virtual void numWheelEventHandlersChanged(unsigned) = 0;
virtual bool isSVGImageChromeClient() const { return false; }
@@ -405,6 +400,8 @@ public:
virtual bool isPointerLocked() { return false; }
#endif
+ virtual void logDiagnosticMessage(const String& message, const String& description, const String& status) { UNUSED_PARAM(message); UNUSED_PARAM(description); UNUSED_PARAM(status); }
+
virtual FloatSize minimumWindowSize() const { return FloatSize(100, 100); };
virtual bool isEmptyChromeClient() const { return false; }
@@ -422,49 +419,11 @@ public:
virtual bool shouldUseTiledBackingForFrameView(const FrameView*) const { return false; }
- virtual void isPlayingMediaDidChange(MediaProducer::MediaStateFlags, uint64_t) { }
-
-#if ENABLE(MEDIA_SESSION)
- virtual void hasMediaSessionWithActiveMediaElementsDidChange(bool) { }
- virtual void mediaSessionMetadataDidChange(const WebCore::MediaSessionMetadata&) { }
- virtual void focusedContentMediaElementDidChange(uint64_t) { }
-#endif
-
- virtual void setPageActivityState(PageActivityState::Flags) { }
-
-#if ENABLE(SUBTLE_CRYPTO)
- virtual bool wrapCryptoKey(const Vector<uint8_t>&, Vector<uint8_t>&) const { return false; }
- virtual bool unwrapCryptoKey(const Vector<uint8_t>&, Vector<uint8_t>&) const { return false; }
-#endif
-
-#if ENABLE(TELEPHONE_NUMBER_DETECTION) && PLATFORM(MAC)
- virtual void handleTelephoneNumberClick(const String&, const WebCore::IntPoint&) { }
-#endif
-#if ENABLE(SERVICE_CONTROLS)
- virtual void handleSelectionServiceClick(WebCore::FrameSelection&, const Vector<String>&, const WebCore::IntPoint&) { }
- virtual bool hasRelevantSelectionServices(bool /* isTextOnly */) const { return false; }
-#endif
-
- virtual bool shouldDispatchFakeMouseMoveEvents() const { return true; }
-
- virtual void handleAutoFillButtonClick(HTMLInputElement&) { }
-
-#if ENABLE(WIRELESS_PLAYBACK_TARGET)
- virtual void addPlaybackTargetPickerClient(uint64_t /*contextId*/) { }
- virtual void removePlaybackTargetPickerClient(uint64_t /*contextId*/) { }
- virtual void showPlaybackTargetPicker(uint64_t /*contextId*/, const WebCore::IntPoint&, bool /* isVideo */) { }
- virtual void playbackTargetPickerClientStateDidChange(uint64_t /*contextId*/, MediaProducer::MediaStateFlags) { }
- virtual void setMockMediaPlaybackTargetPickerEnabled(bool) { }
- virtual void setMockMediaPlaybackTargetPickerState(const String&, WebCore::MediaPlaybackTargetContext::State) { }
-#endif
-
- virtual void imageOrMediaDocumentSizeChanged(const WebCore::IntSize&) { }
-
-#if ENABLE(VIDEO) && USE(GSTREAMER)
- virtual void requestInstallMissingMediaPlugins(const String& /*details*/, const String& /*description*/, MediaPlayerRequestInstallMissingPluginsCallback&) { }
-#endif
-
- virtual void didInvalidateDocumentMarkerRects() { }
+ // These methods are used to report pages that are performing
+ // some task that we consider to be "active", and so the user
+ // would likely want the page to remain running uninterrupted.
+ virtual void incrementActivePageCount() { }
+ virtual void decrementActivePageCount() { }
protected:
virtual ~ChromeClient() { }
diff --git a/Source/WebCore/page/Console.cpp b/Source/WebCore/page/Console.cpp
new file mode 100644
index 000000000..e21b862e9
--- /dev/null
+++ b/Source/WebCore/page/Console.cpp
@@ -0,0 +1,266 @@
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "Console.h"
+
+#include "Chrome.h"
+#include "ChromeClient.h"
+#include "ConsoleAPITypes.h"
+#include "ConsoleTypes.h"
+#include "Document.h"
+#include "Frame.h"
+#include "FrameLoader.h"
+#include "FrameTree.h"
+#include "InspectorConsoleInstrumentation.h"
+#include "InspectorController.h"
+#include "Page.h"
+#include "PageConsole.h"
+#include "PageGroup.h"
+#include "ScriptArguments.h"
+#include "ScriptCallStack.h"
+#include "ScriptCallStackFactory.h"
+#include "ScriptProfile.h"
+#include "ScriptProfiler.h"
+#include "ScriptableDocumentParser.h"
+#include "Settings.h"
+#include <bindings/ScriptValue.h>
+#include <stdio.h>
+#include <wtf/text/CString.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+Console::Console(Frame* frame)
+ : DOMWindowProperty(frame)
+{
+}
+
+Console::~Console()
+{
+}
+
+static void internalAddMessage(Page* page, MessageType type, MessageLevel level, JSC::ExecState* state, PassRefPtr<ScriptArguments> prpArguments, bool acceptNoArguments = false, bool printTrace = false)
+{
+ RefPtr<ScriptArguments> arguments = prpArguments;
+
+ if (!page)
+ return;
+
+ if (!acceptNoArguments && !arguments->argumentCount())
+ return;
+
+ size_t stackSize = printTrace ? ScriptCallStack::maxCallStackSizeToCapture : 1;
+ RefPtr<ScriptCallStack> callStack(createScriptCallStack(state, stackSize));
+ const ScriptCallFrame& lastCaller = callStack->at(0);
+
+ String message;
+ bool gotMessage = arguments->getFirstArgumentAsString(message);
+ InspectorInstrumentation::addMessageToConsole(page, ConsoleAPIMessageSource, type, level, message, state, arguments);
+
+ if (page->settings().privateBrowsingEnabled())
+ return;
+
+ if (gotMessage)
+ page->chrome().client().addMessageToConsole(ConsoleAPIMessageSource, type, level, message, lastCaller.lineNumber(), lastCaller.columnNumber(), lastCaller.sourceURL());
+
+ if (!page->settings().logsPageMessagesToSystemConsoleEnabled() && !PageConsole::shouldPrintExceptions())
+ return;
+
+ PageConsole::printSourceURLAndPosition(lastCaller.sourceURL(), lastCaller.lineNumber());
+
+ printf(": ");
+
+ PageConsole::printMessageSourceAndLevelPrefix(ConsoleAPIMessageSource, level, printTrace);
+
+ for (size_t i = 0; i < arguments->argumentCount(); ++i) {
+ String argAsString = arguments->argumentAt(i).toString(arguments->globalState());
+ printf(" %s", argAsString.utf8().data());
+ }
+
+ printf("\n");
+
+ if (!printTrace)
+ return;
+
+ for (size_t i = 0; i < callStack->size(); ++i) {
+ const ScriptCallFrame& callFrame = callStack->at(i);
+
+ String functionName = String(callFrame.functionName());
+ if (functionName.isEmpty())
+ functionName = ASCIILiteral("(unknown)");
+
+ printf("%lu: %s (", static_cast<unsigned long>(i), functionName.utf8().data());
+
+ PageConsole::printSourceURLAndPosition(callFrame.sourceURL(), callFrame.lineNumber());
+
+ printf(")\n");
+ }
+}
+
+void Console::debug(JSC::ExecState* state, PassRefPtr<ScriptArguments> arguments)
+{
+ internalAddMessage(page(), LogMessageType, DebugMessageLevel, state, arguments);
+}
+
+void Console::error(JSC::ExecState* state, PassRefPtr<ScriptArguments> arguments)
+{
+ internalAddMessage(page(), LogMessageType, ErrorMessageLevel, state, arguments);
+}
+
+void Console::info(JSC::ExecState* state, PassRefPtr<ScriptArguments> arguments)
+{
+ log(state, arguments);
+}
+
+void Console::log(JSC::ExecState* state, PassRefPtr<ScriptArguments> arguments)
+{
+ internalAddMessage(page(), LogMessageType, LogMessageLevel, state, arguments);
+}
+
+void Console::warn(JSC::ExecState* state, PassRefPtr<ScriptArguments> arguments)
+{
+ internalAddMessage(page(), LogMessageType, WarningMessageLevel, state, arguments);
+}
+
+void Console::dir(JSC::ExecState* state, PassRefPtr<ScriptArguments> arguments)
+{
+ internalAddMessage(page(), DirMessageType, LogMessageLevel, state, arguments);
+}
+
+void Console::dirxml(JSC::ExecState* state, PassRefPtr<ScriptArguments> arguments)
+{
+ internalAddMessage(page(), DirXMLMessageType, LogMessageLevel, state, arguments);
+}
+
+void Console::table(JSC::ExecState* state, PassRefPtr<ScriptArguments> arguments)
+{
+ internalAddMessage(page(), TableMessageType, LogMessageLevel, state, arguments);
+}
+
+void Console::clear(JSC::ExecState* state, PassRefPtr<ScriptArguments> arguments)
+{
+ internalAddMessage(page(), ClearMessageType, LogMessageLevel, state, arguments, true);
+}
+
+void Console::trace(JSC::ExecState* state, PassRefPtr<ScriptArguments> arguments)
+{
+ internalAddMessage(page(), TraceMessageType, LogMessageLevel, state, arguments, true, true);
+}
+
+void Console::assertCondition(JSC::ExecState* state, PassRefPtr<ScriptArguments> arguments, bool condition)
+{
+ if (condition)
+ return;
+
+ internalAddMessage(page(), AssertMessageType, ErrorMessageLevel, state, arguments, true);
+}
+
+void Console::count(JSC::ExecState* state, PassRefPtr<ScriptArguments> arguments)
+{
+ InspectorInstrumentation::consoleCount(page(), state, arguments);
+}
+
+void Console::profile(JSC::ExecState* state, const String& title)
+{
+ Page* page = this->page();
+ if (!page)
+ return;
+
+ // FIXME: log a console message when profiling is disabled.
+ if (!InspectorInstrumentation::profilerEnabled(page))
+ return;
+
+ String resolvedTitle = title;
+ if (title.isNull()) // no title so give it the next user initiated profile title.
+ resolvedTitle = InspectorInstrumentation::getCurrentUserInitiatedProfileName(page, true);
+
+ ScriptProfiler::start(state, resolvedTitle);
+
+ RefPtr<ScriptCallStack> callStack(createScriptCallStack(state, 1));
+ const ScriptCallFrame& lastCaller = callStack->at(0);
+ InspectorInstrumentation::addStartProfilingMessageToConsole(page, resolvedTitle, lastCaller.lineNumber(), lastCaller.columnNumber(), lastCaller.sourceURL());
+}
+
+void Console::profileEnd(JSC::ExecState* state, const String& title)
+{
+ Page* page = this->page();
+ if (!page)
+ return;
+
+ if (!InspectorInstrumentation::profilerEnabled(page))
+ return;
+
+ RefPtr<ScriptProfile> profile = ScriptProfiler::stop(state, title);
+ if (!profile)
+ return;
+
+ m_profiles.append(profile);
+ RefPtr<ScriptCallStack> callStack(createScriptCallStack(state, 1));
+ InspectorInstrumentation::addProfile(page, profile, callStack);
+}
+
+void Console::time(const String& title)
+{
+ InspectorInstrumentation::startConsoleTiming(m_frame, title);
+}
+
+void Console::timeEnd(JSC::ExecState* state, const String& title)
+{
+ RefPtr<ScriptCallStack> callStack(createScriptCallStackForConsole(state));
+ InspectorInstrumentation::stopConsoleTiming(m_frame, title, callStack.release());
+}
+
+void Console::timeStamp(PassRefPtr<ScriptArguments> arguments)
+{
+ InspectorInstrumentation::consoleTimeStamp(m_frame, arguments);
+}
+
+void Console::group(JSC::ExecState* state, PassRefPtr<ScriptArguments> arguments)
+{
+ InspectorInstrumentation::addMessageToConsole(page(), ConsoleAPIMessageSource, StartGroupMessageType, LogMessageLevel, String(), state, arguments);
+}
+
+void Console::groupCollapsed(JSC::ExecState* state, PassRefPtr<ScriptArguments> arguments)
+{
+ InspectorInstrumentation::addMessageToConsole(page(), ConsoleAPIMessageSource, StartGroupCollapsedMessageType, LogMessageLevel, String(), state, arguments);
+}
+
+void Console::groupEnd()
+{
+ InspectorInstrumentation::addMessageToConsole(page(), ConsoleAPIMessageSource, EndGroupMessageType, LogMessageLevel, String(), String(), 0, 0);
+}
+
+Page* Console::page() const
+{
+ if (!m_frame)
+ return 0;
+ return m_frame->page();
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/page/Console.h b/Source/WebCore/page/Console.h
new file mode 100644
index 000000000..64eac1ac4
--- /dev/null
+++ b/Source/WebCore/page/Console.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef Console_h
+#define Console_h
+
+#include "DOMWindowProperty.h"
+#include "ScriptProfile.h"
+#include "ScriptState.h"
+#include "ScriptWrappable.h"
+#include <wtf/Forward.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+class Frame;
+class Page;
+class ScriptArguments;
+
+typedef Vector<RefPtr<ScriptProfile>> ProfilesArray;
+
+class Console : public ScriptWrappable, public RefCounted<Console>, public DOMWindowProperty {
+public:
+ static PassRefPtr<Console> create(Frame* frame) { return adoptRef(new Console(frame)); }
+ virtual ~Console();
+
+ void debug(JSC::ExecState*, PassRefPtr<ScriptArguments>);
+ void error(JSC::ExecState*, PassRefPtr<ScriptArguments>);
+ void info(JSC::ExecState*, PassRefPtr<ScriptArguments>);
+ void log(JSC::ExecState*, PassRefPtr<ScriptArguments>);
+ void clear(JSC::ExecState*, PassRefPtr<ScriptArguments>);
+ void warn(JSC::ExecState*, PassRefPtr<ScriptArguments>);
+ void dir(JSC::ExecState*, PassRefPtr<ScriptArguments>);
+ void dirxml(JSC::ExecState*, PassRefPtr<ScriptArguments>);
+ void table(JSC::ExecState*, PassRefPtr<ScriptArguments>);
+ void trace(JSC::ExecState*, PassRefPtr<ScriptArguments>);
+ void assertCondition(JSC::ExecState*, PassRefPtr<ScriptArguments>, bool condition);
+ void count(JSC::ExecState*, PassRefPtr<ScriptArguments>);
+ const ProfilesArray& profiles() const { return m_profiles; }
+ void profile(JSC::ExecState*, const String& = String());
+ void profileEnd(JSC::ExecState*, const String& = String());
+ void time(const String&);
+ void timeEnd(JSC::ExecState*, const String&);
+ void timeStamp(PassRefPtr<ScriptArguments>);
+ void group(JSC::ExecState*, PassRefPtr<ScriptArguments>);
+ void groupCollapsed(JSC::ExecState*, PassRefPtr<ScriptArguments>);
+ void groupEnd();
+
+private:
+ inline Page* page() const;
+
+ explicit Console(Frame*);
+
+ ProfilesArray m_profiles;
+};
+
+} // namespace WebCore
+
+#endif // Console_h
diff --git a/Source/WebCore/page/Console.idl b/Source/WebCore/page/Console.idl
new file mode 100644
index 000000000..90ad10a50
--- /dev/null
+++ b/Source/WebCore/page/Console.idl
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+[
+ NoInterfaceObject,
+ GenerateIsReachable=ImplFrame,
+] interface Console {
+
+ [CallWith=ScriptArguments&ScriptState] void debug();
+ [CallWith=ScriptArguments&ScriptState] void error();
+ [CallWith=ScriptArguments&ScriptState] void info();
+ [CallWith=ScriptArguments&ScriptState] void log();
+ [CallWith=ScriptArguments&ScriptState] void warn();
+ [CallWith=ScriptArguments&ScriptState] void dir();
+ [CallWith=ScriptArguments&ScriptState] void dirxml();
+ [CallWith=ScriptArguments&ScriptState] void table();
+ [CallWith=ScriptArguments&ScriptState] void trace();
+ [CallWith=ScriptArguments&ScriptState, ImplementedAs=assertCondition] void assert(boolean condition);
+ [CallWith=ScriptArguments&ScriptState] void count();
+
+ // As per spec: http://www.w3.org/TR/WebIDL/#idl-sequence
+ // "Sequences must not be used as the type of an attribute, constant or exception field."
+ // FIXME: this will lead to BUG console.profiles !== console.profiles as profile will always returns new array.
+ readonly attribute ScriptProfile[] profiles;
+ [CallWith=ScriptState] void profile([TreatNullAs=NullString, TreatUndefinedAs=NullString] optional DOMString title);
+ [CallWith=ScriptState] void profileEnd([TreatNullAs=NullString, TreatUndefinedAs=NullString] optional DOMString title);
+
+ void time([TreatNullAs=NullString, TreatUndefinedAs=NullString] DOMString title);
+ [CallWith=ScriptState] void timeEnd([TreatNullAs=NullString, TreatUndefinedAs=NullString] DOMString title);
+ [CallWith=ScriptArguments] void timeStamp();
+ [CallWith=ScriptArguments&ScriptState] void group();
+ [CallWith=ScriptArguments&ScriptState] void groupCollapsed();
+ void groupEnd();
+ [CallWith=ScriptArguments&ScriptState] void clear();
+};
+
diff --git a/Source/WebCore/page/LayerFlushThrottleState.h b/Source/WebCore/page/ConsoleTypes.h
index ebb2db291..804a167cc 100644
--- a/Source/WebCore/page/LayerFlushThrottleState.h
+++ b/Source/WebCore/page/ConsoleTypes.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -23,19 +23,31 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef LayerFlushThrottleState_h
-#define LayerFlushThrottleState_h
+#ifndef ConsoleTypes_h
+#define ConsoleTypes_h
namespace WebCore {
-struct LayerFlushThrottleState {
- enum {
- Enabled = 1 << 0,
- UserIsInteracting = 1 << 1
- };
- typedef unsigned Flags;
+enum MessageSource {
+ XMLMessageSource,
+ JSMessageSource,
+ NetworkMessageSource,
+ ConsoleAPIMessageSource,
+ StorageMessageSource,
+ AppCacheMessageSource,
+ RenderingMessageSource,
+ CSSMessageSource,
+ SecurityMessageSource,
+ OtherMessageSource,
+};
+
+enum MessageLevel {
+ DebugMessageLevel = 4,
+ LogMessageLevel = 1,
+ WarningMessageLevel = 2,
+ ErrorMessageLevel = 3
};
} // namespace WebCore
-#endif // LayerFlushThrottleState_h
+#endif // ConsoleTypes_h
diff --git a/Source/WebCore/page/ContentSecurityPolicy.cpp b/Source/WebCore/page/ContentSecurityPolicy.cpp
new file mode 100644
index 000000000..0aea9aad2
--- /dev/null
+++ b/Source/WebCore/page/ContentSecurityPolicy.cpp
@@ -0,0 +1,1919 @@
+/*
+ * Copyright (C) 2011 Google, Inc. All rights reserved.
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ContentSecurityPolicy.h"
+
+#include "Console.h"
+#include "DOMStringList.h"
+#include "Document.h"
+#include "FeatureObserver.h"
+#include "FormData.h"
+#include "FormDataList.h"
+#include "Frame.h"
+#include "InspectorInstrumentation.h"
+#include "URL.h"
+#include "PingLoader.h"
+#include "RuntimeEnabledFeatures.h"
+#include "SchemeRegistry.h"
+#include "ScriptCallStack.h"
+#include "ScriptCallStackFactory.h"
+#include "ScriptState.h"
+#include "SecurityOrigin.h"
+#include "SecurityPolicyViolationEvent.h"
+#include "TextEncoding.h"
+#include <inspector/InspectorValues.h>
+#include <wtf/HashSet.h>
+#include <wtf/text/TextPosition.h>
+#include <wtf/text/WTFString.h>
+
+using namespace Inspector;
+
+namespace WebCore {
+
+// Normally WebKit uses "static" for internal linkage, but using "static" for
+// these functions causes a compile error because these functions are used as
+// template parameters.
+namespace {
+
+bool isDirectiveNameCharacter(UChar c)
+{
+ return isASCIIAlphanumeric(c) || c == '-';
+}
+
+bool isDirectiveValueCharacter(UChar c)
+{
+ return isASCIISpace(c) || (c >= 0x21 && c <= 0x7e); // Whitespace + VCHAR
+}
+
+bool isNonceCharacter(UChar c)
+{
+ return (c >= 0x21 && c <= 0x7e) && c != ',' && c != ';'; // VCHAR - ',' - ';'
+}
+
+bool isSourceCharacter(UChar c)
+{
+ return !isASCIISpace(c);
+}
+
+bool isPathComponentCharacter(UChar c)
+{
+ return c != '?' && c != '#';
+}
+
+bool isHostCharacter(UChar c)
+{
+ return isASCIIAlphanumeric(c) || c == '-';
+}
+
+bool isSchemeContinuationCharacter(UChar c)
+{
+ return isASCIIAlphanumeric(c) || c == '+' || c == '-' || c == '.';
+}
+
+bool isNotASCIISpace(UChar c)
+{
+ return !isASCIISpace(c);
+}
+
+bool isNotColonOrSlash(UChar c)
+{
+ return c != ':' && c != '/';
+}
+
+bool isMediaTypeCharacter(UChar c)
+{
+ return !isASCIISpace(c) && c != '/';
+}
+
+// CSP 1.0 Directives
+static const char connectSrc[] = "connect-src";
+static const char defaultSrc[] = "default-src";
+static const char fontSrc[] = "font-src";
+static const char frameSrc[] = "frame-src";
+static const char imgSrc[] = "img-src";
+static const char mediaSrc[] = "media-src";
+static const char objectSrc[] = "object-src";
+static const char reportURI[] = "report-uri";
+static const char sandbox[] = "sandbox";
+static const char scriptSrc[] = "script-src";
+static const char styleSrc[] = "style-src";
+
+// CSP 1.1 Directives
+static const char baseURI[] = "base-uri";
+static const char formAction[] = "form-action";
+static const char pluginTypes[] = "plugin-types";
+static const char scriptNonce[] = "script-nonce";
+#if ENABLE(CSP_NEXT)
+static const char reflectedXSS[] = "reflected-xss";
+#endif
+
+bool isDirectiveName(const String& name)
+{
+ return (equalIgnoringCase(name, connectSrc)
+ || equalIgnoringCase(name, defaultSrc)
+ || equalIgnoringCase(name, fontSrc)
+ || equalIgnoringCase(name, frameSrc)
+ || equalIgnoringCase(name, imgSrc)
+ || equalIgnoringCase(name, mediaSrc)
+ || equalIgnoringCase(name, objectSrc)
+ || equalIgnoringCase(name, reportURI)
+ || equalIgnoringCase(name, sandbox)
+ || equalIgnoringCase(name, scriptSrc)
+ || equalIgnoringCase(name, styleSrc)
+#if ENABLE(CSP_NEXT)
+ || equalIgnoringCase(name, baseURI)
+ || equalIgnoringCase(name, formAction)
+ || equalIgnoringCase(name, pluginTypes)
+ || equalIgnoringCase(name, scriptNonce)
+ || equalIgnoringCase(name, reflectedXSS)
+#endif
+ );
+}
+
+FeatureObserver::Feature getFeatureObserverType(ContentSecurityPolicy::HeaderType type)
+{
+ switch (type) {
+ case ContentSecurityPolicy::PrefixedEnforce:
+ return FeatureObserver::PrefixedContentSecurityPolicy;
+ case ContentSecurityPolicy::Enforce:
+ return FeatureObserver::ContentSecurityPolicy;
+ case ContentSecurityPolicy::PrefixedReport:
+ return FeatureObserver::PrefixedContentSecurityPolicyReportOnly;
+ case ContentSecurityPolicy::Report:
+ return FeatureObserver::ContentSecurityPolicyReportOnly;
+ }
+ ASSERT_NOT_REACHED();
+ return FeatureObserver::NumberOfFeatures;
+}
+
+const ScriptCallFrame& getFirstNonNativeFrame(PassRefPtr<ScriptCallStack> stack)
+{
+ int frameNumber = 0;
+ if (!stack->at(0).lineNumber() && stack->size() > 1 && stack->at(1).lineNumber())
+ frameNumber = 1;
+
+ return stack->at(frameNumber);
+}
+
+} // namespace
+
+static bool skipExactly(const UChar*& position, const UChar* end, UChar delimiter)
+{
+ if (position < end && *position == delimiter) {
+ ++position;
+ return true;
+ }
+ return false;
+}
+
+template<bool characterPredicate(UChar)>
+static bool skipExactly(const UChar*& position, const UChar* end)
+{
+ if (position < end && characterPredicate(*position)) {
+ ++position;
+ return true;
+ }
+ return false;
+}
+
+static void skipUntil(const UChar*& position, const UChar* end, UChar delimiter)
+{
+ while (position < end && *position != delimiter)
+ ++position;
+}
+
+template<bool characterPredicate(UChar)>
+static void skipWhile(const UChar*& position, const UChar* end)
+{
+ while (position < end && characterPredicate(*position))
+ ++position;
+}
+
+static bool isSourceListNone(const String& value)
+{
+ const UChar* begin = value.deprecatedCharacters();
+ const UChar* end = value.deprecatedCharacters() + value.length();
+ skipWhile<isASCIISpace>(begin, end);
+
+ const UChar* position = begin;
+ skipWhile<isSourceCharacter>(position, end);
+ if (!equalIgnoringCase("'none'", begin, position - begin))
+ return false;
+
+ skipWhile<isASCIISpace>(position, end);
+ if (position != end)
+ return false;
+
+ return true;
+}
+
+class CSPSource {
+public:
+ CSPSource(ContentSecurityPolicy* policy, const String& scheme, const String& host, int port, const String& path, bool hostHasWildcard, bool portHasWildcard)
+ : m_policy(policy)
+ , m_scheme(scheme)
+ , m_host(host)
+ , m_port(port)
+ , m_path(path)
+ , m_hostHasWildcard(hostHasWildcard)
+ , m_portHasWildcard(portHasWildcard)
+ {
+ }
+
+ bool matches(const URL& url) const
+ {
+ if (!schemeMatches(url))
+ return false;
+ if (isSchemeOnly())
+ return true;
+ return hostMatches(url) && portMatches(url) && pathMatches(url);
+ }
+
+private:
+ bool schemeMatches(const URL& url) const
+ {
+ if (m_scheme.isEmpty()) {
+ String protectedResourceScheme(m_policy->securityOrigin()->protocol());
+#if ENABLE(CSP_NEXT)
+ if (equalIgnoringCase("http", protectedResourceScheme))
+ return url.protocolIsInHTTPFamily();
+#endif
+ return equalIgnoringCase(url.protocol(), protectedResourceScheme);
+ }
+ return equalIgnoringCase(url.protocol(), m_scheme);
+ }
+
+ bool hostMatches(const URL& url) const
+ {
+ const String& host = url.host();
+ if (equalIgnoringCase(host, m_host))
+ return true;
+ return m_hostHasWildcard && host.endsWith("." + m_host, false);
+
+ }
+
+ bool pathMatches(const URL& url) const
+ {
+ if (m_path.isEmpty())
+ return true;
+
+ String path = decodeURLEscapeSequences(url.path());
+
+ if (m_path.endsWith("/"))
+ return path.startsWith(m_path, false);
+
+ return path == m_path;
+ }
+
+ bool portMatches(const URL& url) const
+ {
+ if (m_portHasWildcard)
+ return true;
+
+ int port = url.port();
+
+ if (port == m_port)
+ return true;
+
+ if (!port)
+ return isDefaultPortForProtocol(m_port, url.protocol());
+
+ if (!m_port)
+ return isDefaultPortForProtocol(port, url.protocol());
+
+ return false;
+ }
+
+ bool isSchemeOnly() const { return m_host.isEmpty(); }
+
+ ContentSecurityPolicy* m_policy;
+ String m_scheme;
+ String m_host;
+ int m_port;
+ String m_path;
+
+ bool m_hostHasWildcard;
+ bool m_portHasWildcard;
+};
+
+class CSPSourceList {
+public:
+ CSPSourceList(ContentSecurityPolicy*, const String& directiveName);
+
+ void parse(const String&);
+ bool matches(const URL&);
+ bool allowInline() const { return m_allowInline; }
+ bool allowEval() const { return m_allowEval; }
+
+private:
+ void parse(const UChar* begin, const UChar* end);
+
+ bool parseSource(const UChar* begin, const UChar* end, String& scheme, String& host, int& port, String& path, bool& hostHasWildcard, bool& portHasWildcard);
+ bool parseScheme(const UChar* begin, const UChar* end, String& scheme);
+ bool parseHost(const UChar* begin, const UChar* end, String& host, bool& hostHasWildcard);
+ bool parsePort(const UChar* begin, const UChar* end, int& port, bool& portHasWildcard);
+ bool parsePath(const UChar* begin, const UChar* end, String& path);
+
+ void addSourceSelf();
+ void addSourceStar();
+ void addSourceUnsafeInline();
+ void addSourceUnsafeEval();
+
+ ContentSecurityPolicy* m_policy;
+ Vector<CSPSource> m_list;
+ String m_directiveName;
+ bool m_allowStar;
+ bool m_allowInline;
+ bool m_allowEval;
+};
+
+CSPSourceList::CSPSourceList(ContentSecurityPolicy* policy, const String& directiveName)
+ : m_policy(policy)
+ , m_directiveName(directiveName)
+ , m_allowStar(false)
+ , m_allowInline(false)
+ , m_allowEval(false)
+{
+}
+
+void CSPSourceList::parse(const String& value)
+{
+ // We represent 'none' as an empty m_list.
+ if (isSourceListNone(value))
+ return;
+ parse(value.deprecatedCharacters(), value.deprecatedCharacters() + value.length());
+}
+
+bool CSPSourceList::matches(const URL& url)
+{
+ if (m_allowStar)
+ return true;
+
+ URL effectiveURL = SecurityOrigin::shouldUseInnerURL(url) ? SecurityOrigin::extractInnerURL(url) : url;
+
+ for (size_t i = 0; i < m_list.size(); ++i) {
+ if (m_list[i].matches(effectiveURL))
+ return true;
+ }
+
+ return false;
+}
+
+// source-list = *WSP [ source *( 1*WSP source ) *WSP ]
+// / *WSP "'none'" *WSP
+//
+void CSPSourceList::parse(const UChar* begin, const UChar* end)
+{
+ const UChar* position = begin;
+
+ while (position < end) {
+ skipWhile<isASCIISpace>(position, end);
+ if (position == end)
+ return;
+
+ const UChar* beginSource = position;
+ skipWhile<isSourceCharacter>(position, end);
+
+ String scheme, host, path;
+ int port = 0;
+ bool hostHasWildcard = false;
+ bool portHasWildcard = false;
+
+ if (parseSource(beginSource, position, scheme, host, port, path, hostHasWildcard, portHasWildcard)) {
+ // Wildcard hosts and keyword sources ('self', 'unsafe-inline',
+ // etc.) aren't stored in m_list, but as attributes on the source
+ // list itself.
+ if (scheme.isEmpty() && host.isEmpty())
+ continue;
+ if (isDirectiveName(host))
+ m_policy->reportDirectiveAsSourceExpression(m_directiveName, host);
+ m_list.append(CSPSource(m_policy, scheme, host, port, path, hostHasWildcard, portHasWildcard));
+ } else
+ m_policy->reportInvalidSourceExpression(m_directiveName, String(beginSource, position - beginSource));
+
+ ASSERT(position == end || isASCIISpace(*position));
+ }
+}
+
+// source = scheme ":"
+// / ( [ scheme "://" ] host [ port ] [ path ] )
+// / "'self'"
+//
+bool CSPSourceList::parseSource(const UChar* begin, const UChar* end,
+ String& scheme, String& host, int& port, String& path,
+ bool& hostHasWildcard, bool& portHasWildcard)
+{
+ if (begin == end)
+ return false;
+
+ if (equalIgnoringCase("'none'", begin, end - begin))
+ return false;
+
+ if (end - begin == 1 && *begin == '*') {
+ addSourceStar();
+ return true;
+ }
+
+ if (equalIgnoringCase("'self'", begin, end - begin)) {
+ addSourceSelf();
+ return true;
+ }
+
+ if (equalIgnoringCase("'unsafe-inline'", begin, end - begin)) {
+ addSourceUnsafeInline();
+ return true;
+ }
+
+ if (equalIgnoringCase("'unsafe-eval'", begin, end - begin)) {
+ addSourceUnsafeEval();
+ return true;
+ }
+
+ const UChar* position = begin;
+ const UChar* beginHost = begin;
+ const UChar* beginPath = end;
+ const UChar* beginPort = 0;
+
+ skipWhile<isNotColonOrSlash>(position, end);
+
+ if (position == end) {
+ // host
+ // ^
+ return parseHost(beginHost, position, host, hostHasWildcard);
+ }
+
+ if (position < end && *position == '/') {
+ // host/path || host/ || /
+ // ^ ^ ^
+ if (!parseHost(beginHost, position, host, hostHasWildcard)
+ || !parsePath(position, end, path)
+ || position != end)
+ return false;
+ return true;
+ }
+
+ if (position < end && *position == ':') {
+ if (end - position == 1) {
+ // scheme:
+ // ^
+ return parseScheme(begin, position, scheme);
+ }
+
+ if (position[1] == '/') {
+ // scheme://host || scheme://
+ // ^ ^
+ if (!parseScheme(begin, position, scheme)
+ || !skipExactly(position, end, ':')
+ || !skipExactly(position, end, '/')
+ || !skipExactly(position, end, '/'))
+ return false;
+ if (position == end)
+ return true;
+ beginHost = position;
+ skipWhile<isNotColonOrSlash>(position, end);
+ }
+
+ if (position < end && *position == ':') {
+ // host:port || scheme://host:port
+ // ^ ^
+ beginPort = position;
+ skipUntil(position, end, '/');
+ }
+ }
+
+ if (position < end && *position == '/') {
+ // scheme://host/path || scheme://host:port/path
+ // ^ ^
+ if (position == beginHost)
+ return false;
+
+ beginPath = position;
+ }
+
+ if (!parseHost(beginHost, beginPort ? beginPort : beginPath, host, hostHasWildcard))
+ return false;
+
+ if (beginPort) {
+ if (!parsePort(beginPort, beginPath, port, portHasWildcard))
+ return false;
+ } else {
+ port = 0;
+ }
+
+ if (beginPath != end) {
+ if (!parsePath(beginPath, end, path))
+ return false;
+ }
+
+ return true;
+}
+
+// ; <scheme> production from RFC 3986
+// scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
+//
+bool CSPSourceList::parseScheme(const UChar* begin, const UChar* end, String& scheme)
+{
+ ASSERT(begin <= end);
+ ASSERT(scheme.isEmpty());
+
+ if (begin == end)
+ return false;
+
+ const UChar* position = begin;
+
+ if (!skipExactly<isASCIIAlpha>(position, end))
+ return false;
+
+ skipWhile<isSchemeContinuationCharacter>(position, end);
+
+ if (position != end)
+ return false;
+
+ scheme = String(begin, end - begin);
+ return true;
+}
+
+// host = [ "*." ] 1*host-char *( "." 1*host-char )
+// / "*"
+// host-char = ALPHA / DIGIT / "-"
+//
+bool CSPSourceList::parseHost(const UChar* begin, const UChar* end, String& host, bool& hostHasWildcard)
+{
+ ASSERT(begin <= end);
+ ASSERT(host.isEmpty());
+ ASSERT(!hostHasWildcard);
+
+ if (begin == end)
+ return false;
+
+ const UChar* position = begin;
+
+ if (skipExactly(position, end, '*')) {
+ hostHasWildcard = true;
+
+ if (position == end)
+ return true;
+
+ if (!skipExactly(position, end, '.'))
+ return false;
+ }
+
+ const UChar* hostBegin = position;
+
+ while (position < end) {
+ if (!skipExactly<isHostCharacter>(position, end))
+ return false;
+
+ skipWhile<isHostCharacter>(position, end);
+
+ if (position < end && !skipExactly(position, end, '.'))
+ return false;
+ }
+
+ ASSERT(position == end);
+ host = String(hostBegin, end - hostBegin);
+ return true;
+}
+
+bool CSPSourceList::parsePath(const UChar* begin, const UChar* end, String& path)
+{
+ ASSERT(begin <= end);
+ ASSERT(path.isEmpty());
+
+ const UChar* position = begin;
+ skipWhile<isPathComponentCharacter>(position, end);
+ // path/to/file.js?query=string || path/to/file.js#anchor
+ // ^ ^
+ if (position < end)
+ m_policy->reportInvalidPathCharacter(m_directiveName, String(begin, end - begin), *position);
+
+ path = decodeURLEscapeSequences(String(begin, position - begin));
+
+ ASSERT(position <= end);
+ ASSERT(position == end || (*position == '#' || *position == '?'));
+ return true;
+}
+
+// port = ":" ( 1*DIGIT / "*" )
+//
+bool CSPSourceList::parsePort(const UChar* begin, const UChar* end, int& port, bool& portHasWildcard)
+{
+ ASSERT(begin <= end);
+ ASSERT(!port);
+ ASSERT(!portHasWildcard);
+
+ if (!skipExactly(begin, end, ':'))
+ ASSERT_NOT_REACHED();
+
+ if (begin == end)
+ return false;
+
+ if (end - begin == 1 && *begin == '*') {
+ port = 0;
+ portHasWildcard = true;
+ return true;
+ }
+
+ const UChar* position = begin;
+ skipWhile<isASCIIDigit>(position, end);
+
+ if (position != end)
+ return false;
+
+ bool ok;
+ port = charactersToIntStrict(begin, end - begin, &ok);
+ return ok;
+}
+
+void CSPSourceList::addSourceSelf()
+{
+ m_list.append(CSPSource(m_policy, m_policy->securityOrigin()->protocol(), m_policy->securityOrigin()->host(), m_policy->securityOrigin()->port(), String(), false, false));
+}
+
+void CSPSourceList::addSourceStar()
+{
+ m_allowStar = true;
+}
+
+void CSPSourceList::addSourceUnsafeInline()
+{
+ m_allowInline = true;
+}
+
+void CSPSourceList::addSourceUnsafeEval()
+{
+ m_allowEval = true;
+}
+
+class CSPDirective {
+public:
+ CSPDirective(const String& name, const String& value, ContentSecurityPolicy* policy)
+ : m_name(name)
+ , m_text(name + ' ' + value)
+ , m_policy(policy)
+ {
+ }
+
+ const String& text() const { return m_text; }
+
+protected:
+ const ContentSecurityPolicy* policy() const { return m_policy; }
+
+private:
+ String m_name;
+ String m_text;
+ ContentSecurityPolicy* m_policy;
+};
+
+class NonceDirective : public CSPDirective {
+public:
+ NonceDirective(const String& name, const String& value, ContentSecurityPolicy* policy)
+ : CSPDirective(name, value, policy)
+ {
+ parse(value);
+ }
+
+ bool allows(const String& nonce) const
+ {
+ return (!m_scriptNonce.isEmpty() && nonce.stripWhiteSpace() == m_scriptNonce);
+ }
+
+private:
+ void parse(const String& value)
+ {
+ String nonce;
+ const UChar* position = value.deprecatedCharacters();
+ const UChar* end = position + value.length();
+
+ skipWhile<isASCIISpace>(position, end);
+ const UChar* nonceBegin = position;
+ if (position == end) {
+ policy()->reportInvalidNonce(String());
+ m_scriptNonce = "";
+ return;
+ }
+ skipWhile<isNonceCharacter>(position, end);
+ if (nonceBegin < position)
+ nonce = String(nonceBegin, position - nonceBegin);
+
+ // Trim off trailing whitespace: If we're not at the end of the string, log
+ // an error.
+ skipWhile<isASCIISpace>(position, end);
+ if (position < end) {
+ policy()->reportInvalidNonce(value);
+ m_scriptNonce = "";
+ } else
+ m_scriptNonce = nonce;
+ }
+
+ String m_scriptNonce;
+};
+
+class MediaListDirective : public CSPDirective {
+public:
+ MediaListDirective(const String& name, const String& value, ContentSecurityPolicy* policy)
+ : CSPDirective(name, value, policy)
+ {
+ parse(value);
+ }
+
+ bool allows(const String& type)
+ {
+ return m_pluginTypes.contains(type);
+ }
+
+private:
+ void parse(const String& value)
+ {
+ const UChar* begin = value.deprecatedCharacters();
+ const UChar* position = begin;
+ const UChar* end = begin + value.length();
+
+ // 'plugin-types ____;' OR 'plugin-types;'
+ if (value.isEmpty()) {
+ policy()->reportInvalidPluginTypes(value);
+ return;
+ }
+
+ while (position < end) {
+ // _____ OR _____mime1/mime1
+ // ^ ^
+ skipWhile<isASCIISpace>(position, end);
+ if (position == end)
+ return;
+
+ // mime1/mime1 mime2/mime2
+ // ^
+ begin = position;
+ if (!skipExactly<isMediaTypeCharacter>(position, end)) {
+ skipWhile<isNotASCIISpace>(position, end);
+ policy()->reportInvalidPluginTypes(String(begin, position - begin));
+ continue;
+ }
+ skipWhile<isMediaTypeCharacter>(position, end);
+
+ // mime1/mime1 mime2/mime2
+ // ^
+ if (!skipExactly(position, end, '/')) {
+ skipWhile<isNotASCIISpace>(position, end);
+ policy()->reportInvalidPluginTypes(String(begin, position - begin));
+ continue;
+ }
+
+ // mime1/mime1 mime2/mime2
+ // ^
+ if (!skipExactly<isMediaTypeCharacter>(position, end)) {
+ skipWhile<isNotASCIISpace>(position, end);
+ policy()->reportInvalidPluginTypes(String(begin, position - begin));
+ continue;
+ }
+ skipWhile<isMediaTypeCharacter>(position, end);
+
+ // mime1/mime1 mime2/mime2 OR mime1/mime1 OR mime1/mime1/error
+ // ^ ^ ^
+ if (position < end && isNotASCIISpace(*position)) {
+ skipWhile<isNotASCIISpace>(position, end);
+ policy()->reportInvalidPluginTypes(String(begin, position - begin));
+ continue;
+ }
+ m_pluginTypes.add(String(begin, position - begin));
+
+ ASSERT(position == end || isASCIISpace(*position));
+ }
+ }
+
+ HashSet<String> m_pluginTypes;
+};
+
+class SourceListDirective : public CSPDirective {
+public:
+ SourceListDirective(const String& name, const String& value, ContentSecurityPolicy* policy)
+ : CSPDirective(name, value, policy)
+ , m_sourceList(policy, name)
+ {
+ m_sourceList.parse(value);
+ }
+
+ bool allows(const URL& url)
+ {
+ return m_sourceList.matches(url.isEmpty() ? policy()->url() : url);
+ }
+
+ bool allowInline() const { return m_sourceList.allowInline(); }
+ bool allowEval() const { return m_sourceList.allowEval(); }
+
+private:
+ CSPSourceList m_sourceList;
+};
+
+class CSPDirectiveList {
+ WTF_MAKE_FAST_ALLOCATED;
+public:
+ static PassOwnPtr<CSPDirectiveList> create(ContentSecurityPolicy*, const String&, ContentSecurityPolicy::HeaderType);
+
+ const String& header() const { return m_header; }
+ ContentSecurityPolicy::HeaderType headerType() const { return m_headerType; }
+
+ bool allowJavaScriptURLs(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus) const;
+ bool allowInlineEventHandlers(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus) const;
+ bool allowInlineScript(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus) const;
+ bool allowInlineStyle(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus) const;
+ bool allowEval(JSC::ExecState*, ContentSecurityPolicy::ReportingStatus) const;
+ bool allowScriptNonce(const String& nonce, const String& contextURL, const WTF::OrdinalNumber& contextLine, const URL&) const;
+ bool allowPluginType(const String& type, const String& typeAttribute, const URL&, ContentSecurityPolicy::ReportingStatus) const;
+
+ bool allowScriptFromSource(const URL&, ContentSecurityPolicy::ReportingStatus) const;
+ bool allowObjectFromSource(const URL&, ContentSecurityPolicy::ReportingStatus) const;
+ bool allowChildFrameFromSource(const URL&, ContentSecurityPolicy::ReportingStatus) const;
+ bool allowImageFromSource(const URL&, ContentSecurityPolicy::ReportingStatus) const;
+ bool allowStyleFromSource(const URL&, ContentSecurityPolicy::ReportingStatus) const;
+ bool allowFontFromSource(const URL&, ContentSecurityPolicy::ReportingStatus) const;
+ bool allowMediaFromSource(const URL&, ContentSecurityPolicy::ReportingStatus) const;
+ bool allowConnectToSource(const URL&, ContentSecurityPolicy::ReportingStatus) const;
+ bool allowFormAction(const URL&, ContentSecurityPolicy::ReportingStatus) const;
+ bool allowBaseURI(const URL&, ContentSecurityPolicy::ReportingStatus) const;
+
+ void gatherReportURIs(DOMStringList&) const;
+ const String& evalDisabledErrorMessage() const { return m_evalDisabledErrorMessage; }
+ ContentSecurityPolicy::ReflectedXSSDisposition reflectedXSSDisposition() const { return m_reflectedXSSDisposition; }
+ bool isReportOnly() const { return m_reportOnly; }
+ const Vector<URL>& reportURIs() const { return m_reportURIs; }
+
+private:
+ CSPDirectiveList(ContentSecurityPolicy*, ContentSecurityPolicy::HeaderType);
+
+ void parse(const String&);
+
+ bool parseDirective(const UChar* begin, const UChar* end, String& name, String& value);
+ void parseReportURI(const String& name, const String& value);
+ void parseScriptNonce(const String& name, const String& value);
+ void parsePluginTypes(const String& name, const String& value);
+ void parseReflectedXSS(const String& name, const String& value);
+ void addDirective(const String& name, const String& value);
+ void applySandboxPolicy(const String& name, const String& sandboxPolicy);
+
+ template <class CSPDirectiveType>
+ void setCSPDirective(const String& name, const String& value, OwnPtr<CSPDirectiveType>&);
+
+ SourceListDirective* operativeDirective(SourceListDirective*) const;
+ void reportViolation(const String& directiveText, const String& effectiveDirective, const String& consoleMessage, const URL& blockedURL = URL(), const String& contextURL = String(), const WTF::OrdinalNumber& contextLine = WTF::OrdinalNumber::beforeFirst(), JSC::ExecState* = 0) const;
+
+ bool checkEval(SourceListDirective*) const;
+ bool checkInline(SourceListDirective*) const;
+ bool checkNonce(NonceDirective*, const String&) const;
+ bool checkSource(SourceListDirective*, const URL&) const;
+ bool checkMediaType(MediaListDirective*, const String& type, const String& typeAttribute) const;
+
+ void setEvalDisabledErrorMessage(const String& errorMessage) { m_evalDisabledErrorMessage = errorMessage; }
+
+ bool checkEvalAndReportViolation(SourceListDirective*, const String& consoleMessage, const String& contextURL = String(), const WTF::OrdinalNumber& contextLine = WTF::OrdinalNumber::beforeFirst(), JSC::ExecState* = 0) const;
+ bool checkInlineAndReportViolation(SourceListDirective*, const String& consoleMessage, const String& contextURL, const WTF::OrdinalNumber& contextLine, bool isScript) const;
+ bool checkNonceAndReportViolation(NonceDirective*, const String& nonce, const String& consoleMessage, const String& contextURL, const WTF::OrdinalNumber& contextLine) const;
+
+ bool checkSourceAndReportViolation(SourceListDirective*, const URL&, const String& effectiveDirective) const;
+ bool checkMediaTypeAndReportViolation(MediaListDirective*, const String& type, const String& typeAttribute, const String& consoleMessage) const;
+
+ bool denyIfEnforcingPolicy() const { return m_reportOnly; }
+
+ ContentSecurityPolicy* m_policy;
+
+ String m_header;
+ ContentSecurityPolicy::HeaderType m_headerType;
+
+ bool m_reportOnly;
+ bool m_haveSandboxPolicy;
+ ContentSecurityPolicy::ReflectedXSSDisposition m_reflectedXSSDisposition;
+
+ OwnPtr<MediaListDirective> m_pluginTypes;
+ OwnPtr<NonceDirective> m_scriptNonce;
+ OwnPtr<SourceListDirective> m_baseURI;
+ OwnPtr<SourceListDirective> m_connectSrc;
+ OwnPtr<SourceListDirective> m_defaultSrc;
+ OwnPtr<SourceListDirective> m_fontSrc;
+ OwnPtr<SourceListDirective> m_formAction;
+ OwnPtr<SourceListDirective> m_frameSrc;
+ OwnPtr<SourceListDirective> m_imgSrc;
+ OwnPtr<SourceListDirective> m_mediaSrc;
+ OwnPtr<SourceListDirective> m_objectSrc;
+ OwnPtr<SourceListDirective> m_scriptSrc;
+ OwnPtr<SourceListDirective> m_styleSrc;
+
+ Vector<URL> m_reportURIs;
+
+ String m_evalDisabledErrorMessage;
+};
+
+CSPDirectiveList::CSPDirectiveList(ContentSecurityPolicy* policy, ContentSecurityPolicy::HeaderType type)
+ : m_policy(policy)
+ , m_headerType(type)
+ , m_reportOnly(false)
+ , m_haveSandboxPolicy(false)
+ , m_reflectedXSSDisposition(ContentSecurityPolicy::ReflectedXSSUnset)
+{
+ m_reportOnly = (type == ContentSecurityPolicy::Report || type == ContentSecurityPolicy::PrefixedReport);
+}
+
+PassOwnPtr<CSPDirectiveList> CSPDirectiveList::create(ContentSecurityPolicy* policy, const String& header, ContentSecurityPolicy::HeaderType type)
+{
+ OwnPtr<CSPDirectiveList> directives = adoptPtr(new CSPDirectiveList(policy, type));
+ directives->parse(header);
+
+ if (!directives->checkEval(directives->operativeDirective(directives->m_scriptSrc.get()))) {
+ String message = makeString("Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: \"", directives->operativeDirective(directives->m_scriptSrc.get())->text(), "\".\n");
+ directives->setEvalDisabledErrorMessage(message);
+ }
+
+ if (directives->isReportOnly() && directives->reportURIs().isEmpty())
+ policy->reportMissingReportURI(header);
+
+ return directives.release();
+}
+
+void CSPDirectiveList::reportViolation(const String& directiveText, const String& effectiveDirective, const String& consoleMessage, const URL& blockedURL, const String& contextURL, const WTF::OrdinalNumber& contextLine, JSC::ExecState* state) const
+{
+ String message = m_reportOnly ? "[Report Only] " + consoleMessage : consoleMessage;
+ m_policy->reportViolation(directiveText, effectiveDirective, message, blockedURL, m_reportURIs, m_header, contextURL, contextLine, state);
+}
+
+bool CSPDirectiveList::checkEval(SourceListDirective* directive) const
+{
+ return !directive || directive->allowEval();
+}
+
+bool CSPDirectiveList::checkInline(SourceListDirective* directive) const
+{
+ return !directive || directive->allowInline();
+}
+
+bool CSPDirectiveList::checkNonce(NonceDirective* directive, const String& nonce) const
+{
+ return !directive || directive->allows(nonce);
+}
+
+bool CSPDirectiveList::checkSource(SourceListDirective* directive, const URL& url) const
+{
+ return !directive || directive->allows(url);
+}
+
+bool CSPDirectiveList::checkMediaType(MediaListDirective* directive, const String& type, const String& typeAttribute) const
+{
+ if (!directive)
+ return true;
+ if (typeAttribute.isEmpty() || typeAttribute.stripWhiteSpace() != type)
+ return false;
+ return directive->allows(type);
+}
+
+SourceListDirective* CSPDirectiveList::operativeDirective(SourceListDirective* directive) const
+{
+ return directive ? directive : m_defaultSrc.get();
+}
+
+bool CSPDirectiveList::checkEvalAndReportViolation(SourceListDirective* directive, const String& consoleMessage, const String& contextURL, const WTF::OrdinalNumber& contextLine, JSC::ExecState* state) const
+{
+ if (checkEval(directive))
+ return true;
+
+ String suffix = String();
+ if (directive == m_defaultSrc)
+ suffix = " Note that 'script-src' was not explicitly set, so 'default-src' is used as a fallback.";
+
+ reportViolation(directive->text(), scriptSrc, consoleMessage + "\"" + directive->text() + "\"." + suffix + "\n", URL(), contextURL, contextLine, state);
+ if (!m_reportOnly) {
+ m_policy->reportBlockedScriptExecutionToInspector(directive->text());
+ return false;
+ }
+ return true;
+}
+
+bool CSPDirectiveList::checkNonceAndReportViolation(NonceDirective* directive, const String& nonce, const String& consoleMessage, const String& contextURL, const WTF::OrdinalNumber& contextLine) const
+{
+ if (checkNonce(directive, nonce))
+ return true;
+ reportViolation(directive->text(), scriptNonce, consoleMessage + "\"" + directive->text() + "\".\n", URL(), contextURL, contextLine);
+ return denyIfEnforcingPolicy();
+}
+
+bool CSPDirectiveList::checkMediaTypeAndReportViolation(MediaListDirective* directive, const String& type, const String& typeAttribute, const String& consoleMessage) const
+{
+ if (checkMediaType(directive, type, typeAttribute))
+ return true;
+
+ String message = makeString(consoleMessage, "\'", directive->text(), "\'.");
+ if (typeAttribute.isEmpty())
+ message = message + " When enforcing the 'plugin-types' directive, the plugin's media type must be explicitly declared with a 'type' attribute on the containing element (e.g. '<object type=\"[TYPE GOES HERE]\" ...>').";
+
+ reportViolation(directive->text(), pluginTypes, message + "\n", URL());
+ return denyIfEnforcingPolicy();
+}
+
+bool CSPDirectiveList::checkInlineAndReportViolation(SourceListDirective* directive, const String& consoleMessage, const String& contextURL, const WTF::OrdinalNumber& contextLine, bool isScript) const
+{
+ if (checkInline(directive))
+ return true;
+
+ String suffix = String();
+ if (directive == m_defaultSrc)
+ suffix = makeString(" Note that '", (isScript ? "script" : "style"), "-src' was not explicitly set, so 'default-src' is used as a fallback.");
+
+ reportViolation(directive->text(), isScript ? scriptSrc : styleSrc, consoleMessage + "\"" + directive->text() + "\"." + suffix + "\n", URL(), contextURL, contextLine);
+
+ if (!m_reportOnly) {
+ if (isScript)
+ m_policy->reportBlockedScriptExecutionToInspector(directive->text());
+ return false;
+ }
+ return true;
+}
+
+bool CSPDirectiveList::checkSourceAndReportViolation(SourceListDirective* directive, const URL& url, const String& effectiveDirective) const
+{
+ if (checkSource(directive, url))
+ return true;
+
+ String prefix;
+ if (baseURI == effectiveDirective)
+ prefix = "Refused to set the document's base URI to '";
+ else if (connectSrc == effectiveDirective)
+ prefix = "Refused to connect to '";
+ else if (fontSrc == effectiveDirective)
+ prefix = "Refused to load the font '";
+ else if (formAction == effectiveDirective)
+ prefix = "Refused to send form data to '";
+ else if (frameSrc == effectiveDirective)
+ prefix = "Refused to frame '";
+ else if (imgSrc == effectiveDirective)
+ prefix = "Refused to load the image '";
+ else if (mediaSrc == effectiveDirective)
+ prefix = "Refused to load media from '";
+ else if (objectSrc == effectiveDirective)
+ prefix = "Refused to load plugin data from '";
+ else if (scriptSrc == effectiveDirective)
+ prefix = "Refused to load the script '";
+ else if (styleSrc == effectiveDirective)
+ prefix = "Refused to load the stylesheet '";
+
+ String suffix = String();
+ if (directive == m_defaultSrc)
+ suffix = " Note that '" + effectiveDirective + "' was not explicitly set, so 'default-src' is used as a fallback.";
+
+ reportViolation(directive->text(), effectiveDirective, prefix + url.stringCenterEllipsizedToLength() + "' because it violates the following Content Security Policy directive: \"" + directive->text() + "\"." + suffix + "\n", url);
+ return denyIfEnforcingPolicy();
+}
+
+bool CSPDirectiveList::allowJavaScriptURLs(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+ DEFINE_STATIC_LOCAL(String, consoleMessage, (ASCIILiteral("Refused to execute JavaScript URL because it violates the following Content Security Policy directive: ")));
+ if (reportingStatus == ContentSecurityPolicy::SendReport) {
+ return (checkInlineAndReportViolation(operativeDirective(m_scriptSrc.get()), consoleMessage, contextURL, contextLine, true)
+ && checkNonceAndReportViolation(m_scriptNonce.get(), String(), consoleMessage, contextURL, contextLine));
+ } else {
+ return (checkInline(operativeDirective(m_scriptSrc.get()))
+ && checkNonce(m_scriptNonce.get(), String()));
+ }
+}
+
+bool CSPDirectiveList::allowInlineEventHandlers(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+ DEFINE_STATIC_LOCAL(String, consoleMessage, (ASCIILiteral("Refused to execute inline event handler because it violates the following Content Security Policy directive: ")));
+ if (reportingStatus == ContentSecurityPolicy::SendReport) {
+ return (checkInlineAndReportViolation(operativeDirective(m_scriptSrc.get()), consoleMessage, contextURL, contextLine, true)
+ && checkNonceAndReportViolation(m_scriptNonce.get(), String(), consoleMessage, contextURL, contextLine));
+ } else {
+ return (checkInline(operativeDirective(m_scriptSrc.get()))
+ && checkNonce(m_scriptNonce.get(), String()));
+ }
+}
+
+bool CSPDirectiveList::allowInlineScript(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+ DEFINE_STATIC_LOCAL(String, consoleMessage, (ASCIILiteral("Refused to execute inline script because it violates the following Content Security Policy directive: ")));
+ return reportingStatus == ContentSecurityPolicy::SendReport ?
+ checkInlineAndReportViolation(operativeDirective(m_scriptSrc.get()), consoleMessage, contextURL, contextLine, true) :
+ checkInline(operativeDirective(m_scriptSrc.get()));
+}
+
+bool CSPDirectiveList::allowInlineStyle(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+ DEFINE_STATIC_LOCAL(String, consoleMessage, (ASCIILiteral("Refused to apply inline style because it violates the following Content Security Policy directive: ")));
+ return reportingStatus == ContentSecurityPolicy::SendReport ?
+ checkInlineAndReportViolation(operativeDirective(m_styleSrc.get()), consoleMessage, contextURL, contextLine, false) :
+ checkInline(operativeDirective(m_styleSrc.get()));
+}
+
+bool CSPDirectiveList::allowEval(JSC::ExecState* state, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+ DEFINE_STATIC_LOCAL(String, consoleMessage, (ASCIILiteral("Refused to evaluate script because it violates the following Content Security Policy directive: ")));
+ return reportingStatus == ContentSecurityPolicy::SendReport ?
+ checkEvalAndReportViolation(operativeDirective(m_scriptSrc.get()), consoleMessage, String(), WTF::OrdinalNumber::beforeFirst(), state) :
+ checkEval(operativeDirective(m_scriptSrc.get()));
+}
+
+bool CSPDirectiveList::allowScriptNonce(const String& nonce, const String& contextURL, const WTF::OrdinalNumber& contextLine, const URL& url) const
+{
+ DEFINE_STATIC_LOCAL(String, consoleMessage, (ASCIILiteral("Refused to execute script because it violates the following Content Security Policy directive: ")));
+ if (url.isEmpty())
+ return checkNonceAndReportViolation(m_scriptNonce.get(), nonce, consoleMessage, contextURL, contextLine);
+ return checkNonceAndReportViolation(m_scriptNonce.get(), nonce, "Refused to load '" + url.stringCenterEllipsizedToLength() + "' because it violates the following Content Security Policy directive: ", contextURL, contextLine);
+}
+
+bool CSPDirectiveList::allowPluginType(const String& type, const String& typeAttribute, const URL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+ return reportingStatus == ContentSecurityPolicy::SendReport ?
+ checkMediaTypeAndReportViolation(m_pluginTypes.get(), type, typeAttribute, "Refused to load '" + url.stringCenterEllipsizedToLength() + "' (MIME type '" + typeAttribute + "') because it violates the following Content Security Policy Directive: ") :
+ checkMediaType(m_pluginTypes.get(), type, typeAttribute);
+}
+
+bool CSPDirectiveList::allowScriptFromSource(const URL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+ return reportingStatus == ContentSecurityPolicy::SendReport ?
+ checkSourceAndReportViolation(operativeDirective(m_scriptSrc.get()), url, scriptSrc) :
+ checkSource(operativeDirective(m_scriptSrc.get()), url);
+}
+
+bool CSPDirectiveList::allowObjectFromSource(const URL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+ if (url.isBlankURL())
+ return true;
+ return reportingStatus == ContentSecurityPolicy::SendReport ?
+ checkSourceAndReportViolation(operativeDirective(m_objectSrc.get()), url, objectSrc) :
+ checkSource(operativeDirective(m_objectSrc.get()), url);
+}
+
+bool CSPDirectiveList::allowChildFrameFromSource(const URL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+ if (url.isBlankURL())
+ return true;
+ return reportingStatus == ContentSecurityPolicy::SendReport ?
+ checkSourceAndReportViolation(operativeDirective(m_frameSrc.get()), url, frameSrc) :
+ checkSource(operativeDirective(m_frameSrc.get()), url);
+}
+
+bool CSPDirectiveList::allowImageFromSource(const URL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+ return reportingStatus == ContentSecurityPolicy::SendReport ?
+ checkSourceAndReportViolation(operativeDirective(m_imgSrc.get()), url, imgSrc) :
+ checkSource(operativeDirective(m_imgSrc.get()), url);
+}
+
+bool CSPDirectiveList::allowStyleFromSource(const URL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+ return reportingStatus == ContentSecurityPolicy::SendReport ?
+ checkSourceAndReportViolation(operativeDirective(m_styleSrc.get()), url, styleSrc) :
+ checkSource(operativeDirective(m_styleSrc.get()), url);
+}
+
+bool CSPDirectiveList::allowFontFromSource(const URL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+ return reportingStatus == ContentSecurityPolicy::SendReport ?
+ checkSourceAndReportViolation(operativeDirective(m_fontSrc.get()), url, fontSrc) :
+ checkSource(operativeDirective(m_fontSrc.get()), url);
+}
+
+bool CSPDirectiveList::allowMediaFromSource(const URL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+ return reportingStatus == ContentSecurityPolicy::SendReport ?
+ checkSourceAndReportViolation(operativeDirective(m_mediaSrc.get()), url, mediaSrc) :
+ checkSource(operativeDirective(m_mediaSrc.get()), url);
+}
+
+bool CSPDirectiveList::allowConnectToSource(const URL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+ return reportingStatus == ContentSecurityPolicy::SendReport ?
+ checkSourceAndReportViolation(operativeDirective(m_connectSrc.get()), url, connectSrc) :
+ checkSource(operativeDirective(m_connectSrc.get()), url);
+}
+
+void CSPDirectiveList::gatherReportURIs(DOMStringList& list) const
+{
+ for (size_t i = 0; i < m_reportURIs.size(); ++i)
+ list.append(m_reportURIs[i].string());
+}
+
+bool CSPDirectiveList::allowFormAction(const URL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+ return reportingStatus == ContentSecurityPolicy::SendReport ?
+ checkSourceAndReportViolation(m_formAction.get(), url, formAction) :
+ checkSource(m_formAction.get(), url);
+}
+
+bool CSPDirectiveList::allowBaseURI(const URL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+ return reportingStatus == ContentSecurityPolicy::SendReport ?
+ checkSourceAndReportViolation(m_baseURI.get(), url, baseURI) :
+ checkSource(m_baseURI.get(), url);
+}
+
+// policy = directive-list
+// directive-list = [ directive *( ";" [ directive ] ) ]
+//
+void CSPDirectiveList::parse(const String& policy)
+{
+ m_header = policy;
+ if (policy.isEmpty())
+ return;
+
+ const UChar* position = policy.deprecatedCharacters();
+ const UChar* end = position + policy.length();
+
+ while (position < end) {
+ const UChar* directiveBegin = position;
+ skipUntil(position, end, ';');
+
+ String name, value;
+ if (parseDirective(directiveBegin, position, name, value)) {
+ ASSERT(!name.isEmpty());
+ addDirective(name, value);
+ }
+
+ ASSERT(position == end || *position == ';');
+ skipExactly(position, end, ';');
+ }
+}
+
+// directive = *WSP [ directive-name [ WSP directive-value ] ]
+// directive-name = 1*( ALPHA / DIGIT / "-" )
+// directive-value = *( WSP / <VCHAR except ";"> )
+//
+bool CSPDirectiveList::parseDirective(const UChar* begin, const UChar* end, String& name, String& value)
+{
+ ASSERT(name.isEmpty());
+ ASSERT(value.isEmpty());
+
+ const UChar* position = begin;
+ skipWhile<isASCIISpace>(position, end);
+
+ // Empty directive (e.g. ";;;"). Exit early.
+ if (position == end)
+ return false;
+
+ const UChar* nameBegin = position;
+ skipWhile<isDirectiveNameCharacter>(position, end);
+
+ // The directive-name must be non-empty.
+ if (nameBegin == position) {
+ skipWhile<isNotASCIISpace>(position, end);
+ m_policy->reportUnsupportedDirective(String(nameBegin, position - nameBegin));
+ return false;
+ }
+
+ name = String(nameBegin, position - nameBegin);
+
+ if (position == end)
+ return true;
+
+ if (!skipExactly<isASCIISpace>(position, end)) {
+ skipWhile<isNotASCIISpace>(position, end);
+ m_policy->reportUnsupportedDirective(String(nameBegin, position - nameBegin));
+ return false;
+ }
+
+ skipWhile<isASCIISpace>(position, end);
+
+ const UChar* valueBegin = position;
+ skipWhile<isDirectiveValueCharacter>(position, end);
+
+ if (position != end) {
+ m_policy->reportInvalidDirectiveValueCharacter(name, String(valueBegin, end - valueBegin));
+ return false;
+ }
+
+ // The directive-value may be empty.
+ if (valueBegin == position)
+ return true;
+
+ value = String(valueBegin, position - valueBegin);
+ return true;
+}
+
+void CSPDirectiveList::parseReportURI(const String& name, const String& value)
+{
+ if (!m_reportURIs.isEmpty()) {
+ m_policy->reportDuplicateDirective(name);
+ return;
+ }
+ const UChar* position = value.deprecatedCharacters();
+ const UChar* end = position + value.length();
+
+ while (position < end) {
+ skipWhile<isASCIISpace>(position, end);
+
+ const UChar* urlBegin = position;
+ skipWhile<isNotASCIISpace>(position, end);
+
+ if (urlBegin < position) {
+ String url = String(urlBegin, position - urlBegin);
+ m_reportURIs.append(m_policy->completeURL(url));
+ }
+ }
+}
+
+
+template<class CSPDirectiveType>
+void CSPDirectiveList::setCSPDirective(const String& name, const String& value, OwnPtr<CSPDirectiveType>& directive)
+{
+ if (directive) {
+ m_policy->reportDuplicateDirective(name);
+ return;
+ }
+ directive = adoptPtr(new CSPDirectiveType(name, value, m_policy));
+}
+
+void CSPDirectiveList::applySandboxPolicy(const String& name, const String& sandboxPolicy)
+{
+ if (m_haveSandboxPolicy) {
+ m_policy->reportDuplicateDirective(name);
+ return;
+ }
+ m_haveSandboxPolicy = true;
+ String invalidTokens;
+ m_policy->enforceSandboxFlags(SecurityContext::parseSandboxPolicy(sandboxPolicy, invalidTokens));
+ if (!invalidTokens.isNull())
+ m_policy->reportInvalidSandboxFlags(invalidTokens);
+}
+
+void CSPDirectiveList::parseReflectedXSS(const String& name, const String& value)
+{
+ if (m_reflectedXSSDisposition != ContentSecurityPolicy::ReflectedXSSUnset) {
+ m_policy->reportDuplicateDirective(name);
+ m_reflectedXSSDisposition = ContentSecurityPolicy::ReflectedXSSInvalid;
+ return;
+ }
+
+ if (value.isEmpty()) {
+ m_reflectedXSSDisposition = ContentSecurityPolicy::ReflectedXSSInvalid;
+ m_policy->reportInvalidReflectedXSS(value);
+ return;
+ }
+
+ const UChar* position = value.deprecatedCharacters();
+ const UChar* end = position + value.length();
+
+ skipWhile<isASCIISpace>(position, end);
+ const UChar* begin = position;
+ skipWhile<isNotASCIISpace>(position, end);
+
+ // value1
+ // ^
+ if (equalIgnoringCase("allow", begin, position - begin))
+ m_reflectedXSSDisposition = ContentSecurityPolicy::AllowReflectedXSS;
+ else if (equalIgnoringCase("filter", begin, position - begin))
+ m_reflectedXSSDisposition = ContentSecurityPolicy::FilterReflectedXSS;
+ else if (equalIgnoringCase("block", begin, position - begin))
+ m_reflectedXSSDisposition = ContentSecurityPolicy::BlockReflectedXSS;
+ else {
+ m_reflectedXSSDisposition = ContentSecurityPolicy::ReflectedXSSInvalid;
+ m_policy->reportInvalidReflectedXSS(value);
+ return;
+ }
+
+ skipWhile<isASCIISpace>(position, end);
+ if (position == end && m_reflectedXSSDisposition != ContentSecurityPolicy::ReflectedXSSUnset)
+ return;
+
+ // value1 value2
+ // ^
+ m_reflectedXSSDisposition = ContentSecurityPolicy::ReflectedXSSInvalid;
+ m_policy->reportInvalidReflectedXSS(value);
+}
+
+void CSPDirectiveList::addDirective(const String& name, const String& value)
+{
+ ASSERT(!name.isEmpty());
+
+ if (equalIgnoringCase(name, defaultSrc))
+ setCSPDirective<SourceListDirective>(name, value, m_defaultSrc);
+ else if (equalIgnoringCase(name, scriptSrc))
+ setCSPDirective<SourceListDirective>(name, value, m_scriptSrc);
+ else if (equalIgnoringCase(name, objectSrc))
+ setCSPDirective<SourceListDirective>(name, value, m_objectSrc);
+ else if (equalIgnoringCase(name, frameSrc))
+ setCSPDirective<SourceListDirective>(name, value, m_frameSrc);
+ else if (equalIgnoringCase(name, imgSrc))
+ setCSPDirective<SourceListDirective>(name, value, m_imgSrc);
+ else if (equalIgnoringCase(name, styleSrc))
+ setCSPDirective<SourceListDirective>(name, value, m_styleSrc);
+ else if (equalIgnoringCase(name, fontSrc))
+ setCSPDirective<SourceListDirective>(name, value, m_fontSrc);
+ else if (equalIgnoringCase(name, mediaSrc))
+ setCSPDirective<SourceListDirective>(name, value, m_mediaSrc);
+ else if (equalIgnoringCase(name, connectSrc))
+ setCSPDirective<SourceListDirective>(name, value, m_connectSrc);
+ else if (equalIgnoringCase(name, sandbox))
+ applySandboxPolicy(name, value);
+ else if (equalIgnoringCase(name, reportURI))
+ parseReportURI(name, value);
+#if ENABLE(CSP_NEXT)
+ else if (m_policy->experimentalFeaturesEnabled()) {
+ if (equalIgnoringCase(name, baseURI))
+ setCSPDirective<SourceListDirective>(name, value, m_baseURI);
+ else if (equalIgnoringCase(name, formAction))
+ setCSPDirective<SourceListDirective>(name, value, m_formAction);
+ else if (equalIgnoringCase(name, pluginTypes))
+ setCSPDirective<MediaListDirective>(name, value, m_pluginTypes);
+ else if (equalIgnoringCase(name, scriptNonce))
+ setCSPDirective<NonceDirective>(name, value, m_scriptNonce);
+ else if (equalIgnoringCase(name, reflectedXSS))
+ parseReflectedXSS(name, value);
+ else
+ m_policy->reportUnsupportedDirective(name);
+ }
+#endif
+ else
+ m_policy->reportUnsupportedDirective(name);
+}
+
+ContentSecurityPolicy::ContentSecurityPolicy(ScriptExecutionContext* scriptExecutionContext)
+ : m_scriptExecutionContext(scriptExecutionContext)
+ , m_overrideInlineStyleAllowed(false)
+{
+}
+
+ContentSecurityPolicy::~ContentSecurityPolicy()
+{
+}
+
+void ContentSecurityPolicy::copyStateFrom(const ContentSecurityPolicy* other)
+{
+ ASSERT(m_policies.isEmpty());
+ for (CSPDirectiveListVector::const_iterator iter = other->m_policies.begin(); iter != other->m_policies.end(); ++iter)
+ didReceiveHeader((*iter)->header(), (*iter)->headerType());
+}
+
+void ContentSecurityPolicy::didReceiveHeader(const String& header, HeaderType type)
+{
+ if (m_scriptExecutionContext->isDocument()) {
+ Document* document = toDocument(m_scriptExecutionContext);
+ if (document->domWindow())
+ FeatureObserver::observe(document->domWindow(), getFeatureObserverType(type));
+ }
+
+ // RFC2616, section 4.2 specifies that headers appearing multiple times can
+ // be combined with a comma. Walk the header string, and parse each comma
+ // separated chunk as a separate header.
+ const UChar* begin = header.deprecatedCharacters();
+ const UChar* position = begin;
+ const UChar* end = begin + header.length();
+ while (position < end) {
+ skipUntil(position, end, ',');
+
+ // header1,header2 OR header1
+ // ^ ^
+ OwnPtr<CSPDirectiveList> policy = CSPDirectiveList::create(this, String(begin, position - begin), type);
+ if (!policy->isReportOnly() && !policy->allowEval(0, SuppressReport))
+ m_scriptExecutionContext->disableEval(policy->evalDisabledErrorMessage());
+
+ m_policies.append(policy.release());
+
+ // Skip the comma, and begin the next header from the current position.
+ ASSERT(position == end || *position == ',');
+ skipExactly(position, end, ',');
+ begin = position;
+ }
+}
+
+void ContentSecurityPolicy::setOverrideAllowInlineStyle(bool value)
+{
+ m_overrideInlineStyleAllowed = value;
+}
+
+const String& ContentSecurityPolicy::deprecatedHeader() const
+{
+ return m_policies.isEmpty() ? emptyString() : m_policies[0]->header();
+}
+
+ContentSecurityPolicy::HeaderType ContentSecurityPolicy::deprecatedHeaderType() const
+{
+ return m_policies.isEmpty() ? Enforce : m_policies[0]->headerType();
+}
+
+template<bool (CSPDirectiveList::*allowed)(ContentSecurityPolicy::ReportingStatus) const>
+bool isAllowedByAll(const CSPDirectiveListVector& policies, ContentSecurityPolicy::ReportingStatus reportingStatus)
+{
+ for (size_t i = 0; i < policies.size(); ++i) {
+ if (!(policies[i].get()->*allowed)(reportingStatus))
+ return false;
+ }
+ return true;
+}
+
+template<bool (CSPDirectiveList::*allowed)(JSC::ExecState* state, ContentSecurityPolicy::ReportingStatus) const>
+bool isAllowedByAllWithState(const CSPDirectiveListVector& policies, JSC::ExecState* state, ContentSecurityPolicy::ReportingStatus reportingStatus)
+{
+ for (size_t i = 0; i < policies.size(); ++i) {
+ if (!(policies[i].get()->*allowed)(state, reportingStatus))
+ return false;
+ }
+ return true;
+}
+
+template<bool (CSPDirectiveList::*allowed)(const String&, const WTF::OrdinalNumber&, ContentSecurityPolicy::ReportingStatus) const>
+bool isAllowedByAllWithContext(const CSPDirectiveListVector& policies, const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStatus)
+{
+ for (size_t i = 0; i < policies.size(); ++i) {
+ if (!(policies[i].get()->*allowed)(contextURL, contextLine, reportingStatus))
+ return false;
+ }
+ return true;
+}
+
+template<bool (CSPDirectiveList::*allowed)(const String&, const String&, const WTF::OrdinalNumber&, const URL&) const>
+bool isAllowedByAllWithNonce(const CSPDirectiveListVector& policies, const String& nonce, const String& contextURL, const WTF::OrdinalNumber& contextLine, const URL& url)
+{
+ for (size_t i = 0; i < policies.size(); ++i) {
+ if (!(policies[i].get()->*allowed)(nonce, contextURL, contextLine, url))
+ return false;
+ }
+ return true;
+}
+
+template<bool (CSPDirectiveList::*allowFromURL)(const URL&, ContentSecurityPolicy::ReportingStatus) const>
+bool isAllowedByAllWithURL(const CSPDirectiveListVector& policies, const URL& url, ContentSecurityPolicy::ReportingStatus reportingStatus)
+{
+ if (SchemeRegistry::schemeShouldBypassContentSecurityPolicy(url.protocol()))
+ return true;
+
+ for (size_t i = 0; i < policies.size(); ++i) {
+ if (!(policies[i].get()->*allowFromURL)(url, reportingStatus))
+ return false;
+ }
+ return true;
+}
+
+bool ContentSecurityPolicy::allowJavaScriptURLs(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+ return isAllowedByAllWithContext<&CSPDirectiveList::allowJavaScriptURLs>(m_policies, contextURL, contextLine, reportingStatus);
+}
+
+bool ContentSecurityPolicy::allowInlineEventHandlers(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+ return isAllowedByAllWithContext<&CSPDirectiveList::allowInlineEventHandlers>(m_policies, contextURL, contextLine, reportingStatus);
+}
+
+bool ContentSecurityPolicy::allowInlineScript(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+ return isAllowedByAllWithContext<&CSPDirectiveList::allowInlineScript>(m_policies, contextURL, contextLine, reportingStatus);
+}
+
+bool ContentSecurityPolicy::allowInlineStyle(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+ if (m_overrideInlineStyleAllowed)
+ return true;
+ return isAllowedByAllWithContext<&CSPDirectiveList::allowInlineStyle>(m_policies, contextURL, contextLine, reportingStatus);
+}
+
+bool ContentSecurityPolicy::allowEval(JSC::ExecState* state, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+ return isAllowedByAllWithState<&CSPDirectiveList::allowEval>(m_policies, state, reportingStatus);
+}
+
+String ContentSecurityPolicy::evalDisabledErrorMessage() const
+{
+ for (size_t i = 0; i < m_policies.size(); ++i) {
+ if (!m_policies[i]->allowEval(0, SuppressReport))
+ return m_policies[i]->evalDisabledErrorMessage();
+ }
+ return String();
+}
+
+bool ContentSecurityPolicy::allowScriptNonce(const String& nonce, const String& contextURL, const WTF::OrdinalNumber& contextLine, const URL& url) const
+{
+ return isAllowedByAllWithNonce<&CSPDirectiveList::allowScriptNonce>(m_policies, nonce, contextURL, contextLine, url);
+}
+
+bool ContentSecurityPolicy::allowPluginType(const String& type, const String& typeAttribute, const URL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+ for (size_t i = 0; i < m_policies.size(); ++i) {
+ if (!m_policies[i]->allowPluginType(type, typeAttribute, url, reportingStatus))
+ return false;
+ }
+ return true;
+}
+
+bool ContentSecurityPolicy::allowScriptFromSource(const URL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+ return isAllowedByAllWithURL<&CSPDirectiveList::allowScriptFromSource>(m_policies, url, reportingStatus);
+}
+
+bool ContentSecurityPolicy::allowObjectFromSource(const URL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+ return isAllowedByAllWithURL<&CSPDirectiveList::allowObjectFromSource>(m_policies, url, reportingStatus);
+}
+
+bool ContentSecurityPolicy::allowChildFrameFromSource(const URL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+ return isAllowedByAllWithURL<&CSPDirectiveList::allowChildFrameFromSource>(m_policies, url, reportingStatus);
+}
+
+bool ContentSecurityPolicy::allowImageFromSource(const URL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+ return isAllowedByAllWithURL<&CSPDirectiveList::allowImageFromSource>(m_policies, url, reportingStatus);
+}
+
+bool ContentSecurityPolicy::allowStyleFromSource(const URL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+ return isAllowedByAllWithURL<&CSPDirectiveList::allowStyleFromSource>(m_policies, url, reportingStatus);
+}
+
+bool ContentSecurityPolicy::allowFontFromSource(const URL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+ return isAllowedByAllWithURL<&CSPDirectiveList::allowFontFromSource>(m_policies, url, reportingStatus);
+}
+
+bool ContentSecurityPolicy::allowMediaFromSource(const URL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+ return isAllowedByAllWithURL<&CSPDirectiveList::allowMediaFromSource>(m_policies, url, reportingStatus);
+}
+
+bool ContentSecurityPolicy::allowConnectToSource(const URL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+ return isAllowedByAllWithURL<&CSPDirectiveList::allowConnectToSource>(m_policies, url, reportingStatus);
+}
+
+bool ContentSecurityPolicy::allowFormAction(const URL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+ return isAllowedByAllWithURL<&CSPDirectiveList::allowFormAction>(m_policies, url, reportingStatus);
+}
+
+bool ContentSecurityPolicy::allowBaseURI(const URL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+ return isAllowedByAllWithURL<&CSPDirectiveList::allowBaseURI>(m_policies, url, reportingStatus);
+}
+
+bool ContentSecurityPolicy::isActive() const
+{
+ return !m_policies.isEmpty();
+}
+
+ContentSecurityPolicy::ReflectedXSSDisposition ContentSecurityPolicy::reflectedXSSDisposition() const
+{
+ ReflectedXSSDisposition disposition = ReflectedXSSUnset;
+ for (size_t i = 0; i < m_policies.size(); ++i) {
+ if (m_policies[i]->reflectedXSSDisposition() > disposition)
+ disposition = std::max(disposition, m_policies[i]->reflectedXSSDisposition());
+ }
+ return disposition;
+}
+
+void ContentSecurityPolicy::gatherReportURIs(DOMStringList& list) const
+{
+ for (size_t i = 0; i < m_policies.size(); ++i)
+ m_policies[i]->gatherReportURIs(list);
+}
+
+SecurityOrigin* ContentSecurityPolicy::securityOrigin() const
+{
+ return m_scriptExecutionContext->securityOrigin();
+}
+
+const URL& ContentSecurityPolicy::url() const
+{
+ return m_scriptExecutionContext->url();
+}
+
+URL ContentSecurityPolicy::completeURL(const String& url) const
+{
+ return m_scriptExecutionContext->completeURL(url);
+}
+
+void ContentSecurityPolicy::enforceSandboxFlags(SandboxFlags mask) const
+{
+ m_scriptExecutionContext->enforceSandboxFlags(mask);
+}
+
+static String stripURLForUseInReport(Document* document, const URL& url)
+{
+ if (!url.isValid())
+ return String();
+ if (!url.isHierarchical() || url.protocolIs("file"))
+ return url.protocol();
+ return document->securityOrigin()->canRequest(url) ? url.strippedForUseAsReferrer() : SecurityOrigin::create(url)->toString();
+}
+
+#if ENABLE(CSP_NEXT)
+static void gatherSecurityPolicyViolationEventData(SecurityPolicyViolationEventInit& init, Document* document, const String& directiveText, const String& effectiveDirective, const URL& blockedURL, const String& header)
+{
+ init.documentURI = document->url().string();
+ init.referrer = document->referrer();
+ init.blockedURI = stripURLForUseInReport(document, blockedURL);
+ init.violatedDirective = directiveText;
+ init.effectiveDirective = effectiveDirective;
+ init.originalPolicy = header;
+ init.sourceFile = String();
+ init.lineNumber = 0;
+
+ RefPtr<ScriptCallStack> stack = createScriptCallStack(2, false);
+ if (!stack)
+ return;
+
+ const ScriptCallFrame& callFrame = getFirstNonNativeFrame(stack);
+
+ if (callFrame.lineNumber()) {
+ URL source = URL(ParsedURLString, callFrame.sourceURL());
+ init.sourceFile = stripURLForUseInReport(document, source);
+ init.lineNumber = callFrame.lineNumber();
+ }
+}
+#endif
+
+void ContentSecurityPolicy::reportViolation(const String& directiveText, const String& effectiveDirective, const String& consoleMessage, const URL& blockedURL, const Vector<URL>& reportURIs, const String& header, const String& contextURL, const WTF::OrdinalNumber& contextLine, JSC::ExecState* state) const
+{
+ logToConsole(consoleMessage, contextURL, contextLine, state);
+
+ // FIXME: Support sending reports from worker.
+ if (!m_scriptExecutionContext->isDocument())
+ return;
+
+ Document* document = toDocument(m_scriptExecutionContext);
+ Frame* frame = document->frame();
+ if (!frame)
+ return;
+
+#if ENABLE(CSP_NEXT)
+ if (experimentalFeaturesEnabled()) {
+ // FIXME: This code means that we're gathering information like line numbers twice. Once we can bring this out from behind the flag, we should reuse the data gathered here when generating the JSON report below.
+ SecurityPolicyViolationEventInit init;
+ gatherSecurityPolicyViolationEventData(init, document, directiveText, effectiveDirective, blockedURL, header);
+ document->enqueueDocumentEvent(SecurityPolicyViolationEvent::create(eventNames().securitypolicyviolationEvent, init));
+ }
+#endif
+
+ if (reportURIs.isEmpty())
+ return;
+
+ // We need to be careful here when deciding what information to send to the
+ // report-uri. Currently, we send only the current document's URL and the
+ // directive that was violated. The document's URL is safe to send because
+ // it's the document itself that's requesting that it be sent. You could
+ // make an argument that we shouldn't send HTTPS document URLs to HTTP
+ // report-uris (for the same reasons that we supress the Referer in that
+ // case), but the Referer is sent implicitly whereas this request is only
+ // sent explicitly. As for which directive was violated, that's pretty
+ // harmless information.
+
+ RefPtr<InspectorObject> cspReport = InspectorObject::create();
+ cspReport->setString("document-uri", document->url().strippedForUseAsReferrer());
+ cspReport->setString("referrer", document->referrer());
+ cspReport->setString("violated-directive", directiveText);
+#if ENABLE(CSP_NEXT)
+ if (experimentalFeaturesEnabled())
+ cspReport->setString("effective-directive", effectiveDirective);
+#else
+ UNUSED_PARAM(effectiveDirective);
+#endif
+ cspReport->setString("original-policy", header);
+ cspReport->setString("blocked-uri", stripURLForUseInReport(document, blockedURL));
+
+ RefPtr<ScriptCallStack> stack = createScriptCallStack(2, false);
+ if (stack) {
+ const ScriptCallFrame& callFrame = getFirstNonNativeFrame(stack);
+
+ if (callFrame.lineNumber()) {
+ URL source = URL(ParsedURLString, callFrame.sourceURL());
+ cspReport->setString("source-file", stripURLForUseInReport(document, source));
+ cspReport->setNumber("line-number", callFrame.lineNumber());
+ }
+ }
+
+ RefPtr<InspectorObject> reportObject = InspectorObject::create();
+ reportObject->setObject("csp-report", cspReport.release());
+
+ RefPtr<FormData> report = FormData::create(reportObject->toJSONString().utf8());
+
+ for (size_t i = 0; i < reportURIs.size(); ++i)
+ PingLoader::sendViolationReport(frame, reportURIs[i], report);
+}
+
+void ContentSecurityPolicy::reportUnsupportedDirective(const String& name) const
+{
+ DEFINE_STATIC_LOCAL(String, allow, (ASCIILiteral("allow")));
+ DEFINE_STATIC_LOCAL(String, options, (ASCIILiteral("options")));
+ DEFINE_STATIC_LOCAL(String, policyURI, (ASCIILiteral("policy-uri")));
+ DEFINE_STATIC_LOCAL(String, allowMessage, (ASCIILiteral("The 'allow' directive has been replaced with 'default-src'. Please use that directive instead, as 'allow' has no effect.")));
+ DEFINE_STATIC_LOCAL(String, optionsMessage, (ASCIILiteral("The 'options' directive has been replaced with 'unsafe-inline' and 'unsafe-eval' source expressions for the 'script-src' and 'style-src' directives. Please use those directives instead, as 'options' has no effect.")));
+ DEFINE_STATIC_LOCAL(String, policyURIMessage, (ASCIILiteral("The 'policy-uri' directive has been removed from the specification. Please specify a complete policy via the Content-Security-Policy header.")));
+
+ String message = makeString("Unrecognized Content-Security-Policy directive '", name, "'.\n");
+ if (equalIgnoringCase(name, allow))
+ message = allowMessage;
+ else if (equalIgnoringCase(name, options))
+ message = optionsMessage;
+ else if (equalIgnoringCase(name, policyURI))
+ message = policyURIMessage;
+
+ logToConsole(message);
+}
+
+void ContentSecurityPolicy::reportDirectiveAsSourceExpression(const String& directiveName, const String& sourceExpression) const
+{
+ String message = "The Content Security Policy directive '" + directiveName + "' contains '" + sourceExpression + "' as a source expression. Did you mean '" + directiveName + " ...; " + sourceExpression + "...' (note the semicolon)?";
+ logToConsole(message);
+}
+
+void ContentSecurityPolicy::reportDuplicateDirective(const String& name) const
+{
+ String message = makeString("Ignoring duplicate Content-Security-Policy directive '", name, "'.\n");
+ logToConsole(message);
+}
+
+void ContentSecurityPolicy::reportInvalidPluginTypes(const String& pluginType) const
+{
+ String message;
+ if (pluginType.isNull())
+ message = "'plugin-types' Content Security Policy directive is empty; all plugins will be blocked.\n";
+ else
+ message = makeString("Invalid plugin type in 'plugin-types' Content Security Policy directive: '", pluginType, "'.\n");
+ logToConsole(message);
+}
+
+void ContentSecurityPolicy::reportInvalidSandboxFlags(const String& invalidFlags) const
+{
+ logToConsole("Error while parsing the 'sandbox' Content Security Policy directive: " + invalidFlags);
+}
+
+void ContentSecurityPolicy::reportInvalidReflectedXSS(const String& invalidValue) const
+{
+ logToConsole("The 'reflected-xss' Content Security Policy directive has the invalid value \"" + invalidValue + "\". Value values are \"allow\", \"filter\", and \"block\".");
+}
+
+void ContentSecurityPolicy::reportInvalidDirectiveValueCharacter(const String& directiveName, const String& value) const
+{
+ String message = makeString("The value for Content Security Policy directive '", directiveName, "' contains an invalid character: '", value, "'. Non-whitespace characters outside ASCII 0x21-0x7E must be percent-encoded, as described in RFC 3986, section 2.1: http://tools.ietf.org/html/rfc3986#section-2.1.");
+ logToConsole(message);
+}
+
+void ContentSecurityPolicy::reportInvalidPathCharacter(const String& directiveName, const String& value, const char invalidChar) const
+{
+ ASSERT(invalidChar == '#' || invalidChar == '?');
+
+ String ignoring = "The fragment identifier, including the '#', will be ignored.";
+ if (invalidChar == '?')
+ ignoring = "The query component, including the '?', will be ignored.";
+ String message = makeString("The source list for Content Security Policy directive '", directiveName, "' contains a source with an invalid path: '", value, "'. ", ignoring);
+ logToConsole(message);
+}
+
+void ContentSecurityPolicy::reportInvalidNonce(const String& nonce) const
+{
+ String message = makeString("Ignoring invalid Content Security Policy script nonce: '", nonce, "'.\n");
+ logToConsole(message);
+}
+
+void ContentSecurityPolicy::reportInvalidSourceExpression(const String& directiveName, const String& source) const
+{
+ String message = makeString("The source list for Content Security Policy directive '", directiveName, "' contains an invalid source: '", source, "'. It will be ignored.");
+ if (equalIgnoringCase(source, "'none'"))
+ message = makeString(message, " Note that 'none' has no effect unless it is the only expression in the source list.");
+ logToConsole(message);
+}
+
+void ContentSecurityPolicy::reportMissingReportURI(const String& policy) const
+{
+ logToConsole("The Content Security Policy '" + policy + "' was delivered in report-only mode, but does not specify a 'report-uri'; the policy will have no effect. Please either add a 'report-uri' directive, or deliver the policy via the 'Content-Security-Policy' header.");
+}
+
+void ContentSecurityPolicy::logToConsole(const String& message, const String& contextURL, const WTF::OrdinalNumber& contextLine, JSC::ExecState* state) const
+{
+ // FIXME: <http://webkit.org/b/114317> ContentSecurityPolicy::logToConsole should include a column number
+ m_scriptExecutionContext->addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, message, contextURL, contextLine.oneBasedInt(), 0, state);
+}
+
+void ContentSecurityPolicy::reportBlockedScriptExecutionToInspector(const String& directiveText) const
+{
+ InspectorInstrumentation::scriptExecutionBlockedByCSP(m_scriptExecutionContext, directiveText);
+}
+
+bool ContentSecurityPolicy::experimentalFeaturesEnabled() const
+{
+#if ENABLE(CSP_NEXT)
+ return RuntimeEnabledFeatures::sharedFeatures().experimentalContentSecurityPolicyFeaturesEnabled();
+#else
+ return false;
+#endif
+}
+
+}
diff --git a/Source/WebCore/page/ContentSecurityPolicy.h b/Source/WebCore/page/ContentSecurityPolicy.h
new file mode 100644
index 000000000..a834bbbf6
--- /dev/null
+++ b/Source/WebCore/page/ContentSecurityPolicy.h
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2011 Google, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ContentSecurityPolicy_h
+#define ContentSecurityPolicy_h
+
+#include "URL.h"
+#include "ScriptState.h"
+#include <wtf/PassOwnPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/Vector.h>
+#include <wtf/text/TextPosition.h>
+#include <wtf/text/WTFString.h>
+
+namespace WTF {
+class OrdinalNumber;
+}
+
+namespace WebCore {
+
+class CSPDirectiveList;
+class DOMStringList;
+class ScriptExecutionContext;
+class SecurityOrigin;
+
+typedef int SandboxFlags;
+typedef Vector<OwnPtr<CSPDirectiveList>> CSPDirectiveListVector;
+
+class ContentSecurityPolicy {
+ WTF_MAKE_FAST_ALLOCATED;
+public:
+ static PassOwnPtr<ContentSecurityPolicy> create(ScriptExecutionContext* scriptExecutionContext)
+ {
+ return adoptPtr(new ContentSecurityPolicy(scriptExecutionContext));
+ }
+ ~ContentSecurityPolicy();
+
+ void copyStateFrom(const ContentSecurityPolicy*);
+
+ enum HeaderType {
+ Report,
+ Enforce,
+ PrefixedReport,
+ PrefixedEnforce
+ };
+
+ enum ReportingStatus {
+ SendReport,
+ SuppressReport
+ };
+
+ // Be sure to update the behavior of XSSAuditor::combineXSSProtectionHeaderAndCSP whenever you change this enum's content or ordering.
+ enum ReflectedXSSDisposition {
+ ReflectedXSSUnset = 0,
+ AllowReflectedXSS,
+ ReflectedXSSInvalid,
+ FilterReflectedXSS,
+ BlockReflectedXSS
+ };
+
+ void didReceiveHeader(const String&, HeaderType);
+
+ // These functions are wrong because they assume that there is only one header.
+ // FIXME: Replace them with functions that return vectors.
+ const String& deprecatedHeader() const;
+ HeaderType deprecatedHeaderType() const;
+
+ bool allowJavaScriptURLs(const String& contextURL, const WTF::OrdinalNumber& contextLine, ReportingStatus = SendReport) const;
+ bool allowInlineEventHandlers(const String& contextURL, const WTF::OrdinalNumber& contextLine, ReportingStatus = SendReport) const;
+ bool allowInlineScript(const String& contextURL, const WTF::OrdinalNumber& contextLine, ReportingStatus = SendReport) const;
+ bool allowInlineStyle(const String& contextURL, const WTF::OrdinalNumber& contextLine, ReportingStatus = SendReport) const;
+ bool allowEval(JSC::ExecState* = 0, ReportingStatus = SendReport) const;
+ bool allowScriptNonce(const String& nonce, const String& contextURL, const WTF::OrdinalNumber& contextLine, const URL& = URL()) const;
+ bool allowPluginType(const String& type, const String& typeAttribute, const URL&, ReportingStatus = SendReport) const;
+
+ bool allowScriptFromSource(const URL&, ReportingStatus = SendReport) const;
+ bool allowObjectFromSource(const URL&, ReportingStatus = SendReport) const;
+ bool allowChildFrameFromSource(const URL&, ReportingStatus = SendReport) const;
+ bool allowImageFromSource(const URL&, ReportingStatus = SendReport) const;
+ bool allowStyleFromSource(const URL&, ReportingStatus = SendReport) const;
+ bool allowFontFromSource(const URL&, ReportingStatus = SendReport) const;
+ bool allowMediaFromSource(const URL&, ReportingStatus = SendReport) const;
+ bool allowConnectToSource(const URL&, ReportingStatus = SendReport) const;
+ bool allowFormAction(const URL&, ReportingStatus = SendReport) const;
+ bool allowBaseURI(const URL&, ReportingStatus = SendReport) const;
+
+ ReflectedXSSDisposition reflectedXSSDisposition() const;
+
+ void setOverrideAllowInlineStyle(bool);
+
+ bool isActive() const;
+ void gatherReportURIs(DOMStringList&) const;
+
+ void reportDirectiveAsSourceExpression(const String& directiveName, const String& sourceExpression) const;
+ void reportDuplicateDirective(const String&) const;
+ void reportInvalidDirectiveValueCharacter(const String& directiveName, const String& value) const;
+ void reportInvalidPathCharacter(const String& directiveName, const String& value, const char) const;
+ void reportInvalidNonce(const String&) const;
+ void reportInvalidPluginTypes(const String&) const;
+ void reportInvalidSandboxFlags(const String&) const;
+ void reportInvalidSourceExpression(const String& directiveName, const String& source) const;
+ void reportInvalidReflectedXSS(const String&) const;
+ void reportMissingReportURI(const String&) const;
+ void reportUnsupportedDirective(const String&) const;
+ void reportViolation(const String& directiveText, const String& effectiveDirective, const String& consoleMessage, const URL& blockedURL, const Vector<URL>& reportURIs, const String& header, const String& contextURL = String(), const WTF::OrdinalNumber& contextLine = WTF::OrdinalNumber::beforeFirst(), JSC::ExecState* = 0) const;
+
+ void reportBlockedScriptExecutionToInspector(const String& directiveText) const;
+
+ const URL& url() const;
+ URL completeURL(const String&) const;
+ SecurityOrigin* securityOrigin() const;
+ void enforceSandboxFlags(SandboxFlags) const;
+ String evalDisabledErrorMessage() const;
+
+ bool experimentalFeaturesEnabled() const;
+
+private:
+ explicit ContentSecurityPolicy(ScriptExecutionContext*);
+
+ void logToConsole(const String& message, const String& contextURL = String(), const WTF::OrdinalNumber& contextLine = WTF::OrdinalNumber::beforeFirst(), JSC::ExecState* = 0) const;
+
+ ScriptExecutionContext* m_scriptExecutionContext;
+ bool m_overrideInlineStyleAllowed;
+ CSPDirectiveListVector m_policies;
+};
+
+}
+
+#endif
diff --git a/Source/WebCore/page/ContextMenuClient.h b/Source/WebCore/page/ContextMenuClient.h
index 211df8d26..23d3a5aa6 100644
--- a/Source/WebCore/page/ContextMenuClient.h
+++ b/Source/WebCore/page/ContextMenuClient.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006 Apple Inc. All rights reserved.
+ * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -29,7 +29,9 @@
#if ENABLE(CONTEXT_MENUS)
#include "ContextMenu.h"
+#include "PlatformMenuDescription.h"
#include <wtf/Forward.h>
+#include <wtf/PassOwnPtr.h>
namespace WebCore {
class ContextMenuItem;
@@ -42,6 +44,14 @@ namespace WebCore {
virtual ~ContextMenuClient() { }
virtual void contextMenuDestroyed() = 0;
+#if USE(CROSS_PLATFORM_CONTEXT_MENUS)
+ virtual PassOwnPtr<ContextMenu> customizeMenu(PassOwnPtr<ContextMenu>) = 0;
+#else
+ virtual PlatformMenuDescription getCustomMenuFromDefaultItems(ContextMenu*) = 0;
+#endif
+
+ virtual void contextMenuItemSelected(ContextMenuItem*, const ContextMenu*) = 0;
+
virtual void downloadURL(const URL& url) = 0;
virtual void searchWithGoogle(const Frame*) = 0;
virtual void lookUpInDictionary(Frame*) = 0;
@@ -49,7 +59,7 @@ namespace WebCore {
virtual void speak(const String&) = 0;
virtual void stopSpeaking() = 0;
-#if PLATFORM(COCOA)
+#if PLATFORM(MAC)
virtual void searchWithSpotlight() = 0;
#endif
diff --git a/Source/WebCore/page/ContextMenuContext.h b/Source/WebCore/page/ContextMenuContext.h
deleted file mode 100644
index 281c90d80..000000000
--- a/Source/WebCore/page/ContextMenuContext.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#ifndef ContextMenuContext_h
-#define ContextMenuContext_h
-
-#if ENABLE(CONTEXT_MENUS)
-
-#include "HitTestResult.h"
-#include "Image.h"
-
-namespace WebCore {
-
-class ContextMenuContext {
-public:
- ContextMenuContext();
- ContextMenuContext(const HitTestResult&);
-
- const HitTestResult& hitTestResult() const { return m_hitTestResult; }
-
- void setSelectedText(const String& selectedText) { m_selectedText = selectedText; }
- const String& selectedText() const { return m_selectedText; }
-
-#if ENABLE(SERVICE_CONTROLS)
- void setControlledImage(Image* controlledImage) { m_controlledImage = controlledImage; }
- Image* controlledImage() const { return m_controlledImage.get(); }
-#endif
-
-private:
-
- HitTestResult m_hitTestResult;
- String m_selectedText;
-
-#if ENABLE(SERVICE_CONTROLS)
- RefPtr<Image> m_controlledImage;
-#endif
-};
-
-} // namespace WebCore
-
-#endif // ENABLE(CONTEXT_MENUS)
-#endif // ContextMenuContext_h
diff --git a/Source/WebCore/page/ContextMenuController.cpp b/Source/WebCore/page/ContextMenuController.cpp
index 890da8827..04a06d11d 100644
--- a/Source/WebCore/page/ContextMenuController.cpp
+++ b/Source/WebCore/page/ContextMenuController.cpp
@@ -11,10 +11,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -49,7 +49,6 @@
#include "FrameLoader.h"
#include "FrameLoaderClient.h"
#include "FrameSelection.h"
-#include "HTMLFormControlElement.h"
#include "HTMLFormElement.h"
#include "HitTestRequest.h"
#include "HitTestResult.h"
@@ -61,7 +60,6 @@
#include "Node.h"
#include "Page.h"
#include "PlatformEvent.h"
-#include "RenderImage.h"
#include "ReplaceSelectionCommand.h"
#include "ResourceRequest.h"
#include "Settings.h"
@@ -71,6 +69,7 @@
#include "WindowFeatures.h"
#include "markup.h"
#include <wtf/unicode/CharacterNames.h>
+#include <wtf/unicode/Unicode.h>
using namespace WTF;
using namespace Unicode;
@@ -90,15 +89,15 @@ ContextMenuController::~ContextMenuController()
void ContextMenuController::clearContextMenu()
{
- m_contextMenu = nullptr;
+ m_contextMenu.clear();
if (m_menuProvider)
m_menuProvider->contextMenuCleared();
- m_menuProvider = nullptr;
+ m_menuProvider = 0;
}
void ContextMenuController::handleContextMenuEvent(Event* event)
{
- m_contextMenu = maybeCreateContextMenu(event);
+ m_contextMenu = createContextMenu(event);
if (!m_contextMenu)
return;
@@ -107,96 +106,80 @@ void ContextMenuController::handleContextMenuEvent(Event* event)
showContextMenu(event);
}
-static std::unique_ptr<ContextMenuItem> separatorItem()
+static PassOwnPtr<ContextMenuItem> separatorItem()
{
- return std::unique_ptr<ContextMenuItem>(new ContextMenuItem(SeparatorType, ContextMenuItemTagNoAction, String()));
+ return adoptPtr(new ContextMenuItem(SeparatorType, ContextMenuItemTagNoAction, String()));
}
void ContextMenuController::showContextMenu(Event* event, PassRefPtr<ContextMenuProvider> menuProvider)
{
m_menuProvider = menuProvider;
- m_contextMenu = maybeCreateContextMenu(event);
+ m_contextMenu = createContextMenu(event);
if (!m_contextMenu) {
clearContextMenu();
return;
}
m_menuProvider->populateContextMenu(m_contextMenu.get());
- if (m_context.hitTestResult().isSelected()) {
+ if (m_hitTestResult.isSelected()) {
appendItem(*separatorItem(), m_contextMenu.get());
populate();
}
showContextMenu(event);
}
-#if ENABLE(SERVICE_CONTROLS)
-static Image* imageFromImageElementNode(Node& node)
-{
- RenderObject* renderer = node.renderer();
- if (!is<RenderImage>(renderer))
- return nullptr;
- CachedImage* image = downcast<RenderImage>(*renderer).cachedImage();
- if (!image || image->errorOccurred())
- return nullptr;
-
- return image->imageForRenderer(renderer);
-}
-#endif
-
-std::unique_ptr<ContextMenu> ContextMenuController::maybeCreateContextMenu(Event* event)
+PassOwnPtr<ContextMenu> ContextMenuController::createContextMenu(Event* event)
{
ASSERT(event);
- if (!is<MouseEvent>(*event))
+ if (!event->isMouseEvent())
return nullptr;
- MouseEvent& mouseEvent = downcast<MouseEvent>(*event);
- HitTestResult result(mouseEvent.absoluteLocation());
+ MouseEvent* mouseEvent = static_cast<MouseEvent*>(event);
+ HitTestResult result(mouseEvent->absoluteLocation());
+
+ if (Frame* frame = event->target()->toNode()->document().frame())
+ result = frame->eventHandler().hitTestResultAtPoint(mouseEvent->absoluteLocation());
- Node* node = event->target()->toNode();
- if (Frame* frame = node->document().frame())
- result = frame->eventHandler().hitTestResultAtPoint(mouseEvent.absoluteLocation());
-
if (!result.innerNonSharedNode())
return nullptr;
- m_context = ContextMenuContext(result);
+ m_hitTestResult = result;
-#if ENABLE(SERVICE_CONTROLS)
- if (node->isImageControlsButtonElement()) {
- if (Image* image = imageFromImageElementNode(*result.innerNonSharedNode()))
- m_context.setControlledImage(image);
-
- // FIXME: If we couldn't get the image then we shouldn't try to show the image controls menu for it.
- return nullptr;
- }
-#endif
-
- return std::unique_ptr<ContextMenu>(new ContextMenu);
+ return adoptPtr(new ContextMenu);
}
void ContextMenuController::showContextMenu(Event* event)
{
+#if ENABLE(INSPECTOR)
if (m_page.inspectorController().enabled())
addInspectElementItem();
+#endif
+#if USE(CROSS_PLATFORM_CONTEXT_MENUS)
+ m_contextMenu = m_client.customizeMenu(m_contextMenu.release());
+#else
+ PlatformMenuDescription customMenu = m_client.getCustomMenuFromDefaultItems(m_contextMenu.get());
+ m_contextMenu->setPlatformDescription(customMenu);
+#endif
event->setDefaultHandled();
}
-static void openNewWindow(const URL& urlToLoad, Frame* frame, ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy)
+static void openNewWindow(const URL& urlToLoad, Frame* frame)
{
Page* oldPage = frame->page();
if (!oldPage)
return;
+
+ FrameLoadRequest request(frame->document()->securityOrigin(), ResourceRequest(urlToLoad, frame->loader().outgoingReferrer()));
+ Page* newPage = oldPage;
- FrameLoadRequest request(frame->document()->securityOrigin(), ResourceRequest(urlToLoad, frame->loader().outgoingReferrer()), LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Suppress, shouldOpenExternalURLsPolicy);
-
- Page* newPage = oldPage->chrome().createWindow(frame, request, WindowFeatures(), NavigationAction(request.resourceRequest()));
+ newPage = oldPage->chrome().createWindow(frame, request, WindowFeatures(), NavigationAction(request.resourceRequest()));
if (!newPage)
return;
newPage->chrome().show();
- newPage->mainFrame().loader().loadFrameRequest(request, nullptr, nullptr);
+ newPage->mainFrame().loader().loadFrameRequest(request, false, false, 0, 0, MaybeSendReferrer);
}
#if PLATFORM(GTK)
@@ -211,80 +194,87 @@ static void insertUnicodeCharacter(UChar character, Frame* frame)
}
#endif
-void ContextMenuController::contextMenuItemSelected(ContextMenuAction action, const String& title)
+void ContextMenuController::contextMenuItemSelected(ContextMenuItem* item)
{
- if (action >= ContextMenuItemBaseCustomTag) {
+ ASSERT(item->type() == ActionType || item->type() == CheckableActionType);
+
+ if (item->action() >= ContextMenuItemBaseApplicationTag) {
+ m_client.contextMenuItemSelected(item, m_contextMenu.get());
+ return;
+ }
+
+ if (item->action() >= ContextMenuItemBaseCustomTag) {
ASSERT(m_menuProvider);
- m_menuProvider->contextMenuItemSelected(action, title);
+ m_menuProvider->contextMenuItemSelected(item);
return;
}
- Frame* frame = m_context.hitTestResult().innerNonSharedNode()->document().frame();
+ Frame* frame = m_hitTestResult.innerNonSharedNode()->document().frame();
if (!frame)
return;
- switch (action) {
+ switch (item->action()) {
case ContextMenuItemTagOpenLinkInNewWindow:
- openNewWindow(m_context.hitTestResult().absoluteLinkURL(), frame, ShouldOpenExternalURLsPolicy::ShouldAllowExternalSchemes);
+ openNewWindow(m_hitTestResult.absoluteLinkURL(), frame);
break;
case ContextMenuItemTagDownloadLinkToDisk:
// FIXME: Some day we should be able to do this from within WebCore. (Bug 117709)
- m_client.downloadURL(m_context.hitTestResult().absoluteLinkURL());
+ m_client.downloadURL(m_hitTestResult.absoluteLinkURL());
break;
case ContextMenuItemTagCopyLinkToClipboard:
- frame->editor().copyURL(m_context.hitTestResult().absoluteLinkURL(), m_context.hitTestResult().textContent());
+ frame->editor().copyURL(m_hitTestResult.absoluteLinkURL(), m_hitTestResult.textContent());
break;
case ContextMenuItemTagOpenImageInNewWindow:
- openNewWindow(m_context.hitTestResult().absoluteImageURL(), frame, ShouldOpenExternalURLsPolicy::ShouldNotAllow);
+ openNewWindow(m_hitTestResult.absoluteImageURL(), frame);
break;
case ContextMenuItemTagDownloadImageToDisk:
// FIXME: Some day we should be able to do this from within WebCore. (Bug 117709)
- m_client.downloadURL(m_context.hitTestResult().absoluteImageURL());
+ m_client.downloadURL(m_hitTestResult.absoluteImageURL());
break;
case ContextMenuItemTagCopyImageToClipboard:
// FIXME: The Pasteboard class is not written yet
// For now, call into the client. This is temporary!
- frame->editor().copyImage(m_context.hitTestResult());
+ frame->editor().copyImage(m_hitTestResult);
break;
#if PLATFORM(GTK) || PLATFORM(EFL)
case ContextMenuItemTagCopyImageUrlToClipboard:
- frame->editor().copyURL(m_context.hitTestResult().absoluteImageURL(), m_context.hitTestResult().textContent());
+ frame->editor().copyURL(m_hitTestResult.absoluteImageURL(), m_hitTestResult.textContent());
break;
#endif
case ContextMenuItemTagOpenMediaInNewWindow:
- openNewWindow(m_context.hitTestResult().absoluteMediaURL(), frame, ShouldOpenExternalURLsPolicy::ShouldNotAllow);
+ openNewWindow(m_hitTestResult.absoluteMediaURL(), frame);
break;
case ContextMenuItemTagDownloadMediaToDisk:
// FIXME: Some day we should be able to do this from within WebCore. (Bug 117709)
- m_client.downloadURL(m_context.hitTestResult().absoluteMediaURL());
+ m_client.downloadURL(m_hitTestResult.absoluteMediaURL());
break;
case ContextMenuItemTagCopyMediaLinkToClipboard:
- frame->editor().copyURL(m_context.hitTestResult().absoluteMediaURL(), m_context.hitTestResult().textContent());
+ frame->editor().copyURL(m_hitTestResult.absoluteMediaURL(), m_hitTestResult.textContent());
break;
case ContextMenuItemTagToggleMediaControls:
- m_context.hitTestResult().toggleMediaControlsDisplay();
+ m_hitTestResult.toggleMediaControlsDisplay();
break;
case ContextMenuItemTagToggleMediaLoop:
- m_context.hitTestResult().toggleMediaLoopPlayback();
+ m_hitTestResult.toggleMediaLoopPlayback();
break;
case ContextMenuItemTagToggleVideoFullscreen:
- m_context.hitTestResult().toggleMediaFullscreenState();
+ m_hitTestResult.toggleMediaFullscreenState();
break;
case ContextMenuItemTagEnterVideoFullscreen:
- m_context.hitTestResult().enterFullscreenForVideo();
+ m_hitTestResult.enterFullscreenForVideo();
break;
case ContextMenuItemTagMediaPlayPause:
- m_context.hitTestResult().toggleMediaPlayState();
+ m_hitTestResult.toggleMediaPlayState();
break;
case ContextMenuItemTagMediaMute:
- m_context.hitTestResult().toggleMediaMuteState();
+ m_hitTestResult.toggleMediaMuteState();
break;
case ContextMenuItemTagOpenFrameInNewWindow: {
DocumentLoader* loader = frame->loader().documentLoader();
if (!loader->unreachableURL().isEmpty())
- openNewWindow(loader->unreachableURL(), frame, ShouldOpenExternalURLsPolicy::ShouldNotAllow);
+ openNewWindow(loader->unreachableURL(), frame);
else
- openNewWindow(loader->url(), frame, ShouldOpenExternalURLsPolicy::ShouldNotAllow);
+ openNewWindow(loader->url(), frame);
break;
}
case ContextMenuItemTagCopy:
@@ -351,15 +341,15 @@ void ContextMenuController::contextMenuItemSelected(ContextMenuAction action, co
break;
#endif
case ContextMenuItemTagSpellingGuess: {
- VisibleSelection selection = frame->selection().selection();
- if (frame->editor().shouldInsertText(title, selection.toNormalizedRange().get(), EditorInsertActionPasted)) {
+ FrameSelection& frameSelection = frame->selection();
+ if (frame->editor().shouldInsertText(item->title(), frameSelection.toNormalizedRange().get(), EditorInsertActionPasted)) {
ReplaceSelectionCommand::CommandOptions replaceOptions = ReplaceSelectionCommand::MatchStyle | ReplaceSelectionCommand::PreventNesting;
if (frame->editor().behavior().shouldAllowSpellingSuggestionsWithoutSelection()) {
- ASSERT(selection.isCaretOrRange());
- VisibleSelection wordSelection(selection.base());
+ ASSERT(frameSelection.isCaretOrRange());
+ VisibleSelection wordSelection(frameSelection.base());
wordSelection.expandUsingGranularity(WordGranularity);
- frame->selection().setSelection(wordSelection);
+ frameSelection.setSelection(wordSelection);
} else {
ASSERT(frame->editor().selectedText().length());
replaceOptions |= ReplaceSelectionCommand::SelectReplacement;
@@ -367,9 +357,9 @@ void ContextMenuController::contextMenuItemSelected(ContextMenuAction action, co
Document* document = frame->document();
ASSERT(document);
- RefPtr<ReplaceSelectionCommand> command = ReplaceSelectionCommand::create(*document, createFragmentFromMarkup(*document, title, ""), replaceOptions);
+ RefPtr<ReplaceSelectionCommand> command = ReplaceSelectionCommand::create(*document, createFragmentFromMarkup(*document, item->title(), ""), replaceOptions);
applyCommand(command);
- frame->selection().revealSelection(ScrollAlignment::alignToEdgeIfNeeded);
+ frameSelection.revealSelection(ScrollAlignment::alignToEdgeIfNeeded);
}
break;
}
@@ -387,10 +377,13 @@ void ContextMenuController::contextMenuItemSelected(ContextMenuAction action, co
m_client.lookUpInDictionary(frame);
break;
case ContextMenuItemTagOpenLink:
- if (Frame* targetFrame = m_context.hitTestResult().targetFrame())
- targetFrame->loader().loadFrameRequest(FrameLoadRequest(frame->document()->securityOrigin(), ResourceRequest(m_context.hitTestResult().absoluteLinkURL(), frame->loader().outgoingReferrer()), LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Suppress, targetFrame->isMainFrame() ? ShouldOpenExternalURLsPolicy::ShouldAllow : ShouldOpenExternalURLsPolicy::ShouldNotAllow), nullptr, nullptr);
+ if (Frame* targetFrame = m_hitTestResult.targetFrame())
+ targetFrame->loader().loadFrameRequest(FrameLoadRequest(frame->document()->securityOrigin(), ResourceRequest(m_hitTestResult.absoluteLinkURL(), frame->loader().outgoingReferrer())), false, false, 0, 0, MaybeSendReferrer);
else
- openNewWindow(m_context.hitTestResult().absoluteLinkURL(), frame, ShouldOpenExternalURLsPolicy::ShouldAllow);
+ openNewWindow(m_hitTestResult.absoluteLinkURL(), frame);
+ break;
+ case ContextMenuItemTagOpenLinkInThisWindow:
+ frame->loader().loadFrameRequest(FrameLoadRequest(frame->document()->securityOrigin(), ResourceRequest(m_hitTestResult.absoluteLinkURL(), frame->loader().outgoingReferrer())), false, false, 0, 0, MaybeSendReferrer);
break;
case ContextMenuItemTagBold:
frame->editor().command("ToggleBold").execute();
@@ -407,8 +400,8 @@ void ContextMenuController::contextMenuItemSelected(ContextMenuAction action, co
break;
case ContextMenuItemTagStartSpeaking: {
RefPtr<Range> selectedRange = frame->selection().toNormalizedRange();
- if (!selectedRange || selectedRange->collapsed()) {
- Document& document = m_context.hitTestResult().innerNonSharedNode()->document();
+ if (!selectedRange || selectedRange->collapsed(IGNORE_EXCEPTION)) {
+ Document& document = m_hitTestResult.innerNonSharedNode()->document();
selectedRange = document.createRange();
selectedRange->selectNode(document.documentElement(), IGNORE_EXCEPTION);
}
@@ -436,7 +429,7 @@ void ContextMenuController::contextMenuItemSelected(ContextMenuAction action, co
case ContextMenuItemTagTextDirectionRightToLeft:
frame->editor().command("MakeTextWritingDirectionRightToLeft").execute();
break;
-#if PLATFORM(COCOA)
+#if PLATFORM(MAC)
case ContextMenuItemTagSearchInSpotlight:
m_client.searchWithSpotlight();
break;
@@ -453,7 +446,7 @@ void ContextMenuController::contextMenuItemSelected(ContextMenuAction action, co
case ContextMenuItemTagCheckGrammarWithSpelling:
frame->editor().toggleGrammarChecking();
break;
-#if PLATFORM(COCOA)
+#if PLATFORM(MAC)
case ContextMenuItemTagShowFonts:
frame->editor().showFontPanel();
break;
@@ -475,9 +468,9 @@ void ContextMenuController::contextMenuItemSelected(ContextMenuAction action, co
frame->editor().capitalizeWord();
break;
#endif
-#if PLATFORM(COCOA)
+#if PLATFORM(MAC)
case ContextMenuItemTagChangeBack:
- frame->editor().changeBackToReplacedString(m_context.hitTestResult().replacedString());
+ frame->editor().changeBackToReplacedString(m_hitTestResult.replacedString());
break;
#endif
#if USE(AUTOMATIC_TEXT_REPLACEMENT)
@@ -503,12 +496,14 @@ void ContextMenuController::contextMenuItemSelected(ContextMenuAction action, co
frame->editor().toggleAutomaticSpellingCorrection();
break;
#endif
+#if ENABLE(INSPECTOR)
case ContextMenuItemTagInspectElement:
if (Page* page = frame->page())
- page->inspectorController().inspect(m_context.hitTestResult().innerNonSharedNode());
+ page->inspectorController().inspect(m_hitTestResult.innerNonSharedNode());
break;
+#endif
case ContextMenuItemTagDictationAlternative:
- frame->editor().applyDictationAlternativelternative(title);
+ frame->editor().applyDictationAlternativelternative(item->title());
break;
default:
break;
@@ -526,26 +521,26 @@ void ContextMenuController::createAndAppendFontSubMenu(ContextMenuItem& fontMenu
{
ContextMenu fontMenu;
-#if PLATFORM(COCOA)
+#if PLATFORM(MAC)
ContextMenuItem showFonts(ActionType, ContextMenuItemTagShowFonts, contextMenuItemTagShowFonts());
#endif
ContextMenuItem bold(CheckableActionType, ContextMenuItemTagBold, contextMenuItemTagBold());
ContextMenuItem italic(CheckableActionType, ContextMenuItemTagItalic, contextMenuItemTagItalic());
ContextMenuItem underline(CheckableActionType, ContextMenuItemTagUnderline, contextMenuItemTagUnderline());
ContextMenuItem outline(ActionType, ContextMenuItemTagOutline, contextMenuItemTagOutline());
-#if PLATFORM(COCOA)
+#if PLATFORM(MAC)
ContextMenuItem styles(ActionType, ContextMenuItemTagStyles, contextMenuItemTagStyles());
ContextMenuItem showColors(ActionType, ContextMenuItemTagShowColors, contextMenuItemTagShowColors());
#endif
-#if PLATFORM(COCOA)
+#if PLATFORM(MAC)
appendItem(showFonts, &fontMenu);
#endif
appendItem(bold, &fontMenu);
appendItem(italic, &fontMenu);
appendItem(underline, &fontMenu);
appendItem(outline, &fontMenu);
-#if PLATFORM(COCOA)
+#if PLATFORM(MAC)
appendItem(styles, &fontMenu);
appendItem(*separatorItem(), &fontMenu);
appendItem(showColors, &fontMenu);
@@ -569,19 +564,19 @@ void ContextMenuController::createAndAppendSpellingAndGrammarSubMenu(ContextMenu
contextMenuItemTagCheckSpellingWhileTyping());
ContextMenuItem grammarWithSpelling(CheckableActionType, ContextMenuItemTagCheckGrammarWithSpelling,
contextMenuItemTagCheckGrammarWithSpelling());
-#if PLATFORM(COCOA)
+#if PLATFORM(MAC)
ContextMenuItem correctSpelling(CheckableActionType, ContextMenuItemTagCorrectSpellingAutomatically,
contextMenuItemTagCorrectSpellingAutomatically());
#endif
appendItem(showSpellingPanel, &spellingAndGrammarMenu);
appendItem(checkSpelling, &spellingAndGrammarMenu);
-#if PLATFORM(COCOA)
+#if PLATFORM(MAC)
appendItem(*separatorItem(), &spellingAndGrammarMenu);
#endif
appendItem(checkAsYouType, &spellingAndGrammarMenu);
appendItem(grammarWithSpelling, &spellingAndGrammarMenu);
-#if PLATFORM(COCOA)
+#if PLATFORM(MAC)
appendItem(correctSpelling, &spellingAndGrammarMenu);
#endif
@@ -591,7 +586,7 @@ void ContextMenuController::createAndAppendSpellingAndGrammarSubMenu(ContextMenu
#endif // !PLATFORM(GTK)
-#if PLATFORM(COCOA)
+#if PLATFORM(MAC)
void ContextMenuController::createAndAppendSpeechSubMenu(ContextMenuItem& speechMenuItem)
{
@@ -674,7 +669,7 @@ void ContextMenuController::createAndAppendTextDirectionSubMenu(ContextMenuItem&
#endif
-#if PLATFORM(COCOA)
+#if PLATFORM(MAC)
void ContextMenuController::createAndAppendSubstitutionsSubMenu(ContextMenuItem& substitutionsMenuItem)
{
@@ -715,13 +710,26 @@ void ContextMenuController::createAndAppendTransformationsSubMenu(ContextMenuIte
#endif
-#if PLATFORM(COCOA)
+static bool selectionContainsPossibleWord(Frame* frame)
+{
+ // Current algorithm: look for a character that's not just a separator.
+ for (TextIterator it(frame->selection().toNormalizedRange().get()); !it.atEnd(); it.advance()) {
+ int length = it.length();
+ for (int i = 0; i < length; ++i) {
+ if (!(U_GET_GC_MASK(it.characterAt(i)) & U_GC_Z_MASK))
+ return true;
+ }
+ }
+ return false;
+}
+
+#if PLATFORM(MAC)
#define SUPPORTS_TOGGLE_VIDEO_FULLSCREEN 1
#else
#define SUPPORTS_TOGGLE_VIDEO_FULLSCREEN 0
#endif
-#if PLATFORM(COCOA)
+#if PLATFORM(MAC)
#define SUPPORTS_TOGGLE_SHOW_HIDE_MEDIA_CONTROLS 1
#else
#define SUPPORTS_TOGGLE_SHOW_HIDE_MEDIA_CONTROLS 0
@@ -766,7 +774,7 @@ void ContextMenuController::populate()
contextMenuItemTagEnterVideoFullscreen());
ContextMenuItem ToggleVideoFullscreen(ActionType, ContextMenuItemTagToggleVideoFullscreen,
contextMenuItemTagEnterVideoFullscreen());
-#if PLATFORM(COCOA)
+#if PLATFORM(MAC)
ContextMenuItem SearchSpotlightItem(ActionType, ContextMenuItemTagSearchInSpotlight,
contextMenuItemTagSearchInSpotlight());
#endif
@@ -797,35 +805,20 @@ void ContextMenuController::populate()
ContextMenuItem SelectAllItem(ActionType, ContextMenuItemTagSelectAll, contextMenuItemTagSelectAll());
#endif
-#if PLATFORM(GTK) || PLATFORM(EFL) || PLATFORM(WIN)
- ContextMenuItem ShareMenuItem;
-#else
- ContextMenuItem ShareMenuItem(SubmenuType, ContextMenuItemTagShareMenu, emptyString());
-#endif
-
- Node* node = m_context.hitTestResult().innerNonSharedNode();
+ Node* node = m_hitTestResult.innerNonSharedNode();
if (!node)
return;
#if PLATFORM(GTK)
- if (!m_context.hitTestResult().isContentEditable() && is<HTMLFormControlElement>(*node))
+ if (!m_hitTestResult.isContentEditable() && (node->isElementNode() && toElement(node)->isFormControlElement()))
return;
#endif
Frame* frame = node->document().frame();
if (!frame)
return;
-#if ENABLE(SERVICE_CONTROLS)
- // The default image control menu gets populated solely by the platform.
- if (m_context.controlledImage())
- return;
-#endif
-
- if (!m_context.hitTestResult().isContentEditable()) {
- String selectedString = m_context.hitTestResult().selectedText();
- m_context.setSelectedText(selectedString);
-
+ if (!m_hitTestResult.isContentEditable()) {
FrameLoader& loader = frame->loader();
- URL linkURL = m_context.hitTestResult().absoluteLinkURL();
+ URL linkURL = m_hitTestResult.absoluteLinkURL();
if (!linkURL.isEmpty()) {
if (loader.client().canHandleRequest(ResourceRequest(linkURL))) {
appendItem(OpenLinkItem, m_contextMenu.get());
@@ -835,21 +828,21 @@ void ContextMenuController::populate()
appendItem(CopyLinkItem, m_contextMenu.get());
}
- URL imageURL = m_context.hitTestResult().absoluteImageURL();
+ URL imageURL = m_hitTestResult.absoluteImageURL();
if (!imageURL.isEmpty()) {
if (!linkURL.isEmpty())
appendItem(*separatorItem(), m_contextMenu.get());
appendItem(OpenImageInNewWindowItem, m_contextMenu.get());
appendItem(DownloadImageItem, m_contextMenu.get());
- if (imageURL.isLocalFile() || m_context.hitTestResult().image())
+ if (imageURL.isLocalFile() || m_hitTestResult.image())
appendItem(CopyImageItem, m_contextMenu.get());
#if PLATFORM(GTK) || PLATFORM(EFL)
appendItem(CopyImageUrlItem, m_contextMenu.get());
#endif
}
- URL mediaURL = m_context.hitTestResult().absoluteMediaURL();
+ URL mediaURL = m_hitTestResult.absoluteMediaURL();
if (!mediaURL.isEmpty()) {
if (!linkURL.isEmpty() || !imageURL.isEmpty())
appendItem(*separatorItem(), m_contextMenu.get());
@@ -866,14 +859,15 @@ void ContextMenuController::populate()
appendItem(*separatorItem(), m_contextMenu.get());
appendItem(CopyMediaLinkItem, m_contextMenu.get());
appendItem(OpenMediaInNewWindowItem, m_contextMenu.get());
- if (m_context.hitTestResult().isDownloadableMedia() && loader.client().canHandleRequest(ResourceRequest(mediaURL)))
+ if (loader.client().canHandleRequest(ResourceRequest(mediaURL)))
appendItem(DownloadMediaItem, m_contextMenu.get());
}
if (imageURL.isEmpty() && linkURL.isEmpty() && mediaURL.isEmpty()) {
- if (m_context.hitTestResult().isSelected()) {
- if (!selectedString.isEmpty()) {
-#if PLATFORM(COCOA)
+ if (m_hitTestResult.isSelected()) {
+ if (selectionContainsPossibleWord(frame)) {
+#if PLATFORM(MAC)
+ String selectedString = frame->displayStringModifiedByEncoding(frame->editor().selectedText());
ContextMenuItem LookUpInDictionaryItem(ActionType, ContextMenuItemTagLookUpInDictionary, contextMenuItemTagLookUpInDictionary(selectedString));
appendItem(LookUpInDictionaryItem, m_contextMenu.get());
@@ -886,10 +880,7 @@ void ContextMenuController::populate()
}
appendItem(CopyItem, m_contextMenu.get());
-#if PLATFORM(COCOA)
- appendItem(*separatorItem(), m_contextMenu.get());
-
- appendItem(ShareMenuItem, m_contextMenu.get());
+#if PLATFORM(MAC)
appendItem(*separatorItem(), m_contextMenu.get());
ContextMenuItem SpeechMenuItem(SubmenuType, ContextMenuItemTagSpeechMenu, contextMenuItemTagSpeechMenu());
@@ -897,7 +888,9 @@ void ContextMenuController::populate()
appendItem(SpeechMenuItem, m_contextMenu.get());
#endif
} else {
- if (!(frame->page() && (frame->page()->inspectorController().inspectionLevel() > 0 || frame->page()->inspectorController().hasRemoteFrontend()))) {
+#if ENABLE(INSPECTOR)
+ if (!(frame->page() && (frame->page()->inspectorController().hasInspectorFrontendClient() || frame->page()->inspectorController().hasRemoteFrontend()))) {
+#endif
// In GTK+ unavailable items are not hidden but insensitive.
#if PLATFORM(GTK)
@@ -919,22 +912,16 @@ void ContextMenuController::populate()
else
appendItem(ReloadItem, m_contextMenu.get());
#endif
+#if ENABLE(INSPECTOR)
}
+#endif
if (frame->page() && !frame->isMainFrame())
appendItem(OpenFrameItem, m_contextMenu.get());
-
- if (!ShareMenuItem.isNull()) {
- appendItem(*separatorItem(), m_contextMenu.get());
- appendItem(ShareMenuItem, m_contextMenu.get());
- }
}
- } else if (!ShareMenuItem.isNull()) {
- appendItem(*separatorItem(), m_contextMenu.get());
- appendItem(ShareMenuItem, m_contextMenu.get());
}
} else { // Make an editing context menu
- bool inPasswordField = frame->selection().selection().isInPasswordField();
+ bool inPasswordField = frame->selection().isInPasswordField();
if (!inPasswordField) {
bool haveContextMenuItemsForMisspellingOrGrammer = false;
bool spellCheckingEnabled = frame->editor().isSpellCheckingEnabledFor(node);
@@ -945,7 +932,8 @@ void ContextMenuController::populate()
bool badGrammar;
Vector<String> guesses = frame->editor().guessesForMisspelledOrUngrammatical(misspelling, badGrammar);
if (misspelling || badGrammar) {
- if (guesses.isEmpty()) {
+ size_t size = guesses.size();
+ if (!size) {
// If there's bad grammar but no suggestions (e.g., repeated word), just leave off the suggestions
// list and trailing separator rather than adding a "No Guesses Found" item (matches AppKit)
if (misspelling) {
@@ -953,7 +941,8 @@ void ContextMenuController::populate()
appendItem(*separatorItem(), m_contextMenu.get());
}
} else {
- for (const auto& guess : guesses) {
+ for (unsigned i = 0; i < size; i++) {
+ const String &guess = guesses[i];
if (!guess.isEmpty()) {
ContextMenuItem item(ActionType, ContextMenuItemTagSpellingGuess, guess);
appendItem(item, m_contextMenu.get());
@@ -968,10 +957,10 @@ void ContextMenuController::populate()
appendItem(IgnoreGrammarItem, m_contextMenu.get());
appendItem(*separatorItem(), m_contextMenu.get());
haveContextMenuItemsForMisspellingOrGrammer = true;
-#if PLATFORM(COCOA)
+#if PLATFORM(MAC)
} else {
// If the string was autocorrected, generate a contextual menu item allowing it to be changed back.
- String replacedString = m_context.hitTestResult().replacedString();
+ String replacedString = m_hitTestResult.replacedString();
if (!replacedString.isEmpty()) {
ContextMenuItem item(ActionType, ContextMenuItemTagChangeBack, contextMenuItemTagChangeBack(replacedString));
appendItem(item, m_contextMenu.get());
@@ -984,10 +973,10 @@ void ContextMenuController::populate()
if (!haveContextMenuItemsForMisspellingOrGrammer) {
// Spelling and grammar checking is mutually exclusive with dictation alternatives.
- Vector<String> dictationAlternatives = m_context.hitTestResult().dictationAlternatives();
+ Vector<String> dictationAlternatives = m_hitTestResult.dictationAlternatives();
if (!dictationAlternatives.isEmpty()) {
- for (auto& alternative : dictationAlternatives) {
- ContextMenuItem item(ActionType, ContextMenuItemTagDictationAlternative, alternative);
+ for (size_t i = 0; i < dictationAlternatives.size(); ++i) {
+ ContextMenuItem item(ActionType, ContextMenuItemTagDictationAlternative, dictationAlternatives[i]);
appendItem(item, m_contextMenu.get());
}
appendItem(*separatorItem(), m_contextMenu.get());
@@ -996,7 +985,7 @@ void ContextMenuController::populate()
}
FrameLoader& loader = frame->loader();
- URL linkURL = m_context.hitTestResult().absoluteLinkURL();
+ URL linkURL = m_hitTestResult.absoluteLinkURL();
if (!linkURL.isEmpty()) {
if (loader.client().canHandleRequest(ResourceRequest(linkURL))) {
appendItem(OpenLinkItem, m_contextMenu.get());
@@ -1007,10 +996,10 @@ void ContextMenuController::populate()
appendItem(*separatorItem(), m_contextMenu.get());
}
- String selectedText = m_context.hitTestResult().selectedText();
- if (m_context.hitTestResult().isSelected() && !inPasswordField && !selectedText.isEmpty()) {
-#if PLATFORM(COCOA)
- ContextMenuItem LookUpInDictionaryItem(ActionType, ContextMenuItemTagLookUpInDictionary, contextMenuItemTagLookUpInDictionary(selectedText));
+ if (m_hitTestResult.isSelected() && !inPasswordField && selectionContainsPossibleWord(frame)) {
+#if PLATFORM(MAC)
+ String selectedString = frame->displayStringModifiedByEncoding(frame->editor().selectedText());
+ ContextMenuItem LookUpInDictionaryItem(ActionType, ContextMenuItemTagLookUpInDictionary, contextMenuItemTagLookUpInDictionary(selectedString));
appendItem(LookUpInDictionaryItem, m_contextMenu.get());
#endif
@@ -1040,7 +1029,7 @@ void ContextMenuController::populate()
createAndAppendSpellingAndGrammarSubMenu(SpellingAndGrammarMenuItem);
appendItem(SpellingAndGrammarMenuItem, m_contextMenu.get());
#endif
-#if PLATFORM(COCOA)
+#if PLATFORM(MAC)
ContextMenuItem substitutionsMenuItem(SubmenuType, ContextMenuItemTagSubstitutionsMenu,
contextMenuItemTagSubstitutionsMenu());
createAndAppendSubstitutionsSubMenu(substitutionsMenuItem);
@@ -1061,7 +1050,7 @@ void ContextMenuController::populate()
createAndAppendFontSubMenu(FontMenuItem);
appendItem(FontMenuItem, m_contextMenu.get());
}
-#if PLATFORM(COCOA)
+#if PLATFORM(MAC)
ContextMenuItem SpeechMenuItem(SubmenuType, ContextMenuItemTagSpeechMenu, contextMenuItemTagSpeechMenu());
createAndAppendSpeechSubMenu(SpeechMenuItem);
appendItem(SpeechMenuItem, m_contextMenu.get());
@@ -1090,17 +1079,13 @@ void ContextMenuController::populate()
}
#endif
}
-
- if (!ShareMenuItem.isNull()) {
- appendItem(*separatorItem(), m_contextMenu.get());
- appendItem(ShareMenuItem, m_contextMenu.get());
- }
}
}
+#if ENABLE(INSPECTOR)
void ContextMenuController::addInspectElementItem()
{
- Node* node = m_context.hitTestResult().innerNonSharedNode();
+ Node* node = m_hitTestResult.innerNonSharedNode();
if (!node)
return;
@@ -1113,17 +1098,22 @@ void ContextMenuController::addInspectElementItem()
return;
ContextMenuItem InspectElementItem(ActionType, ContextMenuItemTagInspectElement, contextMenuItemTagInspectElement());
+#if USE(CROSS_PLATFORM_CONTEXT_MENUS)
if (m_contextMenu && !m_contextMenu->items().isEmpty())
+#else
+ if (m_contextMenu && m_contextMenu->itemCount())
+#endif
appendItem(*separatorItem(), m_contextMenu.get());
appendItem(InspectElementItem, m_contextMenu.get());
}
+#endif // ENABLE(INSPECTOR)
void ContextMenuController::checkOrEnableIfNeeded(ContextMenuItem& item) const
{
if (item.type() == SeparatorType)
return;
- Frame* frame = m_context.hitTestResult().innerNonSharedNode()->document().frame();
+ Frame* frame = m_hitTestResult.innerNonSharedNode()->document().frame();
if (!frame)
return;
@@ -1243,7 +1233,7 @@ void ContextMenuController::checkOrEnableIfNeeded(ContextMenuItem& item) const
case ContextMenuItemTagCheckSpellingWhileTyping:
shouldCheck = frame->editor().isContinuousSpellCheckingEnabled();
break;
-#if PLATFORM(COCOA)
+#if PLATFORM(MAC)
case ContextMenuItemTagSubstitutionsMenu:
case ContextMenuItemTagTransformationsMenu:
break;
@@ -1281,7 +1271,7 @@ void ContextMenuController::checkOrEnableIfNeeded(ContextMenuItem& item) const
case ContextMenuItemTagStopSpeaking:
shouldEnable = m_client.isSpeaking();
break;
-#else // PLATFORM(COCOA) ends here
+#else // PLATFORM(MAC) ends here
case ContextMenuItemTagStopSpeaking:
break;
#endif
@@ -1310,57 +1300,51 @@ void ContextMenuController::checkOrEnableIfNeeded(ContextMenuItem& item) const
#endif
case ContextMenuItemTagNoAction:
case ContextMenuItemTagOpenLinkInNewWindow:
+ case ContextMenuItemTagOpenLinkInThisWindow:
case ContextMenuItemTagDownloadLinkToDisk:
case ContextMenuItemTagCopyLinkToClipboard:
case ContextMenuItemTagOpenImageInNewWindow:
+ case ContextMenuItemTagDownloadImageToDisk:
case ContextMenuItemTagCopyImageToClipboard:
#if PLATFORM(GTK) || PLATFORM(EFL)
case ContextMenuItemTagCopyImageUrlToClipboard:
#endif
break;
- case ContextMenuItemTagDownloadImageToDisk:
-#if PLATFORM(MAC)
- if (WebCore::protocolIs(m_context.hitTestResult().absoluteImageURL(), "file"))
- shouldEnable = false;
-#endif
- break;
case ContextMenuItemTagOpenMediaInNewWindow:
- if (m_context.hitTestResult().mediaIsVideo())
+ if (m_hitTestResult.mediaIsVideo())
item.setTitle(contextMenuItemTagOpenVideoInNewWindow());
else
item.setTitle(contextMenuItemTagOpenAudioInNewWindow());
break;
case ContextMenuItemTagDownloadMediaToDisk:
- if (m_context.hitTestResult().mediaIsVideo())
+ if (m_hitTestResult.mediaIsVideo())
item.setTitle(contextMenuItemTagDownloadVideoToDisk());
else
item.setTitle(contextMenuItemTagDownloadAudioToDisk());
- if (WebCore::protocolIs(m_context.hitTestResult().absoluteImageURL(), "file"))
- shouldEnable = false;
break;
case ContextMenuItemTagCopyMediaLinkToClipboard:
- if (m_context.hitTestResult().mediaIsVideo())
+ if (m_hitTestResult.mediaIsVideo())
item.setTitle(contextMenuItemTagCopyVideoLinkToClipboard());
else
item.setTitle(contextMenuItemTagCopyAudioLinkToClipboard());
break;
case ContextMenuItemTagToggleMediaControls:
#if SUPPORTS_TOGGLE_SHOW_HIDE_MEDIA_CONTROLS
- item.setTitle(m_context.hitTestResult().mediaControlsEnabled() ? contextMenuItemTagHideMediaControls() : contextMenuItemTagShowMediaControls());
+ item.setTitle(m_hitTestResult.mediaControlsEnabled() ? contextMenuItemTagHideMediaControls() : contextMenuItemTagShowMediaControls());
#else
- shouldCheck = m_context.hitTestResult().mediaControlsEnabled();
+ shouldCheck = m_hitTestResult.mediaControlsEnabled();
#endif
break;
case ContextMenuItemTagToggleMediaLoop:
- shouldCheck = m_context.hitTestResult().mediaLoopEnabled();
+ shouldCheck = m_hitTestResult.mediaLoopEnabled();
break;
case ContextMenuItemTagToggleVideoFullscreen:
#if SUPPORTS_TOGGLE_VIDEO_FULLSCREEN
- item.setTitle(m_context.hitTestResult().mediaIsInFullscreen() ? contextMenuItemTagExitVideoFullscreen() : contextMenuItemTagEnterVideoFullscreen());
+ item.setTitle(m_hitTestResult.mediaIsInFullscreen() ? contextMenuItemTagExitVideoFullscreen() : contextMenuItemTagEnterVideoFullscreen());
break;
#endif
case ContextMenuItemTagEnterVideoFullscreen:
- shouldEnable = m_context.hitTestResult().mediaSupportsFullscreen();
+ shouldEnable = m_hitTestResult.mediaSupportsFullscreen();
break;
case ContextMenuItemTagOpenFrameInNewWindow:
case ContextMenuItemTagSpellingGuess:
@@ -1389,22 +1373,24 @@ void ContextMenuController::checkOrEnableIfNeeded(ContextMenuItem& item) const
case ContextMenuItemTagTextDirectionMenu:
case ContextMenuItemTagPDFSinglePageScrolling:
case ContextMenuItemTagPDFFacingPagesScrolling:
+#if ENABLE(INSPECTOR)
case ContextMenuItemTagInspectElement:
+#endif
case ContextMenuItemBaseCustomTag:
+ case ContextMenuItemCustomTagNoAction:
case ContextMenuItemLastCustomTag:
case ContextMenuItemBaseApplicationTag:
case ContextMenuItemTagDictationAlternative:
- case ContextMenuItemTagShareMenu:
break;
case ContextMenuItemTagMediaPlayPause:
- if (m_context.hitTestResult().mediaPlaying())
+ if (m_hitTestResult.mediaPlaying())
item.setTitle(contextMenuItemTagMediaPause());
else
item.setTitle(contextMenuItemTagMediaPlay());
break;
case ContextMenuItemTagMediaMute:
- shouldEnable = m_context.hitTestResult().mediaHasAudio();
- shouldCheck = shouldEnable && m_context.hitTestResult().mediaMuted();
+ shouldEnable = m_hitTestResult.mediaHasAudio();
+ shouldCheck = shouldEnable && m_hitTestResult.mediaMuted();
break;
}
@@ -1418,7 +1404,7 @@ void ContextMenuController::showContextMenuAt(Frame* frame, const IntPoint& clic
clearContextMenu();
// Simulate a click in the middle of the accessibility object.
- PlatformMouseEvent mouseEvent(clickPoint, clickPoint, RightButton, PlatformEvent::MousePressed, 1, false, false, false, false, currentTime(), ForceAtClick);
+ PlatformMouseEvent mouseEvent(clickPoint, clickPoint, RightButton, PlatformEvent::MousePressed, 1, false, false, false, false, currentTime());
frame->eventHandler().handleMousePressEvent(mouseEvent);
bool handled = frame->eventHandler().sendContextMenuEvent(mouseEvent);
if (handled)
@@ -1426,15 +1412,6 @@ void ContextMenuController::showContextMenuAt(Frame* frame, const IntPoint& clic
}
#endif
-#if ENABLE(SERVICE_CONTROLS)
-void ContextMenuController::showImageControlsMenu(Event* event)
-{
- clearContextMenu();
- handleContextMenuEvent(event);
- m_client.showContextMenu();
-}
-#endif
-
} // namespace WebCore
#endif // ENABLE(CONTEXT_MENUS)
diff --git a/Source/WebCore/page/ContextMenuController.h b/Source/WebCore/page/ContextMenuController.h
index 7b11850f9..fef13537d 100644
--- a/Source/WebCore/page/ContextMenuController.h
+++ b/Source/WebCore/page/ContextMenuController.h
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -28,78 +28,70 @@
#if ENABLE(CONTEXT_MENUS)
-#include "ContextMenuContext.h"
-#include "ContextMenuItem.h"
+#include "HitTestResult.h"
#include <wtf/Noncopyable.h>
+#include <wtf/OwnPtr.h>
#include <wtf/PassRefPtr.h>
#include <wtf/RefPtr.h>
namespace WebCore {
-class ContextMenu;
-class ContextMenuClient;
-class ContextMenuItem;
-class ContextMenuProvider;
-class Event;
-class Page;
+ class ContextMenu;
+ class ContextMenuClient;
+ class ContextMenuItem;
+ class ContextMenuProvider;
+ class Event;
+ class Page;
-class ContextMenuController {
- WTF_MAKE_NONCOPYABLE(ContextMenuController); WTF_MAKE_FAST_ALLOCATED;
-public:
- ContextMenuController(Page&, ContextMenuClient&);
- ~ContextMenuController();
+ class ContextMenuController {
+ WTF_MAKE_NONCOPYABLE(ContextMenuController); WTF_MAKE_FAST_ALLOCATED;
+ public:
+ ContextMenuController(Page&, ContextMenuClient&);
+ ~ContextMenuController();
- Page& page() { return m_page; }
- ContextMenuClient& client() { return m_client; }
+ ContextMenu* contextMenu() const { return m_contextMenu.get(); }
+ void clearContextMenu();
- ContextMenu* contextMenu() const { return m_contextMenu.get(); }
- WEBCORE_EXPORT void clearContextMenu();
+ void handleContextMenuEvent(Event*);
+ void showContextMenu(Event*, PassRefPtr<ContextMenuProvider>);
- void handleContextMenuEvent(Event*);
- void showContextMenu(Event*, PassRefPtr<ContextMenuProvider>);
+ void populate();
+ void contextMenuItemSelected(ContextMenuItem*);
+ void addInspectElementItem();
- void populate();
- WEBCORE_EXPORT void contextMenuItemSelected(ContextMenuAction, const String& title);
- void addInspectElementItem();
+ void checkOrEnableIfNeeded(ContextMenuItem&) const;
- WEBCORE_EXPORT void checkOrEnableIfNeeded(ContextMenuItem&) const;
-
- void setContextMenuContext(const ContextMenuContext& context) { m_context = context; }
- const ContextMenuContext& context() const { return m_context; }
- const HitTestResult& hitTestResult() const { return m_context.hitTestResult(); }
+ void setHitTestResult(const HitTestResult& result) { m_hitTestResult = result; }
+ const HitTestResult& hitTestResult() { return m_hitTestResult; }
#if USE(ACCESSIBILITY_CONTEXT_MENUS)
- void showContextMenuAt(Frame*, const IntPoint& clickPoint);
-#endif
-
-#if ENABLE(SERVICE_CONTROLS)
- void showImageControlsMenu(Event*);
+ void showContextMenuAt(Frame*, const IntPoint& clickPoint);
#endif
-private:
- std::unique_ptr<ContextMenu> maybeCreateContextMenu(Event*);
- void showContextMenu(Event*);
-
- void appendItem(ContextMenuItem&, ContextMenu* parentMenu);
-
- void createAndAppendFontSubMenu(ContextMenuItem&);
- void createAndAppendSpellingAndGrammarSubMenu(ContextMenuItem&);
- void createAndAppendSpellingSubMenu(ContextMenuItem&);
- void createAndAppendSpeechSubMenu(ContextMenuItem&);
- void createAndAppendWritingDirectionSubMenu(ContextMenuItem&);
- void createAndAppendTextDirectionSubMenu(ContextMenuItem&);
- void createAndAppendSubstitutionsSubMenu(ContextMenuItem&);
- void createAndAppendTransformationsSubMenu(ContextMenuItem&);
+ private:
+ PassOwnPtr<ContextMenu> createContextMenu(Event*);
+ void showContextMenu(Event*);
+
+ void appendItem(ContextMenuItem&, ContextMenu* parentMenu);
+
+ void createAndAppendFontSubMenu(ContextMenuItem&);
+ void createAndAppendSpellingAndGrammarSubMenu(ContextMenuItem&);
+ void createAndAppendSpellingSubMenu(ContextMenuItem&);
+ void createAndAppendSpeechSubMenu(ContextMenuItem& );
+ void createAndAppendWritingDirectionSubMenu(ContextMenuItem&);
+ void createAndAppendTextDirectionSubMenu(ContextMenuItem&);
+ void createAndAppendSubstitutionsSubMenu(ContextMenuItem&);
+ void createAndAppendTransformationsSubMenu(ContextMenuItem&);
#if PLATFORM(GTK)
- void createAndAppendUnicodeSubMenu(ContextMenuItem&);
+ void createAndAppendUnicodeSubMenu(ContextMenuItem&);
#endif
- Page& m_page;
- ContextMenuClient& m_client;
- std::unique_ptr<ContextMenu> m_contextMenu;
- RefPtr<ContextMenuProvider> m_menuProvider;
- ContextMenuContext m_context;
-};
+ Page& m_page;
+ ContextMenuClient& m_client;
+ OwnPtr<ContextMenu> m_contextMenu;
+ RefPtr<ContextMenuProvider> m_menuProvider;
+ HitTestResult m_hitTestResult;
+ };
}
diff --git a/Source/WebCore/page/ContextMenuProvider.h b/Source/WebCore/page/ContextMenuProvider.h
index 17138b78c..57598d1bc 100644
--- a/Source/WebCore/page/ContextMenuProvider.h
+++ b/Source/WebCore/page/ContextMenuProvider.h
@@ -31,7 +31,6 @@
#ifndef ContextMenuProvider_h
#define ContextMenuProvider_h
-#include "ContextMenuItem.h"
#include <wtf/RefCounted.h>
namespace WebCore {
@@ -44,7 +43,7 @@ public:
virtual ~ContextMenuProvider() { };
virtual void populateContextMenu(ContextMenu*) = 0;
- virtual void contextMenuItemSelected(ContextMenuAction, const String& title) = 0;
+ virtual void contextMenuItemSelected(ContextMenuItem*) = 0;
virtual void contextMenuCleared() = 0;
};
diff --git a/Source/WebCore/page/Crypto.cpp b/Source/WebCore/page/Crypto.cpp
index 5aaa709bd..335873051 100644
--- a/Source/WebCore/page/Crypto.cpp
+++ b/Source/WebCore/page/Crypto.cpp
@@ -39,6 +39,15 @@
namespace WebCore {
+namespace {
+
+bool isIntegerArray(ArrayBufferView* array)
+{
+ return JSC::isInt(array->getType());
+}
+
+}
+
Crypto::Crypto(Document& document)
: ContextDestructionObserver(&document)
{
@@ -50,12 +59,12 @@ Crypto::~Crypto()
Document* Crypto::document() const
{
- return downcast<Document>(scriptExecutionContext());
+ return toDocument(scriptExecutionContext());
}
void Crypto::getRandomValues(ArrayBufferView* array, ExceptionCode& ec)
{
- if (!array || !JSC::isInt(array->getType())) {
+ if (!array || !isIntegerArray(array)) {
ec = TYPE_MISMATCH_ERR;
return;
}
diff --git a/Source/WebCore/page/Crypto.h b/Source/WebCore/page/Crypto.h
index af0fc0468..94eab5678 100644
--- a/Source/WebCore/page/Crypto.h
+++ b/Source/WebCore/page/Crypto.h
@@ -49,7 +49,7 @@ class SubtleCrypto;
class Crypto : public ContextDestructionObserver, public RefCounted<Crypto> {
public:
- static Ref<Crypto> create(Document& document) { return adoptRef(*new Crypto(document)); }
+ static PassRefPtr<Crypto> create(Document& document) { return adoptRef(new Crypto(document)); }
virtual ~Crypto();
Document* document() const;
diff --git a/Source/WebCore/page/DOMSecurityPolicy.cpp b/Source/WebCore/page/DOMSecurityPolicy.cpp
new file mode 100644
index 000000000..7a264ee4a
--- /dev/null
+++ b/Source/WebCore/page/DOMSecurityPolicy.cpp
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2012 Google, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "DOMSecurityPolicy.h"
+
+#include "ContentSecurityPolicy.h"
+#include "ContextDestructionObserver.h"
+#include "DOMStringList.h"
+#include "Frame.h"
+#include "ScriptCallStack.h"
+#include "ScriptExecutionContext.h"
+#include <wtf/text/TextPosition.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+namespace {
+
+bool isPolicyActiveInContext(ScriptExecutionContext* context)
+{
+ // If the ScriptExecutionContext has been destroyed, there's no active policy.
+ if (!context)
+ return false;
+
+ return context->contentSecurityPolicy()->isActive();
+}
+
+template<bool (ContentSecurityPolicy::*allowWithType)(const String&, const String&, const URL&, ContentSecurityPolicy::ReportingStatus) const>
+bool isAllowedWithType(ScriptExecutionContext* context, const String& type)
+{
+ if (!isPolicyActiveInContext(context))
+ return true;
+
+ return (context->contentSecurityPolicy()->*allowWithType)(type, type, URL(), ContentSecurityPolicy::SuppressReport);
+}
+
+template<bool (ContentSecurityPolicy::*allowWithURL)(const URL&, ContentSecurityPolicy::ReportingStatus) const>
+bool isAllowedWithURL(ScriptExecutionContext* context, const String& url)
+{
+ if (!isPolicyActiveInContext(context))
+ return true;
+
+ URL parsedURL = context->completeURL(url);
+ if (!parsedURL.isValid())
+ return false; // FIXME: Figure out how to throw a JavaScript error.
+
+ return (context->contentSecurityPolicy()->*allowWithURL)(parsedURL, ContentSecurityPolicy::SuppressReport);
+}
+
+template<bool (ContentSecurityPolicy::*allowWithContext)(const String&, const WTF::OrdinalNumber&, ContentSecurityPolicy::ReportingStatus) const>
+bool isAllowed(ScriptExecutionContext* context)
+{
+ if (!isPolicyActiveInContext(context))
+ return true;
+
+ return (context->contentSecurityPolicy()->*allowWithContext)(String(), WTF::OrdinalNumber::beforeFirst(), ContentSecurityPolicy::SuppressReport);
+}
+
+} // namespace
+
+DOMSecurityPolicy::DOMSecurityPolicy(ScriptExecutionContext* context)
+ : ContextDestructionObserver(context)
+{
+}
+
+DOMSecurityPolicy::~DOMSecurityPolicy()
+{
+}
+
+bool DOMSecurityPolicy::isActive() const
+{
+ return isPolicyActiveInContext(scriptExecutionContext());
+}
+
+PassRefPtr<DOMStringList> DOMSecurityPolicy::reportURIs() const
+{
+ RefPtr<DOMStringList> result = DOMStringList::create();
+
+ if (isActive())
+ scriptExecutionContext()->contentSecurityPolicy()->gatherReportURIs(*result.get());
+
+ return result.release();
+}
+
+bool DOMSecurityPolicy::allowsInlineScript() const
+{
+ return isAllowed<&ContentSecurityPolicy::allowInlineScript>(scriptExecutionContext());
+}
+
+bool DOMSecurityPolicy::allowsInlineStyle() const
+{
+ return isAllowed<&ContentSecurityPolicy::allowInlineStyle>(scriptExecutionContext());
+}
+
+bool DOMSecurityPolicy::allowsEval() const
+{
+ if (!isActive())
+ return true;
+
+ return scriptExecutionContext()->contentSecurityPolicy()->allowEval(0, ContentSecurityPolicy::SuppressReport);
+}
+
+
+bool DOMSecurityPolicy::allowsConnectionTo(const String& url) const
+{
+ return isAllowedWithURL<&ContentSecurityPolicy::allowConnectToSource>(scriptExecutionContext(), url);
+}
+
+bool DOMSecurityPolicy::allowsFontFrom(const String& url) const
+{
+ return isAllowedWithURL<&ContentSecurityPolicy::allowFontFromSource>(scriptExecutionContext(), url);
+}
+
+bool DOMSecurityPolicy::allowsFormAction(const String& url) const
+{
+ return isAllowedWithURL<&ContentSecurityPolicy::allowFormAction>(scriptExecutionContext(), url);
+}
+
+bool DOMSecurityPolicy::allowsFrameFrom(const String& url) const
+{
+ return isAllowedWithURL<&ContentSecurityPolicy::allowChildFrameFromSource>(scriptExecutionContext(), url);
+}
+
+bool DOMSecurityPolicy::allowsImageFrom(const String& url) const
+{
+ return isAllowedWithURL<&ContentSecurityPolicy::allowImageFromSource>(scriptExecutionContext(), url);
+}
+
+bool DOMSecurityPolicy::allowsMediaFrom(const String& url) const
+{
+ return isAllowedWithURL<&ContentSecurityPolicy::allowMediaFromSource>(scriptExecutionContext(), url);
+}
+
+bool DOMSecurityPolicy::allowsObjectFrom(const String& url) const
+{
+ return isAllowedWithURL<&ContentSecurityPolicy::allowObjectFromSource>(scriptExecutionContext(), url);
+}
+
+bool DOMSecurityPolicy::allowsPluginType(const String& type) const
+{
+ return isAllowedWithType<&ContentSecurityPolicy::allowPluginType>(scriptExecutionContext(), type);
+}
+
+bool DOMSecurityPolicy::allowsScriptFrom(const String& url) const
+{
+ return isAllowedWithURL<&ContentSecurityPolicy::allowScriptFromSource>(scriptExecutionContext(), url);
+}
+
+bool DOMSecurityPolicy::allowsStyleFrom(const String& url) const
+{
+ return isAllowedWithURL<&ContentSecurityPolicy::allowStyleFromSource>(scriptExecutionContext(), url);
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/page/csp/ContentSecurityPolicyDirective.h b/Source/WebCore/page/DOMSecurityPolicy.h
index 44aa13f01..97dbae11a 100644
--- a/Source/WebCore/page/csp/ContentSecurityPolicyDirective.h
+++ b/Source/WebCore/page/DOMSecurityPolicy.h
@@ -1,6 +1,5 @@
/*
* Copyright (C) 2011 Google, Inc. All rights reserved.
- * Copyright (C) 2016 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -14,7 +13,7 @@
* THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -24,35 +23,51 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef ContentSecurityPolicyDirective_h
-#define ContentSecurityPolicyDirective_h
+#ifndef DOMSecurityPolicy_h
+#define DOMSecurityPolicy_h
+#include "ContextDestructionObserver.h"
+#include <wtf/PassOwnPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/Vector.h>
#include <wtf/text/WTFString.h>
namespace WebCore {
class ContentSecurityPolicy;
+class DOMStringList;
+class Frame;
-class ContentSecurityPolicyDirective {
+class DOMSecurityPolicy : public RefCounted<DOMSecurityPolicy>, public ContextDestructionObserver {
public:
- ContentSecurityPolicyDirective(const String& name, const String& value, const ContentSecurityPolicy& policy)
- : m_name(name)
- , m_text(name + ' ' + value)
- , m_policy(policy)
+ static PassRefPtr<DOMSecurityPolicy> create(ScriptExecutionContext* context)
{
+ return adoptRef(new DOMSecurityPolicy(context));
}
+ ~DOMSecurityPolicy();
- const String& text() const { return m_text; }
+ bool isActive() const;
+ PassRefPtr<DOMStringList> reportURIs() const;
-protected:
- const ContentSecurityPolicy& policy() const { return m_policy; }
+ bool allowsInlineScript() const;
+ bool allowsInlineStyle() const;
+ bool allowsEval() const;
+
+ bool allowsConnectionTo(const String& url) const;
+ bool allowsFontFrom(const String& url) const;
+ bool allowsFormAction(const String& url) const;
+ bool allowsFrameFrom(const String& url) const;
+ bool allowsImageFrom(const String& url) const;
+ bool allowsMediaFrom(const String& url) const;
+ bool allowsObjectFrom(const String& url) const;
+ bool allowsPluginType(const String& type) const;
+ bool allowsScriptFrom(const String& url) const;
+ bool allowsStyleFrom(const String& url) const;
private:
- String m_name;
- String m_text;
- const ContentSecurityPolicy& m_policy;
+ explicit DOMSecurityPolicy(ScriptExecutionContext*);
};
-} // namespace WebCore
+}
-#endif /* ContentSecurityPolicyDirective_h */
+#endif
diff --git a/Source/WebCore/page/DOMSecurityPolicy.idl b/Source/WebCore/page/DOMSecurityPolicy.idl
new file mode 100644
index 000000000..fe473b35d
--- /dev/null
+++ b/Source/WebCore/page/DOMSecurityPolicy.idl
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2012 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+[
+ Conditional=CSP_NEXT,
+ InterfaceName=SecurityPolicy,
+] interface DOMSecurityPolicy {
+ readonly attribute boolean allowsEval;
+ readonly attribute boolean allowsInlineScript;
+ readonly attribute boolean allowsInlineStyle;
+ readonly attribute boolean isActive;
+
+ readonly attribute DOMStringList reportURIs;
+
+ boolean allowsConnectionTo(DOMString url);
+ boolean allowsFontFrom(DOMString url);
+ boolean allowsFormAction(DOMString url);
+ boolean allowsFrameFrom(DOMString url);
+ boolean allowsImageFrom(DOMString url);
+ boolean allowsMediaFrom(DOMString url);
+ boolean allowsObjectFrom(DOMString url);
+ boolean allowsPluginType(DOMString type);
+ boolean allowsScriptFrom(DOMString url);
+ boolean allowsStyleFrom(DOMString url);
+};
diff --git a/Source/WebCore/page/DOMSelection.cpp b/Source/WebCore/page/DOMSelection.cpp
index e119f64d8..b0875d97c 100644
--- a/Source/WebCore/page/DOMSelection.cpp
+++ b/Source/WebCore/page/DOMSelection.cpp
@@ -11,7 +11,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Inc. ("Apple") nor the names of
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
@@ -57,14 +57,14 @@ static Node* selectionShadowAncestor(Frame* frame)
}
DOMSelection::DOMSelection(const TreeScope* treeScope)
- : DOMWindowProperty(treeScope->rootNode().document().frame())
+ : DOMWindowProperty(treeScope->rootNode()->document().frame())
, m_treeScope(treeScope)
{
}
void DOMSelection::clearTreeScope()
{
- m_treeScope = nullptr;
+ m_treeScope = 0;
}
const VisibleSelection& DOMSelection::visibleSelection() const
@@ -204,7 +204,7 @@ void DOMSelection::collapse(Node* node, int offset, ExceptionCode& ec)
return;
// FIXME: Eliminate legacy editing positions
- m_frame->selection().moveTo(createLegacyEditingPosition(node, offset), DOWNSTREAM);
+ m_frame->selection().moveTo(VisiblePosition(createLegacyEditingPosition(node, offset), DOWNSTREAM));
}
void DOMSelection::collapseToEnd(ExceptionCode& ec)
@@ -219,7 +219,7 @@ void DOMSelection::collapseToEnd(ExceptionCode& ec)
return;
}
- m_frame->selection().moveTo(selection.end(), DOWNSTREAM);
+ m_frame->selection().moveTo(VisiblePosition(selection.end(), DOWNSTREAM));
}
void DOMSelection::collapseToStart(ExceptionCode& ec)
@@ -234,7 +234,7 @@ void DOMSelection::collapseToStart(ExceptionCode& ec)
return;
}
- m_frame->selection().moveTo(selection.start(), DOWNSTREAM);
+ m_frame->selection().moveTo(VisiblePosition(selection.start(), DOWNSTREAM));
}
void DOMSelection::empty()
@@ -258,7 +258,10 @@ void DOMSelection::setBaseAndExtent(Node* baseNode, int baseOffset, Node* extent
return;
// FIXME: Eliminate legacy editing positions
- m_frame->selection().moveTo(createLegacyEditingPosition(baseNode, baseOffset), createLegacyEditingPosition(extentNode, extentOffset), DOWNSTREAM);
+ VisiblePosition visibleBase = VisiblePosition(createLegacyEditingPosition(baseNode, baseOffset), DOWNSTREAM);
+ VisiblePosition visibleExtent = VisiblePosition(createLegacyEditingPosition(extentNode, extentOffset), DOWNSTREAM);
+
+ m_frame->selection().moveTo(visibleBase, visibleExtent);
}
void DOMSelection::setPosition(Node* node, int offset, ExceptionCode& ec)
@@ -274,7 +277,7 @@ void DOMSelection::setPosition(Node* node, int offset, ExceptionCode& ec)
return;
// FIXME: Eliminate legacy editing positions
- m_frame->selection().moveTo(createLegacyEditingPosition(node, offset), DOWNSTREAM);
+ m_frame->selection().moveTo(VisiblePosition(createLegacyEditingPosition(node, offset), DOWNSTREAM));
}
void DOMSelection::modify(const String& alterString, const String& directionString, const String& granularityString)
@@ -283,43 +286,43 @@ void DOMSelection::modify(const String& alterString, const String& directionStri
return;
FrameSelection::EAlteration alter;
- if (equalLettersIgnoringASCIICase(alterString, "extend"))
+ if (equalIgnoringCase(alterString, "extend"))
alter = FrameSelection::AlterationExtend;
- else if (equalLettersIgnoringASCIICase(alterString, "move"))
+ else if (equalIgnoringCase(alterString, "move"))
alter = FrameSelection::AlterationMove;
else
return;
SelectionDirection direction;
- if (equalLettersIgnoringASCIICase(directionString, "forward"))
+ if (equalIgnoringCase(directionString, "forward"))
direction = DirectionForward;
- else if (equalLettersIgnoringASCIICase(directionString, "backward"))
+ else if (equalIgnoringCase(directionString, "backward"))
direction = DirectionBackward;
- else if (equalLettersIgnoringASCIICase(directionString, "left"))
+ else if (equalIgnoringCase(directionString, "left"))
direction = DirectionLeft;
- else if (equalLettersIgnoringASCIICase(directionString, "right"))
+ else if (equalIgnoringCase(directionString, "right"))
direction = DirectionRight;
else
return;
TextGranularity granularity;
- if (equalLettersIgnoringASCIICase(granularityString, "character"))
+ if (equalIgnoringCase(granularityString, "character"))
granularity = CharacterGranularity;
- else if (equalLettersIgnoringASCIICase(granularityString, "word"))
+ else if (equalIgnoringCase(granularityString, "word"))
granularity = WordGranularity;
- else if (equalLettersIgnoringASCIICase(granularityString, "sentence"))
+ else if (equalIgnoringCase(granularityString, "sentence"))
granularity = SentenceGranularity;
- else if (equalLettersIgnoringASCIICase(granularityString, "line"))
+ else if (equalIgnoringCase(granularityString, "line"))
granularity = LineGranularity;
- else if (equalLettersIgnoringASCIICase(granularityString, "paragraph"))
+ else if (equalIgnoringCase(granularityString, "paragraph"))
granularity = ParagraphGranularity;
- else if (equalLettersIgnoringASCIICase(granularityString, "lineboundary"))
+ else if (equalIgnoringCase(granularityString, "lineboundary"))
granularity = LineBoundary;
- else if (equalLettersIgnoringASCIICase(granularityString, "sentenceboundary"))
+ else if (equalIgnoringCase(granularityString, "sentenceboundary"))
granularity = SentenceBoundary;
- else if (equalLettersIgnoringASCIICase(granularityString, "paragraphboundary"))
+ else if (equalIgnoringCase(granularityString, "paragraphboundary"))
granularity = ParagraphBoundary;
- else if (equalLettersIgnoringASCIICase(granularityString, "documentboundary"))
+ else if (equalIgnoringCase(granularityString, "documentboundary"))
granularity = DocumentBoundary;
else
return;
@@ -337,7 +340,7 @@ void DOMSelection::extend(Node* node, int offset, ExceptionCode& ec)
return;
}
- if (offset < 0 || offset > (node->offsetInCharacters() ? caretMaxOffset(node) : static_cast<int>(node->countChildNodes()))) {
+ if (offset < 0 || offset > (node->offsetInCharacters() ? caretMaxOffset(node) : (int)node->childNodeCount())) {
ec = INDEX_SIZE_ERR;
return;
}
@@ -346,7 +349,7 @@ void DOMSelection::extend(Node* node, int offset, ExceptionCode& ec)
return;
// FIXME: Eliminate legacy editing positions
- m_frame->selection().setExtent(createLegacyEditingPosition(node, offset), DOWNSTREAM);
+ m_frame->selection().setExtent(VisiblePosition(createLegacyEditingPosition(node, offset), DOWNSTREAM));
}
PassRefPtr<Range> DOMSelection::getRangeAt(int index, ExceptionCode& ec)
@@ -364,11 +367,12 @@ PassRefPtr<Range> DOMSelection::getRangeAt(int index, ExceptionCode& ec)
if (Node* shadowAncestor = selectionShadowAncestor(m_frame)) {
ContainerNode* container = shadowAncestor->parentNodeGuaranteedHostFree();
- unsigned offset = shadowAncestor->computeNodeIndex();
+ int offset = shadowAncestor->nodeIndex();
return Range::create(shadowAncestor->document(), container, offset, container, offset);
}
- return m_frame->selection().selection().firstRange();
+ const VisibleSelection& selection = m_frame->selection().selection();
+ return selection.firstRange();
}
void DOMSelection::removeAllRanges()
@@ -388,7 +392,7 @@ void DOMSelection::addRange(Range* r)
FrameSelection& selection = m_frame->selection();
if (selection.isNone()) {
- selection.moveTo(r);
+ selection.setSelection(VisibleSelection(r));
return;
}
@@ -396,25 +400,23 @@ void DOMSelection::addRange(Range* r)
if (r->compareBoundaryPoints(Range::START_TO_START, range.get(), IGNORE_EXCEPTION) == -1) {
// We don't support discontiguous selection. We don't do anything if r and range don't intersect.
if (r->compareBoundaryPoints(Range::START_TO_END, range.get(), IGNORE_EXCEPTION) > -1) {
- if (r->compareBoundaryPoints(Range::END_TO_END, range.get(), IGNORE_EXCEPTION) == -1) {
+ if (r->compareBoundaryPoints(Range::END_TO_END, range.get(), IGNORE_EXCEPTION) == -1)
// The original range and r intersect.
- selection.moveTo(r->startPosition(), range->endPosition(), DOWNSTREAM);
- } else {
+ selection.setSelection(VisibleSelection(r->startPosition(), range->endPosition(), DOWNSTREAM));
+ else
// r contains the original range.
- selection.moveTo(r);
- }
+ selection.setSelection(VisibleSelection(r));
}
} else {
// We don't support discontiguous selection. We don't do anything if r and range don't intersect.
ExceptionCode ec = 0;
if (r->compareBoundaryPoints(Range::END_TO_START, range.get(), ec) < 1 && !ec) {
- if (r->compareBoundaryPoints(Range::END_TO_END, range.get(), IGNORE_EXCEPTION) == -1) {
+ if (r->compareBoundaryPoints(Range::END_TO_END, range.get(), IGNORE_EXCEPTION) == -1)
// The original range contains r.
- selection.moveTo(range.get());
- } else {
+ selection.setSelection(VisibleSelection(range.get()));
+ else
// The original range and r intersect.
- selection.moveTo(range->startPosition(), r->endPosition(), DOWNSTREAM);
- }
+ selection.setSelection(VisibleSelection(range->startPosition(), r->endPosition(), DOWNSTREAM));
}
}
}
@@ -429,13 +431,16 @@ void DOMSelection::deleteFromDocument()
if (selection.isNone())
return;
+ if (isCollapsed())
+ selection.modify(FrameSelection::AlterationExtend, DirectionBackward, CharacterGranularity);
+
RefPtr<Range> selectedRange = selection.selection().toNormalizedRange();
if (!selectedRange)
return;
selectedRange->deleteContents(ASSERT_NO_EXCEPTION);
- setBaseAndExtent(&selectedRange->startContainer(), selectedRange->startOffset(), &selectedRange->startContainer(), selectedRange->startOffset(), ASSERT_NO_EXCEPTION);
+ setBaseAndExtent(selectedRange->startContainer(ASSERT_NO_EXCEPTION), selectedRange->startOffset(), selectedRange->startContainer(), selectedRange->startOffset(), ASSERT_NO_EXCEPTION);
}
bool DOMSelection::containsNode(Node* n, bool allowPartial) const
@@ -454,17 +459,17 @@ bool DOMSelection::containsNode(Node* n, bool allowPartial) const
ContainerNode* parentNode = node->parentNode();
if (!parentNode || !parentNode->inDocument())
return false;
- unsigned nodeIndex = node->computeNodeIndex();
+ unsigned nodeIndex = node->nodeIndex();
ExceptionCode ec = 0;
- bool nodeFullySelected = Range::compareBoundaryPoints(parentNode, nodeIndex, &selectedRange->startContainer(), selectedRange->startOffset(), ec) >= 0 && !ec
- && Range::compareBoundaryPoints(parentNode, nodeIndex + 1, &selectedRange->endContainer(), selectedRange->endOffset(), ec) <= 0 && !ec;
+ bool nodeFullySelected = Range::compareBoundaryPoints(parentNode, nodeIndex, selectedRange->startContainer(), selectedRange->startOffset(), ec) >= 0 && !ec
+ && Range::compareBoundaryPoints(parentNode, nodeIndex + 1, selectedRange->endContainer(), selectedRange->endOffset(), ec) <= 0 && !ec;
ASSERT(!ec);
if (nodeFullySelected)
return true;
- bool nodeFullyUnselected = (Range::compareBoundaryPoints(parentNode, nodeIndex, &selectedRange->endContainer(), selectedRange->endOffset(), ec) > 0 && !ec)
- || (Range::compareBoundaryPoints(parentNode, nodeIndex + 1, &selectedRange->startContainer(), selectedRange->startOffset(), ec) < 0 && !ec);
+ bool nodeFullyUnselected = (Range::compareBoundaryPoints(parentNode, nodeIndex, selectedRange->endContainer(), selectedRange->endOffset(), ec) > 0 && !ec)
+ || (Range::compareBoundaryPoints(parentNode, nodeIndex + 1, selectedRange->startContainer(), selectedRange->startOffset(), ec) < 0 && !ec);
ASSERT(!ec);
if (nodeFullyUnselected)
return false;
@@ -478,7 +483,7 @@ void DOMSelection::selectAllChildren(Node* n, ExceptionCode& ec)
return;
// This doesn't (and shouldn't) select text node characters.
- setBaseAndExtent(n, 0, n, n->countChildNodes(), ec);
+ setBaseAndExtent(n, 0, n, n->childNodeCount(), ec);
}
String DOMSelection::toString()
@@ -520,7 +525,7 @@ int DOMSelection::shadowAdjustedOffset(const Position& position) const
if (containerNode == adjustedNode)
return position.computeOffsetInContainerNode();
- return adjustedNode->computeNodeIndex();
+ return adjustedNode->nodeIndex();
}
bool DOMSelection::isValidForPosition(Node* node) const
diff --git a/Source/WebCore/page/DOMSelection.h b/Source/WebCore/page/DOMSelection.h
index 2fa1e87a9..1dda6abea 100644
--- a/Source/WebCore/page/DOMSelection.h
+++ b/Source/WebCore/page/DOMSelection.h
@@ -11,7 +11,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Inc. ("Apple") nor the names of
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
@@ -49,7 +49,7 @@ namespace WebCore {
class DOMSelection : public RefCounted<DOMSelection>, public DOMWindowProperty {
public:
- static Ref<DOMSelection> create(const TreeScope* treeScope) { return adoptRef(*new DOMSelection(treeScope)); }
+ static PassRefPtr<DOMSelection> create(const TreeScope* treeScope) { return adoptRef(new DOMSelection(treeScope)); }
void clearTreeScope();
diff --git a/Source/WebCore/page/DOMSelection.idl b/Source/WebCore/page/DOMSelection.idl
index cb89fd415..c1f763f9c 100644
--- a/Source/WebCore/page/DOMSelection.idl
+++ b/Source/WebCore/page/DOMSelection.idl
@@ -11,7 +11,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Inc. ("Apple") nor the names of
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
diff --git a/Source/WebCore/page/DOMTimer.cpp b/Source/WebCore/page/DOMTimer.cpp
index 26bea5dcf..0c99e0d39 100644
--- a/Source/WebCore/page/DOMTimer.cpp
+++ b/Source/WebCore/page/DOMTimer.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008, 2014 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -27,183 +27,72 @@
#include "config.h"
#include "DOMTimer.h"
-#include "HTMLPlugInElement.h"
#include "InspectorInstrumentation.h"
-#include "Logging.h"
-#include "Page.h"
-#include "PluginViewBase.h"
#include "ScheduledAction.h"
#include "ScriptExecutionContext.h"
-#include "Settings.h"
#include "UserGestureIndicator.h"
#include <wtf/CurrentTime.h>
-#include <wtf/HashMap.h>
-#include <wtf/MathExtras.h>
-#include <wtf/NeverDestroyed.h>
-#include <wtf/RandomNumber.h>
+#include <wtf/HashSet.h>
#include <wtf/StdLibExtras.h>
#if PLATFORM(IOS)
#include "Chrome.h"
#include "ChromeClient.h"
#include "Frame.h"
+#include "Page.h"
#include "WKContentObservation.h"
#endif
namespace WebCore {
static const int maxIntervalForUserGestureForwarding = 1000; // One second matches Gecko.
-static const int minIntervalForNonUserObservableChangeTimers = 1000; // Empirically determined to maximize battery life.
static const int maxTimerNestingLevel = 5;
static const double oneMillisecond = 0.001;
-class DOMTimerFireState {
-public:
- explicit DOMTimerFireState(ScriptExecutionContext& context)
- : m_context(context)
- , m_contextIsDocument(is<Document>(m_context))
- {
- // For worker threads, don't update the current DOMTimerFireState.
- // Setting this from workers would not be thread-safe, and its not relevant to current uses.
- if (m_contextIsDocument) {
- m_initialDOMTreeVersion = downcast<Document>(context).domTreeVersion();
- m_previous = current;
- current = this;
- }
- }
-
- ~DOMTimerFireState()
- {
- if (m_contextIsDocument)
- current = m_previous;
- }
-
- Document* contextDocument() const { return m_contextIsDocument ? &downcast<Document>(m_context) : nullptr; }
-
- void setScriptMadeUserObservableChanges() { m_scriptMadeUserObservableChanges = true; }
- void setScriptMadeNonUserObservableChanges() { m_scriptMadeNonUserObservableChanges = true; }
-
- bool scriptMadeNonUserObservableChanges() const { return m_scriptMadeNonUserObservableChanges; }
- bool scriptMadeUserObservableChanges() const
- {
- if (m_scriptMadeUserObservableChanges)
- return true;
-
- Document* document = contextDocument();
- // To be conservative, we also consider any DOM Tree change to be user observable.
- return document && document->domTreeVersion() != m_initialDOMTreeVersion;
- }
-
- static DOMTimerFireState* current;
-
-private:
- ScriptExecutionContext& m_context;
- uint64_t m_initialDOMTreeVersion;
- DOMTimerFireState* m_previous;
- bool m_contextIsDocument;
- bool m_scriptMadeNonUserObservableChanges { false };
- bool m_scriptMadeUserObservableChanges { false };
-};
-
-DOMTimerFireState* DOMTimerFireState::current = nullptr;
-
-struct NestedTimersMap {
- typedef HashMap<int, DOMTimer*>::const_iterator const_iterator;
-
- static NestedTimersMap* instanceForContext(ScriptExecutionContext& context)
- {
- // For worker threads, we don't use NestedTimersMap as doing so would not
- // be thread safe.
- if (is<Document>(context))
- return &instance();
- return nullptr;
- }
-
- void startTracking()
- {
- // Make sure we start with an empty HashMap. In theory, it is possible the HashMap is not
- // empty if a timer fires during the execution of another timer (may happen with the
- // in-process Web Inspector).
- nestedTimers.clear();
- isTrackingNestedTimers = true;
- }
-
- void stopTracking()
- {
- isTrackingNestedTimers = false;
- nestedTimers.clear();
- }
-
- void add(int timeoutId, DOMTimer* timer)
- {
- if (isTrackingNestedTimers)
- nestedTimers.add(timeoutId, timer);
- }
-
- void remove(int timeoutId)
- {
- if (isTrackingNestedTimers)
- nestedTimers.remove(timeoutId);
- }
-
- const_iterator begin() const { return nestedTimers.begin(); }
- const_iterator end() const { return nestedTimers.end(); }
-
-private:
- static NestedTimersMap& instance()
- {
- static NeverDestroyed<NestedTimersMap> map;
- return map;
- }
-
- static bool isTrackingNestedTimers;
- HashMap<int /* timeoutId */, DOMTimer*> nestedTimers;
-};
-
-bool NestedTimersMap::isTrackingNestedTimers = false;
-
+static int timerNestingLevel = 0;
+
static inline bool shouldForwardUserGesture(int interval, int nestingLevel)
{
return UserGestureIndicator::processingUserGesture()
&& interval <= maxIntervalForUserGestureForwarding
- && !nestingLevel; // Gestures should not be forwarded to nested timers.
+ && nestingLevel == 1; // Gestures should not be forwarded to nested timers.
}
-DOMTimer::DOMTimer(ScriptExecutionContext& context, std::unique_ptr<ScheduledAction> action, int interval, bool singleShot)
+DOMTimer::DOMTimer(ScriptExecutionContext* context, PassOwnPtr<ScheduledAction> action, int interval, bool singleShot)
: SuspendableTimer(context)
- , m_nestingLevel(context.timerNestingLevel())
- , m_action(WTFMove(action))
+ , m_nestingLevel(timerNestingLevel + 1)
+ , m_action(action)
, m_originalInterval(interval)
- , m_throttleState(Undetermined)
- , m_currentTimerInterval(intervalClampedToMinimum())
, m_shouldForwardUserGesture(shouldForwardUserGesture(interval, m_nestingLevel))
{
- RefPtr<DOMTimer> reference = adoptRef(this);
-
// Keep asking for the next id until we're given one that we don't already have.
do {
- m_timeoutId = context.circularSequentialID();
- } while (!context.addTimeout(m_timeoutId, reference));
+ m_timeoutId = context->circularSequentialID();
+ } while (!context->addTimeout(m_timeoutId, this));
+ double intervalMilliseconds = intervalClampedToMinimum(interval, context->minimumTimerInterval());
if (singleShot)
- startOneShot(m_currentTimerInterval);
+ startOneShot(intervalMilliseconds);
else
- startRepeating(m_currentTimerInterval);
+ startRepeating(intervalMilliseconds);
}
DOMTimer::~DOMTimer()
{
+ if (scriptExecutionContext())
+ scriptExecutionContext()->removeTimeout(m_timeoutId);
}
-int DOMTimer::install(ScriptExecutionContext& context, std::unique_ptr<ScheduledAction> action, int timeout, bool singleShot)
+int DOMTimer::install(ScriptExecutionContext* context, PassOwnPtr<ScheduledAction> action, int timeout, bool singleShot)
{
- // DOMTimer constructor passes ownership of the initial ref on the object to the constructor.
- // This reference will be released automatically when a one-shot timer fires, when the context
- // is destroyed, or if explicitly cancelled by removeById.
- DOMTimer* timer = new DOMTimer(context, WTFMove(action), timeout, singleShot);
+ // DOMTimer constructor links the new timer into a list of ActiveDOMObjects held by the 'context'.
+ // The timer is deleted when context is deleted (DOMTimer::contextDestroyed) or explicitly via DOMTimer::removeById(),
+ // or if it is a one-time timer and it has fired (DOMTimer::fired).
+ DOMTimer* timer = new DOMTimer(context, action, timeout, singleShot);
#if PLATFORM(IOS)
- if (is<Document>(context)) {
- bool didDeferTimeout = context.activeDOMObjectsAreSuspended();
+ if (context->isDocument()) {
+ Document& document = toDocument(*context);
+ bool didDeferTimeout = document.frame() && document.frame()->timersPaused();
if (!didDeferTimeout && timeout <= 100 && singleShot) {
WKSetObservedContentChange(WKContentIndeterminateChange);
WebThreadAddObservedContentModifier(timer); // Will only take affect if not already visibility change.
@@ -212,16 +101,12 @@ int DOMTimer::install(ScriptExecutionContext& context, std::unique_ptr<Scheduled
#endif
timer->suspendIfNeeded();
- InspectorInstrumentation::didInstallTimer(&context, timer->m_timeoutId, timeout, singleShot);
-
- // Keep track of nested timer installs.
- if (NestedTimersMap* nestedTimers = NestedTimersMap::instanceForContext(context))
- nestedTimers->add(timer->m_timeoutId, timer);
+ InspectorInstrumentation::didInstallTimer(context, timer->m_timeoutId, timeout, singleShot);
return timer->m_timeoutId;
}
-void DOMTimer::removeById(ScriptExecutionContext& context, int timeoutId)
+void DOMTimer::removeById(ScriptExecutionContext* context, int timeoutId)
{
// timeout IDs have to be positive, and 0 and -1 are unsafe to
// even look up since they are the empty and deleted value
@@ -229,105 +114,58 @@ void DOMTimer::removeById(ScriptExecutionContext& context, int timeoutId)
if (timeoutId <= 0)
return;
- if (NestedTimersMap* nestedTimers = NestedTimersMap::instanceForContext(context))
- nestedTimers->remove(timeoutId);
-
- InspectorInstrumentation::didRemoveTimer(&context, timeoutId);
- context.removeTimeout(timeoutId);
-}
-
-inline bool DOMTimer::isDOMTimersThrottlingEnabled(Document& document) const
-{
- auto* page = document.page();
- if (!page)
- return true;
- return page->settings().domTimersThrottlingEnabled();
-}
-
-void DOMTimer::updateThrottlingStateIfNecessary(const DOMTimerFireState& fireState)
-{
- Document* contextDocument = fireState.contextDocument();
- // We don't throttle timers in worker threads.
- if (!contextDocument)
- return;
-
- if (UNLIKELY(!isDOMTimersThrottlingEnabled(*contextDocument))) {
- if (m_throttleState == ShouldThrottle) {
- // Unthrottle the timer in case it was throttled before the setting was updated.
- LOG(DOMTimers, "%p - Unthrottling DOM timer because throttling was disabled via settings.", this);
- m_throttleState = ShouldNotThrottle;
- updateTimerIntervalIfNecessary();
- }
- return;
- }
-
- if (fireState.scriptMadeUserObservableChanges()) {
- if (m_throttleState != ShouldNotThrottle) {
- m_throttleState = ShouldNotThrottle;
- updateTimerIntervalIfNecessary();
- }
- } else if (fireState.scriptMadeNonUserObservableChanges()) {
- if (m_throttleState != ShouldThrottle) {
- m_throttleState = ShouldThrottle;
- updateTimerIntervalIfNecessary();
- }
- }
-}
-
-void DOMTimer::scriptDidInteractWithPlugin(HTMLPlugInElement& pluginElement)
-{
- if (!DOMTimerFireState::current)
- return;
+ InspectorInstrumentation::didRemoveTimer(context, timeoutId);
- if (pluginElement.isUserObservable())
- DOMTimerFireState::current->setScriptMadeUserObservableChanges();
- else
- DOMTimerFireState::current->setScriptMadeNonUserObservableChanges();
+ delete context->findTimeout(timeoutId);
}
void DOMTimer::fired()
{
- // Retain this - if the timer is cancelled while this function is on the stack (implicitly and always
- // for one-shot timers, or if removeById is called on itself from within an interval timer fire) then
- // wait unit the end of this function to delete DOMTimer.
- RefPtr<DOMTimer> reference = this;
-
- ASSERT(scriptExecutionContext());
- ScriptExecutionContext& context = *scriptExecutionContext();
-
- DOMTimerFireState fireState(context);
-
- context.setTimerNestingLevel(std::min(m_nestingLevel + 1, maxTimerNestingLevel));
-
+ ScriptExecutionContext* context = scriptExecutionContext();
+ ASSERT(context);
+#if PLATFORM(IOS)
+ Document* document = nullptr;
+ if (!context->isDocument()) {
+ document = toDocument(context);
+ ASSERT(!document->frame()->timersPaused());
+ }
+#endif
+ timerNestingLevel = m_nestingLevel;
ASSERT(!isSuspended());
- ASSERT(!context.activeDOMObjectsAreSuspended());
+ ASSERT(!context->activeDOMObjectsAreSuspended());
UserGestureIndicator gestureIndicator(m_shouldForwardUserGesture ? DefinitelyProcessingUserGesture : PossiblyProcessingUserGesture);
// Only the first execution of a multi-shot timer should get an affirmative user gesture indicator.
m_shouldForwardUserGesture = false;
- InspectorInstrumentationCookie cookie = InspectorInstrumentation::willFireTimer(&context, m_timeoutId);
+ InspectorInstrumentationCookie cookie = InspectorInstrumentation::willFireTimer(context, m_timeoutId);
// Simple case for non-one-shot timers.
if (isActive()) {
- if (m_nestingLevel < maxTimerNestingLevel) {
+ double minimumInterval = context->minimumTimerInterval();
+ if (repeatInterval() && repeatInterval() < minimumInterval) {
m_nestingLevel++;
- updateTimerIntervalIfNecessary();
+ if (m_nestingLevel >= maxTimerNestingLevel)
+ augmentRepeatInterval(minimumInterval - repeatInterval());
}
+ // No access to member variables after this point, it can delete the timer.
m_action->execute(context);
InspectorInstrumentation::didFireTimer(cookie);
- updateThrottlingStateIfNecessary(fireState);
return;
}
- context.removeTimeout(m_timeoutId);
+ // Delete timer before executing the action for one-shot timers.
+ OwnPtr<ScheduledAction> action = m_action.release();
+
+ // No access to member variables after this point.
+ delete this;
#if PLATFORM(IOS)
bool shouldReportLackOfChanges;
bool shouldBeginObservingChanges;
- if (is<Document>(context)) {
+ if (document) {
shouldReportLackOfChanges = WebThreadCountOfObservedContentModifiers() == 1;
shouldBeginObservingChanges = WebThreadContainsObservedContentModifier(this);
} else {
@@ -341,38 +179,27 @@ void DOMTimer::fired()
}
#endif
- // Keep track nested timer installs.
- NestedTimersMap* nestedTimers = NestedTimersMap::instanceForContext(context);
- if (nestedTimers)
- nestedTimers->startTracking();
-
- m_action->execute(context);
+ action->execute(context);
#if PLATFORM(IOS)
if (shouldBeginObservingChanges) {
WKStopObservingContentChanges();
- if (WKObservedContentChange() == WKContentVisibilityChange || shouldReportLackOfChanges) {
- Document& document = downcast<Document>(context);
- if (Page* page = document.page())
- page->chrome().client().observedContentChange(document.frame());
- }
+ if (WKObservedContentChange() == WKContentVisibilityChange || shouldReportLackOfChanges)
+ if (document && document->page())
+ document->page()->chrome().client().observedContentChange(document->frame());
}
#endif
InspectorInstrumentation::didFireTimer(cookie);
- // Check if we should throttle nested single-shot timers.
- if (nestedTimers) {
- for (auto& keyValue : *nestedTimers) {
- auto* timer = keyValue.value;
- if (timer->isActive() && !timer->repeatInterval())
- timer->updateThrottlingStateIfNecessary(fireState);
- }
- nestedTimers->stopTracking();
- }
+ timerNestingLevel = 0;
+}
- context.setTimerNestingLevel(0);
+void DOMTimer::contextDestroyed()
+{
+ SuspendableTimer::contextDestroyed();
+ delete this;
}
void DOMTimer::didStop()
@@ -380,65 +207,48 @@ void DOMTimer::didStop()
// Need to release JS objects potentially protected by ScheduledAction
// because they can form circular references back to the ScriptExecutionContext
// which will cause a memory leak.
- m_action = nullptr;
+ m_action.clear();
}
-void DOMTimer::updateTimerIntervalIfNecessary()
+void DOMTimer::adjustMinimumTimerInterval(double oldMinimumTimerInterval)
{
- ASSERT(m_nestingLevel <= maxTimerNestingLevel);
-
- double previousInterval = m_currentTimerInterval;
- m_currentTimerInterval = intervalClampedToMinimum();
-
- if (WTF::areEssentiallyEqual(previousInterval, m_currentTimerInterval, oneMillisecond))
+ if (m_nestingLevel < maxTimerNestingLevel)
return;
+ double newMinimumInterval = scriptExecutionContext()->minimumTimerInterval();
+ double newClampedInterval = intervalClampedToMinimum(m_originalInterval, newMinimumInterval);
+
if (repeatInterval()) {
- ASSERT(WTF::areEssentiallyEqual(repeatInterval(), previousInterval, oneMillisecond));
- LOG(DOMTimers, "%p - Updating DOMTimer's repeat interval from %g ms to %g ms due to throttling.", this, previousInterval * 1000., m_currentTimerInterval * 1000.);
- augmentRepeatInterval(m_currentTimerInterval - previousInterval);
- } else {
- LOG(DOMTimers, "%p - Updating DOMTimer's fire interval from %g ms to %g ms due to throttling.", this, previousInterval * 1000., m_currentTimerInterval * 1000.);
- augmentFireInterval(m_currentTimerInterval - previousInterval);
+ augmentRepeatInterval(newClampedInterval - repeatInterval());
+ return;
}
+
+ double previousClampedInterval = intervalClampedToMinimum(m_originalInterval, oldMinimumTimerInterval);
+ augmentFireInterval(newClampedInterval - previousClampedInterval);
}
-double DOMTimer::intervalClampedToMinimum() const
+double DOMTimer::intervalClampedToMinimum(int timeout, double minimumTimerInterval) const
{
- ASSERT(scriptExecutionContext());
- ASSERT(m_nestingLevel <= maxTimerNestingLevel);
-
- double intervalInSeconds = std::max(oneMillisecond, m_originalInterval * oneMillisecond);
-
- // Only apply throttling to repeating timers.
- if (m_nestingLevel < maxTimerNestingLevel)
- return intervalInSeconds;
+ double intervalMilliseconds = std::max(oneMillisecond, timeout * oneMillisecond);
- // Apply two throttles - the global (per Page) minimum, and also a per-timer throttle.
- intervalInSeconds = std::max(intervalInSeconds, scriptExecutionContext()->minimumTimerInterval());
- if (m_throttleState == ShouldThrottle)
- intervalInSeconds = std::max(intervalInSeconds, minIntervalForNonUserObservableChangeTimers * oneMillisecond);
- return intervalInSeconds;
+ if (intervalMilliseconds < minimumTimerInterval && m_nestingLevel >= maxTimerNestingLevel)
+ intervalMilliseconds = minimumTimerInterval;
+ return intervalMilliseconds;
}
double DOMTimer::alignedFireTime(double fireTime) const
{
- if (double alignmentInterval = scriptExecutionContext()->timerAlignmentInterval(m_nestingLevel >= maxTimerNestingLevel)) {
- // Don't mess with zero-delay timers.
- if (!fireTime)
+ double alignmentInterval = scriptExecutionContext()->timerAlignmentInterval();
+ if (alignmentInterval) {
+ double currentTime = monotonicallyIncreasingTime();
+ if (fireTime <= currentTime)
return fireTime;
- static const double randomizedAlignment = randomNumber();
- // Force alignment to randomizedAlignment fraction of the way between alignemntIntervals, e.g.
- // if alignmentInterval is 10 and randomizedAlignment is 0.3 this will align to 3, 13, 23, ...
- return (ceil(fireTime / alignmentInterval - randomizedAlignment) + randomizedAlignment) * alignmentInterval;
+
+ double alignedTime = ceil(fireTime / alignmentInterval) * alignmentInterval;
+ return alignedTime;
}
return fireTime;
}
-const char* DOMTimer::activeDOMObjectName() const
-{
- return "DOMTimer";
-}
-
} // namespace WebCore
diff --git a/Source/WebCore/page/DOMTimer.h b/Source/WebCore/page/DOMTimer.h
index 390d0b110..a47dd5f7c 100644
--- a/Source/WebCore/page/DOMTimer.h
+++ b/Source/WebCore/page/DOMTimer.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008, 2014 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -28,68 +28,45 @@
#define DOMTimer_h
#include "SuspendableTimer.h"
-#include <memory>
-#include <wtf/RefCounted.h>
+#include <wtf/OwnPtr.h>
+#include <wtf/PassOwnPtr.h>
namespace WebCore {
- class DOMTimerFireState;
- class Document;
- class Element;
- class HTMLPlugInElement;
- class IntRect;
class ScheduledAction;
- class DOMTimer final : public RefCounted<DOMTimer>, public SuspendableTimer {
- WTF_MAKE_NONCOPYABLE(DOMTimer);
- WTF_MAKE_FAST_ALLOCATED;
+ class DOMTimer final : public SuspendableTimer {
public:
virtual ~DOMTimer();
-
- static double defaultMinimumInterval() { return 0.004; } // 4 milliseconds.
- static double defaultAlignmentInterval() { return 0; }
- static double hiddenPageAlignmentInterval() { return 1.0; } // 1 second.
-
// Creates a new timer owned by specified ScriptExecutionContext, starts it
// and returns its Id.
- static int install(ScriptExecutionContext&, std::unique_ptr<ScheduledAction>, int timeout, bool singleShot);
- static void removeById(ScriptExecutionContext&, int timeoutId);
+ static int install(ScriptExecutionContext*, PassOwnPtr<ScheduledAction>, int timeout, bool singleShot);
+ static void removeById(ScriptExecutionContext*, int timeoutId);
- // Notify that the interval may need updating (e.g. because the minimum interval
- // setting for the context has changed).
- void updateTimerIntervalIfNecessary();
-
- static void scriptDidInteractWithPlugin(HTMLPlugInElement&);
+ // Adjust to a change in the ScriptExecutionContext's minimum timer interval.
+ // This allows the minimum allowable interval time to be changed in response
+ // to events like moving a tab to the background.
+ void adjustMinimumTimerInterval(double oldMinimumTimerInterval);
private:
- DOMTimer(ScriptExecutionContext&, std::unique_ptr<ScheduledAction>, int interval, bool singleShot);
- friend class Internals;
-
- double intervalClampedToMinimum() const;
+ DOMTimer(ScriptExecutionContext*, PassOwnPtr<ScheduledAction>, int interval, bool singleShot);
+ virtual void fired() override;
- bool isDOMTimersThrottlingEnabled(Document&) const;
- void updateThrottlingStateIfNecessary(const DOMTimerFireState&);
+ // ActiveDOMObject
+ virtual void contextDestroyed() override;
// SuspendableTimer
- virtual void fired() override;
virtual void didStop() override;
- virtual double alignedFireTime(double) const override;
- // ActiveDOMObject API.
- const char* activeDOMObjectName() const override;
+ double intervalClampedToMinimum(int timeout, double minimumTimerInterval) const;
- enum TimerThrottleState {
- Undetermined,
- ShouldThrottle,
- ShouldNotThrottle
- };
+ // Retuns timer fire time rounded to the next multiple of timer alignment interval.
+ virtual double alignedFireTime(double) const override;
int m_timeoutId;
int m_nestingLevel;
- std::unique_ptr<ScheduledAction> m_action;
+ OwnPtr<ScheduledAction> m_action;
int m_originalInterval;
- TimerThrottleState m_throttleState;
- double m_currentTimerInterval;
bool m_shouldForwardUserGesture;
};
diff --git a/Source/WebCore/page/DOMWindow.cpp b/Source/WebCore/page/DOMWindow.cpp
index d91420c58..7533b009a 100644
--- a/Source/WebCore/page/DOMWindow.cpp
+++ b/Source/WebCore/page/DOMWindow.cpp
@@ -11,17 +11,17 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
@@ -35,11 +35,11 @@
#include "CSSRuleList.h"
#include "Chrome.h"
#include "ChromeClient.h"
-#include "ContentExtensionActions.h"
-#include "ContentExtensionRule.h"
+#include "Console.h"
#include "Crypto.h"
#include "DOMApplicationCache.h"
#include "DOMSelection.h"
+#include "DOMSettableTokenList.h"
#include "DOMStringList.h"
#include "DOMTimer.h"
#include "DOMTokenList.h"
@@ -53,6 +53,7 @@
#include "DocumentLoader.h"
#include "Editor.h"
#include "Element.h"
+#include "EventException.h"
#include "EventHandler.h"
#include "EventListener.h"
#include "EventNames.h"
@@ -68,7 +69,7 @@
#include "HTMLFrameOwnerElement.h"
#include "History.h"
#include "InspectorInstrumentation.h"
-#include "JSMainThreadExecState.h"
+#include "URL.h"
#include "Location.h"
#include "MainFrame.h"
#include "MediaQueryList.h"
@@ -76,15 +77,16 @@
#include "MessageEvent.h"
#include "Navigator.h"
#include "Page.h"
-#include "PageConsoleClient.h"
+#include "PageConsole.h"
#include "PageGroup.h"
#include "PageTransitionEvent.h"
#include "Performance.h"
#include "PlatformScreen.h"
-#include "ResourceLoadInfo.h"
#include "RuntimeEnabledFeatures.h"
#include "ScheduledAction.h"
#include "Screen.h"
+#include "ScriptCallStack.h"
+#include "ScriptCallStackFactory.h"
#include "ScriptController.h"
#include "SecurityOrigin.h"
#include "SecurityPolicy.h"
@@ -93,33 +95,20 @@
#include "Storage.h"
#include "StorageArea.h"
#include "StorageNamespace.h"
-#include "StorageNamespaceProvider.h"
#include "StyleMedia.h"
#include "StyleResolver.h"
#include "SuddenTermination.h"
-#include "URL.h"
#include "WebKitPoint.h"
#include "WindowFeatures.h"
#include "WindowFocusAllowedIndicator.h"
-#include <JavaScriptCore/Profile.h>
#include <algorithm>
-#include <inspector/ScriptCallStack.h>
-#include <inspector/ScriptCallStackFactory.h>
-#include <memory>
#include <wtf/CurrentTime.h>
#include <wtf/MainThread.h>
#include <wtf/MathExtras.h>
-#include <wtf/NeverDestroyed.h>
#include <wtf/Ref.h>
#include <wtf/text/Base64.h>
#include <wtf/text/WTFString.h>
-#if ENABLE(USER_MESSAGE_HANDLERS)
-#include "UserContentController.h"
-#include "UserMessageHandlerDescriptor.h"
-#include "WebKitNamespace.h"
-#endif
-
#if ENABLE(PROXIMITY_EVENTS)
#include "DeviceProximityController.h"
#endif
@@ -128,10 +117,6 @@
#include "RequestAnimationFrameCallback.h"
#endif
-#if ENABLE(GAMEPAD)
-#include "GamepadManager.h"
-#endif
-
#if PLATFORM(IOS)
#if ENABLE(GEOLOCATION)
#include "NavigatorGeolocation.h"
@@ -139,27 +124,25 @@
#include "WKContentObservation.h"
#endif
-using namespace Inspector;
-
namespace WebCore {
class PostMessageTimer : public TimerBase {
public:
- PostMessageTimer(DOMWindow* window, PassRefPtr<SerializedScriptValue> message, const String& sourceOrigin, PassRefPtr<DOMWindow> source, std::unique_ptr<MessagePortChannelArray> channels, SecurityOrigin* targetOrigin, PassRefPtr<ScriptCallStack> stackTrace)
+ PostMessageTimer(DOMWindow* window, PassRefPtr<SerializedScriptValue> message, const String& sourceOrigin, PassRefPtr<DOMWindow> source, PassOwnPtr<MessagePortChannelArray> channels, SecurityOrigin* targetOrigin, PassRefPtr<ScriptCallStack> stackTrace)
: m_window(window)
, m_message(message)
, m_origin(sourceOrigin)
, m_source(source)
- , m_channels(WTFMove(channels))
+ , m_channels(channels)
, m_targetOrigin(targetOrigin)
, m_stackTrace(stackTrace)
{
}
- Ref<MessageEvent> event(ScriptExecutionContext* context)
+ PassRefPtr<MessageEvent> event(ScriptExecutionContext* context)
{
- std::unique_ptr<MessagePortArray> messagePorts = MessagePort::entanglePorts(*context, WTFMove(m_channels));
- return MessageEvent::create(WTFMove(messagePorts), m_message, m_origin, String(), m_source);
+ OwnPtr<MessagePortArray> messagePorts = MessagePort::entanglePorts(*context, m_channels.release());
+ return MessageEvent::create(messagePorts.release(), m_message, m_origin, String(), m_source);
}
SecurityOrigin* targetOrigin() const { return m_targetOrigin.get(); }
ScriptCallStack* stackTrace() const { return m_stackTrace.get(); }
@@ -167,16 +150,15 @@ public:
private:
virtual void fired()
{
- // This object gets deleted when std::unique_ptr falls out of scope..
- std::unique_ptr<PostMessageTimer> timer(this);
- m_window->postMessageTimerFired(*timer);
+ m_window->postMessageTimerFired(adoptPtr(this));
+ // This object is deleted now.
}
RefPtr<DOMWindow> m_window;
RefPtr<SerializedScriptValue> m_message;
String m_origin;
RefPtr<DOMWindow> m_source;
- std::unique_ptr<MessagePortChannelArray> m_channels;
+ OwnPtr<MessagePortChannelArray> m_channels;
RefPtr<SecurityOrigin> m_targetOrigin;
RefPtr<ScriptCallStack> m_stackTrace;
};
@@ -185,13 +167,13 @@ typedef HashCountedSet<DOMWindow*> DOMWindowSet;
static DOMWindowSet& windowsWithUnloadEventListeners()
{
- static NeverDestroyed<DOMWindowSet> windowsWithUnloadEventListeners;
+ DEFINE_STATIC_LOCAL(DOMWindowSet, windowsWithUnloadEventListeners, ());
return windowsWithUnloadEventListeners;
}
static DOMWindowSet& windowsWithBeforeUnloadEventListeners()
{
- static NeverDestroyed<DOMWindowSet> windowsWithBeforeUnloadEventListeners;
+ DEFINE_STATIC_LOCAL(DOMWindowSet, windowsWithBeforeUnloadEventListeners, ());
return windowsWithBeforeUnloadEventListeners;
}
@@ -255,21 +237,22 @@ bool DOMWindow::dispatchAllPendingBeforeUnloadEvents()
Vector<Ref<DOMWindow>> windows;
windows.reserveInitialCapacity(set.size());
- for (auto& window : set)
- windows.uncheckedAppend(*window.key);
+ for (auto it = set.begin(), end = set.end(); it != end; ++it)
+ windows.uncheckedAppend(*it->key);
- for (auto& window : windows) {
- if (!set.contains(window.ptr()))
+ for (unsigned i = 0; i < windows.size(); ++i) {
+ DOMWindow& window = windows[i].get();
+ if (!set.contains(&window))
continue;
- Frame* frame = window->frame();
+ Frame* frame = window.frame();
if (!frame)
continue;
if (!frame->loader().shouldClose())
return false;
- window->enableSuddenTermination();
+ window.enableSuddenTermination();
}
alreadyDispatched = true;
@@ -294,17 +277,18 @@ void DOMWindow::dispatchAllPendingUnloadEvents()
Vector<Ref<DOMWindow>> windows;
windows.reserveInitialCapacity(set.size());
- for (auto& keyValue : set)
- windows.uncheckedAppend(*keyValue.key);
+ for (auto it = set.begin(), end = set.end(); it != end; ++it)
+ windows.uncheckedAppend(*it->key);
- for (auto& window : windows) {
- if (!set.contains(window.ptr()))
+ for (unsigned i = 0; i < windows.size(); ++i) {
+ DOMWindow& window = windows[i].get();
+ if (!set.contains(&window))
continue;
- window->dispatchEvent(PageTransitionEvent::create(eventNames().pagehideEvent, false), window->document());
- window->dispatchEvent(Event::create(eventNames().unloadEvent, false, false), window->document());
+ window.dispatchEvent(PageTransitionEvent::create(eventNames().pagehideEvent, false), window.document());
+ window.dispatchEvent(Event::create(eventNames().unloadEvent, false, false), window.document());
- window->enableSuddenTermination();
+ window.enableSuddenTermination();
}
alreadyDispatched = true;
@@ -373,40 +357,34 @@ bool DOMWindow::canShowModalDialog(const Frame* frame)
{
if (!frame)
return false;
-
- // Override support for layout testing purposes.
- if (auto* document = frame->document()) {
- if (auto* window = document->domWindow()) {
- if (window->m_canShowModalDialogOverride)
- return window->m_canShowModalDialogOverride.value();
- }
- }
-
- auto* page = frame->page();
- return page ? page->chrome().canRunModal() : false;
+ Page* page = frame->page();
+ if (!page)
+ return false;
+ return page->chrome().canRunModal();
}
-void DOMWindow::setCanShowModalDialogOverride(bool allow)
+bool DOMWindow::canShowModalDialogNow(const Frame* frame)
{
- m_canShowModalDialogOverride = allow;
+ if (!frame)
+ return false;
+ Page* page = frame->page();
+ if (!page)
+ return false;
+ return page->chrome().canRunModalNow();
}
DOMWindow::DOMWindow(Document* document)
: ContextDestructionObserver(document)
, FrameDestructionObserver(document->frame())
, m_shouldPrintWhenFinishedLoading(false)
- , m_suspendedForDocumentSuspension(false)
+ , m_suspendedForPageCache(false)
, m_lastPageStatus(PageStatusNone)
- , m_weakPtrFactory(this)
#if PLATFORM(IOS)
, m_scrollEventListenerCount(0)
#endif
#if ENABLE(IOS_TOUCH_EVENTS) || ENABLE(IOS_GESTURE_EVENTS)
, m_touchEventListenerCount(0)
#endif
-#if ENABLE(GAMEPAD)
- , m_gamepadEventListenerCount(0)
-#endif
{
ASSERT(frame());
ASSERT(DOMWindow::document());
@@ -420,7 +398,7 @@ void DOMWindow::didSecureTransitionTo(Document* document)
DOMWindow::~DOMWindow()
{
#ifndef NDEBUG
- if (!m_suspendedForDocumentSuspension) {
+ if (!m_suspendedForPageCache) {
ASSERT(!m_screen);
ASSERT(!m_history);
ASSERT(!m_crypto);
@@ -430,6 +408,7 @@ DOMWindow::~DOMWindow()
ASSERT(!m_scrollbars);
ASSERT(!m_statusbar);
ASSERT(!m_toolbar);
+ ASSERT(!m_console);
ASSERT(!m_navigator);
#if ENABLE(WEB_TIMING)
ASSERT(!m_performance);
@@ -442,7 +421,7 @@ DOMWindow::~DOMWindow()
}
#endif
- if (m_suspendedForDocumentSuspension)
+ if (m_suspendedForPageCache)
willDestroyCachedFrame();
else
willDestroyDocumentInFrame();
@@ -453,11 +432,6 @@ DOMWindow::~DOMWindow()
removeAllUnloadEventListeners(this);
removeAllBeforeUnloadEventListeners(this);
-
-#if ENABLE(GAMEPAD)
- if (m_gamepadEventListenerCount)
- GamepadManager::singleton().unregisterDOMWindow(this);
-#endif
}
DOMWindow* DOMWindow::toDOMWindow()
@@ -480,7 +454,6 @@ void DOMWindow::frameDestroyed()
willDestroyDocumentInFrame();
FrameDestructionObserver::frameDestroyed();
resetDOMWindowProperties();
- JSDOMWindowBase::fireFrameClearedWatchpointsForWindow(this);
}
void DOMWindow::willDetachPage()
@@ -494,8 +467,8 @@ void DOMWindow::willDestroyCachedFrame()
// unregister themselves from the DOMWindow as a result of the call to willDestroyGlobalObjectInCachedFrame.
Vector<DOMWindowProperty*> properties;
copyToVector(m_properties, properties);
- for (auto& property : properties)
- property->willDestroyGlobalObjectInCachedFrame();
+ for (size_t i = 0; i < properties.size(); ++i)
+ properties[i]->willDestroyGlobalObjectInCachedFrame();
}
void DOMWindow::willDestroyDocumentInFrame()
@@ -504,8 +477,8 @@ void DOMWindow::willDestroyDocumentInFrame()
// unregister themselves from the DOMWindow as a result of the call to willDestroyGlobalObjectInFrame.
Vector<DOMWindowProperty*> properties;
copyToVector(m_properties, properties);
- for (auto& property : properties)
- property->willDestroyGlobalObjectInFrame();
+ for (size_t i = 0; i < properties.size(); ++i)
+ properties[i]->willDestroyGlobalObjectInFrame();
}
void DOMWindow::willDetachDocumentFromFrame()
@@ -514,26 +487,10 @@ void DOMWindow::willDetachDocumentFromFrame()
// unregister themselves from the DOMWindow as a result of the call to willDetachGlobalObjectFromFrame.
Vector<DOMWindowProperty*> properties;
copyToVector(m_properties, properties);
- for (auto& property : properties)
- property->willDetachGlobalObjectFromFrame();
-}
-
-#if ENABLE(GAMEPAD)
-void DOMWindow::incrementGamepadEventListenerCount()
-{
- if (++m_gamepadEventListenerCount == 1)
- GamepadManager::singleton().registerDOMWindow(this);
+ for (size_t i = 0; i < properties.size(); ++i)
+ properties[i]->willDetachGlobalObjectFromFrame();
}
-void DOMWindow::decrementGamepadEventListenerCount()
-{
- ASSERT(m_gamepadEventListenerCount);
-
- if (!--m_gamepadEventListenerCount)
- GamepadManager::singleton().unregisterDOMWindow(this);
-}
-#endif
-
void DOMWindow::registerProperty(DOMWindowProperty* property)
{
m_properties.add(property);
@@ -544,69 +501,70 @@ void DOMWindow::unregisterProperty(DOMWindowProperty* property)
m_properties.remove(property);
}
-void DOMWindow::resetUnlessSuspendedForDocumentSuspension()
+void DOMWindow::resetUnlessSuspendedForPageCache()
{
- if (m_suspendedForDocumentSuspension)
+ if (m_suspendedForPageCache)
return;
willDestroyDocumentInFrame();
resetDOMWindowProperties();
}
-void DOMWindow::suspendForDocumentSuspension()
+void DOMWindow::suspendForPageCache()
{
disconnectDOMWindowProperties();
- m_suspendedForDocumentSuspension = true;
+ m_suspendedForPageCache = true;
}
-void DOMWindow::resumeFromDocumentSuspension()
+void DOMWindow::resumeFromPageCache()
{
reconnectDOMWindowProperties();
- m_suspendedForDocumentSuspension = false;
+ m_suspendedForPageCache = false;
}
void DOMWindow::disconnectDOMWindowProperties()
{
// It is necessary to copy m_properties to a separate vector because the DOMWindowProperties may
- // unregister themselves from the DOMWindow as a result of the call to disconnectFrameForDocumentSuspension.
+ // unregister themselves from the DOMWindow as a result of the call to disconnectFrameForPageCache.
Vector<DOMWindowProperty*> properties;
copyToVector(m_properties, properties);
- for (auto& property : properties)
- property->disconnectFrameForDocumentSuspension();
+ for (size_t i = 0; i < properties.size(); ++i)
+ properties[i]->disconnectFrameForPageCache();
}
void DOMWindow::reconnectDOMWindowProperties()
{
- ASSERT(m_suspendedForDocumentSuspension);
+ ASSERT(m_suspendedForPageCache);
// It is necessary to copy m_properties to a separate vector because the DOMWindowProperties may
// unregister themselves from the DOMWindow as a result of the call to reconnectFromPageCache.
Vector<DOMWindowProperty*> properties;
copyToVector(m_properties, properties);
- for (auto& property : properties)
- property->reconnectFrameFromDocumentSuspension(m_frame);
+ for (size_t i = 0; i < properties.size(); ++i)
+ properties[i]->reconnectFrameFromPageCache(m_frame);
}
void DOMWindow::resetDOMWindowProperties()
{
m_properties.clear();
- m_screen = nullptr;
- m_history = nullptr;
- m_crypto = nullptr;
- m_locationbar = nullptr;
- m_menubar = nullptr;
- m_personalbar = nullptr;
- m_scrollbars = nullptr;
- m_statusbar = nullptr;
- m_toolbar = nullptr;
- m_navigator = nullptr;
+ m_screen = 0;
+ m_history = 0;
+ m_crypto = 0;
+ m_locationbar = 0;
+ m_menubar = 0;
+ m_personalbar = 0;
+ m_scrollbars = 0;
+ m_statusbar = 0;
+ m_toolbar = 0;
+ m_console = 0;
+ m_navigator = 0;
#if ENABLE(WEB_TIMING)
- m_performance = nullptr;
+ m_performance = 0;
#endif
- m_location = nullptr;
- m_media = nullptr;
- m_sessionStorage = nullptr;
- m_localStorage = nullptr;
- m_applicationCache = nullptr;
+ m_location = 0;
+ m_media = 0;
+ m_sessionStorage = 0;
+ m_localStorage = 0;
+ m_applicationCache = 0;
}
bool DOMWindow::isCurrentlyDisplayedInFrame() const
@@ -706,11 +664,20 @@ BarProp* DOMWindow::toolbar() const
return m_toolbar.get();
}
-PageConsoleClient* DOMWindow::console() const
+Console* DOMWindow::console() const
{
if (!isCurrentlyDisplayedInFrame())
- return nullptr;
- return m_frame->page() ? &m_frame->page()->console() : nullptr;
+ return 0;
+ if (!m_console)
+ m_console = Console::create(m_frame);
+ return m_console.get();
+}
+
+PageConsole* DOMWindow::pageConsole() const
+{
+ if (!isCurrentlyDisplayedInFrame())
+ return 0;
+ return m_frame->page() ? &m_frame->page()->console() : 0;
}
DOMApplicationCache* DOMWindow::applicationCache() const
@@ -725,7 +692,7 @@ DOMApplicationCache* DOMWindow::applicationCache() const
Navigator* DOMWindow::navigator() const
{
if (!isCurrentlyDisplayedInFrame())
- return nullptr;
+ return 0;
if (!m_navigator)
m_navigator = Navigator::create(m_frame);
return m_navigator.get();
@@ -735,9 +702,9 @@ Navigator* DOMWindow::navigator() const
Performance* DOMWindow::performance() const
{
if (!isCurrentlyDisplayedInFrame())
- return nullptr;
+ return 0;
if (!m_performance)
- m_performance = Performance::create(*m_frame);
+ m_performance = Performance::create(m_frame);
return m_performance.get();
}
#endif
@@ -745,48 +712,12 @@ Performance* DOMWindow::performance() const
Location* DOMWindow::location() const
{
if (!isCurrentlyDisplayedInFrame())
- return nullptr;
+ return 0;
if (!m_location)
m_location = Location::create(m_frame);
return m_location.get();
}
-#if ENABLE(USER_MESSAGE_HANDLERS)
-bool DOMWindow::shouldHaveWebKitNamespaceForWorld(DOMWrapperWorld& world)
-{
- if (!m_frame)
- return false;
-
- auto* page = m_frame->page();
- if (!page)
- return false;
-
- auto* userContentController = page->userContentController();
- if (!userContentController)
- return false;
-
- auto* descriptorMap = userContentController->userMessageHandlerDescriptors();
- if (!descriptorMap)
- return false;
-
- for (auto& descriptor : descriptorMap->values()) {
- if (&descriptor->world() == &world)
- return true;
- }
-
- return false;
-}
-
-WebKitNamespace* DOMWindow::webkitNamespace() const
-{
- if (!isCurrentlyDisplayedInFrame())
- return nullptr;
- if (!m_webkitNamespace)
- m_webkitNamespace = WebKitNamespace::create(*m_frame);
- return m_webkitNamespace.get();
-}
-#endif
-
Storage* DOMWindow::sessionStorage(ExceptionCode& ec) const
{
if (!isCurrentlyDisplayedInFrame())
@@ -826,44 +757,41 @@ Storage* DOMWindow::sessionStorage(ExceptionCode& ec) const
Storage* DOMWindow::localStorage(ExceptionCode& ec) const
{
if (!isCurrentlyDisplayedInFrame())
- return nullptr;
+ return 0;
Document* document = this->document();
if (!document)
- return nullptr;
+ return 0;
- if (!document->securityOrigin()->canAccessLocalStorage(nullptr)) {
+ if (!document->securityOrigin()->canAccessLocalStorage(0)) {
ec = SECURITY_ERR;
- return nullptr;
+ return 0;
}
- Page* page = document->page();
- // FIXME: We should consider supporting access/modification to local storage
- // after calling window.close(). See <https://bugs.webkit.org/show_bug.cgi?id=135330>.
- if (!page || !page->isClosing()) {
- if (m_localStorage) {
- if (!m_localStorage->area().canAccessStorage(m_frame)) {
- ec = SECURITY_ERR;
- return nullptr;
- }
- return m_localStorage.get();
+ if (m_localStorage) {
+ if (!m_localStorage->area().canAccessStorage(m_frame)) {
+ ec = SECURITY_ERR;
+ return 0;
}
+ return m_localStorage.get();
}
+ Page* page = document->page();
if (!page)
- return nullptr;
-
- if (page->isClosing())
- return nullptr;
+ return 0;
if (!page->settings().localStorageEnabled())
- return nullptr;
+ return 0;
- RefPtr<StorageArea> storageArea = page->storageNamespaceProvider().localStorageArea(*document);
+ RefPtr<StorageArea> storageArea;
+ if (!document->securityOrigin()->canAccessLocalStorage(document->topOrigin()))
+ storageArea = page->group().transientLocalStorage(document->topOrigin())->storageArea(document->securityOrigin());
+ else
+ storageArea = page->group().localStorage()->storageArea(document->securityOrigin());
if (!storageArea->canAccessStorage(m_frame)) {
ec = SECURITY_ERR;
- return nullptr;
+ return 0;
}
m_localStorage = Storage::create(m_frame, storageArea.release());
@@ -902,7 +830,7 @@ void DOMWindow::postMessage(PassRefPtr<SerializedScriptValue> message, const Mes
}
}
- std::unique_ptr<MessagePortChannelArray> channels = MessagePort::disentanglePorts(ports, ec);
+ OwnPtr<MessagePortChannelArray> channels = MessagePort::disentanglePorts(ports, ec);
if (ec)
return;
@@ -915,30 +843,31 @@ void DOMWindow::postMessage(PassRefPtr<SerializedScriptValue> message, const Mes
// Capture stack trace only when inspector front-end is loaded as it may be time consuming.
RefPtr<ScriptCallStack> stackTrace;
if (InspectorInstrumentation::consoleAgentEnabled(sourceDocument))
- stackTrace = createScriptCallStack(JSMainThreadExecState::currentState(), ScriptCallStack::maxCallStackSizeToCapture);
+ stackTrace = createScriptCallStack(ScriptCallStack::maxCallStackSizeToCapture, true);
// Schedule the message.
- PostMessageTimer* timer = new PostMessageTimer(this, message, sourceOrigin, &source, WTFMove(channels), target.get(), stackTrace.release());
+ PostMessageTimer* timer = new PostMessageTimer(this, message, sourceOrigin, &source, channels.release(), target.get(), stackTrace.release());
timer->startOneShot(0);
}
-void DOMWindow::postMessageTimerFired(PostMessageTimer& timer)
+void DOMWindow::postMessageTimerFired(PassOwnPtr<PostMessageTimer> t)
{
+ OwnPtr<PostMessageTimer> timer(t);
+
if (!document() || !isCurrentlyDisplayedInFrame())
return;
- dispatchMessageEventWithOriginCheck(timer.targetOrigin(), timer.event(document()), timer.stackTrace());
+ dispatchMessageEventWithOriginCheck(timer->targetOrigin(), timer->event(document()), timer->stackTrace());
}
-void DOMWindow::dispatchMessageEventWithOriginCheck(SecurityOrigin* intendedTargetOrigin, Event& event, PassRefPtr<ScriptCallStack> stackTrace)
+void DOMWindow::dispatchMessageEventWithOriginCheck(SecurityOrigin* intendedTargetOrigin, PassRefPtr<Event> event, PassRefPtr<ScriptCallStack> stackTrace)
{
if (intendedTargetOrigin) {
// Check target origin now since the target document may have changed since the timer was scheduled.
if (!intendedTargetOrigin->isSameSchemeHostPort(document()->securityOrigin())) {
- if (PageConsoleClient* pageConsole = console()) {
- String message = makeString("Unable to post message to ", intendedTargetOrigin->toString(), ". Recipient has origin ", document()->securityOrigin()->toString(), ".\n");
- pageConsole->addMessage(MessageSource::Security, MessageLevel::Error, message, stackTrace);
- }
+ String message = "Unable to post message to " + intendedTargetOrigin->toString() +
+ ". Recipient has origin " + document()->securityOrigin()->toString() + ".\n";
+ pageConsole()->addMessage(SecurityMessageSource, ErrorMessageLevel, message, stackTrace);
return;
}
}
@@ -974,8 +903,8 @@ void DOMWindow::focus(ScriptExecutionContext* context)
bool allowFocus = WindowFocusAllowedIndicator::windowFocusAllowed() || !m_frame->settings().windowFocusRestricted();
if (context) {
ASSERT(isMainThread());
- Document& activeDocument = downcast<Document>(*context);
- if (opener() && opener() != this && activeDocument.domWindow() == opener())
+ Document* activeDocument = toDocument(context);
+ if (opener() && opener() != this && activeDocument->domWindow() == opener())
allowFocus = true;
}
@@ -989,7 +918,7 @@ void DOMWindow::focus(ScriptExecutionContext* context)
// Clear the current frame's focused node if a new frame is about to be focused.
Frame* focusedFrame = page->focusController().focusedFrame();
if (focusedFrame && focusedFrame != m_frame)
- focusedFrame->document()->setFocusedElement(nullptr);
+ focusedFrame->document()->setFocusedElement(0);
m_frame->eventHandler().focusDocumentView();
}
@@ -1026,21 +955,24 @@ void DOMWindow::close(ScriptExecutionContext* context)
if (context) {
ASSERT(isMainThread());
- if (!downcast<Document>(*context).canNavigate(m_frame))
+ Document* activeDocument = toDocument(context);
+ if (!activeDocument)
+ return;
+
+ if (!activeDocument->canNavigate(m_frame))
return;
}
bool allowScriptsToCloseWindows = m_frame->settings().allowScriptsToCloseWindows();
if (!(page->openedByDOM() || page->backForward().count() <= 1 || allowScriptsToCloseWindows)) {
- console()->addMessage(MessageSource::JS, MessageLevel::Warning, ASCIILiteral("Can't close the window since it was not opened by JavaScript"));
+ pageConsole()->addMessage(JSMessageSource, WarningMessageLevel, ASCIILiteral("Can't close the window since it was not opened by JavaScript"));
return;
}
if (!m_frame->loader().shouldClose())
return;
- page->setIsClosing();
page->chrome().closeWindowSoon();
}
@@ -1049,12 +981,13 @@ void DOMWindow::print()
if (!m_frame)
return;
- auto* page = m_frame->page();
+ Page* page = m_frame->page();
if (!page)
return;
- if (!page->arePromptsAllowed()) {
- printErrorMessage("Use of window.print is not allowed while unloading a page.");
+ // Pages are not allowed to bring up a modal print dialog during BeforeUnload dispatch.
+ if (page->isAnyFrameHandlingBeforeUnloadEvent()) {
+ printErrorMessage("Use of window.print is not allowed during beforeunload event dispatch.");
return;
}
@@ -1081,17 +1014,18 @@ void DOMWindow::alert(const String& message)
if (!m_frame)
return;
- auto* page = m_frame->page();
- if (!page)
- return;
-
- if (!page->arePromptsAllowed()) {
- printErrorMessage("Use of window.alert is not allowed while unloading a page.");
+ // Pages are not allowed to cause modal alerts during BeforeUnload dispatch.
+ if (page() && page()->isAnyFrameHandlingBeforeUnloadEvent()) {
+ printErrorMessage("Use of window.alert is not allowed during beforeunload event dispatch.");
return;
}
m_frame->document()->updateStyleIfNeeded();
+ Page* page = m_frame->page();
+ if (!page)
+ return;
+
page->chrome().runJavaScriptAlert(m_frame, message);
}
@@ -1100,17 +1034,18 @@ bool DOMWindow::confirm(const String& message)
if (!m_frame)
return false;
- auto* page = m_frame->page();
- if (!page)
- return false;
-
- if (!page->arePromptsAllowed()) {
- printErrorMessage("Use of window.confirm is not allowed while unloading a page.");
+ // Pages are not allowed to cause modal alerts during BeforeUnload dispatch.
+ if (page() && page()->isAnyFrameHandlingBeforeUnloadEvent()) {
+ printErrorMessage("Use of window.confirm is not allowed during beforeunload event dispatch.");
return false;
}
m_frame->document()->updateStyleIfNeeded();
+ Page* page = m_frame->page();
+ if (!page)
+ return false;
+
return page->chrome().runJavaScriptConfirm(m_frame, message);
}
@@ -1119,17 +1054,18 @@ String DOMWindow::prompt(const String& message, const String& defaultValue)
if (!m_frame)
return String();
- auto* page = m_frame->page();
- if (!page)
- return String();
-
- if (!page->arePromptsAllowed()) {
- printErrorMessage("Use of window.prompt is not allowed while unloading a page.");
+ // Pages are not allowed to cause modal alerts during BeforeUnload dispatch.
+ if (page() && page()->isAnyFrameHandlingBeforeUnloadEvent()) {
+ printErrorMessage("Use of window.prompt is not allowed during beforeunload event dispatch.");
return String();
}
m_frame->document()->updateStyleIfNeeded();
+ Page* page = m_frame->page();
+ if (!page)
+ return String();
+
String returnValue;
if (page->chrome().runJavaScriptPrompt(m_frame, message, defaultValue, returnValue))
return returnValue;
@@ -1161,7 +1097,7 @@ String DOMWindow::atob(const String& encodedString, ExceptionCode& ec)
}
Vector<char> out;
- if (!base64Decode(encodedString, out, Base64ValidatePadding | Base64IgnoreSpacesAndNewLines)) {
+ if (!base64Decode(encodedString, out, Base64FailOnInvalidCharacterOrExcessPadding)) {
ec = INVALID_CHARACTER_ERR;
return String();
}
@@ -1186,9 +1122,6 @@ bool DOMWindow::offscreenBuffering() const
int DOMWindow::outerHeight() const
{
-#if PLATFORM(IOS)
- return 0;
-#else
if (!m_frame)
return 0;
@@ -1197,14 +1130,10 @@ int DOMWindow::outerHeight() const
return 0;
return static_cast<int>(page->chrome().windowRect().height());
-#endif
}
int DOMWindow::outerWidth() const
{
-#if PLATFORM(IOS)
- return 0;
-#else
if (!m_frame)
return 0;
@@ -1213,7 +1142,6 @@ int DOMWindow::outerWidth() const
return 0;
return static_cast<int>(page->chrome().windowRect().width());
-#endif
}
int DOMWindow::innerHeight() const
@@ -1225,7 +1153,7 @@ int DOMWindow::innerHeight() const
if (!view)
return 0;
- return view->mapFromLayoutToCSSUnits(static_cast<int>(view->unobscuredContentRectIncludingScrollbars().height()));
+ return view->mapFromLayoutToCSSUnits(static_cast<int>(view->visibleContentRectIncludingScrollbars().height()));
}
int DOMWindow::innerWidth() const
@@ -1237,7 +1165,7 @@ int DOMWindow::innerWidth() const
if (!view)
return 0;
- return view->mapFromLayoutToCSSUnits(static_cast<int>(view->unobscuredContentRectIncludingScrollbars().width()));
+ return view->mapFromLayoutToCSSUnits(static_cast<int>(view->visibleContentRectIncludingScrollbars().width()));
}
int DOMWindow::screenX() const
@@ -1273,13 +1201,16 @@ int DOMWindow::scrollX() const
if (!view)
return 0;
- int scrollX = view->contentsScrollPosition().x();
- if (!scrollX)
+ if (!view->scrollX())
return 0;
m_frame->document()->updateLayoutIgnorePendingStylesheets();
- return view->mapFromLayoutToCSSUnits(view->contentsScrollPosition().x());
+#if PLATFORM(IOS)
+ return static_cast<int>(view->actualScrollX() / (m_frame->pageZoomFactor() * m_frame->frameScaleFactor()));
+#else
+ return view->mapFromLayoutToCSSUnits(view->scrollX());
+#endif
}
int DOMWindow::scrollY() const
@@ -1291,13 +1222,16 @@ int DOMWindow::scrollY() const
if (!view)
return 0;
- int scrollY = view->contentsScrollPosition().y();
- if (!scrollY)
+ if (!view->scrollY())
return 0;
m_frame->document()->updateLayoutIgnorePendingStylesheets();
- return view->mapFromLayoutToCSSUnits(view->contentsScrollPosition().y());
+#if PLATFORM(IOS)
+ return static_cast<int>(view->actualScrollY() / (m_frame->pageZoomFactor() * m_frame->frameScaleFactor()));
+#else
+ return view->mapFromLayoutToCSSUnits(view->scrollY());
+#endif
}
bool DOMWindow::closed() const
@@ -1406,24 +1340,24 @@ DOMWindow* DOMWindow::top() const
Document* DOMWindow::document() const
{
ScriptExecutionContext* context = ContextDestructionObserver::scriptExecutionContext();
- return downcast<Document>(context);
+ return toDocument(context);
}
PassRefPtr<StyleMedia> DOMWindow::styleMedia() const
{
if (!isCurrentlyDisplayedInFrame())
- return nullptr;
+ return 0;
if (!m_media)
m_media = StyleMedia::create(m_frame);
return m_media.get();
}
-PassRefPtr<CSSStyleDeclaration> DOMWindow::getComputedStyle(Element* element, const String& pseudoElt) const
+PassRefPtr<CSSStyleDeclaration> DOMWindow::getComputedStyle(Element* elt, const String& pseudoElt) const
{
- if (!element)
- return nullptr;
+ if (!elt)
+ return 0;
- return CSSComputedStyleDeclaration::create(element, false, pseudoElt);
+ return CSSComputedStyleDeclaration::create(elt, false, pseudoElt);
}
PassRefPtr<CSSRuleList> DOMWindow::getMatchedCSSRules(Element* element, const String& pseudoElement, bool authorOnly) const
@@ -1432,8 +1366,8 @@ PassRefPtr<CSSRuleList> DOMWindow::getMatchedCSSRules(Element* element, const St
return 0;
unsigned colonStart = pseudoElement[0] == ':' ? (pseudoElement[1] == ':' ? 2 : 1) : 0;
- CSSSelector::PseudoElementType pseudoType = CSSSelector::parsePseudoElementType(pseudoElement.substringSharingImpl(colonStart));
- if (pseudoType == CSSSelector::PseudoElementUnknown && !pseudoElement.isEmpty())
+ CSSSelector::PseudoType pseudoType = CSSSelector::parsePseudoType(AtomicString(pseudoElement.substring(colonStart)));
+ if (pseudoType == CSSSelector::PseudoUnknown && !pseudoElement.isEmpty())
return 0;
unsigned rulesToInclude = StyleResolver::AuthorCSSRules;
@@ -1444,13 +1378,13 @@ PassRefPtr<CSSRuleList> DOMWindow::getMatchedCSSRules(Element* element, const St
PseudoId pseudoId = CSSSelector::pseudoId(pseudoType);
- auto matchedRules = m_frame->document()->ensureStyleResolver().pseudoStyleRulesForElement(element, pseudoId, rulesToInclude);
+ Vector<RefPtr<StyleRuleBase>> matchedRules = m_frame->document()->ensureStyleResolver().pseudoStyleRulesForElement(element, pseudoId, rulesToInclude);
if (matchedRules.isEmpty())
return 0;
RefPtr<StaticCSSRuleList> ruleList = StaticCSSRuleList::create();
- for (auto& rule : matchedRules)
- ruleList->rules().append(rule->createCSSOMWrapper());
+ for (unsigned i = 0; i < matchedRules.size(); ++i)
+ ruleList->rules().append(matchedRules[i]->createCSSOMWrapper());
return ruleList.release();
}
@@ -1509,7 +1443,11 @@ void DOMWindow::scrollBy(int x, int y) const
return;
IntSize scaledOffset(view->mapFromCSSToLayoutUnits(x), view->mapFromCSSToLayoutUnits(y));
- view->setContentsScrollPosition(view->contentsScrollPosition() + scaledOffset);
+#if PLATFORM(IOS)
+ view->setActualScrollPosition(view->actualScrollPosition() + scaledOffset);
+#else
+ view->scrollBy(scaledOffset);
+#endif
}
void DOMWindow::scrollTo(int x, int y) const
@@ -1517,17 +1455,21 @@ void DOMWindow::scrollTo(int x, int y) const
if (!isCurrentlyDisplayedInFrame())
return;
+ document()->updateLayoutIgnorePendingStylesheets();
+
RefPtr<FrameView> view = m_frame->view();
if (!view)
return;
- if (!x && !y && view->contentsScrollPosition() == IntPoint(0, 0))
- return;
-
- document()->updateLayoutIgnorePendingStylesheets();
+#if PLATFORM(IOS)
+ int zoomedX = static_cast<int>(x * m_frame->pageZoomFactor() * m_frame->frameScaleFactor());
+ int zoomedY = static_cast<int>(y * m_frame->pageZoomFactor() * m_frame->frameScaleFactor());
+ view->setActualScrollPosition(IntPoint(zoomedX, zoomedY));
+#else
IntPoint layoutPos(view->mapFromCSSToLayoutUnits(x), view->mapFromCSSToLayoutUnits(y));
- view->setContentsScrollPosition(layoutPos);
+ view->setScrollPosition(layoutPos);
+#endif
}
bool DOMWindow::allowedToChangeWindowGeometry() const
@@ -1596,14 +1538,14 @@ void DOMWindow::resizeTo(float width, float height) const
page->chrome().setWindowRect(adjustWindowRect(page, update));
}
-int DOMWindow::setTimeout(std::unique_ptr<ScheduledAction> action, int timeout, ExceptionCode& ec)
+int DOMWindow::setTimeout(PassOwnPtr<ScheduledAction> action, int timeout, ExceptionCode& ec)
{
ScriptExecutionContext* context = scriptExecutionContext();
if (!context) {
ec = INVALID_ACCESS_ERR;
return -1;
}
- return DOMTimer::install(*context, WTFMove(action), timeout, true);
+ return DOMTimer::install(context, action, timeout, true);
}
void DOMWindow::clearTimeout(int timeoutId)
@@ -1627,17 +1569,17 @@ void DOMWindow::clearTimeout(int timeoutId)
ScriptExecutionContext* context = scriptExecutionContext();
if (!context)
return;
- DOMTimer::removeById(*context, timeoutId);
+ DOMTimer::removeById(context, timeoutId);
}
-int DOMWindow::setInterval(std::unique_ptr<ScheduledAction> action, int timeout, ExceptionCode& ec)
+int DOMWindow::setInterval(PassOwnPtr<ScheduledAction> action, int timeout, ExceptionCode& ec)
{
ScriptExecutionContext* context = scriptExecutionContext();
if (!context) {
ec = INVALID_ACCESS_ERR;
return -1;
}
- return DOMTimer::install(*context, WTFMove(action), timeout, false);
+ return DOMTimer::install(context, action, timeout, false);
}
void DOMWindow::clearInterval(int timeoutId)
@@ -1645,7 +1587,7 @@ void DOMWindow::clearInterval(int timeoutId)
ScriptExecutionContext* context = scriptExecutionContext();
if (!context)
return;
- DOMTimer::removeById(*context, timeoutId);
+ DOMTimer::removeById(context, timeoutId);
}
#if ENABLE(REQUEST_ANIMATION_FRAME)
@@ -1672,12 +1614,14 @@ void DOMWindow::cancelAnimationFrame(int id)
}
#endif
+#if ENABLE(CSS3_CONDITIONAL_RULES)
DOMWindowCSS* DOMWindow::css()
{
if (!m_css)
m_css = DOMWindowCSS::create();
return m_css.get();
}
+#endif
static void didAddStorageEventListener(DOMWindow* window)
{
@@ -1689,33 +1633,17 @@ static void didAddStorageEventListener(DOMWindow* window)
window->sessionStorage(IGNORE_EXCEPTION);
}
-bool DOMWindow::isSameSecurityOriginAsMainFrame() const
+bool DOMWindow::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture)
{
- if (!m_frame || !m_frame->page() || !document())
- return false;
-
- if (m_frame->isMainFrame())
- return true;
-
- Document* mainFrameDocument = m_frame->mainFrame().document();
-
- if (mainFrameDocument && document()->securityOrigin()->canAccess(mainFrameDocument->securityOrigin()))
- return true;
-
- return false;
-}
-
-bool DOMWindow::addEventListener(const AtomicString& eventType, RefPtr<EventListener>&& listener, bool useCapture)
-{
- if (!EventTarget::addEventListener(eventType, WTFMove(listener), useCapture))
+ if (!EventTarget::addEventListener(eventType, listener, useCapture))
return false;
if (Document* document = this->document()) {
document->addListenerTypeIfNeeded(eventType);
- if (eventNames().isWheelEventType(eventType))
- document->didAddWheelEventHandler(*document);
+ if (eventType == eventNames().wheelEvent || eventType == eventNames().mousewheelEvent)
+ document->didAddWheelEventHandler();
else if (eventNames().isTouchEventType(eventType))
- document->didAddTouchEventHandler(*document);
+ document->didAddTouchEventHandler(document);
else if (eventType == eventNames().storageEvent)
didAddStorageEventListener(this);
}
@@ -1726,28 +1654,17 @@ bool DOMWindow::addEventListener(const AtomicString& eventType, RefPtr<EventList
addBeforeUnloadEventListener(this);
#if ENABLE(DEVICE_ORIENTATION)
#if PLATFORM(IOS)
- else if ((eventType == eventNames().devicemotionEvent || eventType == eventNames().deviceorientationEvent) && document()) {
- if (isSameSecurityOriginAsMainFrame()) {
- if (eventType == eventNames().deviceorientationEvent)
- document()->deviceOrientationController()->addDeviceEventListener(this);
- else
- document()->deviceMotionController()->addDeviceEventListener(this);
- } else if (document())
- document()->addConsoleMessage(MessageSource::JS, MessageLevel::Warning, ASCIILiteral("Blocked attempt add device motion or orientation listener from child frame that wasn't the same security origin as the main page."));
- }
+ else if (eventType == eventNames().devicemotionEvent && document())
+ document()->deviceMotionController()->addDeviceEventListener(this);
+ else if (eventType == eventNames().deviceorientationEvent && document())
+ document()->deviceOrientationController()->addDeviceEventListener(this);
#else
else if (eventType == eventNames().devicemotionEvent && RuntimeEnabledFeatures::sharedFeatures().deviceMotionEnabled()) {
- if (isSameSecurityOriginAsMainFrame()) {
- if (DeviceMotionController* controller = DeviceMotionController::from(page()))
- controller->addDeviceEventListener(this);
- } else if (document())
- document()->addConsoleMessage(MessageSource::JS, MessageLevel::Warning, ASCIILiteral("Blocked attempt add device motion listener from child frame that wasn't the same security origin as the main page."));
+ if (DeviceMotionController* controller = DeviceMotionController::from(page()))
+ controller->addDeviceEventListener(this);
} else if (eventType == eventNames().deviceorientationEvent && RuntimeEnabledFeatures::sharedFeatures().deviceOrientationEnabled()) {
- if (isSameSecurityOriginAsMainFrame()) {
- if (DeviceOrientationController* controller = DeviceOrientationController::from(page()))
- controller->addDeviceEventListener(this);
- } else if (document())
- document()->addConsoleMessage(MessageSource::JS, MessageLevel::Warning, ASCIILiteral("Blocked attempt add device orientation listener from child frame that wasn't the same security origin as the main page."));
+ if (DeviceOrientationController* controller = DeviceOrientationController::from(page()))
+ controller->addDeviceEventListener(this);
}
#endif // PLATFORM(IOS)
#endif // ENABLE(DEVICE_ORIENTATION)
@@ -1763,10 +1680,7 @@ bool DOMWindow::addEventListener(const AtomicString& eventType, RefPtr<EventList
else if (eventNames().isGestureEventType(eventType))
++m_touchEventListenerCount;
#endif
-#if ENABLE(GAMEPAD)
- else if (eventNames().isGamepadEventType(eventType))
- incrementGamepadEventListenerCount();
-#endif
+
#if ENABLE(PROXIMITY_EVENTS)
else if (eventType == eventNames().webkitdeviceproximityEvent) {
if (DeviceProximityController* controller = DeviceProximityController::from(page()))
@@ -1814,10 +1728,10 @@ bool DOMWindow::removeEventListener(const AtomicString& eventType, EventListener
return false;
if (Document* document = this->document()) {
- if (eventNames().isWheelEventType(eventType))
- document->didRemoveWheelEventHandler(*document);
+ if (eventType == eventNames().wheelEvent || eventType == eventNames().mousewheelEvent)
+ document->didRemoveWheelEventHandler();
else if (eventNames().isTouchEventType(eventType))
- document->didRemoveTouchEventHandler(*document);
+ document->didRemoveTouchEventHandler(document);
}
if (eventType == eventNames().unloadEvent)
@@ -1856,10 +1770,7 @@ bool DOMWindow::removeEventListener(const AtomicString& eventType, EventListener
--m_touchEventListenerCount;
}
#endif
-#if ENABLE(GAMEPAD)
- else if (eventNames().isGamepadEventType(eventType))
- decrementGamepadEventListenerCount();
-#endif
+
#if ENABLE(PROXIMITY_EVENTS)
else if (eventType == eventNames().webkitdeviceproximityEvent) {
if (DeviceProximityController* controller = DeviceProximityController::from(page()))
@@ -1872,55 +1783,56 @@ bool DOMWindow::removeEventListener(const AtomicString& eventType, EventListener
void DOMWindow::dispatchLoadEvent()
{
- Ref<Event> loadEvent = Event::create(eventNames().loadEvent, false, false);
- if (m_frame && m_frame->loader().documentLoader() && !m_frame->loader().documentLoader()->timing().loadEventStart()) {
+ RefPtr<Event> loadEvent(Event::create(eventNames().loadEvent, false, false));
+ if (m_frame && m_frame->loader().documentLoader() && !m_frame->loader().documentLoader()->timing()->loadEventStart()) {
// The DocumentLoader (and thus its DocumentLoadTiming) might get destroyed while dispatching
// the event, so protect it to prevent writing the end time into freed memory.
RefPtr<DocumentLoader> documentLoader = m_frame->loader().documentLoader();
- DocumentLoadTiming& timing = documentLoader->timing();
- timing.markLoadEventStart();
+ DocumentLoadTiming* timing = documentLoader->timing();
+ timing->markLoadEventStart();
dispatchEvent(loadEvent, document());
- timing.markLoadEventEnd();
+ timing->markLoadEventEnd();
} else
dispatchEvent(loadEvent, document());
// For load events, send a separate load event to the enclosing frame only.
// This is a DOM extension and is independent of bubbling/capturing rules of
// the DOM.
- Element* ownerElement = m_frame ? m_frame->ownerElement() : nullptr;
+ Element* ownerElement = m_frame ? m_frame->ownerElement() : 0;
if (ownerElement)
ownerElement->dispatchEvent(Event::create(eventNames().loadEvent, false, false));
InspectorInstrumentation::loadEventFired(frame());
}
-bool DOMWindow::dispatchEvent(Event& event, EventTarget* target)
+bool DOMWindow::dispatchEvent(PassRefPtr<Event> prpEvent, PassRefPtr<EventTarget> prpTarget)
{
Ref<EventTarget> protect(*this);
+ RefPtr<Event> event = prpEvent;
// Pausing a page may trigger pagehide and pageshow events. WebCore also implicitly fires these
// events when closing a WebView. Here we keep track of the state of the page to prevent duplicate,
// unbalanced events per the definition of the pageshow event:
// <http://www.whatwg.org/specs/web-apps/current-work/multipage/history.html#event-pageshow>.
- if (event.eventInterface() == PageTransitionEventInterfaceType) {
- if (event.type() == eventNames().pageshowEvent) {
+ if (event->eventInterface() == PageTransitionEventInterfaceType) {
+ if (event->type() == eventNames().pageshowEvent) {
if (m_lastPageStatus == PageStatusShown)
return true; // Event was previously dispatched; do not fire a duplicate event.
m_lastPageStatus = PageStatusShown;
- } else if (event.type() == eventNames().pagehideEvent) {
+ } else if (event->type() == eventNames().pagehideEvent) {
if (m_lastPageStatus == PageStatusHidden)
return true; // Event was previously dispatched; do not fire a duplicate event.
m_lastPageStatus = PageStatusHidden;
}
}
- event.setTarget(target ? target : this);
- event.setCurrentTarget(this);
- event.setEventPhase(Event::AT_TARGET);
+ event->setTarget(prpTarget ? prpTarget : this);
+ event->setCurrentTarget(this);
+ event->setEventPhase(Event::AT_TARGET);
- InspectorInstrumentationCookie cookie = InspectorInstrumentation::willDispatchEventOnWindow(frame(), event, *this);
+ InspectorInstrumentationCookie cookie = InspectorInstrumentation::willDispatchEventOnWindow(frame(), *event, this);
- bool result = fireEventListeners(event);
+ bool result = fireEventListeners(event.get());
InspectorInstrumentation::didDispatchEventOnWindow(cookie);
@@ -1958,7 +1870,7 @@ void DOMWindow::removeAllEventListeners()
#if ENABLE(TOUCH_EVENTS)
if (Document* document = this->document())
- document->didRemoveEventTargetNode(*document);
+ document->didRemoveEventTargetNode(document);
#endif
#if ENABLE(PROXIMITY_EVENTS)
@@ -1984,12 +1896,11 @@ void DOMWindow::finishedLoading()
{
if (m_shouldPrintWhenFinishedLoading) {
m_shouldPrintWhenFinishedLoading = false;
- if (m_frame->loader().activeDocumentLoader()->mainDocumentError().isNull())
- print();
+ print();
}
}
-void DOMWindow::setLocation(DOMWindow& activeWindow, DOMWindow& firstWindow, const String& urlString, SetLocationLocking locking)
+void DOMWindow::setLocation(const String& urlString, DOMWindow& activeWindow, DOMWindow& firstWindow, SetLocationLocking locking)
{
if (!isCurrentlyDisplayedInFrame())
return;
@@ -2013,12 +1924,11 @@ void DOMWindow::setLocation(DOMWindow& activeWindow, DOMWindow& firstWindow, con
return;
// We want a new history item if we are processing a user gesture.
- LockHistory lockHistory = (locking != LockHistoryBasedOnGestureState || !ScriptController::processingUserGesture()) ? LockHistory::Yes : LockHistory::No;
- LockBackForwardList lockBackForwardList = (locking != LockHistoryBasedOnGestureState) ? LockBackForwardList::Yes : LockBackForwardList::No;
- m_frame->navigationScheduler().scheduleLocationChange(activeDocument, activeDocument->securityOrigin(),
+ m_frame->navigationScheduler().scheduleLocationChange(activeDocument->securityOrigin(),
// FIXME: What if activeDocument()->frame() is 0?
completedURL, activeDocument->frame()->loader().outgoingReferrer(),
- lockHistory, lockBackForwardList);
+ locking != LockHistoryBasedOnGestureState || !ScriptController::processingUserGesture(),
+ locking != LockHistoryBasedOnGestureState);
}
void DOMWindow::printErrorMessage(const String& message)
@@ -2026,8 +1936,7 @@ void DOMWindow::printErrorMessage(const String& message)
if (message.isEmpty())
return;
- if (PageConsoleClient* pageConsole = console())
- pageConsole->addMessage(MessageSource::JS, MessageLevel::Error, message);
+ pageConsole()->addMessage(JSMessageSource, ErrorMessageLevel, message);
}
String DOMWindow::crossDomainAccessErrorMessage(const DOMWindow& activeWindow)
@@ -2047,7 +1956,7 @@ String DOMWindow::crossDomainAccessErrorMessage(const DOMWindow& activeWindow)
URL activeURL = activeWindow.document()->url();
URL targetURL = document()->url();
if (document()->isSandboxed(SandboxOrigin) || activeWindow.document()->isSandboxed(SandboxOrigin)) {
- message = "Blocked a frame at \"" + SecurityOrigin::create(activeURL).get().toString() + "\" from accessing a frame at \"" + SecurityOrigin::create(targetURL).get().toString() + "\". ";
+ message = "Blocked a frame at \"" + SecurityOrigin::create(activeURL)->toString() + "\" from accessing a frame at \"" + SecurityOrigin::create(targetURL)->toString() + "\". ";
if (document()->isSandboxed(SandboxOrigin) && activeWindow.document()->isSandboxed(SandboxOrigin))
return "Sandbox access violation: " + message + " Both frames are sandboxed and lack the \"allow-same-origin\" flag.";
if (document()->isSandboxed(SandboxOrigin))
@@ -2095,101 +2004,76 @@ bool DOMWindow::isInsecureScriptAccess(DOMWindow& activeWindow, const String& ur
return true;
}
-RefPtr<Frame> DOMWindow::createWindow(const String& urlString, const AtomicString& frameName, const WindowFeatures& windowFeatures, DOMWindow& activeWindow, Frame& firstFrame, Frame& openerFrame, std::function<void (DOMWindow&)> prepareDialogFunction)
+PassRefPtr<Frame> DOMWindow::createWindow(const String& urlString, const AtomicString& frameName, const WindowFeatures& windowFeatures, DOMWindow& activeWindow, Frame* firstFrame, Frame* openerFrame, std::function<void (DOMWindow&)> prepareDialogFunction)
{
Frame* activeFrame = activeWindow.frame();
- if (!activeFrame)
- return nullptr;
- Document* activeDocument = activeWindow.document();
- if (!activeDocument)
- return nullptr;
-
- URL completedURL = urlString.isEmpty() ? URL(ParsedURLString, emptyString()) : firstFrame.document()->completeURL(urlString);
+ URL completedURL = urlString.isEmpty() ? URL(ParsedURLString, emptyString()) : firstFrame->document()->completeURL(urlString);
if (!completedURL.isEmpty() && !completedURL.isValid()) {
// Don't expose client code to invalid URLs.
activeWindow.printErrorMessage("Unable to open a window with invalid URL '" + completedURL.string() + "'.\n");
- return nullptr;
+ return 0;
}
// For whatever reason, Firefox uses the first frame to determine the outgoingReferrer. We replicate that behavior here.
- String referrer = SecurityPolicy::generateReferrerHeader(firstFrame.document()->referrerPolicy(), completedURL, firstFrame.loader().outgoingReferrer());
+ String referrer = SecurityPolicy::generateReferrerHeader(firstFrame->document()->referrerPolicy(), completedURL, firstFrame->loader().outgoingReferrer());
ResourceRequest request(completedURL, referrer);
- FrameLoader::addHTTPOriginIfNeeded(request, firstFrame.loader().outgoingOrigin());
- FrameLoadRequest frameRequest(activeDocument->securityOrigin(), request, frameName, LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, ReplaceDocumentIfJavaScriptURL, activeDocument->shouldOpenExternalURLsPolicyToPropagate());
+ FrameLoader::addHTTPOriginIfNeeded(request, firstFrame->loader().outgoingOrigin());
+ FrameLoadRequest frameRequest(activeWindow.document()->securityOrigin(), request, frameName);
// We pass the opener frame for the lookupFrame in case the active frame is different from
// the opener frame, and the name references a frame relative to the opener frame.
bool created;
- RefPtr<Frame> newFrame = WebCore::createWindow(*activeFrame, openerFrame, frameRequest, windowFeatures, created);
+ RefPtr<Frame> newFrame = WebCore::createWindow(activeFrame, openerFrame, frameRequest, windowFeatures, created);
if (!newFrame)
- return nullptr;
+ return 0;
- newFrame->loader().setOpener(&openerFrame);
+ newFrame->loader().setOpener(openerFrame);
newFrame->page()->setOpenedByDOM();
if (newFrame->document()->domWindow()->isInsecureScriptAccess(activeWindow, completedURL))
- return newFrame;
+ return newFrame.release();
if (prepareDialogFunction)
prepareDialogFunction(*newFrame->document()->domWindow());
- if (created) {
- ResourceRequest resourceRequest(completedURL, referrer, UseProtocolCachePolicy);
- FrameLoadRequest frameRequest(activeWindow.document()->securityOrigin(), resourceRequest, "_self", LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, activeDocument->shouldOpenExternalURLsPolicyToPropagate());
- newFrame->loader().changeLocation(frameRequest);
- } else if (!urlString.isEmpty()) {
- LockHistory lockHistory = ScriptController::processingUserGesture() ? LockHistory::No : LockHistory::Yes;
- newFrame->navigationScheduler().scheduleLocationChange(activeWindow.document(), activeWindow.document()->securityOrigin(), completedURL, referrer, lockHistory, LockBackForwardList::No);
+ if (created)
+ newFrame->loader().changeLocation(activeWindow.document()->securityOrigin(), completedURL, referrer, false, false);
+ else if (!urlString.isEmpty()) {
+ bool lockHistory = !ScriptController::processingUserGesture();
+ newFrame->navigationScheduler().scheduleLocationChange(activeWindow.document()->securityOrigin(), completedURL.string(), referrer, lockHistory, false);
}
// Navigating the new frame could result in it being detached from its page by a navigation policy delegate.
if (!newFrame->page())
- return nullptr;
+ return 0;
- return newFrame;
+ return newFrame.release();
}
PassRefPtr<DOMWindow> DOMWindow::open(const String& urlString, const AtomicString& frameName, const String& windowFeaturesString,
DOMWindow& activeWindow, DOMWindow& firstWindow)
{
if (!isCurrentlyDisplayedInFrame())
- return nullptr;
-
+ return 0;
Document* activeDocument = activeWindow.document();
if (!activeDocument)
- return nullptr;
-
+ return 0;
Frame* firstFrame = firstWindow.frame();
if (!firstFrame)
- return nullptr;
-
-#if ENABLE(CONTENT_EXTENSIONS)
- if (firstFrame->document()
- && firstFrame->mainFrame().page()
- && firstFrame->mainFrame().page()->userContentController()
- && firstFrame->mainFrame().document()
- && firstFrame->mainFrame().document()->loader()) {
- ResourceLoadInfo resourceLoadInfo = {firstFrame->document()->completeURL(urlString), firstFrame->mainFrame().document()->url(), ResourceType::Popup};
- Vector<ContentExtensions::Action> actions = firstFrame->mainFrame().page()->userContentController()->actionsForResourceLoad(resourceLoadInfo, *firstFrame->mainFrame().document()->loader());
- for (const ContentExtensions::Action& action : actions) {
- if (action.type() == ContentExtensions::ActionType::BlockLoad)
- return nullptr;
- }
- }
-#endif
+ return 0;
if (!firstWindow.allowPopUp()) {
// Because FrameTree::find() returns true for empty strings, we must check for empty frame names.
// Otherwise, illegitimate window.open() calls with no name will pass right through the popup blocker.
if (frameName.isEmpty() || !m_frame->tree().find(frameName))
- return nullptr;
+ return 0;
}
// Get the target frame for the special cases of _top and _parent.
// In those cases, we schedule a location change right now and return early.
- Frame* targetFrame = nullptr;
+ Frame* targetFrame = 0;
if (frameName == "_top")
targetFrame = &m_frame->tree().top();
else if (frameName == "_parent") {
@@ -2200,7 +2084,7 @@ PassRefPtr<DOMWindow> DOMWindow::open(const String& urlString, const AtomicStrin
}
if (targetFrame) {
if (!activeDocument->canNavigate(targetFrame))
- return nullptr;
+ return 0;
URL completedURL = firstFrame->document()->completeURL(urlString);
@@ -2212,14 +2096,19 @@ PassRefPtr<DOMWindow> DOMWindow::open(const String& urlString, const AtomicStrin
// For whatever reason, Firefox uses the first window rather than the active window to
// determine the outgoing referrer. We replicate that behavior here.
- LockHistory lockHistory = ScriptController::processingUserGesture() ? LockHistory::No : LockHistory::Yes;
- targetFrame->navigationScheduler().scheduleLocationChange(activeDocument, activeDocument->securityOrigin(), completedURL, firstFrame->loader().outgoingReferrer(),
- lockHistory, LockBackForwardList::No);
+ bool lockHistory = !ScriptController::processingUserGesture();
+ targetFrame->navigationScheduler().scheduleLocationChange(
+ activeDocument->securityOrigin(),
+ completedURL,
+ firstFrame->loader().outgoingReferrer(),
+ lockHistory,
+ false);
return targetFrame->document()->domWindow();
}
- RefPtr<Frame> result = createWindow(urlString, frameName, parseWindowFeatures(windowFeaturesString), activeWindow, *firstFrame, *m_frame);
- return result ? result->document()->domWindow() : nullptr;
+ WindowFeatures windowFeatures(windowFeaturesString);
+ RefPtr<Frame> result = createWindow(urlString, frameName, windowFeatures, activeWindow, firstFrame, m_frame);
+ return result ? result->document()->domWindow() : 0;
}
void DOMWindow::showModalDialog(const String& urlString, const String& dialogFeaturesString, DOMWindow& activeWindow, DOMWindow& firstWindow, std::function<void (DOMWindow&)> prepareDialogFunction)
@@ -2233,19 +2122,17 @@ void DOMWindow::showModalDialog(const String& urlString, const String& dialogFea
if (!firstFrame)
return;
- auto* page = m_frame->page();
- if (!page)
- return;
-
- if (!page->arePromptsAllowed()) {
- printErrorMessage("Use of window.showModalDialog is not allowed while unloading a page.");
+ // Pages are not allowed to cause modal alerts during BeforeUnload dispatch.
+ if (page() && page()->isAnyFrameHandlingBeforeUnloadEvent()) {
+ printErrorMessage("Use of window.showModalDialog is not allowed during beforeunload event dispatch.");
return;
}
- if (!canShowModalDialog(m_frame) || !firstWindow.allowPopUp())
+ if (!canShowModalDialogNow(m_frame) || !firstWindow.allowPopUp())
return;
- RefPtr<Frame> dialogFrame = createWindow(urlString, emptyAtom, parseDialogFeatures(dialogFeaturesString, screenAvailableRect(m_frame->view())), activeWindow, *firstFrame, *m_frame, WTFMove(prepareDialogFunction));
+ WindowFeatures windowFeatures(dialogFeaturesString, screenAvailableRect(m_frame->view()));
+ RefPtr<Frame> dialogFrame = createWindow(urlString, emptyAtom, windowFeatures, activeWindow, firstFrame, m_frame, std::move(prepareDialogFunction));
if (!dialogFrame)
return;
dialogFrame->page()->chrome().runModal();
diff --git a/Source/WebCore/page/DOMWindow.h b/Source/WebCore/page/DOMWindow.h
index 2674a0cab..b681f77c3 100644
--- a/Source/WebCore/page/DOMWindow.h
+++ b/Source/WebCore/page/DOMWindow.h
@@ -11,17 +11,17 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef DOMWindow_h
@@ -33,26 +33,18 @@
#include "URL.h"
#include "Supplementable.h"
#include <functional>
-#include <memory>
-#include <wtf/Optional.h>
-#include <wtf/WeakPtr.h>
-
-namespace Inspector {
-class ScriptCallStack;
-}
namespace WebCore {
class BarProp;
class CSSRuleList;
class CSSStyleDeclaration;
+ class Console;
class Crypto;
class DOMApplicationCache;
class DOMSelection;
class DOMURL;
- class DOMWindowCSS;
class DOMWindowProperty;
- class DOMWrapperWorld;
class Database;
class DatabaseCallback;
class Document;
@@ -68,17 +60,18 @@ namespace WebCore {
class Navigator;
class Node;
class Page;
- class PageConsoleClient;
+ class PageConsole;
class Performance;
class PostMessageTimer;
class ScheduledAction;
class Screen;
+ class ScriptCallStack;
class SecurityOrigin;
class SerializedScriptValue;
class Storage;
class StyleMedia;
- class WebKitNamespace;
class WebKitPoint;
+ class DOMWindowCSS;
#if ENABLE(REQUEST_ANIMATION_FRAME)
class RequestAnimationFrameCallback;
@@ -100,8 +93,8 @@ namespace WebCore {
, public FrameDestructionObserver
, public Supplementable<DOMWindow> {
public:
- static Ref<DOMWindow> create(Document* document) { return adoptRef(*new DOMWindow(document)); }
- WEBCORE_EXPORT virtual ~DOMWindow();
+ static PassRefPtr<DOMWindow> create(Document* document) { return adoptRef(new DOMWindow(document)); }
+ virtual ~DOMWindow();
// In some rare cases, we'll re-used a DOMWindow for a new Document. For example,
// when a script calls window.open("..."), the browser gives JavaScript a window
@@ -120,23 +113,23 @@ namespace WebCore {
void registerProperty(DOMWindowProperty*);
void unregisterProperty(DOMWindowProperty*);
- void resetUnlessSuspendedForDocumentSuspension();
- void suspendForDocumentSuspension();
- void resumeFromDocumentSuspension();
+ void resetUnlessSuspendedForPageCache();
+ void suspendForPageCache();
+ void resumeFromPageCache();
PassRefPtr<MediaQueryList> matchMedia(const String&);
- WEBCORE_EXPORT unsigned pendingUnloadEventListeners() const;
+ unsigned pendingUnloadEventListeners() const;
- WEBCORE_EXPORT static bool dispatchAllPendingBeforeUnloadEvents();
- WEBCORE_EXPORT static void dispatchAllPendingUnloadEvents();
+ static bool dispatchAllPendingBeforeUnloadEvents();
+ static void dispatchAllPendingUnloadEvents();
static FloatRect adjustWindowRect(Page*, const FloatRect& pendingChanges);
bool allowPopUp(); // Call on first window, not target window.
static bool allowPopUp(Frame* firstFrame);
static bool canShowModalDialog(const Frame*);
- WEBCORE_EXPORT void setCanShowModalDialogOverride(bool);
+ static bool canShowModalDialogNow(const Frame*);
// DOM Level 0
@@ -153,20 +146,20 @@ namespace WebCore {
Navigator* clientInformation() const { return navigator(); }
Location* location() const;
- void setLocation(DOMWindow& activeWindow, DOMWindow& firstWindow, const String& location,
+ void setLocation(const String& location, DOMWindow& activeWindow, DOMWindow& firstWindow,
SetLocationLocking = LockHistoryBasedOnGestureState);
DOMSelection* getSelection();
Element* frameElement() const;
- void focus(ScriptExecutionContext* = nullptr);
+ void focus(ScriptExecutionContext* = 0);
void blur();
- WEBCORE_EXPORT void close(ScriptExecutionContext* = nullptr);
+ void close(ScriptExecutionContext* = 0);
void print();
void stop();
- WEBCORE_EXPORT PassRefPtr<DOMWindow> open(const String& urlString, const AtomicString& frameName, const String& windowFeaturesString,
+ PassRefPtr<DOMWindow> open(const String& urlString, const AtomicString& frameName, const String& windowFeaturesString,
DOMWindow& activeWindow, DOMWindow& firstWindow);
void showModalDialog(const String& urlString, const String& dialogFeaturesString, DOMWindow& activeWindow, DOMWindow& firstWindow, std::function<void (DOMWindow&)> prepareDialogFunction);
@@ -218,7 +211,7 @@ namespace WebCore {
// DOM Level 2 AbstractView Interface
- WEBCORE_EXPORT Document* document() const;
+ Document* document() const;
// CSSOM View Module
@@ -234,9 +227,10 @@ namespace WebCore {
double devicePixelRatio() const;
PassRefPtr<WebKitPoint> webkitConvertPointFromPageToNode(Node*, const WebKitPoint*) const;
- PassRefPtr<WebKitPoint> webkitConvertPointFromNodeToPage(Node*, const WebKitPoint*) const;
+ PassRefPtr<WebKitPoint> webkitConvertPointFromNodeToPage(Node*, const WebKitPoint*) const;
- PageConsoleClient* console() const;
+ Console* console() const;
+ PageConsole* pageConsole() const;
void printErrorMessage(const String&);
String crossDomainAccessErrorMessage(const DOMWindow& activeWindow);
@@ -244,8 +238,8 @@ namespace WebCore {
void postMessage(PassRefPtr<SerializedScriptValue> message, const MessagePortArray*, const String& targetOrigin, DOMWindow& source, ExceptionCode&);
// Needed for Objective-C bindings (see bug 28774).
void postMessage(PassRefPtr<SerializedScriptValue> message, MessagePort*, const String& targetOrigin, DOMWindow& source, ExceptionCode&);
- void postMessageTimerFired(PostMessageTimer&);
- void dispatchMessageEventWithOriginCheck(SecurityOrigin* intendedTargetOrigin, Event&, PassRefPtr<Inspector::ScriptCallStack>);
+ void postMessageTimerFired(PassOwnPtr<PostMessageTimer>);
+ void dispatchMessageEventWithOriginCheck(SecurityOrigin* intendedTargetOrigin, PassRefPtr<Event>, PassRefPtr<ScriptCallStack>);
void scrollBy(int x, int y) const;
void scrollTo(int x, int y) const;
@@ -258,9 +252,9 @@ namespace WebCore {
void resizeTo(float width, float height) const;
// Timers
- int setTimeout(std::unique_ptr<ScheduledAction>, int timeout, ExceptionCode&);
+ int setTimeout(PassOwnPtr<ScheduledAction>, int timeout, ExceptionCode&);
void clearTimeout(int timeoutId);
- int setInterval(std::unique_ptr<ScheduledAction>, int timeout, ExceptionCode&);
+ int setInterval(PassOwnPtr<ScheduledAction>, int timeout, ExceptionCode&);
void clearInterval(int timeoutId);
// WebKit animation extensions
@@ -270,19 +264,96 @@ namespace WebCore {
void cancelAnimationFrame(int id);
#endif
+#if ENABLE(CSS3_CONDITIONAL_RULES)
DOMWindowCSS* css();
+#endif
// Events
// EventTarget API
- virtual bool addEventListener(const AtomicString& eventType, RefPtr<EventListener>&&, bool useCapture) override;
+ virtual bool addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture) override;
virtual bool removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture) override;
virtual void removeAllEventListeners() override;
using EventTarget::dispatchEvent;
- bool dispatchEvent(Event&, EventTarget*);
+ bool dispatchEvent(PassRefPtr<Event> prpEvent, PassRefPtr<EventTarget> prpTarget);
void dispatchLoadEvent();
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(abort);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(beforeunload);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(blur);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(canplay);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(canplaythrough);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(change);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(click);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(contextmenu);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(dblclick);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(drag);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(dragend);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(dragenter);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(dragleave);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(dragover);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(dragstart);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(drop);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(durationchange);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(emptied);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(ended);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(error);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(focus);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(hashchange);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(input);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(invalid);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(keydown);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(keypress);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(keyup);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(load);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(loadeddata);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(loadedmetadata);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(loadstart);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(message);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(mousedown);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseenter);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseleave);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(mousemove);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseout);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseover);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseup);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(mousewheel);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(offline);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(online);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(pagehide);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(pageshow);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(pause);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(play);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(playing);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(popstate);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(progress);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(ratechange);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(reset);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(resize);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(scroll);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(search);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(seeked);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(seeking);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(select);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(stalled);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(storage);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(submit);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(suspend);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(timeupdate);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(unload);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(volumechange);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(waiting);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitbeginfullscreen);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitendfullscreen);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(wheel);
+
+ DEFINE_MAPPED_ATTRIBUTE_EVENT_LISTENER(webkitanimationstart, webkitAnimationStart);
+ DEFINE_MAPPED_ATTRIBUTE_EVENT_LISTENER(webkitanimationiteration, webkitAnimationIteration);
+ DEFINE_MAPPED_ATTRIBUTE_EVENT_LISTENER(webkitanimationend, webkitAnimationEnd);
+ DEFINE_MAPPED_ATTRIBUTE_EVENT_LISTENER(webkittransitionend, webkitTransitionEnd);
+ DEFINE_MAPPED_ATTRIBUTE_EVENT_LISTENER(transitionend, transitionend);
+
void captureEvents();
void releaseEvents();
@@ -291,6 +362,15 @@ namespace WebCore {
using RefCounted<DOMWindow>::ref;
using RefCounted<DOMWindow>::deref;
+#if ENABLE(DEVICE_ORIENTATION)
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(devicemotion);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(deviceorientation);
+#endif
+
+#if ENABLE(PROXIMITY_EVENTS)
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitdeviceproximity);
+#endif
+
// HTML 5 key/value storage
Storage* sessionStorage(ExceptionCode&) const;
Storage* localStorage(ExceptionCode&) const;
@@ -305,6 +385,21 @@ namespace WebCore {
// 0 is straight up; -90 is when the device is rotated 90 clockwise;
// 90 is when rotated counter clockwise.
int orientation() const;
+
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(orientationchange);
+#endif
+
+#if ENABLE(TOUCH_EVENTS)
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(touchstart);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(touchmove);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(touchend);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(touchcancel);
+#endif
+
+#if ENABLE(IOS_GESTURE_EVENTS)
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(gesturestart);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(gesturechange);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(gestureend);
#endif
#if ENABLE(WEB_TIMING)
@@ -323,11 +418,6 @@ namespace WebCore {
bool hasTouchEventListeners() const { return m_touchEventListenerCount > 0; }
#endif
-#if ENABLE(USER_MESSAGE_HANDLERS)
- bool shouldHaveWebKitNamespaceForWorld(DOMWrapperWorld&);
- WebKitNamespace* webkitNamespace() const;
-#endif
-
// FIXME: When this DOMWindow is no longer the active DOMWindow (i.e.,
// when its document is no longer the document that is displayed in its
// frame), we would like to zero out m_frame to avoid being confused
@@ -340,8 +430,6 @@ namespace WebCore {
void enableSuddenTermination();
void disableSuddenTermination();
- WeakPtr<DOMWindow> createWeakPtr() { return m_weakPtrFactory.createWeakPtr(); }
-
private:
explicit DOMWindow(Document*);
@@ -354,7 +442,7 @@ namespace WebCore {
virtual void refEventTarget() override { ref(); }
virtual void derefEventTarget() override { deref(); }
- static RefPtr<Frame> createWindow(const String& urlString, const AtomicString& frameName, const WindowFeatures&, DOMWindow& activeWindow, Frame& firstFrame, Frame& openerFrame, std::function<void (DOMWindow&)> prepareDialogFunction = nullptr);
+ static PassRefPtr<Frame> createWindow(const String& urlString, const AtomicString& frameName, const WindowFeatures&, DOMWindow& activeWindow, Frame* firstFrame, Frame* openerFrame, std::function<void (DOMWindow&)> prepareDialogFunction = nullptr);
bool isInsecureScriptAccess(DOMWindow& activeWindow, const String& urlString);
void resetDOMWindowProperties();
@@ -362,16 +450,8 @@ namespace WebCore {
void reconnectDOMWindowProperties();
void willDestroyDocumentInFrame();
- bool isSameSecurityOriginAsMainFrame() const;
-
-#if ENABLE(GAMEPAD)
- void incrementGamepadEventListenerCount();
- void decrementGamepadEventListenerCount();
-#endif
-
bool m_shouldPrintWhenFinishedLoading;
- bool m_suspendedForDocumentSuspension;
- Optional<bool> m_canShowModalDialogOverride;
+ bool m_suspendedForPageCache;
HashSet<DOMWindowProperty*> m_properties;
@@ -384,6 +464,7 @@ namespace WebCore {
mutable RefPtr<BarProp> m_scrollbars;
mutable RefPtr<BarProp> m_statusbar;
mutable RefPtr<BarProp> m_toolbar;
+ mutable RefPtr<Console> m_console;
mutable RefPtr<Navigator> m_navigator;
mutable RefPtr<Location> m_location;
mutable RefPtr<StyleMedia> m_media;
@@ -394,8 +475,6 @@ namespace WebCore {
enum PageStatus { PageStatusNone, PageStatusShown, PageStatusHidden };
PageStatus m_lastPageStatus;
- WeakPtrFactory<DOMWindow> m_weakPtrFactory;
-
#if PLATFORM(IOS)
unsigned m_scrollEventListenerCount;
#endif
@@ -404,9 +483,6 @@ namespace WebCore {
unsigned m_touchEventListenerCount;
#endif
-#if ENABLE(GAMEPAD)
- unsigned m_gamepadEventListenerCount;
-#endif
mutable RefPtr<Storage> m_sessionStorage;
mutable RefPtr<Storage> m_localStorage;
mutable RefPtr<DOMApplicationCache> m_applicationCache;
@@ -415,10 +491,8 @@ namespace WebCore {
mutable RefPtr<Performance> m_performance;
#endif
+#if ENABLE(CSS3_CONDITIONAL_RULES)
mutable RefPtr<DOMWindowCSS> m_css;
-
-#if ENABLE(USER_MESSAGE_HANDLERS)
- mutable RefPtr<WebKitNamespace> m_webkitNamespace;
#endif
};
@@ -430,7 +504,7 @@ namespace WebCore {
inline String DOMWindow::defaultStatus() const
{
return m_defaultStatus;
- }
+ }
} // namespace WebCore
diff --git a/Source/WebCore/page/DOMWindow.idl b/Source/WebCore/page/DOMWindow.idl
index 595707557..a067f5431 100644
--- a/Source/WebCore/page/DOMWindow.idl
+++ b/Source/WebCore/page/DOMWindow.idl
@@ -11,10 +11,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -25,41 +25,44 @@
*/
[
- ImplicitThis,
CheckSecurity,
JSCustomDefineOwnProperty,
CustomDeleteProperty,
CustomGetOwnPropertySlot,
CustomEnumerateProperty,
- CustomProxyToJSObject,
JSCustomMarkFunction,
JSCustomToNativeObject,
CustomPutFunction,
+ EventTarget,
+ JSGenerateToNativeObject,
+ ReplaceableConstructor,
JSLegacyParent=JSDOMWindowBase,
InterfaceName=Window,
-] interface DOMWindow : EventTarget {
+] interface DOMWindow {
// DOM Level 0
[Replaceable] readonly attribute Screen screen;
- readonly attribute History history;
+ [Replaceable, DoNotCheckSecurityOnGetter] readonly attribute History history;
[Replaceable] readonly attribute BarProp locationbar;
[Replaceable] readonly attribute BarProp menubar;
[Replaceable] readonly attribute BarProp personalbar;
[Replaceable] readonly attribute BarProp scrollbars;
[Replaceable] readonly attribute BarProp statusbar;
[Replaceable] readonly attribute BarProp toolbar;
- readonly attribute Navigator navigator;
+ [Replaceable] readonly attribute Navigator navigator;
[Replaceable] readonly attribute Navigator clientInformation;
readonly attribute Crypto crypto;
- [DoNotCheckSecurity, CustomSetter, Unforgeable] attribute Location location;
+#if !defined(LANGUAGE_CPP) || !LANGUAGE_CPP
+ [DoNotCheckSecurity, CustomSetter] attribute Location location;
+#endif
[Replaceable, CustomGetter] readonly attribute Event event;
DOMSelection getSelection();
[CheckSecurityForNode] readonly attribute Element frameElement;
- [DoNotCheckSecurity, CallWith=ScriptExecutionContext, ForwardDeclareInHeader] void focus();
- [DoNotCheckSecurity, ForwardDeclareInHeader] void blur();
- [DoNotCheckSecurity, CallWith=ScriptExecutionContext, ForwardDeclareInHeader] void close();
+ [DoNotCheckSecurity, CallWith=ScriptExecutionContext] void focus();
+ [DoNotCheckSecurity] void blur();
+ [DoNotCheckSecurity, CallWith=ScriptExecutionContext] void close();
void print();
void stop();
@@ -103,12 +106,12 @@
void scrollBy([Default=Undefined] optional long x, [Default=Undefined] optional long y);
void scrollTo([Default=Undefined] optional long x, [Default=Undefined] optional long y);
void scroll([Default=Undefined] optional long x, [Default=Undefined] optional long y);
- void moveBy([Default=Undefined] optional unrestricted float x, [Default=Undefined] optional unrestricted float y); // FIXME: this should take longs not floats.
- void moveTo([Default=Undefined] optional unrestricted float x, [Default=Undefined] optional unrestricted float y); // FIXME: this should take longs not floats.
- void resizeBy([Default=Undefined] optional unrestricted float x, [Default=Undefined] optional unrestricted float y); // FIXME: this should take longs not floats.
- void resizeTo([Default=Undefined] optional unrestricted float width, [Default=Undefined] optional unrestricted float height); // FIXME: this should take longs not floats.
+ void moveBy([Default=Undefined] optional float x, [Default=Undefined] optional float y); // FIXME: this should take longs not floats.
+ void moveTo([Default=Undefined] optional float x, [Default=Undefined] optional float y); // FIXME: this should take longs not floats.
+ void resizeBy([Default=Undefined] optional float x, [Default=Undefined] optional float y); // FIXME: this should take longs not floats.
+ void resizeTo([Default=Undefined] optional float width, [Default=Undefined] optional float height); // FIXME: this should take longs not floats.
- [DoNotCheckSecurity, ForwardDeclareInHeader] readonly attribute boolean closed;
+ [DoNotCheckSecurity] readonly attribute boolean closed;
[Replaceable, DoNotCheckSecurityOnGetter] readonly attribute unsigned long length;
@@ -123,15 +126,15 @@
// Self referential attributes
[Replaceable, DoNotCheckSecurityOnGetter] readonly attribute DOMWindow self;
- [DoNotCheckSecurity, Unforgeable] readonly attribute DOMWindow window;
+ [DoNotCheckSecurity] readonly attribute DOMWindow window;
[Replaceable, DoNotCheckSecurityOnGetter] readonly attribute DOMWindow frames;
[Replaceable, DoNotCheckSecurityOnGetter] readonly attribute DOMWindow opener;
[Replaceable, DoNotCheckSecurityOnGetter] readonly attribute DOMWindow parent;
- [DoNotCheckSecurityOnGetter, Unforgeable] readonly attribute DOMWindow top;
+ [DoNotCheckSecurityOnGetter] readonly attribute DOMWindow top;
// DOM Level 2 AbstractView Interface
- [Unforgeable] readonly attribute Document document;
+ readonly attribute Document document;
// CSSOM View Module
MediaQueryList matchMedia(DOMString query);
@@ -149,7 +152,7 @@
[TreatNullAs=NullString, TreatUndefinedAs=NullString,Default=Undefined] optional DOMString pseudoElement);
#endif
- [Replaceable] readonly attribute unrestricted double devicePixelRatio;
+ [Replaceable] readonly attribute double devicePixelRatio;
WebKitPoint webkitConvertPointFromPageToNode([Default=Undefined] optional Node node,
[Default=Undefined] optional WebKitPoint p);
@@ -161,28 +164,144 @@
[GetterRaisesException] readonly attribute Storage sessionStorage;
[GetterRaisesException] readonly attribute Storage localStorage;
+#if defined(ENABLE_ORIENTATION_EVENTS) && ENABLE_ORIENTATION_EVENTS
// This is the interface orientation in degrees. Some examples are:
// 0 is straight up; -90 is when the device is rotated 90 clockwise;
// 90 is when rotated counter clockwise.
- [Conditional=ORIENTATION_EVENTS] readonly attribute long orientation;
+ readonly attribute long orientation;
+#endif
+
+ [Replaceable] readonly attribute Console console;
// cross-document messaging
#if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT
- [DoNotCheckSecurity, Custom, RaisesException, ForwardDeclareInHeader] void postMessage(SerializedScriptValue message, DOMString targetOrigin, optional Array messagePorts);
+ [DoNotCheckSecurity, Custom, RaisesException] void postMessage(SerializedScriptValue message, DOMString targetOrigin, optional Array messagePorts);
#else
// There's no good way to expose an array via the ObjC bindings, so for now just allow passing in a single port.
- [DoNotCheckSecurity, Custom, RaisesException, ForwardDeclareInHeader] void postMessage(SerializedScriptValue message, optional MessagePort messagePort, DOMString targetOrigin);
+ [DoNotCheckSecurity, Custom, RaisesException] void postMessage(SerializedScriptValue message, optional MessagePort messagePort, DOMString targetOrigin);
+#endif
+
+#if defined(ENABLE_WEB_TIMING) && ENABLE_WEB_TIMING
+ [Replaceable] readonly attribute Performance performance;
+#endif
+
+#if defined(ENABLE_REQUEST_ANIMATION_FRAME) && ENABLE_REQUEST_ANIMATION_FRAME
+ long requestAnimationFrame(RequestAnimationFrameCallback callback);
+ void cancelAnimationFrame(long id);
+ long webkitRequestAnimationFrame(RequestAnimationFrameCallback callback);
+ [ImplementedAs=cancelAnimationFrame] void webkitCancelAnimationFrame(long id);
+ [ImplementedAs=cancelAnimationFrame] void webkitCancelRequestAnimationFrame(long id); // This is a deprecated alias for webkitCancelAnimationFrame(). Remove this when removing vendor prefix.
#endif
- [Conditional=WEB_TIMING, Replaceable] readonly attribute Performance performance;
+ [Replaceable,Conditional=CSS3_CONDITIONAL_RULES] readonly attribute DOMWindowCSS CSS;
+
+ // Events
+ attribute EventListener onabort;
+ attribute EventListener onbeforeunload;
+ attribute EventListener onblur;
+ attribute EventListener oncanplay;
+ attribute EventListener oncanplaythrough;
+ attribute EventListener onchange;
+ attribute EventListener onclick;
+ attribute EventListener oncontextmenu;
+ attribute EventListener ondblclick;
+ attribute EventListener ondrag;
+ attribute EventListener ondragend;
+ attribute EventListener ondragenter;
+ attribute EventListener ondragleave;
+ attribute EventListener ondragover;
+ attribute EventListener ondragstart;
+ attribute EventListener ondrop;
+ attribute EventListener ondurationchange;
+ attribute EventListener onemptied;
+ attribute EventListener onended;
+ attribute EventListener onerror;
+ attribute EventListener onfocus;
+ attribute EventListener onhashchange;
+ attribute EventListener oninput;
+ attribute EventListener oninvalid;
+ attribute EventListener onkeydown;
+ attribute EventListener onkeypress;
+ attribute EventListener onkeyup;
+ attribute EventListener onload;
+ attribute EventListener onloadeddata;
+ attribute EventListener onloadedmetadata;
+ attribute EventListener onloadstart;
+ attribute EventListener onmessage;
+ attribute EventListener onmousedown;
+ attribute EventListener onmouseenter;
+ attribute EventListener onmouseleave;
+ attribute EventListener onmousemove;
+ attribute EventListener onmouseout;
+ attribute EventListener onmouseover;
+ attribute EventListener onmouseup;
+ attribute EventListener onmousewheel;
+ attribute EventListener onoffline;
+ attribute EventListener ononline;
+ attribute EventListener onpagehide;
+ attribute EventListener onpageshow;
+ attribute EventListener onpause;
+ attribute EventListener onplay;
+ attribute EventListener onplaying;
+ attribute EventListener onpopstate;
+ attribute EventListener onprogress;
+ attribute EventListener onratechange;
+ attribute EventListener onresize;
+ attribute EventListener onscroll;
+ attribute EventListener onseeked;
+ attribute EventListener onseeking;
+ attribute EventListener onselect;
+ attribute EventListener onstalled;
+ attribute EventListener onstorage;
+ attribute EventListener onsubmit;
+ attribute EventListener onsuspend;
+ attribute EventListener ontimeupdate;
+ attribute EventListener onunload;
+ attribute EventListener onvolumechange;
+ attribute EventListener onwaiting;
+ attribute EventListener onwheel;
+
+ // Not implemented yet.
+ // attribute EventListener onafterprint;
+ // attribute EventListener onbeforeprint;
+ // attribute EventListener onreadystatechange;
+ // attribute EventListener onredo;
+ // attribute EventListener onshow;
+ // attribute EventListener onundo;
+
+ // Webkit extensions
+ attribute EventListener onreset;
+ attribute EventListener onsearch;
+ attribute EventListener onwebkitanimationend;
+ attribute EventListener onwebkitanimationiteration;
+ attribute EventListener onwebkitanimationstart;
+ attribute EventListener onwebkittransitionend;
+ attribute EventListener ontransitionend;
+#if defined(ENABLE_ORIENTATION_EVENTS) && ENABLE_ORIENTATION_EVENTS
+ attribute EventListener onorientationchange;
+#endif
+ [Conditional=TOUCH_EVENTS] attribute EventListener ontouchstart;
+ [Conditional=TOUCH_EVENTS] attribute EventListener ontouchmove;
+ [Conditional=TOUCH_EVENTS] attribute EventListener ontouchend;
+ [Conditional=TOUCH_EVENTS] attribute EventListener ontouchcancel;
+
+ [Conditional=IOS_GESTURE_EVENTS] attribute EventListener ongesturestart;
+ [Conditional=IOS_GESTURE_EVENTS] attribute EventListener ongesturechange;
+ [Conditional=IOS_GESTURE_EVENTS] attribute EventListener ongestureend;
- [Conditional=REQUEST_ANIMATION_FRAME] long requestAnimationFrame(RequestAnimationFrameCallback callback);
- [Conditional=REQUEST_ANIMATION_FRAME] void cancelAnimationFrame(long id);
- [Conditional=REQUEST_ANIMATION_FRAME] long webkitRequestAnimationFrame(RequestAnimationFrameCallback callback);
- [Conditional=REQUEST_ANIMATION_FRAME, ImplementedAs=cancelAnimationFrame] void webkitCancelAnimationFrame(long id);
- [Conditional=REQUEST_ANIMATION_FRAME, ImplementedAs=cancelAnimationFrame] void webkitCancelRequestAnimationFrame(long id); // This is a deprecated alias for webkitCancelAnimationFrame(). Remove this when removing vendor prefix.
+ [Conditional=DEVICE_ORIENTATION] attribute EventListener ondevicemotion;
+ [Conditional=DEVICE_ORIENTATION] attribute EventListener ondeviceorientation;
- [Replaceable] readonly attribute DOMWindowCSS CSS;
+ [Conditional=PROXIMITY_EVENTS] attribute EventListener onwebkitdeviceproximity;
+
+ // EventTarget interface
+ [Custom] void addEventListener(DOMString type,
+ EventListener listener,
+ optional boolean useCapture);
+ [Custom] void removeEventListener(DOMString type,
+ EventListener listener,
+ optional boolean useCapture);
+ [RaisesException] boolean dispatchEvent(Event evt);
void captureEvents(/*in long eventFlags*/);
void releaseEvents(/*in long eventFlags*/);
@@ -190,47 +309,25 @@
#if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT
// Additional constructors.
[CustomGetter, CustomConstructor] attribute HTMLImageElementNamedConstructor Image; // Usable with new operator
- attribute DOMTokenListConstructor DOMSettableTokenList; // Map DOMSettableTokenList to DOMTokenList for backward compatibility.
+ // Mozilla has a separate XMLDocument object for XML documents.
+ // We just use Document for this.
+ attribute DocumentConstructor XMLDocument;
[Conditional=IOS_TOUCH_EVENTS, CustomGetter] attribute TouchConstructor Touch; // Usable with the new operator
[Conditional=IOS_TOUCH_EVENTS, CustomGetter] attribute TouchListConstructor TouchList; // Usable with the new operator
- attribute DOMURLConstructor webkitURL; // FIXME: deprecate this.
+ [Conditional=BLOB] attribute DOMURLConstructor webkitURL; // FIXME: deprecate this.
attribute MutationObserverConstructor WebKitMutationObserver; // FIXME: Add metrics to determine when we can remove this.
- [Conditional=INDEXED_DATABASE, EnabledAtRuntime=IndexedDB] attribute IDBCursorConstructor webkitIDBCursor;
- [Conditional=INDEXED_DATABASE, EnabledAtRuntime=IndexedDB] attribute IDBDatabaseConstructor webkitIDBDatabase;
- [Conditional=INDEXED_DATABASE, EnabledAtRuntime=IndexedDB] attribute IDBFactoryConstructor webkitIDBFactory;
- [Conditional=INDEXED_DATABASE, EnabledAtRuntime=IndexedDB] attribute IDBIndexConstructor webkitIDBIndex;
- [Conditional=INDEXED_DATABASE, EnabledAtRuntime=IndexedDB] attribute IDBKeyRangeConstructor webkitIDBKeyRange;
- [Conditional=INDEXED_DATABASE, EnabledAtRuntime=IndexedDB] attribute IDBObjectStoreConstructor webkitIDBObjectStore;
- [Conditional=INDEXED_DATABASE, EnabledAtRuntime=IndexedDB] attribute IDBRequestConstructor webkitIDBRequest;
- [Conditional=INDEXED_DATABASE, EnabledAtRuntime=IndexedDB] attribute IDBTransactionConstructor webkitIDBTransaction;
+ [Conditional=INDEXED_DATABASE] attribute IDBCursorConstructor webkitIDBCursor;
+ [Conditional=INDEXED_DATABASE] attribute IDBDatabaseConstructor webkitIDBDatabase;
+ [Conditional=INDEXED_DATABASE] attribute IDBFactoryConstructor webkitIDBFactory;
+ [Conditional=INDEXED_DATABASE] attribute IDBIndexConstructor webkitIDBIndex;
+ [Conditional=INDEXED_DATABASE] attribute IDBKeyRangeConstructor webkitIDBKeyRange;
+ [Conditional=INDEXED_DATABASE] attribute IDBObjectStoreConstructor webkitIDBObjectStore;
+ [Conditional=INDEXED_DATABASE] attribute IDBRequestConstructor webkitIDBRequest;
+ [Conditional=INDEXED_DATABASE] attribute IDBTransactionConstructor webkitIDBTransaction;
#endif // defined(LANGUAGE_JAVASCRIPT)
-
-
- // Event Handlers
-
- // Unique to Element and DOMWindow
- // FIXME: Should these be exposed on Document as well (and therefore moved to GlobalEventHandlers.idl)?
- [NotEnumerable] attribute EventHandler onanimationend;
- [NotEnumerable] attribute EventHandler onanimationiteration;
- [NotEnumerable] attribute EventHandler onanimationstart;
- [NotEnumerable] attribute EventHandler ontransitionend;
- [NotEnumerable] attribute EventHandler onwebkitanimationend;
- [NotEnumerable] attribute EventHandler onwebkitanimationiteration;
- [NotEnumerable] attribute EventHandler onwebkitanimationstart;
- [NotEnumerable] attribute EventHandler onwebkittransitionend;
- [NotEnumerable, Conditional=IOS_GESTURE_EVENTS] attribute EventHandler ongesturechange;
- [NotEnumerable, Conditional=IOS_GESTURE_EVENTS] attribute EventHandler ongestureend;
- [NotEnumerable, Conditional=IOS_GESTURE_EVENTS] attribute EventHandler ongesturestart;
-
- // Unique to DOMWindow
- [NotEnumerable, Conditional=DEVICE_ORIENTATION] attribute EventHandler ondevicemotion;
- [NotEnumerable, Conditional=DEVICE_ORIENTATION] attribute EventHandler ondeviceorientation;
- [NotEnumerable, Conditional=PROXIMITY_EVENTS] attribute EventHandler onwebkitdeviceproximity;
};
-DOMWindow implements GlobalEventHandlers;
-DOMWindow implements WindowBase64;
-DOMWindow implements WindowEventHandlers;
DOMWindow implements WindowTimers;
+DOMWindow implements WindowBase64;
diff --git a/Source/WebCore/page/DOMWindowExtension.cpp b/Source/WebCore/page/DOMWindowExtension.cpp
index 0e62b3437..cdfe9aa32 100644
--- a/Source/WebCore/page/DOMWindowExtension.cpp
+++ b/Source/WebCore/page/DOMWindowExtension.cpp
@@ -43,7 +43,7 @@ DOMWindowExtension::DOMWindowExtension(Frame* frame, DOMWrapperWorld& world)
ASSERT(this->frame());
}
-void DOMWindowExtension::disconnectFrameForDocumentSuspension()
+void DOMWindowExtension::disconnectFrameForPageCache()
{
// Calling out to the client might result in this DOMWindowExtension being destroyed
// while there is still work to do.
@@ -54,15 +54,15 @@ void DOMWindowExtension::disconnectFrameForDocumentSuspension()
m_disconnectedFrame = frame;
- DOMWindowProperty::disconnectFrameForDocumentSuspension();
+ DOMWindowProperty::disconnectFrameForPageCache();
}
-void DOMWindowExtension::reconnectFrameFromDocumentSuspension(Frame* frame)
+void DOMWindowExtension::reconnectFrameFromPageCache(Frame* frame)
{
ASSERT(m_disconnectedFrame == frame);
- DOMWindowProperty::reconnectFrameFromDocumentSuspension(frame);
- m_disconnectedFrame = nullptr;
+ DOMWindowProperty::reconnectFrameFromPageCache(frame);
+ m_disconnectedFrame = 0;
this->frame()->loader().client().dispatchDidReconnectDOMWindowExtensionToGlobalObject(this);
}
@@ -76,7 +76,7 @@ void DOMWindowExtension::willDestroyGlobalObjectInCachedFrame()
Ref<DOMWindowExtension> protect(*this);
m_disconnectedFrame->loader().client().dispatchWillDestroyGlobalObjectForDOMWindowExtension(this);
- m_disconnectedFrame = nullptr;
+ m_disconnectedFrame = 0;
DOMWindowProperty::willDestroyGlobalObjectInCachedFrame();
}
diff --git a/Source/WebCore/page/DOMWindowExtension.h b/Source/WebCore/page/DOMWindowExtension.h
index 36218d1d5..c184a0e6a 100644
--- a/Source/WebCore/page/DOMWindowExtension.h
+++ b/Source/WebCore/page/DOMWindowExtension.h
@@ -27,6 +27,7 @@
#define DOMWindowExtension_h
#include "DOMWindowProperty.h"
+#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
#include <wtf/RefPtr.h>
@@ -38,13 +39,13 @@ class Frame;
class DOMWindowExtension : public RefCounted<DOMWindowExtension>, public DOMWindowProperty {
public:
- static Ref<DOMWindowExtension> create(Frame* frame, DOMWrapperWorld& world)
+ static PassRefPtr<DOMWindowExtension> create(Frame* frame, DOMWrapperWorld& world)
{
- return adoptRef(*new DOMWindowExtension(frame, world));
+ return adoptRef(new DOMWindowExtension(frame, world));
}
- virtual void disconnectFrameForDocumentSuspension() override;
- virtual void reconnectFrameFromDocumentSuspension(Frame*) override;
+ virtual void disconnectFrameForPageCache() override;
+ virtual void reconnectFrameFromPageCache(Frame*) override;
virtual void willDestroyGlobalObjectInCachedFrame() override;
virtual void willDestroyGlobalObjectInFrame() override;
virtual void willDetachGlobalObjectFromFrame() override;
@@ -52,7 +53,7 @@ public:
DOMWrapperWorld& world() const { return *m_world; }
private:
- WEBCORE_EXPORT DOMWindowExtension(Frame*, DOMWrapperWorld&);
+ DOMWindowExtension(Frame*, DOMWrapperWorld&);
RefPtr<DOMWrapperWorld> m_world;
RefPtr<Frame> m_disconnectedFrame;
diff --git a/Source/WebCore/page/DOMWindowProperty.cpp b/Source/WebCore/page/DOMWindowProperty.cpp
index a3770e8e7..6f109f1ed 100644
--- a/Source/WebCore/page/DOMWindowProperty.cpp
+++ b/Source/WebCore/page/DOMWindowProperty.cpp
@@ -35,7 +35,7 @@ namespace WebCore {
DOMWindowProperty::DOMWindowProperty(Frame* frame)
: m_frame(frame)
- , m_associatedDOMWindow(nullptr)
+ , m_associatedDOMWindow(0)
{
// FIXME: For now it *is* acceptable for a DOMWindowProperty to be created with a null frame.
// See fast/dom/navigator-detached-no-crash.html for the recipe.
@@ -51,21 +51,21 @@ DOMWindowProperty::~DOMWindowProperty()
if (m_associatedDOMWindow)
m_associatedDOMWindow->unregisterProperty(this);
- m_associatedDOMWindow = nullptr;
- m_frame = nullptr;
+ m_associatedDOMWindow = 0;
+ m_frame = 0;
}
-void DOMWindowProperty::disconnectFrameForDocumentSuspension()
+void DOMWindowProperty::disconnectFrameForPageCache()
{
// If this property is being disconnected from its Frame to enter the PageCache, it must have
// been created with a Frame in the first place.
ASSERT(m_frame);
ASSERT(m_associatedDOMWindow);
- m_frame = nullptr;
+ m_frame = 0;
}
-void DOMWindowProperty::reconnectFrameFromDocumentSuspension(Frame* frame)
+void DOMWindowProperty::reconnectFrameFromPageCache(Frame* frame)
{
// If this property is being reconnected to its Frame to enter the PageCache, it must have
// been disconnected from its Frame in the first place and it should still have an associated DOMWindow.
@@ -87,8 +87,8 @@ void DOMWindowProperty::willDestroyGlobalObjectInCachedFrame()
// itself from any DOMWindow it is associated with if that DOMWindow is going away.
if (m_associatedDOMWindow)
m_associatedDOMWindow->unregisterProperty(this);
- m_associatedDOMWindow = nullptr;
- m_frame = nullptr;
+ m_associatedDOMWindow = 0;
+ m_frame = 0;
}
void DOMWindowProperty::willDestroyGlobalObjectInFrame()
@@ -101,8 +101,8 @@ void DOMWindowProperty::willDestroyGlobalObjectInFrame()
// itself from any DOMWindow it is associated with if that DOMWindow is going away.
if (m_associatedDOMWindow)
m_associatedDOMWindow->unregisterProperty(this);
- m_associatedDOMWindow = nullptr;
- m_frame = nullptr;
+ m_associatedDOMWindow = 0;
+ m_frame = 0;
}
void DOMWindowProperty::willDetachGlobalObjectFromFrame()
diff --git a/Source/WebCore/page/DOMWindowProperty.h b/Source/WebCore/page/DOMWindowProperty.h
index f6624adbe..e2dcc4437 100644
--- a/Source/WebCore/page/DOMWindowProperty.h
+++ b/Source/WebCore/page/DOMWindowProperty.h
@@ -35,8 +35,8 @@ class DOMWindowProperty {
public:
explicit DOMWindowProperty(Frame*);
- virtual void disconnectFrameForDocumentSuspension();
- virtual void reconnectFrameFromDocumentSuspension(Frame*);
+ virtual void disconnectFrameForPageCache();
+ virtual void reconnectFrameFromPageCache(Frame*);
virtual void willDestroyGlobalObjectInCachedFrame();
virtual void willDestroyGlobalObjectInFrame();
virtual void willDetachGlobalObjectFromFrame();
diff --git a/Source/WebCore/page/DatabaseProvider.cpp b/Source/WebCore/page/DatabaseProvider.cpp
deleted file mode 100644
index e37a8a872..000000000
--- a/Source/WebCore/page/DatabaseProvider.cpp
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "DatabaseProvider.h"
-
-namespace WebCore {
-
-DatabaseProvider::~DatabaseProvider()
-{
-}
-
-}
diff --git a/Source/WebCore/page/DatabaseProvider.h b/Source/WebCore/page/DatabaseProvider.h
deleted file mode 100644
index de18d73af..000000000
--- a/Source/WebCore/page/DatabaseProvider.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef DatabaseProvider_h
-#define DatabaseProvider_h
-
-#include <wtf/RefCounted.h>
-#include <wtf/RefPtr.h>
-
-namespace WebCore {
-
-class IDBConnectionManager;
-class SessionID;
-
-namespace IDBClient {
-class IDBConnectionToServer;
-}
-
-class WEBCORE_EXPORT DatabaseProvider : public RefCounted<DatabaseProvider> {
-public:
- virtual ~DatabaseProvider();
-
-#if ENABLE(INDEXED_DATABASE)
- virtual IDBClient::IDBConnectionToServer& idbConnectionToServerForSession(const SessionID&) = 0;
-#endif
-};
-
-}
-
-#endif // DatabaseProvider_h
diff --git a/Source/WebCore/page/DebugPageOverlays.cpp b/Source/WebCore/page/DebugPageOverlays.cpp
deleted file mode 100644
index b291f9696..000000000
--- a/Source/WebCore/page/DebugPageOverlays.cpp
+++ /dev/null
@@ -1,305 +0,0 @@
-/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "DebugPageOverlays.h"
-
-#include "ElementIterator.h"
-#include "FrameView.h"
-#include "GraphicsContext.h"
-#include "MainFrame.h"
-#include "Page.h"
-#include "PageOverlay.h"
-#include "PageOverlayController.h"
-#include "Region.h"
-#include "ScrollingCoordinator.h"
-#include "Settings.h"
-#include <wtf/RefPtr.h>
-
-namespace WebCore {
-
-DebugPageOverlays* DebugPageOverlays::sharedDebugOverlays;
-
-class RegionOverlay : public RefCounted<RegionOverlay>, public PageOverlay::Client {
-public:
- static PassRefPtr<RegionOverlay> create(MainFrame&, DebugPageOverlays::RegionType);
- virtual ~RegionOverlay();
-
- void recomputeRegion();
- PageOverlay& overlay() { return *m_overlay; }
-
-protected:
- RegionOverlay(MainFrame&, Color);
-
-private:
- virtual void pageOverlayDestroyed(PageOverlay&) final;
- virtual void willMoveToPage(PageOverlay&, Page*) final;
- virtual void didMoveToPage(PageOverlay&, Page*) final;
- virtual void drawRect(PageOverlay&, GraphicsContext&, const IntRect& dirtyRect) final;
- virtual bool mouseEvent(PageOverlay&, const PlatformMouseEvent&) final;
- virtual void didScrollFrame(PageOverlay&, Frame&) final;
-
-protected:
- // Returns true if the region changed.
- virtual bool updateRegion() = 0;
-
- MainFrame& m_frame;
- RefPtr<PageOverlay> m_overlay;
- std::unique_ptr<Region> m_region;
- Color m_color;
-};
-
-
-class MouseWheelRegionOverlay final : public RegionOverlay {
-public:
- static Ref<MouseWheelRegionOverlay> create(MainFrame& frame)
- {
- return adoptRef(*new MouseWheelRegionOverlay(frame));
- }
-
-private:
- explicit MouseWheelRegionOverlay(MainFrame& frame)
- : RegionOverlay(frame, Color(0.5f, 0.0f, 0.0f, 0.4f))
- {
- }
-
- virtual bool updateRegion() override;
-};
-
-bool MouseWheelRegionOverlay::updateRegion()
-{
- std::unique_ptr<Region> region = std::make_unique<Region>();
-
- for (const Frame* frame = &m_frame; frame; frame = frame->tree().traverseNext()) {
- if (!frame->view() || !frame->document())
- continue;
-
- Document::RegionFixedPair frameRegion = frame->document()->absoluteRegionForEventTargets(frame->document()->wheelEventTargets());
-
- IntPoint frameOffset = frame->view()->contentsToRootView(IntPoint());
- frameRegion.first.translate(toIntSize(frameOffset));
-
- region->unite(frameRegion.first);
- }
-
- region->translate(m_overlay->viewToOverlayOffset());
-
- bool regionChanged = !m_region || !(*m_region == *region);
- m_region = WTFMove(region);
- return regionChanged;
-}
-
-class NonFastScrollableRegionOverlay final : public RegionOverlay {
-public:
- static Ref<NonFastScrollableRegionOverlay> create(MainFrame& frame)
- {
- return adoptRef(*new NonFastScrollableRegionOverlay(frame));
- }
-
-private:
- explicit NonFastScrollableRegionOverlay(MainFrame& frame)
- : RegionOverlay(frame, Color(1.0f, 0.5f, 0.0f, 0.4f))
- {
- }
-
- virtual bool updateRegion() override;
-};
-
-bool NonFastScrollableRegionOverlay::updateRegion()
-{
- std::unique_ptr<Region> region = std::make_unique<Region>();
-
- if (Page* page = m_frame.page()) {
- if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
- *region = scrollingCoordinator->absoluteNonFastScrollableRegion();
- }
-
- bool regionChanged = !m_region || !(*m_region == *region);
- m_region = WTFMove(region);
- return regionChanged;
-}
-
-PassRefPtr<RegionOverlay> RegionOverlay::create(MainFrame& frame, DebugPageOverlays::RegionType regionType)
-{
- switch (regionType) {
- case DebugPageOverlays::RegionType::WheelEventHandlers:
- return MouseWheelRegionOverlay::create(frame);
-
- case DebugPageOverlays::RegionType::NonFastScrollableRegion:
- return NonFastScrollableRegionOverlay::create(frame);
- }
- return nullptr;
-}
-
-RegionOverlay::RegionOverlay(MainFrame& frame, Color regionColor)
- : m_frame(frame)
- , m_overlay(PageOverlay::create(*this, PageOverlay::OverlayType::Document))
- , m_color(regionColor)
-{
-}
-
-RegionOverlay::~RegionOverlay()
-{
- if (m_overlay)
- m_frame.pageOverlayController().uninstallPageOverlay(m_overlay.get(), PageOverlay::FadeMode::DoNotFade);
-}
-
-void RegionOverlay::pageOverlayDestroyed(PageOverlay&)
-{
-}
-
-void RegionOverlay::willMoveToPage(PageOverlay&, Page* page)
-{
- if (!page)
- m_overlay = nullptr;
-}
-
-void RegionOverlay::didMoveToPage(PageOverlay&, Page* page)
-{
- if (page)
- recomputeRegion();
-}
-
-void RegionOverlay::drawRect(PageOverlay&, GraphicsContext& context, const IntRect& dirtyRect)
-{
- context.clearRect(dirtyRect);
-
- if (!m_region)
- return;
-
- GraphicsContextStateSaver saver(context);
- context.setFillColor(m_color);
- for (auto rect : m_region->rects()) {
-
- if (rect.intersects(dirtyRect))
- context.fillRect(rect);
- }
-}
-
-bool RegionOverlay::mouseEvent(PageOverlay&, const PlatformMouseEvent&)
-{
- return false;
-}
-
-void RegionOverlay::didScrollFrame(PageOverlay&, Frame&)
-{
-}
-
-void RegionOverlay::recomputeRegion()
-{
- if (updateRegion())
- m_overlay->setNeedsDisplay();
-}
-
-DebugPageOverlays& DebugPageOverlays::singleton()
-{
- if (!sharedDebugOverlays)
- sharedDebugOverlays = new DebugPageOverlays;
-
- return *sharedDebugOverlays;
-}
-
-static inline size_t indexOf(DebugPageOverlays::RegionType regionType)
-{
- return static_cast<size_t>(regionType);
-}
-
-RegionOverlay& DebugPageOverlays::ensureRegionOverlayForFrame(MainFrame& frame, RegionType regionType)
-{
- auto it = m_frameRegionOverlays.find(&frame);
- if (it != m_frameRegionOverlays.end()) {
- auto& visualizers = it->value;
-
- if (!visualizers[indexOf(regionType)])
- visualizers[indexOf(regionType)] = RegionOverlay::create(frame, regionType);
-
- return *visualizers[indexOf(regionType)];
- }
-
- Vector<RefPtr<RegionOverlay>> visualizers(NumberOfRegionTypes);
-
- RefPtr<RegionOverlay> visualizer = RegionOverlay::create(frame, regionType);
- visualizers[indexOf(regionType)] = visualizer;
-
- m_frameRegionOverlays.add(&frame, WTFMove(visualizers));
- return *visualizer;
-}
-
-void DebugPageOverlays::showRegionOverlay(MainFrame& frame, RegionType regionType)
-{
- RegionOverlay& visualizer = ensureRegionOverlayForFrame(frame, regionType);
- frame.pageOverlayController().installPageOverlay(&visualizer.overlay(), PageOverlay::FadeMode::DoNotFade);
-}
-
-void DebugPageOverlays::hideRegionOverlay(MainFrame& frame, RegionType regionType)
-{
- auto it = m_frameRegionOverlays.find(&frame);
- if (it != m_frameRegionOverlays.end()) {
- auto& visualizers = it->value;
- if (RegionOverlay* visualizer = visualizers[indexOf(regionType)].get()) {
- frame.pageOverlayController().uninstallPageOverlay(&visualizer->overlay(), PageOverlay::FadeMode::DoNotFade);
- visualizers[indexOf(regionType)] = nullptr;
- }
- }
-}
-
-void DebugPageOverlays::regionChanged(Frame& frame, RegionType regionType)
-{
- if (RegionOverlay* visualizer = regionOverlayForFrame(frame.mainFrame(), regionType))
- visualizer->recomputeRegion();
-}
-
-RegionOverlay* DebugPageOverlays::regionOverlayForFrame(MainFrame& frame, RegionType regionType) const
-{
- auto it = m_frameRegionOverlays.find(&frame);
- if (it != m_frameRegionOverlays.end())
- return it->value.at(indexOf(regionType)).get();
-
- return nullptr;
-}
-
-void DebugPageOverlays::updateOverlayRegionVisibility(MainFrame& frame, DebugOverlayRegions visibleRegions)
-{
- if (visibleRegions & NonFastScrollableRegion)
- showRegionOverlay(frame, RegionType::NonFastScrollableRegion);
- else
- hideRegionOverlay(frame, RegionType::NonFastScrollableRegion);
-
- if (visibleRegions & WheelEventHandlerRegion)
- showRegionOverlay(frame, RegionType::WheelEventHandlers);
- else
- hideRegionOverlay(frame, RegionType::WheelEventHandlers);
-}
-
-void DebugPageOverlays::settingsChanged(MainFrame& frame)
-{
- DebugOverlayRegions activeOverlayRegions = frame.settings().visibleDebugOverlayRegions();
- if (!activeOverlayRegions && !hasOverlays(frame))
- return;
-
- DebugPageOverlays::singleton().updateOverlayRegionVisibility(frame, activeOverlayRegions);
-}
-
-}
diff --git a/Source/WebCore/page/DebugPageOverlays.h b/Source/WebCore/page/DebugPageOverlays.h
deleted file mode 100644
index e3df6458b..000000000
--- a/Source/WebCore/page/DebugPageOverlays.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef DebugPageOverlays_h
-#define DebugPageOverlays_h
-
-#include "Frame.h"
-#include "Settings.h"
-#include <wtf/HashMap.h>
-#include <wtf/Vector.h>
-
-namespace WebCore {
-
-class MainFrame;
-class RegionOverlay;
-
-class DebugPageOverlays {
-public:
- static DebugPageOverlays& singleton();
-
- enum class RegionType {
- WheelEventHandlers,
- NonFastScrollableRegion,
- };
- static const unsigned NumberOfRegionTypes = NonFastScrollableRegion + 1;
-
- static void didLayout(Frame&);
- static void didChangeEventHandlers(Frame&);
-
- WEBCORE_EXPORT static void settingsChanged(MainFrame&);
-
-private:
- static bool hasOverlays(MainFrame&);
-
- void showRegionOverlay(MainFrame&, RegionType);
- void hideRegionOverlay(MainFrame&, RegionType);
-
- void regionChanged(Frame&, RegionType);
-
- bool hasOverlaysForFrame(MainFrame& frame) const
- {
- return m_frameRegionOverlays.contains(&frame);
- }
-
- void updateOverlayRegionVisibility(MainFrame&, DebugOverlayRegions);
-
- RegionOverlay* regionOverlayForFrame(MainFrame&, RegionType) const;
- RegionOverlay& ensureRegionOverlayForFrame(MainFrame&, RegionType);
-
- HashMap<MainFrame*, Vector<RefPtr<RegionOverlay>>> m_frameRegionOverlays;
-
- static DebugPageOverlays* sharedDebugOverlays;
-};
-
-#define FAST_RETURN_IF_NO_OVERLAYS(frame) if (LIKELY(!hasOverlays(frame))) return;
-
-inline bool DebugPageOverlays::hasOverlays(MainFrame& frame)
-{
- if (!sharedDebugOverlays)
- return false;
-
- return sharedDebugOverlays->hasOverlaysForFrame(frame);
-}
-
-inline void DebugPageOverlays::didLayout(Frame& frame)
-{
- FAST_RETURN_IF_NO_OVERLAYS(frame.mainFrame());
-
- sharedDebugOverlays->regionChanged(frame, RegionType::WheelEventHandlers);
- sharedDebugOverlays->regionChanged(frame, RegionType::NonFastScrollableRegion);
-}
-
-inline void DebugPageOverlays::didChangeEventHandlers(Frame& frame)
-{
- FAST_RETURN_IF_NO_OVERLAYS(frame.mainFrame());
-
- sharedDebugOverlays->regionChanged(frame, RegionType::WheelEventHandlers);
- sharedDebugOverlays->regionChanged(frame, RegionType::NonFastScrollableRegion);
-}
-
-}
-
-#endif
diff --git a/Source/WebCore/page/DeviceClient.h b/Source/WebCore/page/DeviceClient.h
index 7057f27fa..d5160b717 100644
--- a/Source/WebCore/page/DeviceClient.h
+++ b/Source/WebCore/page/DeviceClient.h
@@ -30,7 +30,6 @@
namespace WebCore {
class DeviceClient {
- WTF_MAKE_FAST_ALLOCATED;
public:
virtual ~DeviceClient() { }
diff --git a/Source/WebCore/page/DeviceController.cpp b/Source/WebCore/page/DeviceController.cpp
index 3c3843095..a2baa23c0 100644
--- a/Source/WebCore/page/DeviceController.cpp
+++ b/Source/WebCore/page/DeviceController.cpp
@@ -35,7 +35,7 @@ namespace WebCore {
DeviceController::DeviceController(DeviceClient* client)
: m_client(client)
- , m_timer(*this, &DeviceController::fireDeviceEvent)
+ , m_timer(this, &DeviceController::fireDeviceEvent)
{
ASSERT(m_client);
}
@@ -71,31 +71,33 @@ void DeviceController::removeAllDeviceEventListeners(DOMWindow* window)
m_client->stopUpdating();
}
-void DeviceController::dispatchDeviceEvent(Event& event)
+void DeviceController::dispatchDeviceEvent(PassRefPtr<Event> prpEvent)
{
+ RefPtr<Event> event = prpEvent;
Vector<RefPtr<DOMWindow>> listenerVector;
copyToVector(m_listeners, listenerVector);
- for (auto& listener : listenerVector) {
- auto document = listener->document();
- if (document && !document->activeDOMObjectsAreSuspended() && !document->activeDOMObjectsAreStopped())
- listener->dispatchEvent(event);
+ for (size_t i = 0; i < listenerVector.size(); ++i) {
+ if (listenerVector[i]->document()
+ && !listenerVector[i]->document()->activeDOMObjectsAreSuspended()
+ && !listenerVector[i]->document()->activeDOMObjectsAreStopped())
+ listenerVector[i]->dispatchEvent(event);
}
}
-void DeviceController::fireDeviceEvent()
+void DeviceController::fireDeviceEvent(Timer<DeviceController>& timer)
{
+ ASSERT_UNUSED(timer, &timer == &m_timer);
ASSERT(hasLastData());
m_timer.stop();
Vector<RefPtr<DOMWindow>> listenerVector;
copyToVector(m_lastEventListeners, listenerVector);
m_lastEventListeners.clear();
- for (auto& listener : listenerVector) {
- auto document = listener->document();
- if (document && !document->activeDOMObjectsAreSuspended() && !document->activeDOMObjectsAreStopped()) {
- if (auto lastEvent = getLastEvent())
- listener->dispatchEvent(*lastEvent);
- }
+ for (size_t i = 0; i < listenerVector.size(); ++i) {
+ if (listenerVector[i]->document()
+ && !listenerVector[i]->document()->activeDOMObjectsAreSuspended()
+ && !listenerVector[i]->document()->activeDOMObjectsAreStopped())
+ listenerVector[i]->dispatchEvent(getLastEvent());
}
}
diff --git a/Source/WebCore/page/DeviceController.h b/Source/WebCore/page/DeviceController.h
index 21861f24e..6a5c242de 100644
--- a/Source/WebCore/page/DeviceController.h
+++ b/Source/WebCore/page/DeviceController.h
@@ -39,29 +39,28 @@ class DeviceClient;
class Page;
class DeviceController : public Supplement<Page> {
- WTF_MAKE_FAST_ALLOCATED;
public:
explicit DeviceController(DeviceClient*);
- virtual ~DeviceController() { }
+ ~DeviceController() { }
void addDeviceEventListener(DOMWindow*);
void removeDeviceEventListener(DOMWindow*);
void removeAllDeviceEventListeners(DOMWindow*);
- void dispatchDeviceEvent(Event&);
+ void dispatchDeviceEvent(PassRefPtr<Event>);
bool isActive() { return !m_listeners.isEmpty(); }
DeviceClient* client() { return m_client; }
virtual bool hasLastData() { return false; }
- virtual RefPtr<Event> getLastEvent() { return nullptr; }
+ virtual PassRefPtr<Event> getLastEvent() { return 0; }
protected:
- void fireDeviceEvent();
+ void fireDeviceEvent(Timer<DeviceController>&);
HashCountedSet<RefPtr<DOMWindow>> m_listeners;
HashCountedSet<RefPtr<DOMWindow>> m_lastEventListeners;
DeviceClient* m_client;
- Timer m_timer;
+ Timer<DeviceController> m_timer;
};
} // namespace WebCore
diff --git a/Source/WebCore/page/DiagnosticLoggingClient.h b/Source/WebCore/page/DiagnosticLoggingClient.h
deleted file mode 100644
index 503792352..000000000
--- a/Source/WebCore/page/DiagnosticLoggingClient.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef DiagnosticLoggingClient_h
-#define DiagnosticLoggingClient_h
-
-#include "DiagnosticLoggingResultType.h"
-#include <wtf/Forward.h>
-#include <wtf/RandomNumber.h>
-
-namespace WebCore {
-
-enum class ShouldSample { No, Yes };
-
-class DiagnosticLoggingClient {
-public:
- virtual void logDiagnosticMessage(const String& message, const String& description, ShouldSample) = 0;
- virtual void logDiagnosticMessageWithResult(const String& message, const String& description, DiagnosticLoggingResultType, ShouldSample) = 0;
- virtual void logDiagnosticMessageWithValue(const String& message, const String& description, const String& value, ShouldSample) = 0;
-
- virtual void mainFrameDestroyed() = 0;
-
- static bool shouldLogAfterSampling(ShouldSample);
-
-protected:
- virtual ~DiagnosticLoggingClient() { }
-};
-
-inline bool DiagnosticLoggingClient::shouldLogAfterSampling(ShouldSample shouldSample)
-{
- if (shouldSample == ShouldSample::No)
- return true;
-
- static const double selectionProbability = 0.05;
- return randomNumber() <= selectionProbability;
-}
-
-}
-
-#endif
diff --git a/Source/WebCore/page/DiagnosticLoggingKeys.cpp b/Source/WebCore/page/DiagnosticLoggingKeys.cpp
index 1112c4cc8..a4354a647 100644
--- a/Source/WebCore/page/DiagnosticLoggingKeys.cpp
+++ b/Source/WebCore/page/DiagnosticLoggingKeys.cpp
@@ -38,11 +38,6 @@ String DiagnosticLoggingKeys::mediaLoadingFailedKey()
return ASCIILiteral("mediaFailedLoading");
}
-String DiagnosticLoggingKeys::missingValidatorFieldsKey()
-{
- return ASCIILiteral("missingValidatorFields");
-}
-
String DiagnosticLoggingKeys::pluginLoadedKey()
{
return ASCIILiteral("pluginLoaded");
@@ -53,11 +48,6 @@ String DiagnosticLoggingKeys::pluginLoadingFailedKey()
return ASCIILiteral("pluginFailedLoading");
}
-String DiagnosticLoggingKeys::provisionalLoadKey()
-{
- return ASCIILiteral("provisionalLoad");
-}
-
String DiagnosticLoggingKeys::pageContainsPluginKey()
{
return ASCIILiteral("pageContainsPlugin");
@@ -78,520 +68,19 @@ String DiagnosticLoggingKeys::pageContainsAtLeastOneMediaEngineKey()
return ASCIILiteral("pageContainsAtLeastOneMediaEngine");
}
-String DiagnosticLoggingKeys::successKey()
-{
- return ASCIILiteral("success");
-}
-
-String DiagnosticLoggingKeys::failureKey()
-{
- return ASCIILiteral("failure");
-}
-
-String DiagnosticLoggingKeys::pageLoadedKey()
-{
- return ASCIILiteral("pageLoaded");
-}
-
-String DiagnosticLoggingKeys::playedKey()
-{
- return ASCIILiteral("played");
-}
-
-String DiagnosticLoggingKeys::engineFailedToLoadKey()
-{
- return ASCIILiteral("engineFailedToLoad");
-}
-
-String DiagnosticLoggingKeys::entryRightlyNotWarmedUpKey()
-{
- return ASCIILiteral("entryRightlyNotWarmedUp");
-}
-
-String DiagnosticLoggingKeys::entryWronglyNotWarmedUpKey()
-{
- return ASCIILiteral("entryWronglyNotWarmedUp");
-}
-
-String DiagnosticLoggingKeys::navigationKey()
-{
- return ASCIILiteral("navigation");
-}
-
-String DiagnosticLoggingKeys::needsRevalidationKey()
-{
- return ASCIILiteral("needsRevalidation");
-}
-
-String DiagnosticLoggingKeys::networkCacheKey()
-{
- return ASCIILiteral("networkCache");
-}
-
-String DiagnosticLoggingKeys::networkKey()
-{
- return ASCIILiteral("network");
-}
-
-String DiagnosticLoggingKeys::neverSeenBeforeKey()
-{
- return ASCIILiteral("neverSeenBefore");
-}
-
-String DiagnosticLoggingKeys::noCacheKey()
-{
- return ASCIILiteral("noCache");
-}
-
-String DiagnosticLoggingKeys::noStoreKey()
-{
- return ASCIILiteral("noStore");
-}
-
-String DiagnosticLoggingKeys::notInMemoryCacheKey()
-{
- return ASCIILiteral("notInMemoryCache");
-}
-
-String DiagnosticLoggingKeys::pageCacheKey()
-{
- return ASCIILiteral("pageCache");
-}
-
-String DiagnosticLoggingKeys::noDocumentLoaderKey()
-{
- return ASCIILiteral("noDocumentLoader");
-}
-
-String DiagnosticLoggingKeys::noLongerInCacheKey()
-{
- return ASCIILiteral("noLongerInCache");
-}
-
-String DiagnosticLoggingKeys::otherKey()
-{
- return ASCIILiteral("other");
-}
-
-String DiagnosticLoggingKeys::mainDocumentErrorKey()
-{
- return ASCIILiteral("mainDocumentError");
-}
-
-String DiagnosticLoggingKeys::mainResourceKey()
-{
- return ASCIILiteral("mainResource");
-}
-
-String DiagnosticLoggingKeys::mediaKey()
-{
- return ASCIILiteral("media");
-}
-
-String DiagnosticLoggingKeys::isErrorPageKey()
-{
- return ASCIILiteral("isErrorPage");
-}
-
-String DiagnosticLoggingKeys::isExpiredKey()
-{
- return ASCIILiteral("isExpired");
-}
-
-String DiagnosticLoggingKeys::isReloadIgnoringCacheDataKey()
-{
- return ASCIILiteral("isReloadIgnoringCacheData");
-}
-
-String DiagnosticLoggingKeys::loadedKey()
-{
- return ASCIILiteral("loaded");
-}
-
-String DiagnosticLoggingKeys::loadingKey()
-{
- return ASCIILiteral("loading");
-}
-
-String DiagnosticLoggingKeys::hasPluginsKey()
-{
- return ASCIILiteral("hasPlugins");
-}
-
-String DiagnosticLoggingKeys::httpsNoStoreKey()
-{
- return ASCIILiteral("httpsNoStore");
-}
-
-String DiagnosticLoggingKeys::imageKey()
-{
- return ASCIILiteral("image");
-}
-
-String DiagnosticLoggingKeys::inMemoryCacheKey()
-{
- return ASCIILiteral("inMemoryCache");
-}
-
-String DiagnosticLoggingKeys::isAttachmentKey()
-{
- return ASCIILiteral("isAttachment");
-}
-
-String DiagnosticLoggingKeys::isConditionalRequestKey()
-{
- return ASCIILiteral("isConditionalRequest");
-}
-
-String DiagnosticLoggingKeys::isDisabledKey()
-{
- return ASCIILiteral("isDisabled");
-}
-
-String DiagnosticLoggingKeys::noCurrentHistoryItemKey()
-{
- return ASCIILiteral("noCurrentHistoryItem");
-}
-
-String DiagnosticLoggingKeys::quirkRedirectComingKey()
-{
- return ASCIILiteral("quirkRedirectComing");
-}
-
-String DiagnosticLoggingKeys::rawKey()
-{
- return ASCIILiteral("raw");
-}
-
-String DiagnosticLoggingKeys::reasonKey()
-{
- return ASCIILiteral("reason");
-}
-
-String DiagnosticLoggingKeys::redirectKey()
-{
- return ASCIILiteral("redirect");
-}
-
-String DiagnosticLoggingKeys::isLoadingKey()
-{
- return ASCIILiteral("isLoading");
-}
-
-String DiagnosticLoggingKeys::documentLoaderStoppingKey()
-{
- return ASCIILiteral("documentLoaderStopping");
-}
-
-String DiagnosticLoggingKeys::cannotSuspendActiveDOMObjectsKey()
-{
- return ASCIILiteral("cannotSuspendActiveDOMObjects");
-}
-
-String DiagnosticLoggingKeys::deltaKey()
-{
- return ASCIILiteral("delta");
-}
-
-String DiagnosticLoggingKeys::applicationCacheKey()
-{
- return ASCIILiteral("applicationCache");
-}
-
-String DiagnosticLoggingKeys::audioKey()
-{
- return ASCIILiteral("audio");
-}
-
-String DiagnosticLoggingKeys::backNavigationKey()
-{
- return ASCIILiteral("backNavigation");
-}
-
-String DiagnosticLoggingKeys::canCacheKey()
-{
- return ASCIILiteral("canCache");
-}
-
-String DiagnosticLoggingKeys::cacheControlNoStoreKey()
-{
- return ASCIILiteral("cacheControlNoStore");
-}
-
-String DiagnosticLoggingKeys::cachedResourceRevalidationKey()
-{
- return ASCIILiteral("cachedResourceRevalidation");
-}
-
-String DiagnosticLoggingKeys::deniedByClientKey()
+String DiagnosticLoggingKeys::passKey()
{
- return ASCIILiteral("deniedByClient");
+ return ASCIILiteral("pass");
}
-String DiagnosticLoggingKeys::deviceMotionKey()
+String DiagnosticLoggingKeys::failKey()
{
- return ASCIILiteral("deviceMotion");
+ return ASCIILiteral("fail");
}
-String DiagnosticLoggingKeys::deviceOrientationKey()
+String DiagnosticLoggingKeys::noopKey()
{
- return ASCIILiteral("deviceOrientation");
+ return ASCIILiteral("noop");
}
-String DiagnosticLoggingKeys::deviceProximityKey()
-{
- return ASCIILiteral("deviceProximity");
-}
-
-String DiagnosticLoggingKeys::diskCacheKey()
-{
- return ASCIILiteral("diskCache");
-}
-
-String DiagnosticLoggingKeys::diskCacheAfterValidationKey()
-{
- return ASCIILiteral("diskCacheAfterValidation");
-}
-
-String DiagnosticLoggingKeys::reloadKey()
-{
- return ASCIILiteral("reload");
}
-
-String DiagnosticLoggingKeys::replaceKey()
-{
- return ASCIILiteral("replace");
-}
-
-String DiagnosticLoggingKeys::requestKey()
-{
- return ASCIILiteral("request");
-}
-
-String DiagnosticLoggingKeys::retrievalRequestKey()
-{
- return ASCIILiteral("retrievalRequest");
-}
-
-String DiagnosticLoggingKeys::resourceKey()
-{
- return ASCIILiteral("resource");
-}
-
-String DiagnosticLoggingKeys::resourceRequestKey()
-{
- return ASCIILiteral("resourceRequest");
-}
-
-String DiagnosticLoggingKeys::resourceResponseKey()
-{
- return ASCIILiteral("resourceResponse");
-}
-
-String DiagnosticLoggingKeys::retrievalKey()
-{
- return ASCIILiteral("retrieval");
-}
-
-String DiagnosticLoggingKeys::revalidatingKey()
-{
- return ASCIILiteral("revalidating");
-}
-
-String DiagnosticLoggingKeys::reloadFromOriginKey()
-{
- return ASCIILiteral("reloadFromOrigin");
-}
-
-String DiagnosticLoggingKeys::sameLoadKey()
-{
- return ASCIILiteral("sameLoad");
-}
-
-String DiagnosticLoggingKeys::scriptKey()
-{
- return ASCIILiteral("script");
-}
-
-String DiagnosticLoggingKeys::sourceKey()
-{
- return ASCIILiteral("source");
-}
-
-String DiagnosticLoggingKeys::streamingMedia()
-{
- return ASCIILiteral("streamingMedia");
-}
-
-String DiagnosticLoggingKeys::styleSheetKey()
-{
- return ASCIILiteral("styleSheet");
-}
-
-String DiagnosticLoggingKeys::successfulSpeculativeWarmupWithRevalidationKey()
-{
- return ASCIILiteral("successfulSpeculativeWarmupWithRevalidation");
-}
-
-String DiagnosticLoggingKeys::successfulSpeculativeWarmupWithoutRevalidationKey()
-{
- return ASCIILiteral("successfulSpeculativeWarmupWithoutRevalidation");
-}
-
-String DiagnosticLoggingKeys::svgDocumentKey()
-{
- return ASCIILiteral("svgDocument");
-}
-
-String DiagnosticLoggingKeys::uncacheableStatusCodeKey()
-{
- return ASCIILiteral("uncacheableStatusCode");
-}
-
-String DiagnosticLoggingKeys::underMemoryPressureKey()
-{
- return ASCIILiteral("underMemoryPressure");
-}
-
-String DiagnosticLoggingKeys::unknownEntryRequestKey()
-{
- return ASCIILiteral("unknownEntryRequest");
-}
-
-String DiagnosticLoggingKeys::unlikelyToReuseKey()
-{
- return ASCIILiteral("unlikelyToReuse");
-}
-
-String DiagnosticLoggingKeys::unsupportedHTTPMethodKey()
-{
- return ASCIILiteral("unsupportedHTTPMethod");
-}
-
-String DiagnosticLoggingKeys::unsuspendableDOMObjectKey()
-{
- return ASCIILiteral("unsuspendableDOMObject");
-}
-
-String DiagnosticLoggingKeys::unusableCachedEntryKey()
-{
- return ASCIILiteral("unusableCachedEntry");
-}
-
-String DiagnosticLoggingKeys::unusedKey()
-{
- return ASCIILiteral("unused");
-}
-
-String DiagnosticLoggingKeys::unusedReasonCredentialSettingsKey()
-{
- return ASCIILiteral("unused.reason.credentialSettings");
-}
-
-String DiagnosticLoggingKeys::unusedReasonErrorKey()
-{
- return ASCIILiteral("unused.reason.error");
-}
-
-String DiagnosticLoggingKeys::unusedReasonMustRevalidateNoValidatorKey()
-{
- return ASCIILiteral("unused.reason.mustRevalidateNoValidator");
-}
-
-String DiagnosticLoggingKeys::unusedReasonNoStoreKey()
-{
- return ASCIILiteral("unused.reason.noStore");
-}
-
-String DiagnosticLoggingKeys::unusedReasonRedirectChainKey()
-{
- return ASCIILiteral("unused.reason.redirectChain");
-}
-
-String DiagnosticLoggingKeys::unusedReasonReloadKey()
-{
- return ASCIILiteral("unused.reason.reload");
-}
-
-String DiagnosticLoggingKeys::unusedReasonTypeMismatchKey()
-{
- return ASCIILiteral("unused.reason.typeMismatch");
-}
-
-String DiagnosticLoggingKeys::usedKey()
-{
- return ASCIILiteral("used");
-}
-
-String DiagnosticLoggingKeys::userKey()
-{
- return ASCIILiteral("user");
-}
-
-String DiagnosticLoggingKeys::varyingHeaderMismatchKey()
-{
- return ASCIILiteral("varyingHeaderMismatch");
-}
-
-String DiagnosticLoggingKeys::videoKey()
-{
- return ASCIILiteral("video");
-}
-
-String DiagnosticLoggingKeys::wastedSpeculativeWarmupWithRevalidationKey()
-{
- return ASCIILiteral("wastedSpeculativeWarmupWithRevalidation");
-}
-
-String DiagnosticLoggingKeys::wastedSpeculativeWarmupWithoutRevalidationKey()
-{
- return ASCIILiteral("wastedSpeculativeWarmupWithoutRevalidation");
-}
-
-String DiagnosticLoggingKeys::webViewKey()
-{
- return ASCIILiteral("webView");
-}
-
-String DiagnosticLoggingKeys::zoomedKey()
-{
- return ASCIILiteral("zoomed");
-}
-
-String DiagnosticLoggingKeys::expiredKey()
-{
- return ASCIILiteral("expired");
-}
-
-String DiagnosticLoggingKeys::fontKey()
-{
- return ASCIILiteral("font");
-}
-
-String DiagnosticLoggingKeys::prunedDueToMemoryPressureKey()
-{
- return ASCIILiteral("pruned.memoryPressure");
-}
-
-String DiagnosticLoggingKeys::prunedDueToMaxSizeReached()
-{
- return ASCIILiteral("pruned.capacityReached");
-}
-
-String DiagnosticLoggingKeys::prunedDueToProcessSuspended()
-{
- return ASCIILiteral("pruned.processSuspended");
-}
-
-String WebCore::DiagnosticLoggingKeys::notHTTPFamilyKey()
-{
- return ASCIILiteral("notHTTPFamily");
-}
-
-String DiagnosticLoggingKeys::notInCacheKey()
-{
- return ASCIILiteral("notInCache");
-}
-
-} // namespace WebCore
-
diff --git a/Source/WebCore/page/DiagnosticLoggingKeys.h b/Source/WebCore/page/DiagnosticLoggingKeys.h
index 1daa9744e..baa51563e 100644
--- a/Source/WebCore/page/DiagnosticLoggingKeys.h
+++ b/Source/WebCore/page/DiagnosticLoggingKeys.h
@@ -32,121 +32,20 @@ namespace WebCore {
class DiagnosticLoggingKeys {
public:
- static String applicationCacheKey();
- static String audioKey();
- WEBCORE_EXPORT static String backNavigationKey();
- WEBCORE_EXPORT static String cacheControlNoStoreKey();
- static String cachedResourceRevalidationKey();
- static String canCacheKey();
- static String cannotSuspendActiveDOMObjectsKey();
- WEBCORE_EXPORT static String deltaKey();
- static String deniedByClientKey();
- static String deviceMotionKey();
- static String deviceOrientationKey();
- static String deviceProximityKey();
- static String diskCacheKey();
- static String diskCacheAfterValidationKey();
- static String documentLoaderStoppingKey();
- static String engineFailedToLoadKey();
- WEBCORE_EXPORT static String entryRightlyNotWarmedUpKey();
- WEBCORE_EXPORT static String entryWronglyNotWarmedUpKey();
- static String expiredKey();
- static String fontKey();
- static String hasPluginsKey();
- static String httpsNoStoreKey();
- static String imageKey();
- static String inMemoryCacheKey();
- WEBCORE_EXPORT static String isAttachmentKey();
- WEBCORE_EXPORT static String isConditionalRequestKey();
- static String isDisabledKey();
- static String isErrorPageKey();
- static String isExpiredKey();
- WEBCORE_EXPORT static String isReloadIgnoringCacheDataKey();
- static String loadedKey();
- static String loadingKey();
- static String isLoadingKey();
- static String mainDocumentErrorKey();
- static String mainResourceKey();
- static String mediaKey();
+ // Message keys.
static String mediaLoadedKey();
static String mediaLoadingFailedKey();
- WEBCORE_EXPORT static String missingValidatorFieldsKey();
- static String navigationKey();
- WEBCORE_EXPORT static String needsRevalidationKey();
- WEBCORE_EXPORT static String networkCacheKey();
- static String networkKey();
- WEBCORE_EXPORT static String neverSeenBeforeKey();
- static String noCacheKey();
- static String noCurrentHistoryItemKey();
- static String noDocumentLoaderKey();
- WEBCORE_EXPORT static String noLongerInCacheKey();
- static String noStoreKey();
- WEBCORE_EXPORT static String notHTTPFamilyKey();
- WEBCORE_EXPORT static String notInCacheKey();
- static String notInMemoryCacheKey();
- WEBCORE_EXPORT static String otherKey();
- static String pageCacheKey();
- static String pageContainsAtLeastOneMediaEngineKey();
- static String pageContainsAtLeastOnePluginKey();
- static String pageContainsMediaEngineKey();
- static String pageContainsPluginKey();
- static String pageLoadedKey();
- static String playedKey();
static String pluginLoadedKey();
static String pluginLoadingFailedKey();
- static String provisionalLoadKey();
- static String prunedDueToMaxSizeReached();
- static String prunedDueToMemoryPressureKey();
- static String prunedDueToProcessSuspended();
- static String quirkRedirectComingKey();
- static String rawKey();
- static String reasonKey();
- static String redirectKey();
- static String reloadFromOriginKey();
- static String reloadKey();
- static String replaceKey();
- WEBCORE_EXPORT static String requestKey();
- static String resourceKey();
- static String resourceRequestKey();
- static String resourceResponseKey();
- WEBCORE_EXPORT static String retrievalKey();
- WEBCORE_EXPORT static String retrievalRequestKey();
- WEBCORE_EXPORT static String revalidatingKey();
- static String sameLoadKey();
- static String scriptKey();
- static String sourceKey();
- WEBCORE_EXPORT static String streamingMedia();
- static String styleSheetKey();
- WEBCORE_EXPORT static String successfulSpeculativeWarmupWithRevalidationKey();
- WEBCORE_EXPORT static String successfulSpeculativeWarmupWithoutRevalidationKey();
- static String svgDocumentKey();
- WEBCORE_EXPORT static String uncacheableStatusCodeKey();
- static String underMemoryPressureKey();
- WEBCORE_EXPORT static String unknownEntryRequestKey();
- WEBCORE_EXPORT static String unlikelyToReuseKey();
- WEBCORE_EXPORT static String unsupportedHTTPMethodKey();
- static String unsuspendableDOMObjectKey();
- WEBCORE_EXPORT static String unusableCachedEntryKey();
- WEBCORE_EXPORT static String unusedKey();
- static String unusedReasonCredentialSettingsKey();
- static String unusedReasonErrorKey();
- static String unusedReasonMustRevalidateNoValidatorKey();
- static String unusedReasonNoStoreKey();
- static String unusedReasonRedirectChainKey();
- static String unusedReasonReloadKey();
- static String unusedReasonTypeMismatchKey();
- static String usedKey();
- WEBCORE_EXPORT static String userKey();
- WEBCORE_EXPORT static String varyingHeaderMismatchKey();
- static String videoKey();
- WEBCORE_EXPORT static String wastedSpeculativeWarmupWithRevalidationKey();
- WEBCORE_EXPORT static String wastedSpeculativeWarmupWithoutRevalidationKey();
- WEBCORE_EXPORT static String webViewKey();
- WEBCORE_EXPORT static String zoomedKey();
+ static String pageContainsPluginKey();
+ static String pageContainsAtLeastOnePluginKey();
+ static String pageContainsMediaEngineKey();
+ static String pageContainsAtLeastOneMediaEngineKey();
- // Success / Failure keys.
- static String successKey();
- static String failureKey();
+ // Success keys.
+ static String passKey();
+ static String failKey();
+ static String noopKey();
};
}
diff --git a/Source/WebCore/page/DragActions.h b/Source/WebCore/page/DragActions.h
index 1be760d04..de8114723 100644
--- a/Source/WebCore/page/DragActions.h
+++ b/Source/WebCore/page/DragActions.h
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -46,9 +46,6 @@ namespace WebCore {
DragSourceActionImage = 2,
DragSourceActionLink = 4,
DragSourceActionSelection = 8,
-#if ENABLE(ATTACHMENT_ELEMENT)
- DragSourceActionAttachment = 16,
-#endif
DragSourceActionAny = UINT_MAX
} DragSourceAction;
diff --git a/Source/WebCore/page/DragClient.h b/Source/WebCore/page/DragClient.h
index d4d4050c5..343490c90 100644
--- a/Source/WebCore/page/DragClient.h
+++ b/Source/WebCore/page/DragClient.h
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -33,7 +33,7 @@
namespace WebCore {
-class DataTransfer;
+class Clipboard;
class DragData;
class Element;
class Frame;
@@ -44,20 +44,17 @@ public:
virtual void dragControllerDestroyed() = 0;
virtual void willPerformDragDestinationAction(DragDestinationAction, DragData&) = 0;
- virtual void willPerformDragSourceAction(DragSourceAction, const IntPoint&, DataTransfer&) = 0;
+ virtual void willPerformDragSourceAction(DragSourceAction, const IntPoint&, Clipboard&) = 0;
virtual DragDestinationAction actionMaskForDrag(DragData&) = 0;
virtual DragSourceAction dragSourceActionMaskForPoint(const IntPoint& rootViewPoint) = 0;
- virtual void startDrag(DragImageRef, const IntPoint& dragImageOrigin, const IntPoint& eventPos, DataTransfer&, Frame&, bool linkDrag = false) = 0;
+ virtual void startDrag(DragImageRef, const IntPoint& dragImageOrigin, const IntPoint& eventPos, Clipboard&, Frame&, bool linkDrag = false) = 0;
virtual void dragEnded() { }
-#if PLATFORM(COCOA)
+#if PLATFORM(MAC)
// Mac-specific helper function to allow access to web archives and NSPasteboard extras in WebKit.
- // This is not abstract as that would require another #if PLATFORM(COCOA) for the SVGImage client empty implentation.
+ // This is not abstract as that would require another #if PLATFORM(MAC) for the SVGImage client empty implentation.
virtual void declareAndWriteDragImage(const String&, Element&, const URL&, const String&, Frame*) { }
-#if ENABLE(ATTACHMENT_ELEMENT)
- virtual void declareAndWriteAttachment(const String&, Element&, const URL&, const String&, Frame*) { }
-#endif
#endif
virtual ~DragClient() { }
diff --git a/Source/WebCore/page/DragController.cpp b/Source/WebCore/page/DragController.cpp
index 1cc8384a4..3d9f4a6aa 100644
--- a/Source/WebCore/page/DragController.cpp
+++ b/Source/WebCore/page/DragController.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007, 2009, 2010, 2013, 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 2009, 2010, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -26,22 +26,23 @@
#include "config.h"
#include "DragController.h"
-#include "HTMLAnchorElement.h"
-#include "SVGAElement.h"
-
#if ENABLE(DRAG_SUPPORT)
+
#include "CachedImage.h"
+#include "Clipboard.h"
+#include "ClipboardAccessPolicy.h"
#include "CachedResourceLoader.h"
-#include "DataTransfer.h"
#include "Document.h"
#include "DocumentFragment.h"
#include "DragActions.h"
#include "DragClient.h"
#include "DragData.h"
#include "DragImage.h"
+#include "DragSession.h"
#include "DragState.h"
#include "Editor.h"
#include "EditorClient.h"
+#include "Element.h"
#include "EventHandler.h"
#include "ExceptionCodePlaceholder.h"
#include "FloatRect.h"
@@ -49,7 +50,7 @@
#include "FrameLoader.h"
#include "FrameSelection.h"
#include "FrameView.h"
-#include "HTMLAttachmentElement.h"
+#include "HTMLAnchorElement.h"
#include "HTMLImageElement.h"
#include "HTMLInputElement.h"
#include "HTMLNames.h"
@@ -80,38 +81,30 @@
#include "markup.h"
#include <wtf/CurrentTime.h>
#include <wtf/RefPtr.h>
-#endif
namespace WebCore {
-bool isDraggableLink(const Element& element)
-{
- if (is<HTMLAnchorElement>(element))
- return downcast<HTMLAnchorElement>(element).isLiveLink();
- if (is<SVGAElement>(element))
- return element.isLink();
- return false;
-}
-
-#if ENABLE(DRAG_SUPPORT)
-
static PlatformMouseEvent createMouseEvent(DragData& dragData)
{
+ bool shiftKey, ctrlKey, altKey, metaKey;
+ shiftKey = ctrlKey = altKey = metaKey = false;
int keyState = dragData.modifierKeyState();
- bool shiftKey = static_cast<bool>(keyState & PlatformEvent::ShiftKey);
- bool ctrlKey = static_cast<bool>(keyState & PlatformEvent::CtrlKey);
- bool altKey = static_cast<bool>(keyState & PlatformEvent::AltKey);
- bool metaKey = static_cast<bool>(keyState & PlatformEvent::MetaKey);
+ shiftKey = static_cast<bool>(keyState & PlatformEvent::ShiftKey);
+ ctrlKey = static_cast<bool>(keyState & PlatformEvent::CtrlKey);
+ altKey = static_cast<bool>(keyState & PlatformEvent::AltKey);
+ metaKey = static_cast<bool>(keyState & PlatformEvent::MetaKey);
return PlatformMouseEvent(dragData.clientPosition(), dragData.globalPosition(),
LeftButton, PlatformEvent::MouseMoved, 0, shiftKey, ctrlKey, altKey,
- metaKey, currentTime(), ForceAtClick);
+ metaKey, currentTime());
}
DragController::DragController(Page& page, DragClient& client)
: m_page(page)
, m_client(client)
- , m_numberOfItemsToBeAccepted(0)
+ , m_documentUnderMouse(0)
+ , m_dragInitiator(0)
+ , m_fileInputElementUnderMouse(0)
, m_documentIsHandlingDrag(false)
, m_dragDestinationAction(DragDestinationActionNone)
, m_dragSourceAction(DragSourceActionNone)
@@ -125,64 +118,65 @@ DragController::~DragController()
m_client.dragControllerDestroyed();
}
-static PassRefPtr<DocumentFragment> documentFragmentFromDragData(DragData& dragData, Frame& frame, Range& context, bool allowPlainText, bool& chosePlainText)
+static PassRefPtr<DocumentFragment> documentFragmentFromDragData(DragData& dragData, Frame* frame, Range& context, bool allowPlainText, bool& chosePlainText)
{
chosePlainText = false;
Document& document = context.ownerDocument();
if (dragData.containsCompatibleContent()) {
- if (PassRefPtr<DocumentFragment> fragment = frame.editor().webContentFromPasteboard(*Pasteboard::createForDragAndDrop(dragData), context, allowPlainText, chosePlainText))
+ if (PassRefPtr<DocumentFragment> fragment = dragData.asFragment(frame, context, allowPlainText, chosePlainText))
return fragment;
- if (dragData.containsURL(DragData::DoNotConvertFilenames)) {
+ if (dragData.containsURL(frame, DragData::DoNotConvertFilenames)) {
String title;
- String url = dragData.asURL(DragData::DoNotConvertFilenames, &title);
+ String url = dragData.asURL(frame, DragData::DoNotConvertFilenames, &title);
if (!url.isEmpty()) {
- Ref<HTMLAnchorElement> anchor = HTMLAnchorElement::create(document);
+ RefPtr<HTMLAnchorElement> anchor = HTMLAnchorElement::create(document);
anchor->setHref(url);
if (title.isEmpty()) {
// Try the plain text first because the url might be normalized or escaped.
if (dragData.containsPlainText())
- title = dragData.asPlainText();
+ title = dragData.asPlainText(frame);
if (title.isEmpty())
title = url;
}
- anchor->appendChild(document.createTextNode(title), IGNORE_EXCEPTION);
- Ref<DocumentFragment> fragment = document.createDocumentFragment();
- fragment->appendChild(WTFMove(anchor), IGNORE_EXCEPTION);
- return fragment.ptr();
+ RefPtr<Node> anchorText = document.createTextNode(title);
+ anchor->appendChild(anchorText, IGNORE_EXCEPTION);
+ RefPtr<DocumentFragment> fragment = document.createDocumentFragment();
+ fragment->appendChild(anchor, IGNORE_EXCEPTION);
+ return fragment.get();
}
}
}
if (allowPlainText && dragData.containsPlainText()) {
chosePlainText = true;
- return createFragmentFromText(context, dragData.asPlainText()).ptr();
+ return createFragmentFromText(context, dragData.asPlainText(frame)).get();
}
- return nullptr;
+ return 0;
}
bool DragController::dragIsMove(FrameSelection& selection, DragData& dragData)
{
- const VisibleSelection& visibleSelection = selection.selection();
- return m_documentUnderMouse == m_dragInitiator && visibleSelection.isContentEditable() && visibleSelection.isRange() && !isCopyKeyDown(dragData);
+ return m_documentUnderMouse == m_dragInitiator && selection.isContentEditable() && selection.isRange() && !isCopyKeyDown(dragData);
}
-void DragController::clearDragCaret()
+// FIXME: This method is poorly named. We're just clearing the selection from the document this drag is exiting.
+void DragController::cancelDrag()
{
m_page.dragCaretController().clear();
}
void DragController::dragEnded()
{
- m_dragInitiator = nullptr;
+ m_dragInitiator = 0;
m_didInitiateDrag = false;
- clearDragCaret();
+ m_page.dragCaretController().clear();
m_client.dragEnded();
}
-DragOperation DragController::dragEntered(DragData& dragData)
+DragSession DragController::dragEntered(DragData& dragData)
{
return dragEnteredOrUpdated(dragData);
}
@@ -190,66 +184,55 @@ DragOperation DragController::dragEntered(DragData& dragData)
void DragController::dragExited(DragData& dragData)
{
if (RefPtr<FrameView> v = m_page.mainFrame().view()) {
-#if ENABLE(DASHBOARD_SUPPORT)
- DataTransferAccessPolicy policy = (m_page.mainFrame().settings().usesDashboardBackwardCompatibilityMode() && (!m_documentUnderMouse || m_documentUnderMouse->securityOrigin()->isLocal()))
- ? DataTransferAccessPolicy::Readable : DataTransferAccessPolicy::TypesReadable;
-#else
- DataTransferAccessPolicy policy = DataTransferAccessPolicy::TypesReadable;
-#endif
- RefPtr<DataTransfer> dataTransfer = DataTransfer::createForDragAndDrop(policy, dragData);
- dataTransfer->setSourceOperation(dragData.draggingSourceOperationMask());
- m_page.mainFrame().eventHandler().cancelDragAndDrop(createMouseEvent(dragData), dataTransfer.get());
- dataTransfer->setAccessPolicy(DataTransferAccessPolicy::Numb); // Invalidate dataTransfer here for security.
+ ClipboardAccessPolicy policy = (!m_documentUnderMouse || m_documentUnderMouse->securityOrigin()->isLocal()) ? ClipboardReadable : ClipboardTypesReadable;
+ RefPtr<Clipboard> clipboard = Clipboard::createForDragAndDrop(policy, dragData);
+ clipboard->setSourceOperation(dragData.draggingSourceOperationMask());
+ m_page.mainFrame().eventHandler().cancelDragAndDrop(createMouseEvent(dragData), clipboard.get());
+ clipboard->setAccessPolicy(ClipboardNumb); // invalidate clipboard here for security
}
- mouseMovedIntoDocument(nullptr);
+ mouseMovedIntoDocument(0);
if (m_fileInputElementUnderMouse)
m_fileInputElementUnderMouse->setCanReceiveDroppedFiles(false);
- m_fileInputElementUnderMouse = nullptr;
+ m_fileInputElementUnderMouse = 0;
}
-DragOperation DragController::dragUpdated(DragData& dragData)
+DragSession DragController::dragUpdated(DragData& dragData)
{
return dragEnteredOrUpdated(dragData);
}
-bool DragController::performDragOperation(DragData& dragData)
+bool DragController::performDrag(DragData& dragData)
{
m_documentUnderMouse = m_page.mainFrame().documentAtPoint(dragData.clientPosition());
-
- ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy = ShouldOpenExternalURLsPolicy::ShouldNotAllow;
- if (m_documentUnderMouse)
- shouldOpenExternalURLsPolicy = m_documentUnderMouse->shouldOpenExternalURLsPolicyToPropagate();
-
if ((m_dragDestinationAction & DragDestinationActionDHTML) && m_documentIsHandlingDrag) {
m_client.willPerformDragDestinationAction(DragDestinationActionDHTML, dragData);
Ref<MainFrame> mainFrame(m_page.mainFrame());
bool preventedDefault = false;
if (mainFrame->view()) {
// Sending an event can result in the destruction of the view and part.
- RefPtr<DataTransfer> dataTransfer = DataTransfer::createForDragAndDrop(DataTransferAccessPolicy::Readable, dragData);
- dataTransfer->setSourceOperation(dragData.draggingSourceOperationMask());
- preventedDefault = mainFrame->eventHandler().performDragAndDrop(createMouseEvent(dragData), dataTransfer.get());
- dataTransfer->setAccessPolicy(DataTransferAccessPolicy::Numb); // Invalidate dataTransfer here for security.
+ RefPtr<Clipboard> clipboard = Clipboard::createForDragAndDrop(ClipboardReadable, dragData);
+ clipboard->setSourceOperation(dragData.draggingSourceOperationMask());
+ preventedDefault = mainFrame->eventHandler().performDragAndDrop(createMouseEvent(dragData), clipboard.get());
+ clipboard->setAccessPolicy(ClipboardNumb); // Invalidate clipboard here for security
}
if (preventedDefault) {
- clearDragCaret();
- m_documentUnderMouse = nullptr;
+ m_documentUnderMouse = 0;
return true;
}
}
if ((m_dragDestinationAction & DragDestinationActionEdit) && concludeEditDrag(dragData)) {
- m_documentUnderMouse = nullptr;
+ m_documentUnderMouse = 0;
return true;
}
- m_documentUnderMouse = nullptr;
+ m_documentUnderMouse = 0;
if (operationForLoad(dragData) == DragOperationNone)
return false;
m_client.willPerformDragDestinationAction(DragDestinationActionLoad, dragData);
- m_page.mainFrame().loader().load(FrameLoadRequest(&m_page.mainFrame(), ResourceRequest(dragData.asURL()), shouldOpenExternalURLsPolicy));
+ m_page.mainFrame().loader().load(FrameLoadRequest(&m_page.mainFrame(), ResourceRequest(dragData.asURL(&m_page.mainFrame()))));
return true;
}
@@ -260,41 +243,38 @@ void DragController::mouseMovedIntoDocument(Document* newDocument)
// If we were over another document clear the selection
if (m_documentUnderMouse)
- clearDragCaret();
+ cancelDrag();
m_documentUnderMouse = newDocument;
}
-DragOperation DragController::dragEnteredOrUpdated(DragData& dragData)
+DragSession DragController::dragEnteredOrUpdated(DragData& dragData)
{
mouseMovedIntoDocument(m_page.mainFrame().documentAtPoint(dragData.clientPosition()));
m_dragDestinationAction = m_client.actionMaskForDrag(dragData);
if (m_dragDestinationAction == DragDestinationActionNone) {
- clearDragCaret(); // FIXME: Why not call mouseMovedIntoDocument(nullptr)?
- return DragOperationNone;
+ cancelDrag(); // FIXME: Why not call mouseMovedIntoDocument(0)?
+ return DragSession();
}
- DragOperation dragOperation = DragOperationNone;
- m_documentIsHandlingDrag = tryDocumentDrag(dragData, m_dragDestinationAction, dragOperation);
+ DragSession dragSession;
+ m_documentIsHandlingDrag = tryDocumentDrag(dragData, m_dragDestinationAction, dragSession);
if (!m_documentIsHandlingDrag && (m_dragDestinationAction & DragDestinationActionLoad))
- dragOperation = operationForLoad(dragData);
- return dragOperation;
+ dragSession.operation = operationForLoad(dragData);
+ return dragSession;
}
-static HTMLInputElement* asFileInput(Node& node)
+static HTMLInputElement* asFileInput(Node* node)
{
- if (!is<HTMLInputElement>(node))
- return nullptr;
+ ASSERT(node);
- auto* inputElement = &downcast<HTMLInputElement>(node);
+ HTMLInputElement* inputElement = node->toInputElement();
// If this is a button inside of the a file input, move up to the file input.
- if (inputElement->isTextButton() && is<ShadowRoot>(inputElement->treeScope().rootNode())) {
- auto& host = *downcast<ShadowRoot>(inputElement->treeScope().rootNode()).host();
- inputElement = is<HTMLInputElement>(host) ? &downcast<HTMLInputElement>(host) : nullptr;
- }
+ if (inputElement && inputElement->isTextButton() && inputElement->treeScope().rootNode()->isShadowRoot())
+ inputElement = toShadowRoot(inputElement->treeScope().rootNode())->hostElement()->toInputElement();
- return inputElement && inputElement->isFileUpload() ? inputElement : nullptr;
+ return inputElement && inputElement->isFileUpload() ? inputElement : 0;
}
// This can return null if an empty document is loaded.
@@ -302,21 +282,22 @@ static Element* elementUnderMouse(Document* documentUnderMouse, const IntPoint&
{
Frame* frame = documentUnderMouse->frame();
float zoomFactor = frame ? frame->pageZoomFactor() : 1;
- LayoutPoint point(p.x() * zoomFactor, p.y() * zoomFactor);
+ LayoutPoint point = roundedLayoutPoint(FloatPoint(p.x() * zoomFactor, p.y() * zoomFactor));
+ HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::DisallowShadowContent);
HitTestResult result(point);
- documentUnderMouse->renderView()->hitTest(HitTestRequest(), result);
+ documentUnderMouse->renderView()->hitTest(request, result);
- Node* node = result.innerNode();
- while (node && !is<Element>(*node))
- node = node->parentNode();
- if (node)
- node = node->deprecatedShadowAncestorNode();
+ Node* n = result.innerNode();
+ while (n && !n->isElementNode())
+ n = n->parentNode();
+ if (n)
+ n = n->deprecatedShadowAncestorNode();
- return downcast<Element>(node);
+ return toElement(n);
}
-bool DragController::tryDocumentDrag(DragData& dragData, DragDestinationAction actionMask, DragOperation& dragOperation)
+bool DragController::tryDocumentDrag(DragData& dragData, DragDestinationAction actionMask, DragSession& dragSession)
{
if (!m_documentUnderMouse)
return false;
@@ -326,7 +307,7 @@ bool DragController::tryDocumentDrag(DragData& dragData, DragDestinationAction a
bool isHandlingDrag = false;
if (actionMask & DragDestinationActionDHTML) {
- isHandlingDrag = tryDHTMLDrag(dragData, dragOperation);
+ isHandlingDrag = tryDHTMLDrag(dragData, dragSession.operation);
// Do not continue if m_documentUnderMouse has been reset by tryDHTMLDrag.
// tryDHTMLDrag fires dragenter event. The event listener that listens
// to this event may create a nested message loop (open a modal dialog),
@@ -343,13 +324,13 @@ bool DragController::tryDocumentDrag(DragData& dragData, DragDestinationAction a
return false;
if (isHandlingDrag) {
- clearDragCaret();
+ m_page.dragCaretController().clear();
return true;
}
if ((actionMask & DragDestinationActionEdit) && canProcessDrag(dragData)) {
if (dragData.containsColor()) {
- dragOperation = DragOperationGeneric;
+ dragSession.operation = DragOperationGeneric;
return true;
}
@@ -358,7 +339,7 @@ bool DragController::tryDocumentDrag(DragData& dragData, DragDestinationAction a
if (!element)
return false;
- HTMLInputElement* elementAsFileInput = asFileInput(*element);
+ HTMLInputElement* elementAsFileInput = asFileInput(element);
if (m_fileInputElementUnderMouse != elementAsFileInput) {
if (m_fileInputElementUnderMouse)
m_fileInputElementUnderMouse->setCanReceiveDroppedFiles(false);
@@ -367,41 +348,40 @@ bool DragController::tryDocumentDrag(DragData& dragData, DragDestinationAction a
if (!m_fileInputElementUnderMouse)
m_page.dragCaretController().setCaretPosition(m_documentUnderMouse->frame()->visiblePositionForPoint(point));
- else
- clearDragCaret();
Frame* innerFrame = element->document().frame();
- dragOperation = dragIsMove(innerFrame->selection(), dragData) ? DragOperationMove : DragOperationCopy;
- m_numberOfItemsToBeAccepted = 0;
+ dragSession.operation = dragIsMove(innerFrame->selection(), dragData) ? DragOperationMove : DragOperationCopy;
+ dragSession.mouseIsOverFileInput = m_fileInputElementUnderMouse;
+ dragSession.numberOfItemsToBeAccepted = 0;
unsigned numberOfFiles = dragData.numberOfFiles();
if (m_fileInputElementUnderMouse) {
if (m_fileInputElementUnderMouse->isDisabledFormControl())
- m_numberOfItemsToBeAccepted = 0;
+ dragSession.numberOfItemsToBeAccepted = 0;
else if (m_fileInputElementUnderMouse->multiple())
- m_numberOfItemsToBeAccepted = numberOfFiles;
+ dragSession.numberOfItemsToBeAccepted = numberOfFiles;
else if (numberOfFiles > 1)
- m_numberOfItemsToBeAccepted = 0;
+ dragSession.numberOfItemsToBeAccepted = 0;
else
- m_numberOfItemsToBeAccepted = 1;
+ dragSession.numberOfItemsToBeAccepted = 1;
- if (!m_numberOfItemsToBeAccepted)
- dragOperation = DragOperationNone;
- m_fileInputElementUnderMouse->setCanReceiveDroppedFiles(m_numberOfItemsToBeAccepted);
+ if (!dragSession.numberOfItemsToBeAccepted)
+ dragSession.operation = DragOperationNone;
+ m_fileInputElementUnderMouse->setCanReceiveDroppedFiles(dragSession.numberOfItemsToBeAccepted);
} else {
// We are not over a file input element. The dragged item(s) will only
// be loaded into the view the number of dragged items is 1.
- m_numberOfItemsToBeAccepted = numberOfFiles != 1 ? 0 : 1;
+ dragSession.numberOfItemsToBeAccepted = numberOfFiles != 1 ? 0 : 1;
}
return true;
}
// We are not over an editable region. Make sure we're clearing any prior drag cursor.
- clearDragCaret();
+ m_page.dragCaretController().clear();
if (m_fileInputElementUnderMouse)
m_fileInputElementUnderMouse->setCanReceiveDroppedFiles(false);
- m_fileInputElementUnderMouse = nullptr;
+ m_fileInputElementUnderMouse = 0;
return false;
}
@@ -413,19 +393,19 @@ DragSourceAction DragController::delegateDragSourceAction(const IntPoint& rootVi
DragOperation DragController::operationForLoad(DragData& dragData)
{
- Document* document = m_page.mainFrame().documentAtPoint(dragData.clientPosition());
+ Document* doc = m_page.mainFrame().documentAtPoint(dragData.clientPosition());
bool pluginDocumentAcceptsDrags = false;
- if (is<PluginDocument>(document)) {
- const Widget* widget = downcast<PluginDocument>(*document).pluginWidget();
- const PluginViewBase* pluginView = is<PluginViewBase>(widget) ? downcast<PluginViewBase>(widget) : nullptr;
+ if (doc && doc->isPluginDocument()) {
+ const Widget* widget = toPluginDocument(doc)->pluginWidget();
+ const PluginViewBase* pluginView = (widget && widget->isPluginViewBase()) ? toPluginViewBase(widget) : nullptr;
if (pluginView)
pluginDocumentAcceptsDrags = pluginView->shouldAllowNavigationFromDrags();
}
- if (document && (m_didInitiateDrag || (is<PluginDocument>(*document) && !pluginDocumentAcceptsDrags) || document->hasEditableStyle()))
+ if (doc && (m_didInitiateDrag || (doc->isPluginDocument() && !pluginDocumentAcceptsDrags) || doc->hasEditableStyle()))
return DragOperationNone;
return dragOperation(dragData);
}
@@ -433,20 +413,20 @@ DragOperation DragController::operationForLoad(DragData& dragData)
static bool setSelectionToDragCaret(Frame* frame, VisibleSelection& dragCaret, RefPtr<Range>& range, const IntPoint& point)
{
frame->selection().setSelection(dragCaret);
- if (frame->selection().selection().isNone()) {
+ if (frame->selection().isNone()) {
dragCaret = frame->visiblePositionForPoint(point);
frame->selection().setSelection(dragCaret);
range = dragCaret.toNormalizedRange();
}
- return !frame->selection().isNone() && frame->selection().selection().isContentEditable();
+ return !frame->selection().isNone() && frame->selection().isContentEditable();
}
bool DragController::dispatchTextInputEventFor(Frame* innerFrame, DragData& dragData)
{
ASSERT(m_page.dragCaretController().hasCaret());
- String text = m_page.dragCaretController().isContentRichlyEditable() ? emptyString() : dragData.asPlainText();
+ String text = m_page.dragCaretController().isContentRichlyEditable() ? emptyString() : dragData.asPlainText(innerFrame);
Node* target = innerFrame->editor().findEventTargetFrom(m_page.dragCaretController().caretPosition());
- return target->dispatchEvent(TextEvent::createForDrop(innerFrame->document()->domWindow(), text));
+ return target->dispatchEvent(TextEvent::createForDrop(innerFrame->document()->domWindow(), text), IGNORE_EXCEPTION);
}
bool DragController::concludeEditDrag(DragData& dragData)
@@ -454,7 +434,7 @@ bool DragController::concludeEditDrag(DragData& dragData)
RefPtr<HTMLInputElement> fileInput = m_fileInputElementUnderMouse;
if (m_fileInputElementUnderMouse) {
m_fileInputElementUnderMouse->setCanReceiveDroppedFiles(false);
- m_fileInputElementUnderMouse = nullptr;
+ m_fileInputElementUnderMouse = 0;
}
if (!m_documentUnderMouse)
@@ -495,24 +475,25 @@ bool DragController::concludeEditDrag(DragData& dragData)
}
if (!m_page.dragController().canProcessDrag(dragData)) {
- clearDragCaret();
+ m_page.dragCaretController().clear();
return false;
}
VisibleSelection dragCaret = m_page.dragCaretController().caretPosition();
- clearDragCaret();
+ m_page.dragCaretController().clear();
RefPtr<Range> range = dragCaret.toNormalizedRange();
- RefPtr<Element> rootEditableElement = innerFrame->selection().selection().rootEditableElement();
+ RefPtr<Element> rootEditableElement = innerFrame->selection().rootEditableElement();
// For range to be null a WebKit client must have done something bad while
// manually controlling drag behaviour
if (!range)
return false;
- ResourceCacheValidationSuppressor validationSuppressor(range->ownerDocument().cachedResourceLoader());
+ CachedResourceLoader* cachedResourceLoader = range->ownerDocument().cachedResourceLoader();
+ ResourceCacheValidationSuppressor validationSuppressor(cachedResourceLoader);
if (dragIsMove(innerFrame->selection(), dragData) || dragCaret.isContentRichlyEditable()) {
bool chosePlainText = false;
- RefPtr<DocumentFragment> fragment = documentFragmentFromDragData(dragData, *innerFrame, *range, true, chosePlainText);
+ RefPtr<DocumentFragment> fragment = documentFragmentFromDragData(dragData, innerFrame.get(), *range, true, chosePlainText);
if (!fragment || !innerFrame->editor().shouldInsertFragment(fragment, range, EditorInsertActionDropped)) {
return false;
}
@@ -531,11 +512,11 @@ bool DragController::concludeEditDrag(DragData& dragData)
options |= ReplaceSelectionCommand::SmartReplace;
if (chosePlainText)
options |= ReplaceSelectionCommand::MatchStyle;
- applyCommand(ReplaceSelectionCommand::create(*m_documentUnderMouse, WTFMove(fragment), options));
+ applyCommand(ReplaceSelectionCommand::create(*m_documentUnderMouse, fragment, options));
}
}
} else {
- String text = dragData.asPlainText();
+ String text = dragData.asPlainText(innerFrame.get());
if (text.isEmpty() || !innerFrame->editor().shouldInsertText(text, range.get(), EditorInsertActionDropped)) {
return false;
}
@@ -568,11 +549,11 @@ bool DragController::canProcessDrag(DragData& dragData)
if (!result.innerNonSharedNode())
return false;
- if (dragData.containsFiles() && asFileInput(*result.innerNonSharedNode()))
+ if (dragData.containsFiles() && asFileInput(result.innerNonSharedNode()))
return true;
- if (is<HTMLPlugInElement>(*result.innerNonSharedNode())) {
- if (!downcast<HTMLPlugInElement>(result.innerNonSharedNode())->canProcessDrag() && !result.innerNonSharedNode()->hasEditableStyle())
+ if (result.innerNonSharedNode()->isPluginElement()) {
+ if (!toHTMLPlugInElement(result.innerNonSharedNode())->canProcessDrag() && !result.innerNonSharedNode()->hasEditableStyle())
return false;
} else if (!result.innerNonSharedNode()->hasEditableStyle())
return false;
@@ -610,31 +591,26 @@ bool DragController::tryDHTMLDrag(DragData& dragData, DragOperation& operation)
if (!viewProtector)
return false;
-#if ENABLE(DASHBOARD_SUPPORT)
- DataTransferAccessPolicy policy = (mainFrame->settings().usesDashboardBackwardCompatibilityMode() && m_documentUnderMouse->securityOrigin()->isLocal()) ?
- DataTransferAccessPolicy::Readable : DataTransferAccessPolicy::TypesReadable;
-#else
- DataTransferAccessPolicy policy = DataTransferAccessPolicy::TypesReadable;
-#endif
- RefPtr<DataTransfer> dataTransfer = DataTransfer::createForDragAndDrop(policy, dragData);
+ ClipboardAccessPolicy policy = m_documentUnderMouse->securityOrigin()->isLocal() ? ClipboardReadable : ClipboardTypesReadable;
+ RefPtr<Clipboard> clipboard = Clipboard::createForDragAndDrop(policy, dragData);
DragOperation srcOpMask = dragData.draggingSourceOperationMask();
- dataTransfer->setSourceOperation(srcOpMask);
+ clipboard->setSourceOperation(srcOpMask);
PlatformMouseEvent event = createMouseEvent(dragData);
- if (!mainFrame->eventHandler().updateDragAndDrop(event, dataTransfer.get())) {
- dataTransfer->setAccessPolicy(DataTransferAccessPolicy::Numb); // Invalidate dataTransfer here for security.
+ if (!mainFrame->eventHandler().updateDragAndDrop(event, clipboard.get())) {
+ clipboard->setAccessPolicy(ClipboardNumb); // invalidate clipboard here for security
return false;
}
- operation = dataTransfer->destinationOperation();
- if (dataTransfer->dropEffectIsUninitialized())
+ operation = clipboard->destinationOperation();
+ if (clipboard->dropEffectIsUninitialized())
operation = defaultOperationForDrag(srcOpMask);
else if (!(srcOpMask & operation)) {
// The element picked an operation which is not supported by the source
operation = DragOperationNone;
}
- dataTransfer->setAccessPolicy(DataTransferAccessPolicy::Numb); // Invalidate dataTransfer here for security.
+ clipboard->setAccessPolicy(ClipboardNumb); // invalidate clipboard here for security
return true;
}
@@ -642,17 +618,9 @@ Element* DragController::draggableElement(const Frame* sourceFrame, Element* sta
{
state.type = (sourceFrame->selection().contains(dragOrigin)) ? DragSourceActionSelection : DragSourceActionNone;
if (!startElement)
- return nullptr;
-#if ENABLE(ATTACHMENT_ELEMENT)
- // Unlike image elements, attachment elements are immediately selected upon mouse down,
- // but for those elements we still want to use the single element drag behavior as long as
- // the element is the only content of the selection.
- const VisibleSelection& selection = sourceFrame->selection().selection();
- if (selection.isRange() && is<HTMLAttachmentElement>(selection.start().anchorNode()) && selection.start().anchorNode() == selection.end().anchorNode())
- state.type = DragSourceActionNone;
-#endif
+ return 0;
- for (auto* renderer = startElement->renderer(); renderer; renderer = renderer->parent()) {
+ for (auto renderer = startElement->renderer(); renderer; renderer = renderer->parent()) {
Element* element = renderer->nonPseudoElement();
if (!element) {
// Anonymous render blocks don't correspond to actual DOM elements, so we skip over them
@@ -666,37 +634,31 @@ Element* DragController::draggableElement(const Frame* sourceFrame, Element* sta
}
if (dragMode == DRAG_AUTO) {
if ((m_dragSourceAction & DragSourceActionImage)
- && is<HTMLImageElement>(*element)
+ && isHTMLImageElement(element)
&& sourceFrame->settings().loadsImagesAutomatically()) {
state.type = static_cast<DragSourceAction>(state.type | DragSourceActionImage);
return element;
}
- if ((m_dragSourceAction & DragSourceActionLink) && isDraggableLink(*element)) {
+ if ((m_dragSourceAction & DragSourceActionLink)
+ && isHTMLAnchorElement(element)
+ && toHTMLAnchorElement(element)->isLiveLink()) {
state.type = static_cast<DragSourceAction>(state.type | DragSourceActionLink);
return element;
}
-#if ENABLE(ATTACHMENT_ELEMENT)
- if ((m_dragSourceAction & DragSourceActionAttachment)
- && is<HTMLAttachmentElement>(*element)
- && downcast<HTMLAttachmentElement>(*element).file()) {
- state.type = static_cast<DragSourceAction>(state.type | DragSourceActionAttachment);
- return element;
- }
-#endif
}
}
// We either have nothing to drag or we have a selection and we're not over a draggable element.
- return (state.type & DragSourceActionSelection) ? startElement : nullptr;
+ return (state.type & DragSourceActionSelection) ? startElement : 0;
}
static CachedImage* getCachedImage(Element& element)
{
RenderObject* renderer = element.renderer();
- if (!is<RenderImage>(renderer))
- return nullptr;
- auto& image = downcast<RenderImage>(*renderer);
- return image.cachedImage();
+ if (!renderer || !renderer->isRenderImage())
+ return 0;
+ RenderImage* image = toRenderImage(renderer);
+ return image->cachedImage();
}
static Image* getImage(Element& element)
@@ -706,20 +668,20 @@ static Image* getImage(Element& element)
// Users of getImage() want access to the SVGImage, in order to figure out the filename extensions,
// which would be empty when asking the cached BitmapImages.
return (cachedImage && !cachedImage->errorOccurred()) ?
- cachedImage->image() : nullptr;
+ cachedImage->image() : 0;
}
static void selectElement(Element& element)
{
RefPtr<Range> range = element.document().createRange();
range->selectNode(&element);
- element.document().frame()->selection().setSelection(VisibleSelection(*range, DOWNSTREAM));
+ element.document().frame()->selection().setSelection(VisibleSelection(range.get(), DOWNSTREAM));
}
static IntPoint dragLocForDHTMLDrag(const IntPoint& mouseDraggedPoint, const IntPoint& dragOrigin, const IntPoint& dragImageOffset, bool isLinkImage)
{
// dragImageOffset is the cursor position relative to the lower-left corner of the image.
-#if PLATFORM(COCOA)
+#if PLATFORM(MAC)
// We add in the Y dimension because we are a flipped view, so adding moves the image down.
const int yOffset = dragImageOffset.y();
#else
@@ -734,11 +696,11 @@ static IntPoint dragLocForDHTMLDrag(const IntPoint& mouseDraggedPoint, const Int
static IntPoint dragLocForSelectionDrag(Frame& src)
{
- IntRect draggingRect = enclosingIntRect(src.selection().selectionBounds());
+ IntRect draggingRect = enclosingIntRect(src.selection().bounds());
int xpos = draggingRect.maxX();
xpos = draggingRect.x() < xpos ? draggingRect.x() : xpos;
int ypos = draggingRect.maxY();
-#if PLATFORM(COCOA)
+#if PLATFORM(MAC)
// Deal with flipped coordinates on Mac
ypos = draggingRect.y() > ypos ? draggingRect.y() : ypos;
#else
@@ -749,48 +711,32 @@ static IntPoint dragLocForSelectionDrag(Frame& src)
bool DragController::startDrag(Frame& src, const DragState& state, DragOperation srcOp, const PlatformMouseEvent& dragEvent, const IntPoint& dragOrigin)
{
- if (!src.view() || !src.contentRenderer() || !state.source)
+ if (!src.view() || !src.contentRenderer())
return false;
HitTestResult hitTestResult = src.eventHandler().hitTestResultAtPoint(dragOrigin, HitTestRequest::ReadOnly | HitTestRequest::Active);
-
- // FIXME(136836): Investigate whether all elements should use the containsIncludingShadowDOM() path here.
- bool includeShadowDOM = false;
-#if ENABLE(VIDEO)
- includeShadowDOM = state.source->isMediaElement();
-#endif
- bool sourceContainsHitNode;
- if (!includeShadowDOM)
- sourceContainsHitNode = state.source->contains(hitTestResult.innerNode());
- else
- sourceContainsHitNode = state.source->containsIncludingShadowDOM(hitTestResult.innerNode());
-
- if (!sourceContainsHitNode)
+ if (!state.source->contains(hitTestResult.innerNode()))
// The original node being dragged isn't under the drag origin anymore... maybe it was
// hidden or moved out from under the cursor. Regardless, we don't want to start a drag on
// something that's not actually under the drag origin.
return false;
URL linkURL = hitTestResult.absoluteLinkURL();
URL imageURL = hitTestResult.absoluteImageURL();
-#if ENABLE(ATTACHMENT_ELEMENT)
- URL attachmentURL = hitTestResult.absoluteAttachmentURL();
- m_draggingAttachmentURL = URL();
-#endif
IntPoint mouseDraggedPoint = src.view()->windowToContents(dragEvent.position());
m_draggingImageURL = URL();
m_sourceDragOperation = srcOp;
- DragImageRef dragImage = nullptr;
+ DragImageRef dragImage = 0;
IntPoint dragLoc(0, 0);
IntPoint dragImageOffset(0, 0);
- ASSERT(state.dataTransfer);
+ ASSERT(state.clipboard);
- DataTransfer& dataTransfer = *state.dataTransfer;
+ Clipboard& clipboard = *state.clipboard;
if (state.type == DragSourceActionDHTML)
- dragImage = dataTransfer.createDragImage(dragImageOffset);
+ dragImage = clipboard.createDragImage(dragImageOffset);
if (state.type == DragSourceActionSelection || !imageURL.isEmpty() || !linkURL.isEmpty())
// Selection, image, and link drags receive a default set of allowed drag operations that
// follows from:
@@ -811,7 +757,7 @@ bool DragController::startDrag(Frame& src, const DragState& state, DragOperation
Image* image = getImage(element);
if (state.type == DragSourceActionSelection) {
- if (!dataTransfer.pasteboard().hasData()) {
+ if (!clipboard.pasteboard().hasData()) {
// FIXME: This entire block is almost identical to the code in Editor::copy, and the code should be shared.
RefPtr<Range> selectionRange = src.selection().toNormalizedRange();
@@ -819,73 +765,64 @@ bool DragController::startDrag(Frame& src, const DragState& state, DragOperation
src.editor().willWriteSelectionToPasteboard(selectionRange.get());
- if (enclosingTextFormControl(src.selection().selection().start()))
- dataTransfer.pasteboard().writePlainText(src.editor().selectedTextForDataTransfer(), Pasteboard::CannotSmartReplace);
+ if (enclosingTextFormControl(src.selection().start()))
+ clipboard.pasteboard().writePlainText(src.editor().selectedTextForClipboard(), Pasteboard::CannotSmartReplace);
else {
-#if PLATFORM(COCOA) || PLATFORM(EFL) || PLATFORM(GTK)
- src.editor().writeSelectionToPasteboard(dataTransfer.pasteboard());
+#if PLATFORM(MAC) || PLATFORM(EFL)
+ src.editor().writeSelectionToPasteboard(clipboard.pasteboard());
#else
// FIXME: Convert all other platforms to match Mac and delete this.
- dataTransfer.pasteboard().writeSelection(*selectionRange, src.editor().canSmartCopyOrDelete(), src, IncludeImageAltTextForDataTransfer);
+ clipboard.pasteboard().writeSelection(*selectionRange, src.editor().canSmartCopyOrDelete(), src, IncludeImageAltTextForClipboard);
#endif
}
src.editor().didWriteSelectionToPasteboard();
}
- m_client.willPerformDragSourceAction(DragSourceActionSelection, dragOrigin, dataTransfer);
+ m_client.willPerformDragSourceAction(DragSourceActionSelection, dragOrigin, clipboard);
if (!dragImage) {
dragImage = dissolveDragImageToFraction(createDragImageForSelection(src), DragImageAlpha);
dragLoc = dragLocForSelectionDrag(src);
m_dragOffset = IntPoint(dragOrigin.x() - dragLoc.x(), dragOrigin.y() - dragLoc.y());
}
-
- if (!dragImage)
- return false;
-
- doSystemDrag(dragImage, dragLoc, dragOrigin, dataTransfer, src, false);
- } else if (!src.document()->securityOrigin()->canDisplay(linkURL)) {
- src.document()->addConsoleMessage(MessageSource::Security, MessageLevel::Error, "Not allowed to drag local resource: " + linkURL.stringCenterEllipsizedToLength());
- startedDrag = false;
+ doSystemDrag(dragImage, dragLoc, dragOrigin, clipboard, src, false);
} else if (!imageURL.isEmpty() && image && !image->isNull() && (m_dragSourceAction & DragSourceActionImage)) {
// We shouldn't be starting a drag for an image that can't provide an extension.
// This is an early detection for problems encountered later upon drop.
ASSERT(!image->filenameExtension().isEmpty());
- if (!dataTransfer.pasteboard().hasData()) {
+ if (!clipboard.pasteboard().hasData()) {
m_draggingImageURL = imageURL;
if (element.isContentRichlyEditable())
selectElement(element);
- declareAndWriteDragImage(dataTransfer, element, !linkURL.isEmpty() ? linkURL : imageURL, hitTestResult.altDisplayString());
+ declareAndWriteDragImage(clipboard, element, !linkURL.isEmpty() ? linkURL : imageURL, hitTestResult.altDisplayString());
}
- m_client.willPerformDragSourceAction(DragSourceActionImage, dragOrigin, dataTransfer);
+ m_client.willPerformDragSourceAction(DragSourceActionImage, dragOrigin, clipboard);
if (!dragImage) {
IntRect imageRect = hitTestResult.imageRect();
imageRect.setLocation(m_page.mainFrame().view()->rootViewToContents(src.view()->contentsToRootView(imageRect.location())));
- doImageDrag(element, dragOrigin, hitTestResult.imageRect(), dataTransfer, src, m_dragOffset);
+ doImageDrag(element, dragOrigin, hitTestResult.imageRect(), clipboard, src, m_dragOffset);
} else {
// DHTML defined drag image
- doSystemDrag(dragImage, dragLoc, dragOrigin, dataTransfer, src, false);
+ doSystemDrag(dragImage, dragLoc, dragOrigin, clipboard, src, false);
}
} else if (!linkURL.isEmpty() && (m_dragSourceAction & DragSourceActionLink)) {
- if (!dataTransfer.pasteboard().hasData()) {
- // Simplify whitespace so the title put on the dataTransfer resembles what the user sees
+ if (!clipboard.pasteboard().hasData())
+ // Simplify whitespace so the title put on the clipboard resembles what the user sees
// on the web page. This includes replacing newlines with spaces.
- src.editor().copyURL(linkURL, hitTestResult.textContent().simplifyWhiteSpace(), dataTransfer.pasteboard());
- }
+ src.editor().copyURL(linkURL, hitTestResult.textContent().simplifyWhiteSpace(), clipboard.pasteboard());
- const VisibleSelection& sourceSelection = src.selection().selection();
- if (sourceSelection.isCaret() && sourceSelection.isContentEditable()) {
+ if (src.selection().isCaret() && src.selection().isContentEditable()) {
// a user can initiate a drag on a link without having any text
// selected. In this case, we should expand the selection to
// the enclosing anchor element
- Position pos = sourceSelection.base();
+ Position pos = src.selection().base();
Node* node = enclosingAnchorElement(pos);
if (node)
src.selection().setSelection(VisibleSelection::selectionFromContentsOfNode(node));
}
- m_client.willPerformDragSourceAction(DragSourceActionLink, dragOrigin, dataTransfer);
+ m_client.willPerformDragSourceAction(DragSourceActionLink, dragOrigin, clipboard);
if (!dragImage) {
dragImage = createDragImageForLink(linkURL, hitTestResult.textContent(), src.settings().fontRenderingMode());
IntSize size = dragImageSize(dragImage);
@@ -894,29 +831,12 @@ bool DragController::startDrag(Frame& src, const DragState& state, DragOperation
// Later code expects the drag image to be scaled by device's scale factor.
dragImage = scaleDragImage(dragImage, FloatSize(m_page.deviceScaleFactor(), m_page.deviceScaleFactor()));
}
- doSystemDrag(dragImage, dragLoc, mouseDraggedPoint, dataTransfer, src, true);
-#if ENABLE(ATTACHMENT_ELEMENT)
- } else if (!attachmentURL.isEmpty() && (m_dragSourceAction & DragSourceActionAttachment)) {
- if (!dataTransfer.pasteboard().hasData()) {
- m_draggingAttachmentURL = attachmentURL;
- selectElement(element);
- declareAndWriteAttachment(dataTransfer, element, attachmentURL);
- }
-
- m_client.willPerformDragSourceAction(DragSourceActionAttachment, dragOrigin, dataTransfer);
-
- if (!dragImage) {
- dragImage = dissolveDragImageToFraction(createDragImageForSelection(src), DragImageAlpha);
- dragLoc = dragLocForSelectionDrag(src);
- m_dragOffset = IntPoint(dragOrigin.x() - dragLoc.x(), dragOrigin.y() - dragLoc.y());
- }
- doSystemDrag(dragImage, dragLoc, dragOrigin, dataTransfer, src, false);
-#endif
+ doSystemDrag(dragImage, dragLoc, mouseDraggedPoint, clipboard, src, true);
} else if (state.type == DragSourceActionDHTML) {
if (dragImage) {
ASSERT(m_dragSourceAction & DragSourceActionDHTML);
- m_client.willPerformDragSourceAction(DragSourceActionDHTML, dragOrigin, dataTransfer);
- doSystemDrag(dragImage, dragLoc, dragOrigin, dataTransfer, src, false);
+ m_client.willPerformDragSourceAction(DragSourceActionDHTML, dragOrigin, clipboard);
+ doSystemDrag(dragImage, dragLoc, dragOrigin, clipboard, src, false);
} else
startedDrag = false;
} else {
@@ -930,7 +850,7 @@ bool DragController::startDrag(Frame& src, const DragState& state, DragOperation
return startedDrag;
}
-void DragController::doImageDrag(Element& element, const IntPoint& dragOrigin, const IntRect& layoutRect, DataTransfer& dataTransfer, Frame& frame, IntPoint& dragImageOffset)
+void DragController::doImageDrag(Element& element, const IntPoint& dragOrigin, const IntRect& layoutRect, Clipboard& clipboard, Frame& frame, IntPoint& dragImageOffset)
{
IntPoint mouseDownPoint = dragOrigin;
DragImageRef dragImage = nullptr;
@@ -939,7 +859,10 @@ void DragController::doImageDrag(Element& element, const IntPoint& dragOrigin, c
if (!element.renderer())
return;
- ImageOrientationDescription orientationDescription(element.renderer()->shouldRespectImageOrientation(), element.renderer()->style().imageOrientation());
+ ImageOrientationDescription orientationDescription(element.renderer()->shouldRespectImageOrientation());
+#if ENABLE(CSS_IMAGE_ORIENTATION)
+ orientationDescription.setImageOrientationEnum(element.renderer()->style().imageOrientation());
+#endif
Image* image = getImage(element);
if (image && image->size().height() * image->size().width() <= MaxOriginalImageArea
@@ -955,7 +878,7 @@ void DragController::doImageDrag(Element& element, const IntPoint& dragOrigin, c
float scale = fittedSize.width() / (float)layoutRect.width();
float dx = scale * (layoutRect.x() - mouseDownPoint.x());
float originY = layoutRect.y();
-#if PLATFORM(COCOA)
+#if PLATFORM(MAC)
// Compensate for accursed flipped coordinates in Cocoa.
originY += layoutRect.height();
#endif
@@ -970,12 +893,12 @@ void DragController::doImageDrag(Element& element, const IntPoint& dragOrigin, c
}
dragImageOffset = mouseDownPoint + scaledOrigin;
- doSystemDrag(dragImage, dragImageOffset, dragOrigin, dataTransfer, frame, false);
+ doSystemDrag(dragImage, dragImageOffset, dragOrigin, clipboard, frame, false);
deleteDragImage(dragImage);
}
-void DragController::doSystemDrag(DragImageRef image, const IntPoint& dragLoc, const IntPoint& eventPos, DataTransfer& dataTransfer, Frame& frame, bool forLink)
+void DragController::doSystemDrag(DragImageRef image, const IntPoint& dragLoc, const IntPoint& eventPos, Clipboard& clipboard, Frame& frame, bool forLink)
{
m_didInitiateDrag = true;
m_dragInitiator = frame.document();
@@ -983,7 +906,7 @@ void DragController::doSystemDrag(DragImageRef image, const IntPoint& dragLoc, c
Ref<MainFrame> frameProtector(m_page.mainFrame());
RefPtr<FrameView> viewProtector = frameProtector->view();
m_client.startDrag(image, viewProtector->rootViewToContents(frame.view()->contentsToRootView(dragLoc)),
- viewProtector->rootViewToContents(frame.view()->contentsToRootView(eventPos)), dataTransfer, frameProtector.get(), forLink);
+ viewProtector->rootViewToContents(frame.view()->contentsToRootView(eventPos)), clipboard, frameProtector.get(), forLink);
// DragClient::startDrag can cause our Page to dispear, deallocating |this|.
if (!frameProtector->page())
return;
@@ -1006,6 +929,6 @@ void DragController::placeDragCaret(const IntPoint& windowPoint)
m_page.dragCaretController().setCaretPosition(frame->visiblePositionForPoint(framePoint));
}
-#endif // ENABLE(DRAG_SUPPORT)
-
} // namespace WebCore
+
+#endif // ENABLE(DRAG_SUPPORT)
diff --git a/Source/WebCore/page/DragController.h b/Source/WebCore/page/DragController.h
index ec3ff0522..050899035 100644
--- a/Source/WebCore/page/DragController.h
+++ b/Source/WebCore/page/DragController.h
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -33,7 +33,7 @@
namespace WebCore {
- class DataTransfer;
+ class Clipboard;
class Document;
class DragClient;
class DragData;
@@ -45,6 +45,7 @@ namespace WebCore {
class Page;
class PlatformMouseEvent;
+ struct DragSession;
struct DragState;
class DragController {
@@ -53,27 +54,21 @@ namespace WebCore {
DragController(Page&, DragClient&);
~DragController();
- static std::unique_ptr<DragController> create(Page&, DragClient&);
+ static PassOwnPtr<DragController> create(Page*, DragClient*);
DragClient& client() const { return m_client; }
- WEBCORE_EXPORT DragOperation dragEntered(DragData&);
- WEBCORE_EXPORT void dragExited(DragData&);
- WEBCORE_EXPORT DragOperation dragUpdated(DragData&);
- WEBCORE_EXPORT bool performDragOperation(DragData&);
-
- bool mouseIsOverFileInput() const { return m_fileInputElementUnderMouse; }
- unsigned numberOfItemsToBeAccepted() const { return m_numberOfItemsToBeAccepted; }
-
+ DragSession dragEntered(DragData&);
+ void dragExited(DragData&);
+ DragSession dragUpdated(DragData&);
+ bool performDrag(DragData&);
+
// FIXME: It should be possible to remove a number of these accessors once all
// drag logic is in WebCore.
void setDidInitiateDrag(bool initiated) { m_didInitiateDrag = initiated; }
bool didInitiateDrag() const { return m_didInitiateDrag; }
DragOperation sourceDragOperation() const { return m_sourceDragOperation; }
const URL& draggingImageURL() const { return m_draggingImageURL; }
-#if ENABLE(ATTACHMENT_ELEMENT)
- const URL& draggingAttachmentURL() const { return m_draggingAttachmentURL; }
-#endif
void setDragOffset(const IntPoint& offset) { m_dragOffset = offset; }
const IntPoint& dragOffset() const { return m_dragOffset; }
DragSourceAction dragSourceAction() const { return m_dragSourceAction; }
@@ -83,9 +78,9 @@ namespace WebCore {
DragSourceAction delegateDragSourceAction(const IntPoint& rootViewPoint);
Element* draggableElement(const Frame*, Element* start, const IntPoint&, DragState&) const;
- WEBCORE_EXPORT void dragEnded();
+ void dragEnded();
- WEBCORE_EXPORT void placeDragCaret(const IntPoint&);
+ void placeDragCaret(const IntPoint&);
bool startDrag(Frame& src, const DragState&, DragOperation srcOp, const PlatformMouseEvent& dragEvent, const IntPoint& dragOrigin);
static const IntSize& maxDragImageSize();
@@ -100,31 +95,28 @@ namespace WebCore {
bool dispatchTextInputEventFor(Frame*, DragData&);
bool canProcessDrag(DragData&);
bool concludeEditDrag(DragData&);
- DragOperation dragEnteredOrUpdated(DragData&);
+ DragSession dragEnteredOrUpdated(DragData&);
DragOperation operationForLoad(DragData&);
- bool tryDocumentDrag(DragData&, DragDestinationAction, DragOperation&);
+ bool tryDocumentDrag(DragData&, DragDestinationAction, DragSession&);
bool tryDHTMLDrag(DragData&, DragOperation&);
DragOperation dragOperation(DragData&);
- void clearDragCaret();
+ void cancelDrag();
bool dragIsMove(FrameSelection&, DragData&);
bool isCopyKeyDown(DragData&);
void mouseMovedIntoDocument(Document*);
- void doImageDrag(Element&, const IntPoint&, const IntRect&, DataTransfer&, Frame&, IntPoint&);
- void doSystemDrag(DragImageRef, const IntPoint&, const IntPoint&, DataTransfer&, Frame&, bool forLink);
+ void doImageDrag(Element&, const IntPoint&, const IntRect&, Clipboard&, Frame&, IntPoint&);
+ void doSystemDrag(DragImageRef, const IntPoint&, const IntPoint&, Clipboard&, Frame&, bool forLink);
void cleanupAfterSystemDrag();
- void declareAndWriteDragImage(DataTransfer&, Element&, const URL&, const String& label);
-#if ENABLE(ATTACHMENT_ELEMENT)
- void declareAndWriteAttachment(DataTransfer&, Element&, const URL&);
-#endif
+ void declareAndWriteDragImage(Clipboard&, Element&, const URL&, const String& label);
+
Page& m_page;
DragClient& m_client;
RefPtr<Document> m_documentUnderMouse; // The document the mouse was last dragged over.
RefPtr<Document> m_dragInitiator; // The Document (if any) that initiated the drag.
RefPtr<HTMLInputElement> m_fileInputElementUnderMouse;
- unsigned m_numberOfItemsToBeAccepted;
bool m_documentIsHandlingDrag;
DragDestinationAction m_dragDestinationAction;
@@ -133,13 +125,8 @@ namespace WebCore {
DragOperation m_sourceDragOperation; // Set in startDrag when a drag starts from a mouse down within WebKit
IntPoint m_dragOffset;
URL m_draggingImageURL;
-#if ENABLE(ATTACHMENT_ELEMENT)
- URL m_draggingAttachmentURL;
-#endif
};
- WEBCORE_EXPORT bool isDraggableLink(const Element&);
-
}
#endif
diff --git a/Source/WebCore/page/PageConfiguration.cpp b/Source/WebCore/page/DragSession.h
index e8c3def82..0e9375196 100644
--- a/Source/WebCore/page/PageConfiguration.cpp
+++ b/Source/WebCore/page/DragSession.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -23,24 +23,26 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "config.h"
-#include "PageConfiguration.h"
+#ifndef DragSession_h
+#define DragSession_h
-#include "ApplicationCacheStorage.h"
-#include "BackForwardClient.h"
-#include "DatabaseProvider.h"
-#include "StorageNamespaceProvider.h"
-#include "UserContentController.h"
-#include "VisitedLinkStore.h"
+#include "DragActions.h"
namespace WebCore {
+
+struct DragSession {
+ DragOperation operation;
+ bool mouseIsOverFileInput;
+ unsigned numberOfItemsToBeAccepted;
-PageConfiguration::PageConfiguration()
-{
-}
+ DragSession()
+ : operation(DragOperationNone)
+ , mouseIsOverFileInput(false)
+ , numberOfItemsToBeAccepted(0)
+ {
+ }
+};
-PageConfiguration::~PageConfiguration()
-{
}
-}
+#endif
diff --git a/Source/WebCore/page/DragState.h b/Source/WebCore/page/DragState.h
index 172a88b0a..70849fdc5 100644
--- a/Source/WebCore/page/DragState.h
+++ b/Source/WebCore/page/DragState.h
@@ -11,10 +11,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -27,7 +27,7 @@
#ifndef DragState_h
#define DragState_h
-#include "DataTransfer.h"
+#include "Clipboard.h"
#include "DragActions.h"
#include "Element.h"
@@ -37,7 +37,7 @@ struct DragState {
RefPtr<Element> source; // Element that may be a drag source, for the current mouse gesture.
bool shouldDispatchEvents;
DragSourceAction type;
- RefPtr<DataTransfer> dataTransfer; // Used on only the source side of dragging.
+ RefPtr<Clipboard> clipboard; // Used on only the source side of dragging.
};
} // namespace WebCore
diff --git a/Source/WebCore/page/EditorClient.h b/Source/WebCore/page/EditorClient.h
index 3c53a5380..8623994e4 100644
--- a/Source/WebCore/page/EditorClient.h
+++ b/Source/WebCore/page/EditorClient.h
@@ -11,10 +11,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -35,7 +35,7 @@
#include <wtf/Forward.h>
#include <wtf/Vector.h>
-#if PLATFORM(COCOA)
+#if PLATFORM(MAC)
OBJC_CLASS NSAttributedString;
OBJC_CLASS NSString;
OBJC_CLASS NSURL;
@@ -55,7 +55,6 @@ class Element;
class Frame;
class HTMLElement;
class KeyboardEvent;
-class LayoutRect;
class Node;
class Range;
class SharedBuffer;
@@ -64,7 +63,6 @@ class TextCheckerClient;
class VisibleSelection;
class VisiblePosition;
-struct GapRects;
struct GrammarDetail;
class EditorClient {
@@ -88,22 +86,16 @@ public:
virtual bool shouldChangeSelectedRange(Range* fromRange, Range* toRange, EAffinity, bool stillSelecting) = 0;
virtual bool shouldApplyStyle(StyleProperties*, Range*) = 0;
- virtual void didApplyStyle() = 0;
virtual bool shouldMoveRangeAfterDelete(Range*, Range*) = 0;
virtual void didBeginEditing() = 0;
virtual void respondToChangedContents() = 0;
virtual void respondToChangedSelection(Frame*) = 0;
- virtual void didChangeSelectionAndUpdateLayout() = 0;
virtual void didEndEditing() = 0;
virtual void willWriteSelectionToPasteboard(Range*) = 0;
virtual void didWriteSelectionToPasteboard() = 0;
virtual void getClientPasteboardDataForRange(Range*, Vector<String>& pasteboardTypes, Vector<RefPtr<SharedBuffer>>& pasteboardData) = 0;
-
- // Notify an input method that a composition was voluntarily discarded by WebCore, so that it could clean up too.
- // This function is not called when a composition is closed per a request from an input method.
- virtual void discardedComposition(Frame*) = 0;
-
+
virtual void registerUndoStep(PassRefPtr<UndoStep>) = 0;
virtual void registerRedoStep(PassRefPtr<UndoStep>) = 0;
virtual void clearUndoRedoOperations() = 0;
@@ -125,9 +117,10 @@ public:
virtual bool doTextFieldCommandFromEvent(Element*, KeyboardEvent*) = 0;
virtual void textWillBeDeletedInTextField(Element*) = 0;
virtual void textDidChangeInTextArea(Element*) = 0;
- virtual void overflowScrollPositionChanged() = 0;
#if PLATFORM(IOS)
+ virtual void suppressSelectionNotifications() = 0;
+ virtual void restoreSelectionNotifications() = 0;
virtual void startDelayingAndCoalescingContentChangeNotifications() = 0;
virtual void stopDelayingAndCoalescingContentChangeNotifications() = 0;
virtual void writeDataToPasteboard(NSDictionary*) = 0;
@@ -140,7 +133,7 @@ public:
virtual int pasteboardChangeCount() = 0;
#endif
-#if PLATFORM(COCOA)
+#if PLATFORM(MAC)
virtual NSString* userVisibleString(NSURL*) = 0;
virtual DocumentFragment* documentFragmentFromAttributedString(NSAttributedString*, Vector< RefPtr<ArchiveResource>>&) = 0;
virtual void setInsertionPasteboard(const String& pasteboardName) = 0;
@@ -170,6 +163,10 @@ public:
virtual void toggleAutomaticSpellingCorrection() = 0;
#endif
+#if ENABLE(DELETION_UI)
+ virtual bool shouldShowDeleteInterface(HTMLElement*) = 0;
+#endif
+
#if PLATFORM(GTK)
virtual bool shouldShowUnicodeMenu() = 0;
#endif
diff --git a/Source/WebCore/page/EventHandler.cpp b/Source/WebCore/page/EventHandler.cpp
index 0fdd7766e..bf0f7631c 100644
--- a/Source/WebCore/page/EventHandler.cpp
+++ b/Source/WebCore/page/EventHandler.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006-2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2006-2015 Apple Inc. All rights reserved.
* Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org)
* Copyright (C) 2012 Digia Plc. and/or its subsidiary(-ies)
*
@@ -12,10 +12,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -66,22 +66,17 @@
#include "MouseEvent.h"
#include "MouseEventWithHitTestResults.h"
#include "Page.h"
-#include "PageOverlayController.h"
#include "PlatformEvent.h"
#include "PlatformKeyboardEvent.h"
#include "PlatformWheelEvent.h"
#include "PluginDocument.h"
#include "RenderFrameSet.h"
#include "RenderLayer.h"
-#include "RenderListBox.h"
-#include "RenderNamedFlowThread.h"
#include "RenderTextControlSingleLine.h"
#include "RenderView.h"
#include "RenderWidget.h"
#include "RuntimeApplicationChecks.h"
-#include "SVGDocument.h"
-#include "SVGNames.h"
-#include "ScrollLatchingState.h"
+#include "ScrollAnimator.h"
#include "Scrollbar.h"
#include "Settings.h"
#include "ShadowRoot.h"
@@ -91,35 +86,33 @@
#include "TextIterator.h"
#include "UserGestureIndicator.h"
#include "UserTypingGestureIndicator.h"
-#include "VisibleUnits.h"
#include "WheelEvent.h"
#include "WindowsKeyboardCodes.h"
#include <wtf/Assertions.h>
#include <wtf/CurrentTime.h>
-#include <wtf/NeverDestroyed.h>
#include <wtf/StdLibExtras.h>
#include <wtf/TemporaryChange.h>
#include <wtf/WeakPtr.h>
-#if ENABLE(CSS_IMAGE_SET)
-#include "StyleCachedImageSet.h"
+#if ENABLE(SVG)
+#include "SVGDocument.h"
+#include "SVGElementInstance.h"
+#include "SVGNames.h"
+#include "SVGUseElement.h"
#endif
+#if ENABLE(TOUCH_EVENTS)
#if ENABLE(IOS_TOUCH_EVENTS)
#include "PlatformTouchEventIOS.h"
+#else
+#include "PlatformTouchEvent.h"
#endif
-
-#if ENABLE(TOUCH_EVENTS)
#include "TouchEvent.h"
#include "TouchList.h"
#endif
-#if ENABLE(TOUCH_EVENTS) && !ENABLE(IOS_TOUCH_EVENTS)
-#include "PlatformTouchEvent.h"
-#endif
-
-#if ENABLE(MAC_GESTURE_EVENTS)
-#include "PlatformGestureEventMac.h"
+#if ENABLE(CSS_IMAGE_SET)
+#include "StyleCachedImageSet.h"
#endif
namespace WebCore {
@@ -136,7 +129,7 @@ const int TextDragHysteresis = 3;
const int GeneralDragHysteresis = 3;
#endif // ENABLE(DRAG_SUPPORT)
-#if ENABLE(IOS_GESTURE_EVENTS) || ENABLE(MAC_GESTURE_EVENTS)
+#if ENABLE(IOS_GESTURE_EVENTS)
const float GestureUnknown = 0;
#endif
@@ -149,16 +142,16 @@ const unsigned InvalidTouchIdentifier = 0;
// IE sends VK_PROCESSKEY which has value 229;
const int CompositionEventKeyCode = 229;
+#if ENABLE(SVG)
using namespace SVGNames;
+#endif
-#if !ENABLE(IOS_TOUCH_EVENTS)
// The amount of time to wait before sending a fake mouse event, triggered
// during a scroll. The short interval is used if the content responds to the mouse events
// in fakeMouseMoveDurationThreshold or less, otherwise the long interval is used.
const double fakeMouseMoveDurationThreshold = 0.01;
const double fakeMouseMoveShortInterval = 0.1;
const double fakeMouseMoveLongInterval = 0.25;
-#endif
#if ENABLE(CURSOR_SUPPORT)
// The amount of time to wait for a cursor update on style and layout changes
@@ -289,62 +282,16 @@ static inline ScrollGranularity wheelGranularityToScrollGranularity(unsigned del
}
}
-static inline bool didScrollInScrollableArea(ScrollableArea* scrollableArea, WheelEvent* wheelEvent)
+static inline bool scrollNode(float delta, ScrollGranularity granularity, ScrollDirection positiveDirection, ScrollDirection negativeDirection, Node* node, Element** stopElement, const IntPoint& wheelEventAbsolutePoint)
{
- ScrollGranularity scrollGranularity = wheelGranularityToScrollGranularity(wheelEvent->deltaMode());
- bool didHandleWheelEvent = false;
- if (float absoluteDelta = std::abs(wheelEvent->deltaX()))
- didHandleWheelEvent |= scrollableArea->scroll(wheelEvent->deltaX() > 0 ? ScrollRight : ScrollLeft, scrollGranularity, absoluteDelta);
-
- if (float absoluteDelta = std::abs(wheelEvent->deltaY()))
- didHandleWheelEvent |= scrollableArea->scroll(wheelEvent->deltaY() > 0 ? ScrollDown : ScrollUp, scrollGranularity, absoluteDelta);
-
- return didHandleWheelEvent;
-}
-
-static inline bool handleWheelEventInAppropriateEnclosingBox(Node* startNode, WheelEvent* wheelEvent, Element** stopElement, const FloatSize& filteredPlatformDelta)
-{
- bool shouldHandleEvent = wheelEvent->deltaX() || wheelEvent->deltaY();
-#if PLATFORM(MAC)
- shouldHandleEvent |= wheelEvent->phase() == PlatformWheelEventPhaseEnded;
-#if ENABLE(CSS_SCROLL_SNAP)
- shouldHandleEvent |= wheelEvent->momentumPhase() == PlatformWheelEventPhaseEnded;
-#endif
-#endif
- if (!startNode->renderer() || !shouldHandleEvent)
+ if (!delta)
return false;
+ if (!node->renderer())
+ return false;
+ RenderBox* enclosingBox = node->renderer()->enclosingBox();
+ float absDelta = delta > 0 ? delta : -delta;
- RenderBox& initialEnclosingBox = startNode->renderer()->enclosingBox();
- if (initialEnclosingBox.isListBox())
- return didScrollInScrollableArea(static_cast<RenderListBox*>(&initialEnclosingBox), wheelEvent);
-
- RenderBox* currentEnclosingBox = &initialEnclosingBox;
- while (currentEnclosingBox) {
- if (RenderLayer* boxLayer = currentEnclosingBox->layer()) {
- const PlatformWheelEvent* platformEvent = wheelEvent->wheelEvent();
- bool scrollingWasHandled;
- if (platformEvent != nullptr)
- scrollingWasHandled = boxLayer->handleWheelEvent(platformEvent->copyWithDeltas(filteredPlatformDelta.width(), filteredPlatformDelta.height()));
- else
- scrollingWasHandled = didScrollInScrollableArea(boxLayer, wheelEvent);
-
- if (scrollingWasHandled) {
- if (stopElement)
- *stopElement = currentEnclosingBox->element();
- return true;
- }
- }
-
- if (stopElement && *stopElement && *stopElement == currentEnclosingBox->element())
- return true;
-
- currentEnclosingBox = currentEnclosingBox->containingBlock();
- if (currentEnclosingBox && currentEnclosingBox->isRenderNamedFlowThread())
- currentEnclosingBox = RenderNamedFlowThread::fragmentFromRenderBoxAsRenderBlock(currentEnclosingBox, roundedIntPoint(wheelEvent->absoluteLocation()), initialEnclosingBox);
- if (!currentEnclosingBox || currentEnclosingBox->isRenderView())
- return false;
- }
- return false;
+ return enclosingBox->scroll(delta < 0 ? negativeDirection : positiveDirection, granularity, absDelta, stopElement, enclosingBox, wheelEventAbsolutePoint);
}
#if (ENABLE(TOUCH_EVENTS) && !PLATFORM(IOS))
@@ -357,7 +304,7 @@ static inline bool shouldGesturesTriggerActive()
}
#endif
-#if !PLATFORM(COCOA)
+#if !PLATFORM(MAC)
inline bool EventHandler::eventLoopHandleMouseUp(const MouseEventWithHitTestResults&)
{
@@ -375,25 +322,67 @@ inline bool EventHandler::eventLoopHandleMouseDragged(const MouseEventWithHitTes
EventHandler::EventHandler(Frame& frame)
: m_frame(frame)
- , m_hoverTimer(*this, &EventHandler::hoverTimerFired)
+ , m_mousePressed(false)
+ , m_capturesDragging(false)
+ , m_mouseDownMayStartSelect(false)
+#if ENABLE(DRAG_SUPPORT)
+ , m_mouseDownMayStartDrag(false)
+ , m_dragMayStartSelectionInstead(false)
+#endif
+ , m_mouseDownWasSingleClickInSelection(false)
+ , m_selectionInitiationState(HaveNotStartedSelection)
+ , m_hoverTimer(this, &EventHandler::hoverTimerFired)
#if ENABLE(CURSOR_SUPPORT)
- , m_cursorUpdateTimer(*this, &EventHandler::cursorUpdateTimerFired)
+ , m_cursorUpdateTimer(this, &EventHandler::cursorUpdateTimerFired)
+#endif
+ , m_autoscrollController(adoptPtr(new AutoscrollController))
+ , m_mouseDownMayStartAutoscroll(false)
+ , m_mouseDownWasInSubframe(false)
+ , m_fakeMouseMoveEventTimer(this, &EventHandler::fakeMouseMoveEventTimerFired)
+#if ENABLE(SVG)
+ , m_svgPan(false)
+#endif
+ , m_resizeLayer(0)
+ , m_eventHandlerWillResetCapturingMouseEventsElement(nullptr)
+ , m_clickCount(0)
+#if ENABLE(IOS_GESTURE_EVENTS)
+ , m_gestureInitialDiameter(GestureUnknown)
+ , m_gestureLastDiameter(GestureUnknown)
+ , m_gestureInitialRotation(GestureUnknown)
+ , m_gestureLastRotation(GestureUnknown)
#endif
- , m_autoscrollController(std::make_unique<AutoscrollController>())
-#if !ENABLE(IOS_TOUCH_EVENTS)
- , m_fakeMouseMoveEventTimer(*this, &EventHandler::fakeMouseMoveEventTimerFired)
+#if ENABLE(IOS_TOUCH_EVENTS)
+ , m_firstTouchID(InvalidTouchIdentifier)
#endif
+ , m_mousePositionIsUnknown(true)
+ , m_mouseDownTimestamp(0)
+ , m_inTrackingScrollGesturePhase(false)
+ , m_widgetIsLatched(false)
+#if PLATFORM(MAC)
+ , m_mouseDownView(nil)
+ , m_sendingEventToSubview(false)
+#if !PLATFORM(IOS)
+ , m_activationEventNumber(-1)
+#endif // !PLATFORM(IOS)
+#endif
+#if ENABLE(TOUCH_EVENTS) && !ENABLE(IOS_TOUCH_EVENTS)
+ , m_originatingTouchPointTargetKey(0)
+ , m_touchPressed(false)
+#endif
+ , m_maxMouseMovedDuration(0)
+ , m_baseEventType(PlatformEvent::NoType)
+ , m_didStartDrag(false)
+ , m_didLongPressInvokeContextMenu(false)
+ , m_isHandlingWheelEvent(false)
#if ENABLE(CURSOR_VISIBILITY)
- , m_autoHideCursorTimer(*this, &EventHandler::autoHideCursorTimerFired)
+ , m_autoHideCursorTimer(this, &EventHandler::autoHideCursorTimerFired)
#endif
{
}
EventHandler::~EventHandler()
{
-#if !ENABLE(IOS_TOUCH_EVENTS)
ASSERT(!m_fakeMouseMoveEventTimer.isActive());
-#endif
#if ENABLE(CURSOR_VISIBILITY)
ASSERT(!m_autoHideCursorTimer.isActive());
#endif
@@ -402,7 +391,7 @@ EventHandler::~EventHandler()
#if ENABLE(DRAG_SUPPORT)
DragState& EventHandler::dragState()
{
- static NeverDestroyed<DragState> state;
+ DEFINE_STATIC_LOCAL(DragState, state, ());
return state;
}
#endif // ENABLE(DRAG_SUPPORT)
@@ -413,60 +402,62 @@ void EventHandler::clear()
#if ENABLE(CURSOR_SUPPORT)
m_cursorUpdateTimer.stop();
#endif
-#if !ENABLE(IOS_TOUCH_EVENTS)
m_fakeMouseMoveEventTimer.stop();
-#endif
#if ENABLE(CURSOR_VISIBILITY)
cancelAutoHideCursorTimer();
#endif
- m_resizeLayer = nullptr;
+ m_resizeLayer = 0;
m_elementUnderMouse = nullptr;
m_lastElementUnderMouse = nullptr;
- m_lastMouseMoveEventSubframe = nullptr;
+#if ENABLE(SVG)
+ m_instanceUnderMouse = 0;
+ m_lastInstanceUnderMouse = 0;
+#endif
+ m_lastMouseMoveEventSubframe = 0;
m_lastScrollbarUnderMouse = nullptr;
m_clickCount = 0;
- m_clickNode = nullptr;
+ m_clickNode = 0;
#if ENABLE(IOS_GESTURE_EVENTS)
- m_gestureInitialRotation = GestureUnknown;
-#endif
-#if ENABLE(IOS_GESTURE_EVENTS) || ENABLE(MAC_GESTURE_EVENTS)
m_gestureInitialDiameter = GestureUnknown;
m_gestureLastDiameter = GestureUnknown;
+ m_gestureInitialRotation = GestureUnknown;
m_gestureLastRotation = GestureUnknown;
m_gestureTargets.clear();
#endif
#if ENABLE(IOS_TOUCH_EVENTS)
m_touches.clear();
m_firstTouchID = InvalidTouchIdentifier;
- m_touchEventTargetSubframe = nullptr;
+ m_touchEventTargetSubframe = 0;
#endif
- m_frameSetBeingResized = nullptr;
+ m_frameSetBeingResized = 0;
#if ENABLE(DRAG_SUPPORT)
- m_dragTarget = nullptr;
+ m_dragTarget = 0;
m_shouldOnlyFireDragOverEvent = false;
#endif
m_mousePositionIsUnknown = true;
m_lastKnownMousePosition = IntPoint();
m_lastKnownMouseGlobalPosition = IntPoint();
- m_mousePressNode = nullptr;
+ m_mousePressNode = 0;
m_mousePressed = false;
m_capturesDragging = false;
m_capturingMouseEventsElement = nullptr;
- clearLatchedState();
+ m_latchedWheelEventElement = nullptr;
+ m_previousWheelScrolledElement = nullptr;
#if ENABLE(TOUCH_EVENTS) && !ENABLE(IOS_TOUCH_EVENTS)
m_originatingTouchPointTargets.clear();
- m_originatingTouchPointDocument = nullptr;
+ m_originatingTouchPointDocument.clear();
m_originatingTouchPointTargetKey = 0;
#endif
m_maxMouseMovedDuration = 0;
m_baseEventType = PlatformEvent::NoType;
m_didStartDrag = false;
+ m_didLongPressInvokeContextMenu = false;
}
-void EventHandler::nodeWillBeRemoved(Node& nodeToBeRemoved)
+void EventHandler::nodeWillBeRemoved(Node* nodeToBeRemoved)
{
- if (nodeToBeRemoved.contains(m_clickNode.get()))
- m_clickNode = nullptr;
+ if (nodeToBeRemoved->contains(m_clickNode.get()))
+ m_clickNode = 0;
}
static void setSelectionIfNeeded(FrameSelection& selection, const VisibleSelection& newSelection)
@@ -483,30 +474,22 @@ static inline bool dispatchSelectStart(Node* node)
return node->dispatchEvent(Event::create(eventNames().selectstartEvent, true, true));
}
-static Node* nodeToSelectOnMouseDownForNode(Node& targetNode)
+static VisibleSelection expandSelectionToRespectUserSelectAll(Node* targetNode, const VisibleSelection& selection)
{
#if ENABLE(USERSELECT_ALL)
- if (Node* rootUserSelectAll = Position::rootUserSelectAllForNode(&targetNode))
- return rootUserSelectAll;
-#endif
-
- if (targetNode.shouldSelectOnMouseDown())
- return &targetNode;
-
- return nullptr;
-}
-
-static VisibleSelection expandSelectionToRespectSelectOnMouseDown(Node& targetNode, const VisibleSelection& selection)
-{
- Node* nodeToSelect = nodeToSelectOnMouseDownForNode(targetNode);
- if (!nodeToSelect)
+ Node* rootUserSelectAll = Position::rootUserSelectAllForNode(targetNode);
+ if (!rootUserSelectAll)
return selection;
VisibleSelection newSelection(selection);
- newSelection.setBase(positionBeforeNode(nodeToSelect).upstream(CanCrossEditingBoundary));
- newSelection.setExtent(positionAfterNode(nodeToSelect).downstream(CanCrossEditingBoundary));
+ newSelection.setBase(positionBeforeNode(rootUserSelectAll).upstream(CanCrossEditingBoundary));
+ newSelection.setExtent(positionAfterNode(rootUserSelectAll).downstream(CanCrossEditingBoundary));
return newSelection;
+#else
+ UNUSED_PARAM(targetNode);
+ return selection;
+#endif
}
bool EventHandler::updateSelectionForMouseDownDispatchingSelectStart(Node* targetNode, const VisibleSelection& selection, TextGranularity granularity)
@@ -524,7 +507,7 @@ bool EventHandler::updateSelectionForMouseDownDispatchingSelectStart(Node* targe
m_selectionInitiationState = PlacedCaret;
}
- m_frame.selection().setSelectionByMouseIfDifferent(selection, granularity);
+ m_frame.selection().setNonDirectionalSelectionIfNeeded(selection, granularity);
return true;
}
@@ -535,7 +518,7 @@ void EventHandler::selectClosestWordFromHitTestResult(const HitTestResult& resul
VisibleSelection newSelection;
if (targetNode && targetNode->renderer()) {
- VisiblePosition pos(targetNode->renderer()->positionForPoint(result.localPoint(), nullptr));
+ VisiblePosition pos(targetNode->renderer()->positionForPoint(result.localPoint()));
if (pos.isNotNull()) {
newSelection = VisibleSelection(pos);
newSelection.expandUsingGranularity(WordGranularity);
@@ -544,73 +527,33 @@ void EventHandler::selectClosestWordFromHitTestResult(const HitTestResult& resul
if (appendTrailingWhitespace == ShouldAppendTrailingWhitespace && newSelection.isRange())
newSelection.appendTrailingWhitespace();
- updateSelectionForMouseDownDispatchingSelectStart(targetNode, expandSelectionToRespectSelectOnMouseDown(*targetNode, newSelection), WordGranularity);
+ updateSelectionForMouseDownDispatchingSelectStart(targetNode, expandSelectionToRespectUserSelectAll(targetNode, newSelection), WordGranularity);
}
}
-static AppendTrailingWhitespace shouldAppendTrailingWhitespace(const MouseEventWithHitTestResults& result, const Frame& frame)
-{
- return (result.event().clickCount() == 2 && frame.editor().isSelectTrailingWhitespaceEnabled()) ? ShouldAppendTrailingWhitespace : DontAppendTrailingWhitespace;
-}
-
void EventHandler::selectClosestWordFromMouseEvent(const MouseEventWithHitTestResults& result)
{
- if (m_mouseDownMayStartSelect)
- selectClosestWordFromHitTestResult(result.hitTestResult(), shouldAppendTrailingWhitespace(result, m_frame));
-}
-
-#if !PLATFORM(MAC)
-VisibleSelection EventHandler::selectClosestWordFromHitTestResultBasedOnLookup(const HitTestResult&)
-{
- return VisibleSelection();
-}
-#endif
-
-void EventHandler::selectClosestContextualWordFromMouseEvent(const MouseEventWithHitTestResults& mouseEvent)
-{
- Node* targetNode = mouseEvent.targetNode();
- const HitTestResult& result = mouseEvent.hitTestResult();
- VisibleSelection newSelection;
- bool appendTrailingWhitespace = shouldAppendTrailingWhitespace(mouseEvent, m_frame);
-
- if (targetNode && targetNode->renderer()) {
- newSelection = selectClosestWordFromHitTestResultBasedOnLookup(result);
- if (newSelection.isNone()) {
- VisiblePosition pos(targetNode->renderer()->positionForPoint(result.localPoint(), nullptr));
- if (pos.isNotNull()) {
- newSelection = VisibleSelection(pos);
- newSelection.expandUsingGranularity(WordGranularity);
- }
- }
-
- if (appendTrailingWhitespace == ShouldAppendTrailingWhitespace && newSelection.isRange())
- newSelection.appendTrailingWhitespace();
-
- updateSelectionForMouseDownDispatchingSelectStart(targetNode, expandSelectionToRespectSelectOnMouseDown(*targetNode, newSelection), WordGranularity);
+ if (m_mouseDownMayStartSelect) {
+ selectClosestWordFromHitTestResult(result.hitTestResult(),
+ (result.event().clickCount() == 2 && m_frame.editor().isSelectTrailingWhitespaceEnabled()) ? ShouldAppendTrailingWhitespace : DontAppendTrailingWhitespace);
}
}
-
-void EventHandler::selectClosestContextualWordOrLinkFromMouseEvent(const MouseEventWithHitTestResults& result)
-{
- Element* urlElement = result.hitTestResult().URLElement();
- if (!urlElement || !isDraggableLink(*urlElement)) {
- if (Node* targetNode = result.targetNode()) {
- if (isEditableNode(*targetNode))
- return selectClosestWordFromMouseEvent(result);
- }
- return selectClosestContextualWordFromMouseEvent(result);
- }
+void EventHandler::selectClosestWordOrLinkFromMouseEvent(const MouseEventWithHitTestResults& result)
+{
+ if (!result.hitTestResult().isLiveLink())
+ return selectClosestWordFromMouseEvent(result);
Node* targetNode = result.targetNode();
if (targetNode && targetNode->renderer() && m_mouseDownMayStartSelect) {
VisibleSelection newSelection;
- VisiblePosition pos(targetNode->renderer()->positionForPoint(result.localPoint(), nullptr));
- if (pos.isNotNull() && pos.deepEquivalent().deprecatedNode()->isDescendantOf(urlElement))
- newSelection = VisibleSelection::selectionFromContentsOfNode(urlElement);
+ Element* URLElement = result.hitTestResult().URLElement();
+ VisiblePosition pos(targetNode->renderer()->positionForPoint(result.localPoint()));
+ if (pos.isNotNull() && pos.deepEquivalent().deprecatedNode()->isDescendantOf(URLElement))
+ newSelection = VisibleSelection::selectionFromContentsOfNode(URLElement);
- updateSelectionForMouseDownDispatchingSelectStart(targetNode, expandSelectionToRespectSelectOnMouseDown(*targetNode, newSelection), WordGranularity);
+ updateSelectionForMouseDownDispatchingSelectStart(targetNode, expandSelectionToRespectUserSelectAll(targetNode, newSelection), WordGranularity);
}
}
@@ -642,13 +585,13 @@ bool EventHandler::handleMousePressEventTripleClick(const MouseEventWithHitTestR
return false;
VisibleSelection newSelection;
- VisiblePosition pos(targetNode->renderer()->positionForPoint(event.localPoint(), nullptr));
+ VisiblePosition pos(targetNode->renderer()->positionForPoint(event.localPoint()));
if (pos.isNotNull()) {
newSelection = VisibleSelection(pos);
newSelection.expandUsingGranularity(ParagraphGranularity);
}
- return updateSelectionForMouseDownDispatchingSelectStart(targetNode, expandSelectionToRespectSelectOnMouseDown(*targetNode, newSelection), ParagraphGranularity);
+ return updateSelectionForMouseDownDispatchingSelectStart(targetNode, expandSelectionToRespectUserSelectAll(targetNode, newSelection), ParagraphGranularity);
}
static int textDistance(const Position& start, const Position& end)
@@ -677,7 +620,7 @@ bool EventHandler::handleMousePressEventSingleClick(const MouseEventWithHitTestR
}
}
- VisiblePosition visiblePos(targetNode->renderer()->positionForPoint(event.localPoint(), nullptr));
+ VisiblePosition visiblePos(targetNode->renderer()->positionForPoint(event.localPoint()));
if (visiblePos.isNull())
visiblePos = VisiblePosition(firstPositionInOrBeforeNode(targetNode), DOWNSTREAM);
Position pos = visiblePos.deepEquivalent();
@@ -686,7 +629,7 @@ bool EventHandler::handleMousePressEventSingleClick(const MouseEventWithHitTestR
TextGranularity granularity = CharacterGranularity;
if (extendSelection && newSelection.isCaretOrRange()) {
- VisibleSelection selectionInUserSelectAll = expandSelectionToRespectSelectOnMouseDown(*targetNode, VisibleSelection(pos));
+ VisibleSelection selectionInUserSelectAll = expandSelectionToRespectUserSelectAll(targetNode, VisibleSelection(pos));
if (selectionInUserSelectAll.isRange()) {
if (comparePositions(selectionInUserSelectAll.start(), newSelection.start()) < 0)
pos = selectionInUserSelectAll.start();
@@ -713,7 +656,7 @@ bool EventHandler::handleMousePressEventSingleClick(const MouseEventWithHitTestR
newSelection.expandUsingGranularity(m_frame.selection().granularity());
}
} else
- newSelection = expandSelectionToRespectSelectOnMouseDown(*targetNode, visiblePos);
+ newSelection = expandSelectionToRespectUserSelectAll(targetNode, visiblePos);
bool handled = updateSelectionForMouseDownDispatchingSelectStart(targetNode, newSelection, granularity);
@@ -736,12 +679,10 @@ bool EventHandler::handleMousePressEvent(const MouseEventWithHitTestResults& eve
{
#if ENABLE(DRAG_SUPPORT)
// Reset drag state.
- dragState().source = nullptr;
+ dragState().source = 0;
#endif
-#if !ENABLE(IOS_TOUCH_EVENTS)
cancelFakeMouseMoveEvent();
-#endif
m_frame.document()->updateLayoutIgnorePendingStylesheets();
@@ -758,31 +699,26 @@ bool EventHandler::handleMousePressEvent(const MouseEventWithHitTestResults& eve
#if ENABLE(DRAG_SUPPORT)
// Careful that the drag starting logic stays in sync with eventMayStartDrag()
- // FIXME: eventMayStartDrag() does not check for shift key press, link or image event targets.
- // Bug: https://bugs.webkit.org/show_bug.cgi?id=155390
-
- // Single mouse down on links or images can always trigger drag-n-drop.
- bool isMouseDownOnLinkOrImage = event.isOverLink() || event.hitTestResult().image();
- m_mouseDownMayStartDrag = singleClick && (!event.event().shiftKey() || isMouseDownOnLinkOrImage);
+ m_mouseDownMayStartDrag = singleClick;
#endif
m_mouseDownWasSingleClickInSelection = false;
m_mouseDown = event.event();
- if (m_immediateActionStage != ImmediateActionStage::PerformedHitTest)
- m_immediateActionStage = ImmediateActionStage::None;
-
if (event.isOverWidget() && passWidgetMouseDownEventToWidget(event))
return true;
- if (is<SVGDocument>(*m_frame.document()) && downcast<SVGDocument>(*m_frame.document()).zoomAndPanEnabled()) {
+#if ENABLE(SVG)
+ if (m_frame.document()->isSVGDocument()
+ && toSVGDocument(m_frame.document())->zoomAndPanEnabled()) {
if (event.event().shiftKey() && singleClick) {
m_svgPan = true;
- downcast<SVGDocument>(*m_frame.document()).startPan(m_frame.view()->windowToContents(event.event().position()));
+ toSVGDocument(m_frame.document())->startPan(m_frame.view()->windowToContents(event.event().position()));
return true;
}
}
+#endif
// We don't do this at the start of mouse down handling,
// because we don't want to do it until we know we didn't hit a widget.
@@ -835,7 +771,7 @@ bool EventHandler::handleMouseDraggedEvent(const MouseEventWithHitTestResults& e
return false;
}
-#if PLATFORM(COCOA) // FIXME: Why does this assertion fire on other platforms?
+#if PLATFORM(MAC) // FIXME: Why does this assertion fire on other platforms?
ASSERT(m_mouseDownMayStartSelect || m_mouseDownMayStartAutoscroll);
#endif
@@ -847,8 +783,9 @@ bool EventHandler::handleMouseDraggedEvent(const MouseEventWithHitTestResults& e
}
if (m_selectionInitiationState != ExtendedSelection) {
+ HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::DisallowShadowContent);
HitTestResult result(m_mouseDownPos);
- m_frame.document()->renderView()->hitTest(HitTestRequest(), result);
+ m_frame.document()->renderView()->hitTest(request, result);
updateSelectionForMouseDrag(result);
}
@@ -861,13 +798,13 @@ bool EventHandler::eventMayStartDrag(const PlatformMouseEvent& event) const
// This is a pre-flight check of whether the event might lead to a drag being started. Be careful
// that its logic needs to stay in sync with handleMouseMoveEvent() and the way we setMouseDownMayStartDrag
// in handleMousePressEvent
- RenderView* renderView = m_frame.contentRenderer();
- if (!renderView)
+
+ if (!m_frame.contentRenderer() || !m_frame.contentRenderer()->hasLayer())
return false;
if (event.button() != LeftButton || event.clickCount() != 1)
return false;
-
+
FrameView* view = m_frame.view();
if (!view)
return false;
@@ -879,7 +816,7 @@ bool EventHandler::eventMayStartDrag(const PlatformMouseEvent& event) const
updateDragSourceActionsAllowed();
HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::DisallowShadowContent);
HitTestResult result(view->windowToContents(event.position()));
- renderView->hitTest(request, result);
+ m_frame.contentRenderer()->hitTest(request, result);
DragState state;
return result.innerElement() && page->dragController().draggableElement(&m_frame, result.innerElement(), result.roundedPointInInnerNodeFrame(), state);
}
@@ -889,19 +826,19 @@ void EventHandler::updateSelectionForMouseDrag()
FrameView* view = m_frame.view();
if (!view)
return;
- RenderView* renderView = m_frame.contentRenderer();
- if (!renderView)
+ RenderView* renderer = m_frame.contentRenderer();
+ if (!renderer)
return;
HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::Move | HitTestRequest::DisallowShadowContent);
HitTestResult result(view->windowToContents(m_lastKnownMousePosition));
- renderView->hitTest(request, result);
+ renderer->hitTest(request, result);
updateSelectionForMouseDrag(result);
}
static VisiblePosition selectionExtentRespectingEditingBoundary(const VisibleSelection& selection, const LayoutPoint& localPoint, Node* targetNode)
{
- FloatPoint selectionEndPoint = localPoint;
+ LayoutPoint selectionEndPoint = localPoint;
Element* editableElement = selection.rootEditableElement();
if (!targetNode->renderer())
@@ -912,11 +849,11 @@ static VisiblePosition selectionExtentRespectingEditingBoundary(const VisibleSel
return VisiblePosition();
FloatPoint absolutePoint = targetNode->renderer()->localToAbsolute(FloatPoint(selectionEndPoint));
- selectionEndPoint = editableElement->renderer()->absoluteToLocal(absolutePoint);
+ selectionEndPoint = roundedLayoutPoint(editableElement->renderer()->absoluteToLocal(absolutePoint));
targetNode = editableElement;
}
- return targetNode->renderer()->positionForPoint(LayoutPoint(selectionEndPoint), nullptr);
+ return targetNode->renderer()->positionForPoint(selectionEndPoint);
}
void EventHandler::updateSelectionForMouseDrag(const HitTestResult& hitTestResult)
@@ -938,6 +875,7 @@ void EventHandler::updateSelectionForMouseDrag(const HitTestResult& hitTestResul
// done in handleMousePressEvent, but not if the mouse press was on an existing selection.
VisibleSelection newSelection = m_frame.selection().selection();
+#if ENABLE(SVG)
// Special case to limit selection to the containing block for SVG text.
// FIXME: Isn't there a better non-SVG-specific way to do this?
if (Node* selectionBaseNode = newSelection.base().deprecatedNode())
@@ -945,6 +883,7 @@ void EventHandler::updateSelectionForMouseDrag(const HitTestResult& hitTestResul
if (selectionBaseRenderer->isSVGText())
if (target->renderer()->containingBlock() != selectionBaseRenderer->containingBlock())
return;
+#endif
if (m_selectionInitiationState == HaveNotStartedSelection && !dispatchSelectStart(target))
return;
@@ -962,11 +901,11 @@ void EventHandler::updateSelectionForMouseDrag(const HitTestResult& hitTestResul
newSelection.setExtent(positionAfterNode(rootUserSelectAllForMousePressNode).downstream(CanCrossEditingBoundary));
} else {
// Reset base for user select all when base is inside user-select-all area and extent < base.
- if (rootUserSelectAllForMousePressNode && comparePositions(target->renderer()->positionForPoint(hitTestResult.localPoint(), nullptr), m_mousePressNode->renderer()->positionForPoint(m_dragStartPos, nullptr)) < 0)
+ if (rootUserSelectAllForMousePressNode && comparePositions(target->renderer()->positionForPoint(hitTestResult.localPoint()), m_mousePressNode->renderer()->positionForPoint(m_dragStartPos)) < 0)
newSelection.setBase(positionAfterNode(rootUserSelectAllForMousePressNode).downstream(CanCrossEditingBoundary));
Node* rootUserSelectAllForTarget = Position::rootUserSelectAllForNode(target);
- if (rootUserSelectAllForTarget && m_mousePressNode->renderer() && comparePositions(target->renderer()->positionForPoint(hitTestResult.localPoint(), nullptr), m_mousePressNode->renderer()->positionForPoint(m_dragStartPos, nullptr)) < 0)
+ if (rootUserSelectAllForTarget && m_mousePressNode->renderer() && comparePositions(target->renderer()->positionForPoint(hitTestResult.localPoint()), m_mousePressNode->renderer()->positionForPoint(m_dragStartPos)) < 0)
newSelection.setExtent(positionBeforeNode(rootUserSelectAllForTarget).upstream(CanCrossEditingBoundary));
else if (rootUserSelectAllForTarget && m_mousePressNode->renderer())
newSelection.setExtent(positionAfterNode(rootUserSelectAllForTarget).downstream(CanCrossEditingBoundary));
@@ -980,7 +919,7 @@ void EventHandler::updateSelectionForMouseDrag(const HitTestResult& hitTestResul
if (m_frame.selection().granularity() != CharacterGranularity)
newSelection.expandUsingGranularity(m_frame.selection().granularity());
- m_frame.selection().setSelectionByMouseIfDifferent(newSelection, m_frame.selection().granularity(),
+ m_frame.selection().setNonDirectionalSelectionIfNeeded(newSelection, m_frame.selection().granularity(),
FrameSelection::AdjustEndpointsAtBidiBoundary);
}
#endif // ENABLE(DRAG_SUPPORT)
@@ -1038,7 +977,7 @@ bool EventHandler::handleMouseReleaseEvent(const MouseEventWithHitTestResults& e
Node* node = event.targetNode();
bool caretBrowsing = m_frame.settings().caretBrowsingEnabled();
if (node && node->renderer() && (caretBrowsing || node->hasEditableStyle())) {
- VisiblePosition pos = node->renderer()->positionForPoint(event.localPoint(), nullptr);
+ VisiblePosition pos = node->renderer()->positionForPoint(event.localPoint());
newSelection = VisibleSelection(pos);
}
@@ -1047,6 +986,10 @@ bool EventHandler::handleMouseReleaseEvent(const MouseEventWithHitTestResults& e
handled = true;
}
+ m_frame.selection().updateSelectionCachesIfSelectionIsInsideTextFormControl(UserTriggered);
+
+ m_frame.selection().selectFrameElementInParentIfFullySelected();
+
if (event.event().button() == MiddleButton) {
// Ignore handled, since we want to paste to where the caret was placed anyway.
handled = handlePasteGlobalSelection(event.event()) || handled;
@@ -1070,9 +1013,9 @@ void EventHandler::didPanScrollStop()
void EventHandler::startPanScrolling(RenderElement* renderer)
{
#if !PLATFORM(IOS)
- if (!is<RenderBox>(*renderer))
+ if (!renderer->isBox())
return;
- m_autoscrollController->startPanScrolling(downcast<RenderBox>(renderer), lastKnownMousePosition());
+ m_autoscrollController->startPanScrolling(toRenderBox(renderer), lastKnownMousePosition());
invalidateClick();
#endif
}
@@ -1130,15 +1073,12 @@ HitTestResult EventHandler::hitTestResultAtPoint(const LayoutPoint& point, HitTe
HitTestResult result(point, padding.height(), padding.width(), padding.height(), padding.width());
- RenderView* renderView = m_frame.contentRenderer();
- if (!renderView)
+ if (!m_frame.contentRenderer())
return result;
-
- // We should always start hittesting a clean tree.
- renderView->document().updateLayoutIgnorePendingStylesheets();
+
// hitTestResultAtPoint is specifically used to hitTest into all frames, thus it always allows child frame content.
HitTestRequest request(hitType | HitTestRequest::AllowChildFrameContent);
- renderView->hitTest(request, result);
+ m_frame.contentRenderer()->hitTest(request, result);
if (!request.readOnly())
m_frame.document()->updateHoverActiveState(request, result.innerElement());
@@ -1153,6 +1093,16 @@ void EventHandler::stopAutoscrollTimer(bool rendererIsBeingDestroyed)
m_autoscrollController->stopAutoscrollTimer(rendererIsBeingDestroyed);
}
+Node* EventHandler::mousePressNode() const
+{
+ return m_mousePressNode.get();
+}
+
+void EventHandler::setMousePressNode(PassRefPtr<Node> node)
+{
+ m_mousePressNode = node;
+}
+
bool EventHandler::scrollOverflow(ScrollDirection direction, ScrollGranularity granularity, Node* startingNode)
{
Node* node = startingNode;
@@ -1165,7 +1115,7 @@ bool EventHandler::scrollOverflow(ScrollDirection direction, ScrollGranularity g
if (node) {
auto r = node->renderer();
- if (r && !r->isListBox() && r->enclosingBox().scroll(direction, granularity)) {
+ if (r && !r->isListBox() && r->enclosingBox()->scroll(direction, granularity)) {
setFrameWasScrolledByUser();
return true;
}
@@ -1186,7 +1136,7 @@ bool EventHandler::logicalScrollOverflow(ScrollLogicalDirection direction, Scrol
if (node) {
auto r = node->renderer();
- if (r && !r->isListBox() && r->enclosingBox().logicalScroll(direction, granularity)) {
+ if (r && !r->isListBox() && r->enclosingBox()->logicalScroll(direction, granularity)) {
setFrameWasScrolledByUser();
return true;
}
@@ -1223,7 +1173,7 @@ bool EventHandler::logicalScrollRecursively(ScrollLogicalDirection direction, Sc
FrameView* view = frame->view();
bool scrolled = false;
-#if PLATFORM(COCOA)
+#if PLATFORM(MAC)
// Mac also resets the scroll position in the inline direction.
if (granularity == ScrollByDocument && view && view->logicalScroll(ScrollInlineDirectionBackward, ScrollByDocument))
scrolled = true;
@@ -1256,29 +1206,29 @@ Frame* EventHandler::subframeForHitTestResult(const MouseEventWithHitTestResults
Frame* EventHandler::subframeForTargetNode(Node* node)
{
if (!node)
- return nullptr;
+ return 0;
auto renderer = node->renderer();
- if (!is<RenderWidget>(renderer))
- return nullptr;
+ if (!renderer || !renderer->isWidget())
+ return 0;
- Widget* widget = downcast<RenderWidget>(*renderer).widget();
- if (!is<FrameView>(widget))
- return nullptr;
+ Widget* widget = toRenderWidget(renderer)->widget();
+ if (!widget || !widget->isFrameView())
+ return 0;
- return &downcast<FrameView>(*widget).frame();
+ return &toFrameView(widget)->frame();
}
#if ENABLE(CURSOR_SUPPORT)
static bool isSubmitImage(Node* node)
{
- return is<HTMLInputElement>(node) && downcast<HTMLInputElement>(*node).isImageButton();
+ return node && isHTMLInputElement(node) && toHTMLInputElement(node)->isImageButton();
}
// Returns true if the node's editable block is not current focused for editing
static bool nodeIsNotBeingEdited(const Node& node, const Frame& frame)
{
- return frame.selection().selection().rootEditableElement() != node.rootEditableElement();
+ return frame.selection().rootEditableElement() != node.rootEditableElement();
}
bool EventHandler::useHandCursor(Node* node, bool isOverLink, bool shiftKey)
@@ -1315,7 +1265,7 @@ bool EventHandler::useHandCursor(Node* node, bool isOverLink, bool shiftKey)
return ((isOverLink || isSubmitImage(node)) && (!editable || editableLinkEnabled));
}
-void EventHandler::cursorUpdateTimerFired()
+void EventHandler::cursorUpdateTimerFired(Timer<EventHandler>&)
{
ASSERT(m_frame.document());
updateCursor();
@@ -1343,7 +1293,9 @@ void EventHandler::updateCursor()
bool metaKey;
PlatformKeyboardEvent::getCurrentModifierState(shiftKey, ctrlKey, altKey, metaKey);
- HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::AllowFrameScrollbars);
+ m_frame.document()->updateLayout();
+
+ HitTestRequest request(HitTestRequest::ReadOnly);
HitTestResult result(view->windowToContents(m_lastKnownMousePosition));
renderView->hitTest(request, result);
@@ -1367,14 +1319,6 @@ OptionalCursor EventHandler::selectCursor(const HitTestResult& result, bool shif
return NoCursorChange;
#endif
- // Use always pointer cursor for scrollbars.
- if (result.scrollbar()) {
-#if ENABLE(CURSOR_VISIBILITY)
- cancelAutoHideCursorTimer();
-#endif
- return pointerCursor();
- }
-
Node* node = result.targetNode();
if (!node)
return NoCursorChange;
@@ -1385,9 +1329,10 @@ OptionalCursor EventHandler::selectCursor(const HitTestResult& result, bool shif
const Cursor& iBeam = horizontalText ? iBeamCursor() : verticalTextCursor();
#if ENABLE(CURSOR_VISIBILITY)
- if (style && style->cursorVisibility() == CursorVisibilityAutoHide)
+ if (style && style->cursorVisibility() == CursorVisibilityAutoHide) {
+ FeatureObserver::observe(m_frame.document(), FeatureObserver::CursorVisibility);
startAutoHideCursorTimer();
- else
+ } else
cancelAutoHideCursorTimer();
#endif
@@ -1415,7 +1360,8 @@ OptionalCursor EventHandler::selectCursor(const HitTestResult& result, bool shif
float scale = styleImage->imageScaleFactor();
// Get hotspot and convert from logical pixels to physical pixels.
IntPoint hotSpot = (*cursors)[i].hotSpot();
- FloatSize size = cachedImage->imageForRenderer(renderer)->size();
+ hotSpot.scale(scale, scale);
+ IntSize size = cachedImage->imageForRenderer(renderer)->size();
if (cachedImage->errorOccurred())
continue;
// Limit the size of cursors (in UI pixels) so that they cannot be
@@ -1437,19 +1383,8 @@ OptionalCursor EventHandler::selectCursor(const HitTestResult& result, bool shif
}
}
- // During selection, use an I-beam regardless of the content beneath the cursor.
- // If a drag may be starting or we're capturing mouse events for a particular node, don't treat this as a selection.
- if (m_mousePressed
- && m_mouseDownMayStartSelect
-#if ENABLE(DRAG_SUPPORT)
- && !m_mouseDownMayStartDrag
-#endif
- && m_frame.selection().isCaretOrRange()
- && !m_capturingMouseEventsElement)
- return iBeam;
-
- switch (style ? style->cursor() : CursorAuto) {
- case CursorAuto: {
+ switch (style ? style->cursor() : CURSOR_AUTO) {
+ case CURSOR_AUTO: {
bool editable = node->hasEditableStyle();
if (useHandCursor(node, result.isOverLink(), shiftKey))
@@ -1463,79 +1398,90 @@ OptionalCursor EventHandler::selectCursor(const HitTestResult& result, bool shif
}
}
+ // During selection, use an I-beam regardless of the content beneath the cursor when cursor style is not explicitly specified.
+ // If a drag may be starting or we're capturing mouse events for a particular node, don't treat this as a selection.
+ if (m_mousePressed && m_mouseDownMayStartSelect
+#if ENABLE(DRAG_SUPPORT)
+ && !m_mouseDownMayStartDrag
+#endif
+ && m_frame.selection().isCaretOrRange()
+ && !m_capturingMouseEventsElement) {
+ return iBeam;
+ }
+
if ((editable || (renderer && renderer->isText() && node->canStartSelection())) && !inResizer && !result.scrollbar())
return iBeam;
return pointerCursor();
}
- case CursorCross:
+ case CURSOR_CROSS:
return crossCursor();
- case CursorPointer:
+ case CURSOR_POINTER:
return handCursor();
- case CursorMove:
+ case CURSOR_MOVE:
return moveCursor();
- case CursorAllScroll:
+ case CURSOR_ALL_SCROLL:
return moveCursor();
- case CursorEResize:
+ case CURSOR_E_RESIZE:
return eastResizeCursor();
- case CursorWResize:
+ case CURSOR_W_RESIZE:
return westResizeCursor();
- case CursorNResize:
+ case CURSOR_N_RESIZE:
return northResizeCursor();
- case CursorSResize:
+ case CURSOR_S_RESIZE:
return southResizeCursor();
- case CursorNeResize:
+ case CURSOR_NE_RESIZE:
return northEastResizeCursor();
- case CursorSwResize:
+ case CURSOR_SW_RESIZE:
return southWestResizeCursor();
- case CursorNwResize:
+ case CURSOR_NW_RESIZE:
return northWestResizeCursor();
- case CursorSeResize:
+ case CURSOR_SE_RESIZE:
return southEastResizeCursor();
- case CursorNsResize:
+ case CURSOR_NS_RESIZE:
return northSouthResizeCursor();
- case CursorEwResize:
+ case CURSOR_EW_RESIZE:
return eastWestResizeCursor();
- case CursorNeswResize:
+ case CURSOR_NESW_RESIZE:
return northEastSouthWestResizeCursor();
- case CursorNwseResize:
+ case CURSOR_NWSE_RESIZE:
return northWestSouthEastResizeCursor();
- case CursorColResize:
+ case CURSOR_COL_RESIZE:
return columnResizeCursor();
- case CursorRowResize:
+ case CURSOR_ROW_RESIZE:
return rowResizeCursor();
- case CursorText:
+ case CURSOR_TEXT:
return iBeamCursor();
- case CursorWait:
+ case CURSOR_WAIT:
return waitCursor();
- case CursorHelp:
+ case CURSOR_HELP:
return helpCursor();
- case CursorVerticalText:
+ case CURSOR_VERTICAL_TEXT:
return verticalTextCursor();
- case CursorCell:
+ case CURSOR_CELL:
return cellCursor();
- case CursorContextMenu:
+ case CURSOR_CONTEXT_MENU:
return contextMenuCursor();
- case CursorProgress:
+ case CURSOR_PROGRESS:
return progressCursor();
- case CursorNoDrop:
+ case CURSOR_NO_DROP:
return noDropCursor();
- case CursorAlias:
+ case CURSOR_ALIAS:
return aliasCursor();
- case CursorCopy:
+ case CURSOR_COPY:
return copyCursor();
- case CursorNone:
+ case CURSOR_NONE:
return noneCursor();
- case CursorNotAllowed:
+ case CURSOR_NOT_ALLOWED:
return notAllowedCursor();
- case CursorDefault:
+ case CURSOR_DEFAULT:
return pointerCursor();
- case CursorZoomIn:
+ case CURSOR_WEBKIT_ZOOM_IN:
return zoomInCursor();
- case CursorZoomOut:
+ case CURSOR_WEBKIT_ZOOM_OUT:
return zoomOutCursor();
- case CursorWebkitGrab:
+ case CURSOR_WEBKIT_GRAB:
return grabCursor();
- case CursorWebkitGrabbing:
+ case CURSOR_WEBKIT_GRABBING:
return grabbingCursor();
}
return pointerCursor();
@@ -1551,12 +1497,10 @@ void EventHandler::startAutoHideCursorTimer()
m_autoHideCursorTimer.startOneShot(page->settings().timeWithoutMouseMovementBeforeHidingControls());
-#if !ENABLE(IOS_TOUCH_EVENTS)
// The fake mouse move event screws up the auto-hide feature (by resetting the auto-hide timer)
// so cancel any pending fake mouse moves.
if (m_fakeMouseMoveEventTimer.isActive())
m_fakeMouseMoveEventTimer.stop();
-#endif
}
void EventHandler::cancelAutoHideCursorTimer()
@@ -1565,8 +1509,9 @@ void EventHandler::cancelAutoHideCursorTimer()
m_autoHideCursorTimer.stop();
}
-void EventHandler::autoHideCursorTimerFired()
+void EventHandler::autoHideCursorTimerFired(Timer<EventHandler>& timer)
{
+ ASSERT_UNUSED(timer, &timer == &m_autoHideCursorTimer);
m_currentMouseCursor = noneCursor();
FrameView* view = m_frame.view();
if (view && view->isActive())
@@ -1582,53 +1527,38 @@ static LayoutPoint documentPointForWindowPoint(Frame& frame, const IntPoint& win
return view ? view->windowToContents(windowPoint) : windowPoint;
}
-static Scrollbar* scrollbarForMouseEvent(const MouseEventWithHitTestResults& mouseEvent, FrameView* view)
-{
- if (view) {
- if (auto* scrollbar = view->scrollbarAtPoint(mouseEvent.event().position()))
- return scrollbar;
- }
- return mouseEvent.scrollbar();
-
-}
-
-bool EventHandler::handleMousePressEvent(const PlatformMouseEvent& platformMouseEvent)
+bool EventHandler::handleMousePressEvent(const PlatformMouseEvent& mouseEvent)
{
RefPtr<FrameView> protector(m_frame.view());
- if (InspectorInstrumentation::handleMousePress(m_frame)) {
+ if (InspectorInstrumentation::handleMousePress(m_frame.page())) {
invalidateClick();
return true;
}
- if (m_frame.mainFrame().pageOverlayController().handleMouseEvent(platformMouseEvent))
- return true;
-
#if ENABLE(TOUCH_EVENTS)
- bool defaultPrevented = dispatchSyntheticTouchEventIfEnabled(platformMouseEvent);
+ bool defaultPrevented = dispatchSyntheticTouchEventIfEnabled(mouseEvent);
if (defaultPrevented)
return true;
#endif
- UserGestureIndicator gestureIndicator(DefinitelyProcessingUserGesture, m_frame.document());
+ UserGestureIndicator gestureIndicator(DefinitelyProcessingUserGesture);
// FIXME (bug 68185): this call should be made at another abstraction layer
m_frame.loader().resetMultipleFormSubmissionProtection();
-
-#if !ENABLE(IOS_TOUCH_EVENTS)
+
cancelFakeMouseMoveEvent();
-#endif
m_mousePressed = true;
m_capturesDragging = true;
- setLastKnownMousePosition(platformMouseEvent);
- m_mouseDownTimestamp = platformMouseEvent.timestamp();
+ setLastKnownMousePosition(mouseEvent);
+ m_mouseDownTimestamp = mouseEvent.timestamp();
#if ENABLE(DRAG_SUPPORT)
m_mouseDownMayStartDrag = false;
#endif
m_mouseDownMayStartSelect = false;
m_mouseDownMayStartAutoscroll = false;
if (FrameView* view = m_frame.view())
- m_mouseDownPos = view->windowToContents(platformMouseEvent.position());
+ m_mouseDownPos = view->windowToContents(mouseEvent.position());
else {
invalidateClick();
return false;
@@ -1638,18 +1568,18 @@ bool EventHandler::handleMousePressEvent(const PlatformMouseEvent& platformMouse
HitTestRequest request(HitTestRequest::Active | HitTestRequest::DisallowShadowContent);
// Save the document point we generate in case the window coordinate is invalidated by what happens
// when we dispatch the event.
- LayoutPoint documentPoint = documentPointForWindowPoint(m_frame, platformMouseEvent.position());
- MouseEventWithHitTestResults mouseEvent = m_frame.document()->prepareMouseEvent(request, documentPoint, platformMouseEvent);
+ LayoutPoint documentPoint = documentPointForWindowPoint(m_frame, mouseEvent.position());
+ MouseEventWithHitTestResults mev = m_frame.document()->prepareMouseEvent(request, documentPoint, mouseEvent);
- if (!mouseEvent.targetNode()) {
+ if (!mev.targetNode()) {
invalidateClick();
return false;
}
- m_mousePressNode = mouseEvent.targetNode();
+ m_mousePressNode = mev.targetNode();
- RefPtr<Frame> subframe = subframeForHitTestResult(mouseEvent);
- if (subframe && passMousePressEventToSubframe(mouseEvent, subframe.get())) {
+ RefPtr<Frame> subframe = subframeForHitTestResult(mev);
+ if (subframe && passMousePressEventToSubframe(mev, subframe.get())) {
// Start capturing future events for this frame. We only do this if we didn't clear
// the m_mousePressed flag, which may happen if an AppKit widget entered a modal event loop.
m_capturesDragging = subframe->eventHandler().capturesDragging();
@@ -1674,8 +1604,8 @@ bool EventHandler::handleMousePressEvent(const PlatformMouseEvent& platformMouse
}
#endif
- m_clickCount = platformMouseEvent.clickCount();
- m_clickNode = mouseEvent.targetNode();
+ m_clickCount = mouseEvent.clickCount();
+ m_clickNode = mev.targetNode();
if (!m_clickNode) {
invalidateClick();
@@ -1684,7 +1614,7 @@ bool EventHandler::handleMousePressEvent(const PlatformMouseEvent& platformMouse
if (FrameView* view = m_frame.view()) {
RenderLayer* layer = m_clickNode->renderer() ? m_clickNode->renderer()->enclosingLayer() : 0;
- IntPoint p = view->windowToContents(platformMouseEvent.position());
+ IntPoint p = view->windowToContents(mouseEvent.position());
if (layer && layer->isPointInResizeControl(p)) {
layer->setInResizeMode(true);
m_resizeLayer = layer;
@@ -1696,96 +1626,103 @@ bool EventHandler::handleMousePressEvent(const PlatformMouseEvent& platformMouse
m_frame.selection().setCaretBlinkingSuspended(true);
- bool swallowEvent = !dispatchMouseEvent(eventNames().mousedownEvent, mouseEvent.targetNode(), true, m_clickCount, platformMouseEvent, true);
- m_capturesDragging = !swallowEvent || mouseEvent.scrollbar();
+ bool swallowEvent = !dispatchMouseEvent(eventNames().mousedownEvent, mev.targetNode(), true, m_clickCount, mouseEvent, true);
+ m_capturesDragging = !swallowEvent || mev.scrollbar();
// If the hit testing originally determined the event was in a scrollbar, refetch the MouseEventWithHitTestResults
// in case the scrollbar widget was destroyed when the mouse event was handled.
- if (mouseEvent.scrollbar()) {
- const bool wasLastScrollBar = mouseEvent.scrollbar() == m_lastScrollbarUnderMouse.get();
- mouseEvent = m_frame.document()->prepareMouseEvent(HitTestRequest(), documentPoint, platformMouseEvent);
- if (wasLastScrollBar && mouseEvent.scrollbar() != m_lastScrollbarUnderMouse.get())
+ if (mev.scrollbar()) {
+ const bool wasLastScrollBar = mev.scrollbar() == m_lastScrollbarUnderMouse.get();
+ HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::DisallowShadowContent);
+ mev = m_frame.document()->prepareMouseEvent(request, documentPoint, mouseEvent);
+ if (wasLastScrollBar && mev.scrollbar() != m_lastScrollbarUnderMouse.get())
m_lastScrollbarUnderMouse = nullptr;
}
- if (!swallowEvent) {
+ if (swallowEvent) {
+ // scrollbars should get events anyway, even disabled controls might be scrollable
+ Scrollbar* scrollbar = mev.scrollbar();
+
+ updateLastScrollbarUnderMouse(scrollbar, true);
+
+ if (scrollbar)
+ passMousePressEventToScrollbar(mev, scrollbar);
+ } else {
// Refetch the event target node if it currently is the shadow node inside an <input> element.
// If a mouse event handler changes the input element type to one that has a widget associated,
// we'd like to EventHandler::handleMousePressEvent to pass the event to the widget and thus the
// event target node can't still be the shadow node.
- if (is<ShadowRoot>(*mouseEvent.targetNode()) && is<HTMLInputElement>(*downcast<ShadowRoot>(*mouseEvent.targetNode()).host()))
- mouseEvent = m_frame.document()->prepareMouseEvent(HitTestRequest(), documentPoint, platformMouseEvent);
- }
+ if (mev.targetNode()->isShadowRoot() && isHTMLInputElement(toShadowRoot(mev.targetNode())->hostElement())) {
+ HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::DisallowShadowContent);
+ mev = m_frame.document()->prepareMouseEvent(request, documentPoint, mouseEvent);
+ }
- Scrollbar* scrollbar = scrollbarForMouseEvent(mouseEvent, m_frame.view());
- updateLastScrollbarUnderMouse(scrollbar, true);
+ FrameView* view = m_frame.view();
+ Scrollbar* scrollbar = view ? view->scrollbarAtPoint(mouseEvent.position()) : 0;
+ if (!scrollbar)
+ scrollbar = mev.scrollbar();
- bool passedToScrollbar = scrollbar && passMousePressEventToScrollbar(mouseEvent, scrollbar);
- if (!swallowEvent) {
- if (passedToScrollbar)
+ updateLastScrollbarUnderMouse(scrollbar, true);
+
+ if (scrollbar && passMousePressEventToScrollbar(mev, scrollbar))
swallowEvent = true;
else
- swallowEvent = handleMousePressEvent(mouseEvent);
+ swallowEvent = handleMousePressEvent(mev);
}
+
return swallowEvent;
}
// This method only exists for platforms that don't know how to deliver
-bool EventHandler::handleMouseDoubleClickEvent(const PlatformMouseEvent& platformMouseEvent)
+bool EventHandler::handleMouseDoubleClickEvent(const PlatformMouseEvent& mouseEvent)
{
RefPtr<FrameView> protector(m_frame.view());
m_frame.selection().setCaretBlinkingSuspended(false);
- UserGestureIndicator gestureIndicator(DefinitelyProcessingUserGesture, m_frame.document());
+ UserGestureIndicator gestureIndicator(DefinitelyProcessingUserGesture);
// We get this instead of a second mouse-up
m_mousePressed = false;
- setLastKnownMousePosition(platformMouseEvent);
+ setLastKnownMousePosition(mouseEvent);
HitTestRequest request(HitTestRequest::Active | HitTestRequest::DisallowShadowContent);
- MouseEventWithHitTestResults mouseEvent = prepareMouseEvent(request, platformMouseEvent);
- Frame* subframe = subframeForHitTestResult(mouseEvent);
+ MouseEventWithHitTestResults mev = prepareMouseEvent(request, mouseEvent);
+ Frame* subframe = subframeForHitTestResult(mev);
if (m_eventHandlerWillResetCapturingMouseEventsElement)
m_capturingMouseEventsElement = nullptr;
- if (subframe && passMousePressEventToSubframe(mouseEvent, subframe))
+ if (subframe && passMousePressEventToSubframe(mev, subframe))
return true;
- m_clickCount = platformMouseEvent.clickCount();
- bool swallowMouseUpEvent = !dispatchMouseEvent(eventNames().mouseupEvent, mouseEvent.targetNode(), true, m_clickCount, platformMouseEvent, false);
+ m_clickCount = mouseEvent.clickCount();
+ bool swallowMouseUpEvent = !dispatchMouseEvent(eventNames().mouseupEvent, mev.targetNode(), true, m_clickCount, mouseEvent, false);
- bool swallowClickEvent = platformMouseEvent.button() != RightButton && mouseEvent.targetNode() == m_clickNode && !dispatchMouseEvent(eventNames().clickEvent, mouseEvent.targetNode(), true, m_clickCount, platformMouseEvent, true);
+ bool swallowClickEvent = mouseEvent.button() != RightButton && mev.targetNode() == m_clickNode && !dispatchMouseEvent(eventNames().clickEvent, mev.targetNode(), true, m_clickCount, mouseEvent, true);
if (m_lastScrollbarUnderMouse)
- swallowMouseUpEvent = m_lastScrollbarUnderMouse->mouseUp(platformMouseEvent);
+ swallowMouseUpEvent = m_lastScrollbarUnderMouse->mouseUp(mouseEvent);
- bool swallowMouseReleaseEvent = !swallowMouseUpEvent && handleMouseReleaseEvent(mouseEvent);
+ bool swallowMouseReleaseEvent = !swallowMouseUpEvent && handleMouseReleaseEvent(mev);
invalidateClick();
return swallowMouseUpEvent || swallowClickEvent || swallowMouseReleaseEvent;
}
-static ScrollableArea* enclosingScrollableArea(Node* node)
+static RenderLayer* layerForNode(Node* node)
{
if (!node)
- return nullptr;
-
- for (auto element = node; element; element = element->parentOrShadowHostNode()) {
- if (is<HTMLIFrameElement>(*element) || is<HTMLHtmlElement>(*element) || is<HTMLDocument>(*element))
- return nullptr;
-
- auto renderer = element->renderer();
- if (!renderer)
- continue;
+ return 0;
- if (is<RenderListBox>(*renderer))
- return downcast<RenderListBox>(renderer);
+ auto renderer = node->renderer();
+ if (!renderer)
+ return 0;
- return renderer->enclosingLayer();
- }
+ RenderLayer* layer = renderer->enclosingLayer();
+ if (!layer)
+ return 0;
- return nullptr;
+ return layer;
}
bool EventHandler::mouseMoved(const PlatformMouseEvent& event)
@@ -1793,9 +1730,6 @@ bool EventHandler::mouseMoved(const PlatformMouseEvent& event)
RefPtr<FrameView> protector(m_frame.view());
MaximumDurationTracker maxDurationTracker(&m_maxMouseMovedDuration);
- if (m_frame.mainFrame().pageOverlayController().handleMouseEvent(event))
- return true;
-
HitTestResult hoveredNode = HitTestResult(LayoutPoint());
bool result = handleMouseMoveEvent(event, &hoveredNode);
@@ -1803,10 +1737,10 @@ bool EventHandler::mouseMoved(const PlatformMouseEvent& event)
if (!page)
return result;
- if (auto scrolledArea = enclosingScrollableArea(hoveredNode.innerNode())) {
+ if (RenderLayer* layer = layerForNode(hoveredNode.innerNode())) {
if (FrameView* frameView = m_frame.view()) {
- if (frameView->containsScrollableArea(scrolledArea))
- scrolledArea->mouseMovedInContentArea();
+ if (frameView->containsScrollableArea(layer))
+ layer->mouseMovedInContentArea();
}
}
@@ -1825,17 +1759,17 @@ bool EventHandler::passMouseMovedEventToScrollbars(const PlatformMouseEvent& eve
return handleMouseMoveEvent(event, &hoveredNode, true);
}
-bool EventHandler::handleMouseMoveEvent(const PlatformMouseEvent& platformMouseEvent, HitTestResult* hoveredNode, bool onlyUpdateScrollbars)
+bool EventHandler::handleMouseMoveEvent(const PlatformMouseEvent& mouseEvent, HitTestResult* hoveredNode, bool onlyUpdateScrollbars)
{
#if ENABLE(TOUCH_EVENTS)
- bool defaultPrevented = dispatchSyntheticTouchEventIfEnabled(platformMouseEvent);
+ bool defaultPrevented = dispatchSyntheticTouchEventIfEnabled(mouseEvent);
if (defaultPrevented)
return true;
#endif
RefPtr<FrameView> protector(m_frame.view());
- setLastKnownMousePosition(platformMouseEvent);
+ setLastKnownMousePosition(mouseEvent);
if (m_hoverTimer.isActive())
m_hoverTimer.stop();
@@ -1844,23 +1778,23 @@ bool EventHandler::handleMouseMoveEvent(const PlatformMouseEvent& platformMouseE
m_cursorUpdateTimer.stop();
#endif
-#if !ENABLE(IOS_TOUCH_EVENTS)
cancelFakeMouseMoveEvent();
-#endif
+#if ENABLE(SVG)
if (m_svgPan) {
- downcast<SVGDocument>(*m_frame.document()).updatePan(m_frame.view()->windowToContents(m_lastKnownMousePosition));
+ toSVGDocument(m_frame.document())->updatePan(m_frame.view()->windowToContents(m_lastKnownMousePosition));
return true;
}
+#endif
if (m_frameSetBeingResized)
- return !dispatchMouseEvent(eventNames().mousemoveEvent, m_frameSetBeingResized.get(), false, 0, platformMouseEvent, false);
+ return !dispatchMouseEvent(eventNames().mousemoveEvent, m_frameSetBeingResized.get(), false, 0, mouseEvent, false);
// On iOS, our scrollbars are managed by UIKit.
#if !PLATFORM(IOS)
// Send events right to a scrollbar if the mouse is pressed.
if (m_lastScrollbarUnderMouse && m_mousePressed)
- return m_lastScrollbarUnderMouse->mouseMoved(platformMouseEvent);
+ return m_lastScrollbarUnderMouse->mouseMoved(mouseEvent);
#endif
HitTestRequest::HitTestRequestType hitType = HitTestRequest::Move | HitTestRequest::DisallowShadowContent | HitTestRequest::AllowFrameScrollbars;
@@ -1880,46 +1814,44 @@ bool EventHandler::handleMouseMoveEvent(const PlatformMouseEvent& platformMouseE
hitType |= HitTestRequest::Active | HitTestRequest::ReadOnly;
#endif
HitTestRequest request(hitType);
- MouseEventWithHitTestResults mouseEvent = prepareMouseEvent(request, platformMouseEvent);
+ MouseEventWithHitTestResults mev = prepareMouseEvent(request, mouseEvent);
if (hoveredNode)
- *hoveredNode = mouseEvent.hitTestResult();
+ *hoveredNode = mev.hitTestResult();
if (m_resizeLayer && m_resizeLayer->inResizeMode())
- m_resizeLayer->resize(platformMouseEvent, m_offsetFromResizeCorner);
+ m_resizeLayer->resize(mouseEvent, m_offsetFromResizeCorner);
else {
- Scrollbar* scrollbar = mouseEvent.scrollbar();
+ Scrollbar* scrollbar = mev.scrollbar();
updateLastScrollbarUnderMouse(scrollbar, !m_mousePressed);
// On iOS, our scrollbars are managed by UIKit.
#if !PLATFORM(IOS)
if (!m_mousePressed && scrollbar)
- scrollbar->mouseMoved(platformMouseEvent); // Handle hover effects on platforms that support visual feedback on scrollbar hovering.
+ scrollbar->mouseMoved(mouseEvent); // Handle hover effects on platforms that support visual feedback on scrollbar hovering.
#endif
- if (onlyUpdateScrollbars) {
- updateMouseEventTargetNode(mouseEvent.targetNode(), platformMouseEvent, true);
+ if (onlyUpdateScrollbars)
return true;
- }
}
bool swallowEvent = false;
- RefPtr<Frame> newSubframe = m_capturingMouseEventsElement.get() ? subframeForTargetNode(m_capturingMouseEventsElement.get()) : subframeForHitTestResult(mouseEvent);
+ RefPtr<Frame> newSubframe = m_capturingMouseEventsElement.get() ? subframeForTargetNode(m_capturingMouseEventsElement.get()) : subframeForHitTestResult(mev);
// We want mouseouts to happen first, from the inside out. First send a move event to the last subframe so that it will fire mouseouts.
if (m_lastMouseMoveEventSubframe && m_lastMouseMoveEventSubframe->tree().isDescendantOf(&m_frame) && m_lastMouseMoveEventSubframe != newSubframe)
- passMouseMoveEventToSubframe(mouseEvent, m_lastMouseMoveEventSubframe.get());
+ passMouseMoveEventToSubframe(mev, m_lastMouseMoveEventSubframe.get());
if (newSubframe) {
// Update over/out state before passing the event to the subframe.
- updateMouseEventTargetNode(mouseEvent.targetNode(), platformMouseEvent, true);
+ updateMouseEventTargetNode(mev.targetNode(), mouseEvent, true);
// Event dispatch in updateMouseEventTargetNode may have caused the subframe of the target
// node to be detached from its FrameView, in which case the event should not be passed.
if (newSubframe->view())
- swallowEvent |= passMouseMoveEventToSubframe(mouseEvent, newSubframe.get(), hoveredNode);
+ swallowEvent |= passMouseMoveEventToSubframe(mev, newSubframe.get(), hoveredNode);
#if ENABLE(CURSOR_SUPPORT)
} else {
if (FrameView* view = m_frame.view()) {
- OptionalCursor optionalCursor = selectCursor(mouseEvent.hitTestResult(), platformMouseEvent.shiftKey());
+ OptionalCursor optionalCursor = selectCursor(mev.hitTestResult(), mouseEvent.shiftKey());
if (optionalCursor.isCursorChange()) {
m_currentMouseCursor = optionalCursor.cursor();
view->setCursor(m_currentMouseCursor);
@@ -1933,10 +1865,10 @@ bool EventHandler::handleMouseMoveEvent(const PlatformMouseEvent& platformMouseE
if (swallowEvent)
return true;
- swallowEvent = !dispatchMouseEvent(eventNames().mousemoveEvent, mouseEvent.targetNode(), false, 0, platformMouseEvent, true);
+ swallowEvent = !dispatchMouseEvent(eventNames().mousemoveEvent, mev.targetNode(), false, 0, mouseEvent, true);
#if ENABLE(DRAG_SUPPORT)
if (!swallowEvent)
- swallowEvent = handleMouseDraggedEvent(mouseEvent);
+ swallowEvent = handleMouseDraggedEvent(mev);
#endif // ENABLE(DRAG_SUPPORT)
return swallowEvent;
@@ -1945,116 +1877,102 @@ bool EventHandler::handleMouseMoveEvent(const PlatformMouseEvent& platformMouseE
void EventHandler::invalidateClick()
{
m_clickCount = 0;
- m_clickNode = nullptr;
+ m_clickNode = 0;
+}
+
+inline static bool mouseIsReleasedOnPressedElement(Node* targetNode, Node* clickNode)
+{
+ if (targetNode == clickNode)
+ return true;
+
+ if (!targetNode)
+ return false;
+
+ ShadowRoot* containingShadowRoot = targetNode->containingShadowRoot();
+ if (!containingShadowRoot)
+ return false;
+
+ // FIXME: When an element in UA ShadowDOM (e.g. inner element in <input>) is clicked,
+ // we assume that the host element is clicked. This is necessary for implementing <input type="range"> etc.
+ // However, we should not check ShadowRoot type basically.
+ // https://bugs.webkit.org/show_bug.cgi?id=108047
+ if (containingShadowRoot->type() != ShadowRoot::UserAgentShadowRoot)
+ return false;
+
+ Node* adjustedTargetNode = targetNode->shadowHost();
+ Node* adjustedClickNode = clickNode ? clickNode->shadowHost() : 0;
+ return adjustedTargetNode == adjustedClickNode;
}
-bool EventHandler::handleMouseReleaseEvent(const PlatformMouseEvent& platformMouseEvent)
+bool EventHandler::handleMouseReleaseEvent(const PlatformMouseEvent& mouseEvent)
{
RefPtr<FrameView> protector(m_frame.view());
m_frame.selection().setCaretBlinkingSuspended(false);
- if (m_frame.mainFrame().pageOverlayController().handleMouseEvent(platformMouseEvent))
- return true;
-
#if ENABLE(TOUCH_EVENTS)
- bool defaultPrevented = dispatchSyntheticTouchEventIfEnabled(platformMouseEvent);
+ bool defaultPrevented = dispatchSyntheticTouchEventIfEnabled(mouseEvent);
if (defaultPrevented)
return true;
#endif
- UserGestureIndicator gestureIndicator(DefinitelyProcessingUserGesture, m_frame.document());
+ UserGestureIndicator gestureIndicator(DefinitelyProcessingUserGesture);
#if ENABLE(PAN_SCROLLING)
- m_autoscrollController->handleMouseReleaseEvent(platformMouseEvent);
+ m_autoscrollController->handleMouseReleaseEvent(mouseEvent);
#endif
m_mousePressed = false;
- setLastKnownMousePosition(platformMouseEvent);
+ setLastKnownMousePosition(mouseEvent);
+#if ENABLE(SVG)
if (m_svgPan) {
m_svgPan = false;
- downcast<SVGDocument>(*m_frame.document()).updatePan(m_frame.view()->windowToContents(m_lastKnownMousePosition));
+ toSVGDocument(m_frame.document())->updatePan(m_frame.view()->windowToContents(m_lastKnownMousePosition));
return true;
}
+#endif
if (m_frameSetBeingResized)
- return !dispatchMouseEvent(eventNames().mouseupEvent, m_frameSetBeingResized.get(), true, m_clickCount, platformMouseEvent, false);
-
- // If an immediate action began or was completed using this series of mouse events, then we should send mouseup to
- // the DOM and return now so that we don't perform our own default behaviors.
- if (m_immediateActionStage == ImmediateActionStage::ActionCompleted || m_immediateActionStage == ImmediateActionStage::ActionUpdated || m_immediateActionStage == ImmediateActionStage::ActionCancelledAfterUpdate) {
- m_immediateActionStage = ImmediateActionStage::None;
- return !dispatchMouseEvent(eventNames().mouseupEvent, m_lastElementUnderMouse.get(), true, m_clickCount, platformMouseEvent, false);
- }
- m_immediateActionStage = ImmediateActionStage::None;
+ return !dispatchMouseEvent(eventNames().mouseupEvent, m_frameSetBeingResized.get(), true, m_clickCount, mouseEvent, false);
if (m_lastScrollbarUnderMouse) {
invalidateClick();
- m_lastScrollbarUnderMouse->mouseUp(platformMouseEvent);
+ m_lastScrollbarUnderMouse->mouseUp(mouseEvent);
bool cancelable = true;
bool setUnder = false;
- return !dispatchMouseEvent(eventNames().mouseupEvent, m_lastElementUnderMouse.get(), cancelable, m_clickCount, platformMouseEvent, setUnder);
+ return !dispatchMouseEvent(eventNames().mouseupEvent, m_lastElementUnderMouse.get(), cancelable, m_clickCount, mouseEvent, setUnder);
}
HitTestRequest request(HitTestRequest::Release | HitTestRequest::DisallowShadowContent);
- MouseEventWithHitTestResults mouseEvent = prepareMouseEvent(request, platformMouseEvent);
- Frame* subframe = m_capturingMouseEventsElement.get() ? subframeForTargetNode(m_capturingMouseEventsElement.get()) : subframeForHitTestResult(mouseEvent);
+ MouseEventWithHitTestResults mev = prepareMouseEvent(request, mouseEvent);
+ Frame* subframe = m_capturingMouseEventsElement.get() ? subframeForTargetNode(m_capturingMouseEventsElement.get()) : subframeForHitTestResult(mev);
if (m_eventHandlerWillResetCapturingMouseEventsElement)
m_capturingMouseEventsElement = nullptr;
- if (subframe && passMouseReleaseEventToSubframe(mouseEvent, subframe))
+ if (subframe && passMouseReleaseEventToSubframe(mev, subframe))
return true;
- bool swallowMouseUpEvent = !dispatchMouseEvent(eventNames().mouseupEvent, mouseEvent.targetNode(), true, m_clickCount, platformMouseEvent, false);
+ bool swallowMouseUpEvent = !dispatchMouseEvent(eventNames().mouseupEvent, mev.targetNode(), true, m_clickCount, mouseEvent, false);
- bool contextMenuEvent = platformMouseEvent.button() == RightButton;
+ bool contextMenuEvent = mouseEvent.button() == RightButton;
- Node* targetNode = mouseEvent.targetNode();
- Node* nodeToClick = (m_clickNode && targetNode) ? commonAncestorCrossingShadowBoundary(*m_clickNode, *targetNode) : nullptr;
- bool swallowClickEvent = m_clickCount > 0 && !contextMenuEvent && nodeToClick && !dispatchMouseEvent(eventNames().clickEvent, nodeToClick, true, m_clickCount, platformMouseEvent, true);
+ bool swallowClickEvent = m_clickCount > 0 && !contextMenuEvent && mouseIsReleasedOnPressedElement(mev.targetNode(), m_clickNode.get()) && !dispatchMouseEvent(eventNames().clickEvent, mev.targetNode(), true, m_clickCount, mouseEvent, true);
if (m_resizeLayer) {
m_resizeLayer->setInResizeMode(false);
- m_resizeLayer = nullptr;
+ m_resizeLayer = 0;
}
bool swallowMouseReleaseEvent = false;
if (!swallowMouseUpEvent)
- swallowMouseReleaseEvent = handleMouseReleaseEvent(mouseEvent);
+ swallowMouseReleaseEvent = handleMouseReleaseEvent(mev);
invalidateClick();
return swallowMouseUpEvent || swallowClickEvent || swallowMouseReleaseEvent;
}
-#if ENABLE(MOUSE_FORCE_EVENTS)
-bool EventHandler::handleMouseForceEvent(const PlatformMouseEvent& event)
-{
- RefPtr<FrameView> protector(m_frame.view());
-
- setLastKnownMousePosition(event);
-
- HitTestRequest::HitTestRequestType hitType = HitTestRequest::DisallowShadowContent | HitTestRequest::Active;
-
- HitTestRequest request(hitType);
- MouseEventWithHitTestResults mouseEvent = prepareMouseEvent(request, event);
-
- bool swallowedEvent = !dispatchMouseEvent(eventNames().webkitmouseforcechangedEvent, mouseEvent.targetNode(), false, 0, event, false);
- if (event.type() == PlatformEvent::MouseForceDown)
- swallowedEvent |= !dispatchMouseEvent(eventNames().webkitmouseforcedownEvent, mouseEvent.targetNode(), false, 0, event, false);
- if (event.type() == PlatformEvent::MouseForceUp)
- swallowedEvent |= !dispatchMouseEvent(eventNames().webkitmouseforceupEvent, mouseEvent.targetNode(), false, 0, event, false);
-
- return swallowedEvent;
-}
-#else
-bool EventHandler::handleMouseForceEvent(const PlatformMouseEvent& )
-{
- return false;
-}
-#endif // #if ENABLE(MOUSE_FORCE_EVENTS)
-
-bool EventHandler::handlePasteGlobalSelection(const PlatformMouseEvent& platformMouseEvent)
+bool EventHandler::handlePasteGlobalSelection(const PlatformMouseEvent& mouseEvent)
{
// If the event was a middle click, attempt to copy global selection in after
// the newly set caret position.
@@ -2073,10 +1991,10 @@ bool EventHandler::handlePasteGlobalSelection(const PlatformMouseEvent& platform
// clears the text box. So it's important this happens after the event
// handlers have been fired.
#if PLATFORM(GTK)
- if (platformMouseEvent.type() != PlatformEvent::MousePressed)
+ if (mouseEvent.type() != PlatformEvent::MousePressed)
return false;
#else
- if (platformMouseEvent.type() != PlatformEvent::MouseReleased)
+ if (mouseEvent.type() != PlatformEvent::MouseReleased)
return false;
#endif
@@ -2092,7 +2010,7 @@ bool EventHandler::handlePasteGlobalSelection(const PlatformMouseEvent& platform
#if ENABLE(DRAG_SUPPORT)
-bool EventHandler::dispatchDragEvent(const AtomicString& eventType, Element& dragTarget, const PlatformMouseEvent& event, DataTransfer* dataTransfer)
+bool EventHandler::dispatchDragEvent(const AtomicString& eventType, Element& dragTarget, const PlatformMouseEvent& event, Clipboard* clipboard)
{
FrameView* view = m_frame.view();
@@ -2101,25 +2019,29 @@ bool EventHandler::dispatchDragEvent(const AtomicString& eventType, Element& dra
return false;
view->disableLayerFlushThrottlingTemporarilyForInteraction();
- Ref<MouseEvent> me = MouseEvent::create(eventType,
+ RefPtr<MouseEvent> me = MouseEvent::create(eventType,
true, true, event.timestamp(), m_frame.document()->defaultView(),
0, event.globalPosition().x(), event.globalPosition().y(), event.position().x(), event.position().y(),
#if ENABLE(POINTER_LOCK)
event.movementDelta().x(), event.movementDelta().y(),
#endif
event.ctrlKey(), event.altKey(), event.shiftKey(), event.metaKey(),
- 0, 0, event.force(), dataTransfer);
+ 0, 0, clipboard);
- dragTarget.dispatchEvent(me);
+ dragTarget.dispatchEvent(me.get(), IGNORE_EXCEPTION);
return me->defaultPrevented();
}
static bool targetIsFrame(Node* target, Frame*& frame)
{
- if (!is<HTMLFrameElementBase>(target))
+ if (!target)
return false;
- frame = downcast<HTMLFrameElementBase>(*target).contentFrame();
+ if (!target->hasTagName(frameTag) && !target->hasTagName(iframeTag))
+ return false;
+
+ frame = toHTMLFrameElementBase(target)->contentFrame();
+
return true;
}
@@ -2148,44 +2070,69 @@ static String convertDragOperationToDropZoneOperation(DragOperation operation)
}
}
-static bool hasDropZoneType(DataTransfer& dataTransfer, const String& keyword)
+static inline bool hasFileOfType(Clipboard& clipboard, const String& type)
+{
+ RefPtr<FileList> fileList = clipboard.files();
+ for (unsigned i = 0; i < fileList->length(); i++) {
+ if (equalIgnoringCase(fileList->item(i)->type(), type))
+ return true;
+ }
+ return false;
+}
+
+static inline bool hasStringOfType(Clipboard& clipboard, const String& type)
+{
+ return !type.isNull() && clipboard.types().contains(type);
+}
+
+static bool hasDropZoneType(Clipboard& clipboard, const String& keyword)
{
if (keyword.startsWith("file:"))
- return dataTransfer.hasFileOfType(keyword.substring(5));
+ return hasFileOfType(clipboard, keyword.substring(5));
if (keyword.startsWith("string:"))
- return dataTransfer.hasStringOfType(keyword.substring(7));
+ return hasStringOfType(clipboard, keyword.substring(7));
return false;
}
-static bool findDropZone(Node* target, DataTransfer* dataTransfer)
+static bool findDropZone(Node* target, Clipboard* clipboard)
{
- ASSERT(target);
- Element* element = is<Element>(*target) ? downcast<Element>(target) : target->parentElement();
+ Element* element = target->isElementNode() ? toElement(target) : target->parentElement();
for (; element; element = element->parentElement()) {
- SpaceSplitString keywords(element->fastGetAttribute(webkitdropzoneAttr), true);
bool matched = false;
+ String dropZoneStr = element->fastGetAttribute(webkitdropzoneAttr);
+
+ if (dropZoneStr.isEmpty())
+ continue;
+
+ dropZoneStr = dropZoneStr.lower();
+
+ SpaceSplitString keywords(dropZoneStr, false);
+ if (keywords.isEmpty())
+ continue;
+
DragOperation dragOperation = DragOperationNone;
- for (unsigned i = 0, size = keywords.size(); i < size; ++i) {
+ for (unsigned int i = 0; i < keywords.size(); i++) {
DragOperation op = convertDropZoneOperationToDragOperation(keywords[i]);
if (op != DragOperationNone) {
if (dragOperation == DragOperationNone)
dragOperation = op;
} else
- matched = matched || hasDropZoneType(*dataTransfer, keywords[i].string());
+ matched = matched || hasDropZoneType(*clipboard, keywords[i].string());
+
if (matched && dragOperation != DragOperationNone)
break;
}
if (matched) {
- dataTransfer->setDropEffect(convertDragOperationToDropZoneOperation(dragOperation));
+ clipboard->setDropEffect(convertDragOperationToDropZoneOperation(dragOperation));
return true;
}
}
return false;
}
-bool EventHandler::updateDragAndDrop(const PlatformMouseEvent& event, DataTransfer* dataTransfer)
+bool EventHandler::updateDragAndDrop(const PlatformMouseEvent& event, Clipboard* clipboard)
{
bool accept = false;
@@ -2193,15 +2140,15 @@ bool EventHandler::updateDragAndDrop(const PlatformMouseEvent& event, DataTransf
return false;
HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::DisallowShadowContent);
- MouseEventWithHitTestResults mouseEvent = prepareMouseEvent(request, event);
+ MouseEventWithHitTestResults mev = prepareMouseEvent(request, event);
RefPtr<Element> newTarget;
- if (Node* targetNode = mouseEvent.targetNode()) {
+ if (Node* targetNode = mev.targetNode()) {
// Drag events should never go to non-element nodes (following IE, and proper mouseover/out dispatch)
- if (!is<Element>(*targetNode))
+ if (!targetNode->isElementNode())
newTarget = targetNode->parentOrShadowHostElement();
else
- newTarget = downcast<Element>(targetNode);
+ newTarget = toElement(targetNode);
}
m_autoscrollController->updateDragAndDrop(newTarget.get(), event.position(), event.timestamp());
@@ -2215,23 +2162,23 @@ bool EventHandler::updateDragAndDrop(const PlatformMouseEvent& event, DataTransf
Frame* targetFrame;
if (targetIsFrame(newTarget.get(), targetFrame)) {
if (targetFrame)
- accept = targetFrame->eventHandler().updateDragAndDrop(event, dataTransfer);
+ accept = targetFrame->eventHandler().updateDragAndDrop(event, clipboard);
} else if (newTarget) {
// As per section 7.9.4 of the HTML 5 spec., we must always fire a drag event before firing a dragenter, dragleave, or dragover event.
if (dragState().source && dragState().shouldDispatchEvents) {
// for now we don't care if event handler cancels default behavior, since there is none
dispatchDragSrcEvent(eventNames().dragEvent, event);
}
- accept = dispatchDragEvent(eventNames().dragenterEvent, *newTarget, event, dataTransfer);
+ accept = dispatchDragEvent(eventNames().dragenterEvent, *newTarget, event, clipboard);
if (!accept)
- accept = findDropZone(newTarget.get(), dataTransfer);
+ accept = findDropZone(newTarget.get(), clipboard);
}
if (targetIsFrame(m_dragTarget.get(), targetFrame)) {
if (targetFrame)
- accept = targetFrame->eventHandler().updateDragAndDrop(event, dataTransfer);
+ accept = targetFrame->eventHandler().updateDragAndDrop(event, clipboard);
} else if (m_dragTarget)
- dispatchDragEvent(eventNames().dragleaveEvent, *m_dragTarget, event, dataTransfer);
+ dispatchDragEvent(eventNames().dragleaveEvent, *m_dragTarget, event, clipboard);
if (newTarget) {
// We do not explicitly call dispatchDragEvent here because it could ultimately result in the appearance that
@@ -2242,16 +2189,16 @@ bool EventHandler::updateDragAndDrop(const PlatformMouseEvent& event, DataTransf
Frame* targetFrame;
if (targetIsFrame(newTarget.get(), targetFrame)) {
if (targetFrame)
- accept = targetFrame->eventHandler().updateDragAndDrop(event, dataTransfer);
+ accept = targetFrame->eventHandler().updateDragAndDrop(event, clipboard);
} else if (newTarget) {
// Note, when dealing with sub-frames, we may need to fire only a dragover event as a drag event may have been fired earlier.
if (!m_shouldOnlyFireDragOverEvent && dragState().source && dragState().shouldDispatchEvents) {
// for now we don't care if event handler cancels default behavior, since there is none
dispatchDragSrcEvent(eventNames().dragEvent, event);
}
- accept = dispatchDragEvent(eventNames().dragoverEvent, *newTarget, event, dataTransfer);
+ accept = dispatchDragEvent(eventNames().dragoverEvent, *newTarget, event, clipboard);
if (!accept)
- accept = findDropZone(newTarget.get(), dataTransfer);
+ accept = findDropZone(newTarget.get(), clipboard);
m_shouldOnlyFireDragOverEvent = false;
}
}
@@ -2259,29 +2206,29 @@ bool EventHandler::updateDragAndDrop(const PlatformMouseEvent& event, DataTransf
return accept;
}
-void EventHandler::cancelDragAndDrop(const PlatformMouseEvent& event, DataTransfer* dataTransfer)
+void EventHandler::cancelDragAndDrop(const PlatformMouseEvent& event, Clipboard* clipboard)
{
Frame* targetFrame;
if (targetIsFrame(m_dragTarget.get(), targetFrame)) {
if (targetFrame)
- targetFrame->eventHandler().cancelDragAndDrop(event, dataTransfer);
+ targetFrame->eventHandler().cancelDragAndDrop(event, clipboard);
} else if (m_dragTarget) {
if (dragState().source && dragState().shouldDispatchEvents)
dispatchDragSrcEvent(eventNames().dragEvent, event);
- dispatchDragEvent(eventNames().dragleaveEvent, *m_dragTarget, event, dataTransfer);
+ dispatchDragEvent(eventNames().dragleaveEvent, *m_dragTarget, event, clipboard);
}
clearDragState();
}
-bool EventHandler::performDragAndDrop(const PlatformMouseEvent& event, DataTransfer* dataTransfer)
+bool EventHandler::performDragAndDrop(const PlatformMouseEvent& event, Clipboard* clipboard)
{
Frame* targetFrame;
bool preventedDefault = false;
if (targetIsFrame(m_dragTarget.get(), targetFrame)) {
if (targetFrame)
- preventedDefault = targetFrame->eventHandler().performDragAndDrop(event, dataTransfer);
+ preventedDefault = targetFrame->eventHandler().performDragAndDrop(event, clipboard);
} else if (m_dragTarget)
- preventedDefault = dispatchDragEvent(eventNames().dropEvent, *m_dragTarget, event, dataTransfer);
+ preventedDefault = dispatchDragEvent(eventNames().dropEvent, *m_dragTarget, event, clipboard);
clearDragState();
return preventedDefault;
}
@@ -2292,7 +2239,7 @@ void EventHandler::clearDragState()
m_dragTarget = nullptr;
m_capturingMouseEventsElement = nullptr;
m_shouldOnlyFireDragOverEvent = false;
-#if PLATFORM(COCOA)
+#if PLATFORM(MAC)
m_sendingEventToSubview = false;
#endif
}
@@ -2304,37 +2251,31 @@ void EventHandler::setCapturingMouseEventsElement(PassRefPtr<Element> element)
m_eventHandlerWillResetCapturingMouseEventsElement = false;
}
-MouseEventWithHitTestResults EventHandler::prepareMouseEvent(const HitTestRequest& request, const PlatformMouseEvent& mouseEvent)
+MouseEventWithHitTestResults EventHandler::prepareMouseEvent(const HitTestRequest& request, const PlatformMouseEvent& mev)
{
ASSERT(m_frame.document());
- return m_frame.document()->prepareMouseEvent(request, documentPointForWindowPoint(m_frame, mouseEvent.position()), mouseEvent);
+ return m_frame.document()->prepareMouseEvent(request, documentPointForWindowPoint(m_frame, mev.position()), mev);
}
-static RenderElement* nearestCommonHoverAncestor(RenderElement* obj1, RenderElement* obj2)
+#if ENABLE(SVG)
+static inline SVGElementInstance* instanceAssociatedWithShadowTreeElement(Node* referenceNode)
{
- if (!obj1 || !obj2)
- return nullptr;
+ if (!referenceNode || !referenceNode->isSVGElement())
+ return 0;
- for (RenderElement* currObj1 = obj1; currObj1; currObj1 = currObj1->hoverAncestor()) {
- for (RenderElement* currObj2 = obj2; currObj2; currObj2 = currObj2->hoverAncestor()) {
- if (currObj1 == currObj2)
- return currObj1;
- }
- }
+ ShadowRoot* shadowRoot = referenceNode->containingShadowRoot();
+ if (!shadowRoot)
+ return 0;
- return nullptr;
-}
+ Element* shadowTreeParentElement = shadowRoot->hostElement();
+ if (!shadowTreeParentElement || !shadowTreeParentElement->hasTagName(useTag))
+ return 0;
-static bool hierarchyHasCapturingEventListeners(Element* element, const AtomicString& eventName)
-{
- for (ContainerNode* curr = element; curr; curr = curr->parentOrShadowHostNode()) {
- if (curr->hasCapturingEventListeners(eventName))
- return true;
- }
- return false;
+ return toSVGUseElement(shadowTreeParentElement)->instanceForShadowTreeElement(referenceNode);
}
+#endif
-void EventHandler::updateMouseEventTargetNode(Node* targetNode, const PlatformMouseEvent& platformMouseEvent, bool fireMouseOverOut)
+void EventHandler::updateMouseEventTargetNode(Node* targetNode, const PlatformMouseEvent& mouseEvent, bool fireMouseOverOut)
{
Element* targetElement = nullptr;
@@ -2343,18 +2284,52 @@ void EventHandler::updateMouseEventTargetNode(Node* targetNode, const PlatformMo
targetElement = m_capturingMouseEventsElement.get();
else if (targetNode) {
// If the target node is a non-element, dispatch on the parent. <rdar://problem/4196646>
- if (!is<Element>(*targetNode))
+ if (!targetNode->isElementNode())
targetElement = targetNode->parentOrShadowHostElement();
else
- targetElement = downcast<Element>(targetNode);
+ targetElement = toElement(targetNode);
}
m_elementUnderMouse = targetElement;
+#if ENABLE(SVG)
+ m_instanceUnderMouse = instanceAssociatedWithShadowTreeElement(targetElement);
+
+ // <use> shadow tree elements may have been recloned, update node under mouse in any case
+ if (m_lastInstanceUnderMouse) {
+ SVGElement* lastCorrespondingElement = m_lastInstanceUnderMouse->correspondingElement();
+ SVGElement* lastCorrespondingUseElement = m_lastInstanceUnderMouse->correspondingUseElement();
+
+ if (lastCorrespondingElement && lastCorrespondingUseElement) {
+ HashSet<SVGElementInstance*> instances = lastCorrespondingElement->instancesForElement();
+
+ // Locate the recloned shadow tree element for our corresponding instance
+ HashSet<SVGElementInstance*>::iterator end = instances.end();
+ for (HashSet<SVGElementInstance*>::iterator it = instances.begin(); it != end; ++it) {
+ SVGElementInstance* instance = (*it);
+ ASSERT(instance->correspondingElement() == lastCorrespondingElement);
+
+ if (instance == m_lastInstanceUnderMouse)
+ continue;
+
+ if (instance->correspondingUseElement() != lastCorrespondingUseElement)
+ continue;
+
+ SVGElement* shadowTreeElement = instance->shadowTreeElement();
+ if (!shadowTreeElement->inDocument() || m_lastElementUnderMouse == shadowTreeElement)
+ continue;
+
+ m_lastElementUnderMouse = shadowTreeElement;
+ m_lastInstanceUnderMouse = instance;
+ break;
+ }
+ }
+ }
+#endif
// Fire mouseout/mouseover if the mouse has shifted to a different node.
if (fireMouseOverOut) {
- auto scrollableAreaForLastNode = enclosingScrollableArea(m_lastElementUnderMouse.get());
- auto scrollableAreaForNodeUnderMouse = enclosingScrollableArea(m_elementUnderMouse.get());
+ RenderLayer* layerForLastNode = layerForNode(m_lastElementUnderMouse.get());
+ RenderLayer* layerForNodeUnderMouse = layerForNode(m_elementUnderMouse.get());
Page* page = m_frame.page();
if (m_lastElementUnderMouse && (!m_elementUnderMouse || &m_elementUnderMouse->document() != m_frame.document())) {
@@ -2363,12 +2338,12 @@ void EventHandler::updateMouseEventTargetNode(Node* targetNode, const PlatformMo
if (FrameView* frameView = frame->view())
frameView->mouseExitedContentArea();
}
- } else if (page && (scrollableAreaForLastNode && (!scrollableAreaForNodeUnderMouse || scrollableAreaForNodeUnderMouse != scrollableAreaForLastNode))) {
+ } else if (page && (layerForLastNode && (!layerForNodeUnderMouse || layerForNodeUnderMouse != layerForLastNode))) {
// The mouse has moved between layers.
if (Frame* frame = m_lastElementUnderMouse->document().frame()) {
if (FrameView* frameView = frame->view()) {
- if (frameView->containsScrollableArea(scrollableAreaForLastNode))
- scrollableAreaForLastNode->mouseExitedContentArea();
+ if (frameView->containsScrollableArea(layerForLastNode))
+ layerForLastNode->mouseExitedContentArea();
}
}
}
@@ -2379,12 +2354,12 @@ void EventHandler::updateMouseEventTargetNode(Node* targetNode, const PlatformMo
if (FrameView* frameView = frame->view())
frameView->mouseEnteredContentArea();
}
- } else if (page && (scrollableAreaForNodeUnderMouse && (!scrollableAreaForLastNode || scrollableAreaForNodeUnderMouse != scrollableAreaForLastNode))) {
+ } else if (page && (layerForNodeUnderMouse && (!layerForLastNode || layerForNodeUnderMouse != layerForLastNode))) {
// The mouse has moved between layers.
if (Frame* frame = m_elementUnderMouse->document().frame()) {
if (FrameView* frameView = frame->view()) {
- if (frameView->containsScrollableArea(scrollableAreaForNodeUnderMouse))
- scrollableAreaForNodeUnderMouse->mouseEnteredContentArea();
+ if (frameView->containsScrollableArea(layerForNodeUnderMouse))
+ layerForNodeUnderMouse->mouseEnteredContentArea();
}
}
}
@@ -2392,83 +2367,43 @@ void EventHandler::updateMouseEventTargetNode(Node* targetNode, const PlatformMo
if (m_lastElementUnderMouse && &m_lastElementUnderMouse->document() != m_frame.document()) {
m_lastElementUnderMouse = nullptr;
m_lastScrollbarUnderMouse = nullptr;
+#if ENABLE(SVG)
+ m_lastInstanceUnderMouse = 0;
+#endif
}
if (m_lastElementUnderMouse != m_elementUnderMouse) {
- // mouseenter and mouseleave events are only dispatched if there is a capturing eventhandler on an ancestor
- // or a normal eventhandler on the element itself (they don't bubble).
- // This optimization is necessary since these events can cause O(n^2) capturing event-handler checks.
- bool hasCapturingMouseEnterListener = hierarchyHasCapturingEventListeners(m_elementUnderMouse.get(), eventNames().mouseenterEvent);
- bool hasCapturingMouseLeaveListener = hierarchyHasCapturingEventListeners(m_lastElementUnderMouse.get(), eventNames().mouseleaveEvent);
-
- RenderElement* oldHoverRenderer = m_lastElementUnderMouse ? m_lastElementUnderMouse->renderer() : nullptr;
- RenderElement* newHoverRenderer = m_elementUnderMouse ? m_elementUnderMouse->renderer() : nullptr;
- RenderElement* ancestor = nearestCommonHoverAncestor(oldHoverRenderer, newHoverRenderer);
-
- Vector<Ref<Element>, 32> leftElementsChain;
- if (oldHoverRenderer) {
- for (RenderElement* curr = oldHoverRenderer; curr && curr != ancestor; curr = curr->hoverAncestor()) {
- if (Element* element = curr->element())
- leftElementsChain.append(*element);
- }
- } else {
- // If the old hovered element is not null but it's renderer is, it was probably detached.
- // In this case, the old hovered element (and its ancestors) must be updated, to ensure it's normal style is re-applied.
- for (Element* element = m_lastElementUnderMouse.get(); element; element = element->parentElement())
- leftElementsChain.append(*element);
- }
-
- Vector<Ref<Element>, 32> enteredElementsChain;
- const Element* ancestorElement = ancestor ? ancestor->element() : nullptr;
- for (RenderElement* curr = newHoverRenderer; curr; curr = curr->hoverAncestor()) {
- if (Element *element = curr->element()) {
- if (element == ancestorElement)
- break;
- enteredElementsChain.append(*element);
- }
- }
-
- // Send mouseout event to the old node.
+ // send mouseout event to the old node
if (m_lastElementUnderMouse)
- m_lastElementUnderMouse->dispatchMouseEvent(platformMouseEvent, eventNames().mouseoutEvent, 0, m_elementUnderMouse.get());
-
- // Send mouseleave to the node hierarchy no longer under the mouse.
- for (auto& chain : leftElementsChain) {
- if (hasCapturingMouseLeaveListener || chain->hasEventListeners(eventNames().mouseleaveEvent))
- chain->dispatchMouseEvent(platformMouseEvent, eventNames().mouseleaveEvent, 0, m_elementUnderMouse.get());
- }
-
- // Send mouseover event to the new node.
+ m_lastElementUnderMouse->dispatchMouseEvent(mouseEvent, eventNames().mouseoutEvent, 0, m_elementUnderMouse.get());
+ // send mouseover event to the new node
if (m_elementUnderMouse)
- m_elementUnderMouse->dispatchMouseEvent(platformMouseEvent, eventNames().mouseoverEvent, 0, m_lastElementUnderMouse.get());
-
- // Send mouseleave event to the nodes hierarchy under the mouse.
- for (auto& chain : enteredElementsChain) {
- if (hasCapturingMouseEnterListener || chain->hasEventListeners(eventNames().mouseenterEvent))
- chain->dispatchMouseEvent(platformMouseEvent, eventNames().mouseenterEvent, 0, m_lastElementUnderMouse.get());
- }
+ m_elementUnderMouse->dispatchMouseEvent(mouseEvent, eventNames().mouseoverEvent, 0, m_lastElementUnderMouse.get());
}
m_lastElementUnderMouse = m_elementUnderMouse;
+#if ENABLE(SVG)
+ m_lastInstanceUnderMouse = instanceAssociatedWithShadowTreeElement(m_elementUnderMouse.get());
+#endif
}
}
-bool EventHandler::dispatchMouseEvent(const AtomicString& eventType, Node* targetNode, bool /*cancelable*/, int clickCount, const PlatformMouseEvent& platformMouseEvent, bool setUnder)
+bool EventHandler::dispatchMouseEvent(const AtomicString& eventType, Node* targetNode, bool /*cancelable*/, int clickCount, const PlatformMouseEvent& mouseEvent, bool setUnder)
{
if (FrameView* view = m_frame.view())
view->disableLayerFlushThrottlingTemporarilyForInteraction();
- updateMouseEventTargetNode(targetNode, platformMouseEvent, setUnder);
+ updateMouseEventTargetNode(targetNode, mouseEvent, setUnder);
bool swallowEvent = false;
if (m_elementUnderMouse)
- swallowEvent = !(m_elementUnderMouse->dispatchMouseEvent(platformMouseEvent, eventType, clickCount));
+ swallowEvent = !(m_elementUnderMouse->dispatchMouseEvent(mouseEvent, eventType, clickCount));
if (!swallowEvent && eventType == eventNames().mousedownEvent) {
// If clicking on a frame scrollbar, do not mess up with content focus.
if (FrameView* view = m_frame.view()) {
- if (view->scrollbarAtPoint(platformMouseEvent.position()))
+ if (view->scrollbarAtPoint(mouseEvent.position()))
return true;
}
@@ -2499,7 +2434,7 @@ bool EventHandler::dispatchMouseEvent(const AtomicString& eventType, Node* targe
}
// Only change the focus when clicking scrollbars if it can transfered to a mouse focusable node.
- if ((!element || !element->isMouseFocusable()) && isInsideScrollbar(platformMouseEvent.position()))
+ if ((!element || !element->isMouseFocusable()) && isInsideScrollbar(mouseEvent.position()))
return false;
// If focus shift is blocked, we eat the event. Note we should never clear swallowEvent
@@ -2531,52 +2466,54 @@ bool EventHandler::isInsideScrollbar(const IntPoint& windowPoint) const
}
#if !PLATFORM(GTK)
-
bool EventHandler::shouldTurnVerticalTicksIntoHorizontal(const HitTestResult&, const PlatformWheelEvent&) const
{
return false;
}
-
#endif
-#if !PLATFORM(MAC)
-
-void EventHandler::platformPrepareForWheelEvents(const PlatformWheelEvent&, const HitTestResult&, RefPtr<Element>&, RefPtr<ContainerNode>&, ScrollableArea*&, bool&)
+void EventHandler::recordWheelEventDelta(const PlatformWheelEvent& event)
{
+ const size_t recentEventCount = 3;
+
+ m_recentWheelEventDeltas.append(FloatSize(event.deltaX(), event.deltaY()));
+ if (m_recentWheelEventDeltas.size() > recentEventCount)
+ m_recentWheelEventDeltas.removeFirst();
}
-void EventHandler::platformRecordWheelEvent(const PlatformWheelEvent& event)
+static bool deltaIsPredominantlyVertical(const FloatSize& delta)
{
- m_frame.mainFrame().wheelEventDeltaFilter()->updateFromDelta(FloatSize(event.deltaX(), event.deltaY()));
+ return fabs(delta.height()) > fabs(delta.width());
}
-bool EventHandler::platformCompleteWheelEvent(const PlatformWheelEvent& event, ContainerNode*, ScrollableArea*)
+EventHandler::DominantScrollGestureDirection EventHandler::dominantScrollGestureDirection() const
{
- // We do another check on the frame view because the event handler can run JS which results in the frame getting destroyed.
- FrameView* view = m_frame.view();
+ bool allVertical = m_recentWheelEventDeltas.size();
+ bool allHorizontal = m_recentWheelEventDeltas.size();
+
+ Deque<FloatSize>::const_iterator end = m_recentWheelEventDeltas.end();
+ for (Deque<FloatSize>::const_iterator it = m_recentWheelEventDeltas.begin(); it != end; ++it) {
+ bool isVertical = deltaIsPredominantlyVertical(*it);
+ allVertical &= isVertical;
+ allHorizontal &= !isVertical;
+ }
- bool didHandleEvent = view ? view->wheelEvent(event) : false;
- m_isHandlingWheelEvent = false;
- return didHandleEvent;
-}
+ if (allVertical)
+ return DominantScrollDirectionVertical;
-bool EventHandler::platformCompletePlatformWidgetWheelEvent(const PlatformWheelEvent&, const Widget&, ContainerNode*)
-{
- return true;
+ if (allHorizontal)
+ return DominantScrollDirectionHorizontal;
+
+ return DominantScrollDirectionNone;
}
-void EventHandler::platformNotifyIfEndGesture(const PlatformWheelEvent&, ScrollableArea*)
+bool EventHandler::handleWheelEvent(const PlatformWheelEvent& e)
{
-}
-
-#endif
+ Document* document = m_frame.document();
-bool EventHandler::handleWheelEvent(const PlatformWheelEvent& event)
-{
- RenderView* renderView = m_frame.contentRenderer();
- if (!renderView)
+ if (!document->renderView())
return false;
-
+
RefPtr<FrameView> protector(m_frame.view());
FrameView* view = m_frame.view();
@@ -2585,75 +2522,81 @@ bool EventHandler::handleWheelEvent(const PlatformWheelEvent& event)
m_isHandlingWheelEvent = true;
setFrameWasScrolledByUser();
+ LayoutPoint vPoint = view->windowToContents(e.position());
- HitTestRequest request;
- HitTestResult result(view->windowToContents(event.position()));
- renderView->hitTest(request, result);
+ HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::DisallowShadowContent);
+ HitTestResult result(vPoint);
+ document->renderView()->hitTest(request, result);
- RefPtr<Element> element = result.innerElement();
- RefPtr<ContainerNode> scrollableContainer;
- ScrollableArea* scrollableArea = nullptr;
- bool isOverWidget = result.isOverWidget();
- platformPrepareForWheelEvents(event, result, element, scrollableContainer, scrollableArea, isOverWidget);
+ bool useLatchedWheelEventElement = e.useLatchedEventElement();
-#if PLATFORM(MAC)
- if (event.phase() == PlatformWheelEventPhaseNone && event.momentumPhase() == PlatformWheelEventPhaseNone)
- m_frame.mainFrame().resetLatchingState();
-#endif
+ Element* element = result.innerElement();
+
+ bool isOverWidget;
+ if (useLatchedWheelEventElement) {
+ if (!m_latchedWheelEventElement) {
+ m_latchedWheelEventElement = element;
+ m_widgetIsLatched = result.isOverWidget();
+ } else
+ element = m_latchedWheelEventElement.get();
+
+ isOverWidget = m_widgetIsLatched;
+ } else {
+ if (m_latchedWheelEventElement)
+ m_latchedWheelEventElement = nullptr;
+ if (m_previousWheelScrolledElement)
+ m_previousWheelScrolledElement = nullptr;
+
+ isOverWidget = result.isOverWidget();
+ }
// FIXME: It should not be necessary to do this mutation here.
- // Instead, the handlers should know convert vertical scrolls appropriately.
- PlatformWheelEvent adjustedEvent = event;
- if (m_baseEventType == PlatformEvent::NoType && shouldTurnVerticalTicksIntoHorizontal(result, event))
- adjustedEvent = event.copyTurningVerticalTicksIntoHorizontalTicks();
+ // Instead, the handlers should know convert vertical scrolls
+ // appropriately.
+ PlatformWheelEvent event = e;
+ if (m_baseEventType == PlatformEvent::NoType && shouldTurnVerticalTicksIntoHorizontal(result, e))
+ event = event.copyTurningVerticalTicksIntoHorizontalTicks();
- platformRecordWheelEvent(adjustedEvent);
+#if PLATFORM(MAC)
+ switch (event.phase()) {
+ case PlatformWheelEventPhaseBegan:
+ m_recentWheelEventDeltas.clear();
+ m_inTrackingScrollGesturePhase = true;
+ break;
+ case PlatformWheelEventPhaseEnded:
+ m_inTrackingScrollGesturePhase = false;
+ break;
+ default:
+ break;
+ }
+#endif
+
+ recordWheelEventDelta(event);
if (element) {
- if (isOverWidget) {
- RenderElement* target = element->renderer();
- if (is<RenderWidget>(target)) {
- Widget* widget = downcast<RenderWidget>(*target).widget();
- if (widget && passWheelEventToWidget(event, *widget)) {
- m_isHandlingWheelEvent = false;
- if (scrollableArea)
- scrollableArea->setScrolledProgrammatically(false);
- platformNotifyIfEndGesture(adjustedEvent, scrollableArea);
- if (!widget->platformWidget())
- return true;
- return platformCompletePlatformWidgetWheelEvent(event, *widget, scrollableContainer.get());
- }
+ // Figure out which view to send the event to.
+ RenderElement* target = element->renderer();
+
+ if (isOverWidget && target && target->isWidget()) {
+ Widget* widget = toRenderWidget(target)->widget();
+ if (widget && passWheelEventToWidget(e, widget)) {
+ m_isHandlingWheelEvent = false;
+ return true;
}
}
- if (!element->dispatchWheelEvent(adjustedEvent)) {
+ if (!element->dispatchWheelEvent(event)) {
m_isHandlingWheelEvent = false;
- if (scrollableArea && scrollableArea->isScrolledProgrammatically()) {
- // Web developer is controlling scrolling, so don't attempt to latch.
- clearLatchedState();
- scrollableArea->setScrolledProgrammatically(false);
- }
-
- platformNotifyIfEndGesture(adjustedEvent, scrollableArea);
return true;
}
}
- if (scrollableArea)
- scrollableArea->setScrolledProgrammatically(false);
-
- bool handledEvent = platformCompleteWheelEvent(adjustedEvent, scrollableContainer.get(), scrollableArea);
- platformNotifyIfEndGesture(adjustedEvent, scrollableArea);
- return handledEvent;
-}
-void EventHandler::clearLatchedState()
-{
-#if PLATFORM(MAC)
- m_frame.mainFrame().resetLatchingState();
-#endif
- if (auto filter = m_frame.mainFrame().wheelEventDeltaFilter())
- filter->endFilteringDeltas();
+ // We do another check on the frame view because the event handler can run JS which results in the frame getting destroyed.
+ view = m_frame.view();
+ bool didHandleEvent = view ? view->wheelEvent(event) : false;
+ m_isHandlingWheelEvent = false;
+ return didHandleEvent;
}
void EventHandler::defaultWheelEventHandler(Node* startNode, WheelEvent* wheelEvent)
@@ -2661,62 +2604,53 @@ void EventHandler::defaultWheelEventHandler(Node* startNode, WheelEvent* wheelEv
if (!startNode || !wheelEvent)
return;
- FloatSize filteredPlatformDelta(wheelEvent->deltaX(), wheelEvent->deltaY());
- if (const PlatformWheelEvent* platformWheelEvent = wheelEvent->wheelEvent()) {
- filteredPlatformDelta.setWidth(platformWheelEvent->deltaX());
- filteredPlatformDelta.setHeight(platformWheelEvent->deltaY());
- }
+ Element* stopElement = m_previousWheelScrolledElement.get();
+ ScrollGranularity granularity = wheelGranularityToScrollGranularity(wheelEvent->deltaMode());
-#if PLATFORM(MAC)
- ScrollLatchingState* latchedState = m_frame.mainFrame().latchingState();
- Element* stopElement = latchedState ? latchedState->previousWheelScrolledElement() : nullptr;
-
- if (m_frame.mainFrame().wheelEventDeltaFilter()->isFilteringDeltas())
- filteredPlatformDelta = m_frame.mainFrame().wheelEventDeltaFilter()->filteredDelta();
-#else
- Element* stopElement = nullptr;
-#endif
+ DominantScrollGestureDirection dominantDirection = DominantScrollDirectionNone;
+ // Workaround for scrolling issues in iTunes (<rdar://problem/14758615>).
+ if (m_inTrackingScrollGesturePhase && applicationIsITunes())
+ dominantDirection = dominantScrollGestureDirection();
+ // Break up into two scrolls if we need to. Diagonal movement on
+ // a MacBook pro is an example of a 2-dimensional mouse wheel event (where both deltaX and deltaY can be set).
+ if (dominantDirection != DominantScrollDirectionVertical && scrollNode(wheelEvent->deltaX(), granularity, ScrollRight, ScrollLeft, startNode, &stopElement, roundedIntPoint(wheelEvent->absoluteLocation())))
+ wheelEvent->setDefaultHandled();
- if (handleWheelEventInAppropriateEnclosingBox(startNode, wheelEvent, &stopElement, filteredPlatformDelta))
+ if (dominantDirection != DominantScrollDirectionHorizontal && scrollNode(wheelEvent->deltaY(), granularity, ScrollDown, ScrollUp, startNode, &stopElement, roundedIntPoint(wheelEvent->absoluteLocation())))
wheelEvent->setDefaultHandled();
-#if PLATFORM(MAC)
- if (latchedState && !latchedState->wheelEventElement())
- latchedState->setPreviousWheelScrolledElement(stopElement);
-#endif
+ if (!m_latchedWheelEventElement)
+ m_previousWheelScrolledElement = stopElement;
}
#if ENABLE(CONTEXT_MENUS)
bool EventHandler::sendContextMenuEvent(const PlatformMouseEvent& event)
{
Document* doc = m_frame.document();
- FrameView* view = m_frame.view();
- if (!view)
+ FrameView* v = m_frame.view();
+ if (!v)
return false;
-
+
// Clear mouse press state to avoid initiating a drag while context menu is up.
m_mousePressed = false;
bool swallowEvent;
- LayoutPoint viewportPos = view->windowToContents(event.position());
+ LayoutPoint viewportPos = v->windowToContents(event.position());
HitTestRequest request(HitTestRequest::Active | HitTestRequest::DisallowShadowContent);
- MouseEventWithHitTestResults mouseEvent = doc->prepareMouseEvent(request, viewportPos, event);
-
- // Do not show context menus when clicking on scrollbars.
- if (mouseEvent.scrollbar() || view->scrollbarAtPoint(event.position()))
- return false;
+ MouseEventWithHitTestResults mev = doc->prepareMouseEvent(request, viewportPos, event);
if (m_frame.editor().behavior().shouldSelectOnContextualMenuClick()
&& !m_frame.selection().contains(viewportPos)
+ && !mev.scrollbar()
// FIXME: In the editable case, word selection sometimes selects content that isn't underneath the mouse.
// If the selection is non-editable, we do word selection to make it easier to use the contextual menu items
// available for text selections. But only if we're above text.
- && (m_frame.selection().selection().isContentEditable() || (mouseEvent.targetNode() && mouseEvent.targetNode()->isTextNode()))) {
+ && (m_frame.selection().isContentEditable() || (mev.targetNode() && mev.targetNode()->isTextNode()))) {
m_mouseDownMayStartSelect = true; // context menu events are always allowed to perform a selection
- selectClosestContextualWordOrLinkFromMouseEvent(mouseEvent);
+ selectClosestWordOrLinkFromMouseEvent(mev);
}
- swallowEvent = !dispatchMouseEvent(eventNames().contextmenuEvent, mouseEvent.targetNode(), true, 0, event, false);
+ swallowEvent = !dispatchMouseEvent(eventNames().contextmenuEvent, mev.targetNode(), true, 0, event, false);
return swallowEvent;
}
@@ -2736,7 +2670,7 @@ bool EventHandler::sendContextMenuEventForKey()
static const int kContextMenuMargin = 1;
-#if OS(WINDOWS)
+#if OS(WINDOWS) && !OS(WINCE)
int rightAligned = ::GetSystemMetrics(SM_MENUDROPALIGNMENT);
#else
int rightAligned = 0;
@@ -2744,8 +2678,8 @@ bool EventHandler::sendContextMenuEventForKey()
IntPoint location;
Element* focusedElement = doc->focusedElement();
- const VisibleSelection& selection = m_frame.selection().selection();
- Position start = selection.start();
+ FrameSelection& selection = m_frame.selection();
+ Position start = selection.selection().start();
if (start.deprecatedNode() && (selection.rootEditableElement() || selection.isRange())) {
RefPtr<Range> selectionRange = selection.toNormalizedRange();
@@ -2790,9 +2724,9 @@ bool EventHandler::sendContextMenuEventForKey()
PlatformEvent::Type eventType = PlatformEvent::MousePressed;
#endif
- PlatformMouseEvent platformMouseEvent(position, globalPosition, RightButton, eventType, 1, false, false, false, false, WTF::currentTime(), ForceAtClick);
+ PlatformMouseEvent mouseEvent(position, globalPosition, RightButton, eventType, 1, false, false, false, false, WTF::currentTime());
- return !dispatchMouseEvent(eventNames().contextmenuEvent, targetNode, true, 0, platformMouseEvent, false);
+ return !dispatchMouseEvent(eventNames().contextmenuEvent, targetNode, true, 0, mouseEvent, false);
}
#endif // ENABLE(CONTEXT_MENUS)
@@ -2812,33 +2746,31 @@ void EventHandler::scheduleCursorUpdate()
void EventHandler::dispatchFakeMouseMoveEventSoon()
{
-#if !ENABLE(IOS_TOUCH_EVENTS)
if (m_mousePressed)
return;
if (m_mousePositionIsUnknown)
return;
- if (Page* page = m_frame.page()) {
- if (!page->chrome().client().shouldDispatchFakeMouseMoveEvents())
- return;
- }
+ if (!m_frame.settings().deviceSupportsMouse())
+ return;
// If the content has ever taken longer than fakeMouseMoveShortInterval we
// reschedule the timer and use a longer time. This will cause the content
// to receive these moves only after the user is done scrolling, reducing
// pauses during the scroll.
- if (m_fakeMouseMoveEventTimer.isActive())
- m_fakeMouseMoveEventTimer.stop();
- m_fakeMouseMoveEventTimer.startOneShot(m_maxMouseMovedDuration > fakeMouseMoveDurationThreshold ? fakeMouseMoveLongInterval : fakeMouseMoveShortInterval);
-#endif
+ if (m_maxMouseMovedDuration > fakeMouseMoveDurationThreshold) {
+ if (m_fakeMouseMoveEventTimer.isActive())
+ m_fakeMouseMoveEventTimer.stop();
+ m_fakeMouseMoveEventTimer.startOneShot(fakeMouseMoveLongInterval);
+ } else {
+ if (!m_fakeMouseMoveEventTimer.isActive())
+ m_fakeMouseMoveEventTimer.startOneShot(fakeMouseMoveShortInterval);
+ }
}
void EventHandler::dispatchFakeMouseMoveEventSoonInQuad(const FloatQuad& quad)
{
-#if ENABLE(IOS_TOUCH_EVENTS)
- UNUSED_PARAM(quad);
-#else
FrameView* view = m_frame.view();
if (!view)
return;
@@ -2847,19 +2779,21 @@ void EventHandler::dispatchFakeMouseMoveEventSoonInQuad(const FloatQuad& quad)
return;
dispatchFakeMouseMoveEventSoon();
-#endif
}
-#if !ENABLE(IOS_TOUCH_EVENTS)
void EventHandler::cancelFakeMouseMoveEvent()
{
m_fakeMouseMoveEventTimer.stop();
}
-void EventHandler::fakeMouseMoveEventTimerFired()
+void EventHandler::fakeMouseMoveEventTimerFired(Timer<EventHandler>& timer)
{
+ ASSERT_UNUSED(timer, &timer == &m_fakeMouseMoveEventTimer);
ASSERT(!m_mousePressed);
+ if (!m_frame.settings().deviceSupportsMouse())
+ return;
+
FrameView* view = m_frame.view();
if (!view)
return;
@@ -2872,10 +2806,9 @@ void EventHandler::fakeMouseMoveEventTimerFired()
bool altKey;
bool metaKey;
PlatformKeyboardEvent::getCurrentModifierState(shiftKey, ctrlKey, altKey, metaKey);
- PlatformMouseEvent fakeMouseMoveEvent(m_lastKnownMousePosition, m_lastKnownMouseGlobalPosition, NoButton, PlatformEvent::MouseMoved, 0, shiftKey, ctrlKey, altKey, metaKey, currentTime(), 0);
+ PlatformMouseEvent fakeMouseMoveEvent(m_lastKnownMousePosition, m_lastKnownMouseGlobalPosition, NoButton, PlatformEvent::MouseMoved, 0, shiftKey, ctrlKey, altKey, metaKey, currentTime());
mouseMoved(fakeMouseMoveEvent);
}
-#endif // !ENABLE(IOS_TOUCH_EVENTS)
void EventHandler::setResizingFrameSet(HTMLFrameSetElement* frameSet)
{
@@ -2885,42 +2818,43 @@ void EventHandler::setResizingFrameSet(HTMLFrameSetElement* frameSet)
void EventHandler::resizeLayerDestroyed()
{
ASSERT(m_resizeLayer);
- m_resizeLayer = nullptr;
+ m_resizeLayer = 0;
}
-void EventHandler::hoverTimerFired()
+void EventHandler::hoverTimerFired(Timer<EventHandler>&)
{
m_hoverTimer.stop();
ASSERT(m_frame.document());
- if (RenderView* renderView = m_frame.contentRenderer()) {
+ if (RenderView* renderer = m_frame.contentRenderer()) {
if (FrameView* view = m_frame.view()) {
HitTestRequest request(HitTestRequest::Move | HitTestRequest::DisallowShadowContent);
HitTestResult result(view->windowToContents(m_lastKnownMousePosition));
- renderView->hitTest(request, result);
+ renderer->hitTest(request, result);
m_frame.document()->updateHoverActiveState(request, result.innerElement());
}
}
}
-bool EventHandler::handleAccessKey(const PlatformKeyboardEvent& event)
+bool EventHandler::handleAccessKey(const PlatformKeyboardEvent& evt)
{
// FIXME: Ignoring the state of Shift key is what neither IE nor Firefox do.
// IE matches lower and upper case access keys regardless of Shift key state - but if both upper and
// lower case variants are present in a document, the correct element is matched based on Shift key state.
// Firefox only matches an access key if Shift is not pressed, and does that case-insensitively.
ASSERT(!(accessKeyModifiers() & PlatformEvent::ShiftKey));
- if ((event.modifiers() & ~PlatformEvent::ShiftKey) != accessKeyModifiers())
+ if ((evt.modifiers() & ~PlatformEvent::ShiftKey) != accessKeyModifiers())
return false;
- Element* element = m_frame.document()->getElementByAccessKey(event.unmodifiedText());
- if (!element)
+ String key = evt.unmodifiedText();
+ Element* elem = m_frame.document()->getElementByAccessKey(key.lower());
+ if (!elem)
return false;
- element->accessKeyAction(false);
+ elem->accessKeyAction(false);
return true;
}
-#if !PLATFORM(MAC)
+#if !PLATFORM(MAC) || PLATFORM(IOS)
bool EventHandler::needsKeyboardEventDisambiguationQuirks() const
{
return false;
@@ -2958,12 +2892,8 @@ bool EventHandler::keyEvent(const PlatformKeyboardEvent& initialKeyEvent)
return false;
#endif
- if (initialKeyEvent.windowsVirtualKeyCode() == VK_CAPITAL) {
- if (auto* element = m_frame.document()->focusedElement()) {
- if (is<HTMLInputElement>(*element))
- downcast<HTMLInputElement>(*element).capsLockStateMayHaveChanged();
- }
- }
+ if (initialKeyEvent.windowsVirtualKeyCode() == VK_CAPITAL)
+ capsLockStateMayHaveChanged();
#if ENABLE(PAN_SCROLLING)
if (m_frame.mainFrame().eventHandler().panScrollInProgress()) {
@@ -2982,7 +2912,7 @@ bool EventHandler::keyEvent(const PlatformKeyboardEvent& initialKeyEvent)
if (!element)
return false;
- UserGestureIndicator gestureIndicator(DefinitelyProcessingUserGesture, m_frame.document());
+ UserGestureIndicator gestureIndicator(DefinitelyProcessingUserGesture);
UserTypingGestureIndicator typingGestureIndicator(m_frame);
if (FrameView* view = m_frame.view())
@@ -3009,13 +2939,13 @@ bool EventHandler::keyEvent(const PlatformKeyboardEvent& initialKeyEvent)
PlatformKeyboardEvent keyDownEvent = initialKeyEvent;
if (keyDownEvent.type() != PlatformEvent::RawKeyDown)
keyDownEvent.disambiguateKeyDownEvent(PlatformEvent::RawKeyDown, backwardCompatibilityMode);
- Ref<KeyboardEvent> keydown = KeyboardEvent::create(keyDownEvent, m_frame.document()->defaultView());
+ RefPtr<KeyboardEvent> keydown = KeyboardEvent::create(keyDownEvent, m_frame.document()->defaultView());
if (matchedAnAccessKey)
keydown->setDefaultPrevented(true);
keydown->setTarget(element);
if (initialKeyEvent.type() == PlatformEvent::RawKeyDown) {
- element->dispatchEvent(keydown);
+ element->dispatchEvent(keydown, IGNORE_EXCEPTION);
// If frame changed as a result of keydown dispatch, then return true to avoid sending a subsequent keypress message to the new frame.
bool changedFocusedFrame = m_frame.page() && &m_frame != &m_frame.page()->focusController().focusedOrMainFrame();
return keydown->defaultHandled() || keydown->defaultPrevented() || changedFocusedFrame;
@@ -3026,7 +2956,7 @@ bool EventHandler::keyEvent(const PlatformKeyboardEvent& initialKeyEvent)
// in order to match IE:
// 1. preventing default handling of keydown and keypress events has no effect on IM input;
// 2. if an input method handles the event, its keyCode is set to 229 in keydown event.
- m_frame.editor().handleInputMethodKeydown(keydown.ptr());
+ m_frame.editor().handleInputMethodKeydown(keydown.get());
bool handledByInputMethod = keydown->defaultHandled();
@@ -3036,11 +2966,8 @@ bool EventHandler::keyEvent(const PlatformKeyboardEvent& initialKeyEvent)
keydown->setTarget(element);
keydown->setDefaultHandled();
}
-
- if (accessibilityPreventsEventPropogation(keydown))
- keydown->stopPropagation();
- element->dispatchEvent(keydown);
+ element->dispatchEvent(keydown, IGNORE_EXCEPTION);
// If frame changed as a result of keydown dispatch, then return early to avoid sending a subsequent keypress message to the new frame.
bool changedFocusedFrame = m_frame.page() && &m_frame != &m_frame.page()->focusController().focusedOrMainFrame();
bool keydownResult = keydown->defaultHandled() || keydown->defaultPrevented() || changedFocusedFrame;
@@ -3059,24 +2986,24 @@ bool EventHandler::keyEvent(const PlatformKeyboardEvent& initialKeyEvent)
keyPressEvent.disambiguateKeyDownEvent(PlatformEvent::Char, backwardCompatibilityMode);
if (keyPressEvent.text().isEmpty())
return keydownResult;
- Ref<KeyboardEvent> keypress = KeyboardEvent::create(keyPressEvent, m_frame.document()->defaultView());
+ RefPtr<KeyboardEvent> keypress = KeyboardEvent::create(keyPressEvent, m_frame.document()->defaultView());
keypress->setTarget(element);
if (keydownResult)
keypress->setDefaultPrevented(true);
-#if PLATFORM(COCOA)
+#if PLATFORM(MAC)
keypress->keypressCommands() = keydown->keypressCommands();
#endif
- element->dispatchEvent(keypress);
+ element->dispatchEvent(keypress, IGNORE_EXCEPTION);
return keydownResult || keypress->defaultPrevented() || keypress->defaultHandled();
}
static FocusDirection focusDirectionForKey(const AtomicString& keyIdentifier)
{
- static NeverDestroyed<AtomicString> Down("Down", AtomicString::ConstructFromLiteral);
- static NeverDestroyed<AtomicString> Up("Up", AtomicString::ConstructFromLiteral);
- static NeverDestroyed<AtomicString> Left("Left", AtomicString::ConstructFromLiteral);
- static NeverDestroyed<AtomicString> Right("Right", AtomicString::ConstructFromLiteral);
+ DEFINE_STATIC_LOCAL(AtomicString, Down, ("Down", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(AtomicString, Up, ("Up", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(AtomicString, Left, ("Left", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(AtomicString, Right, ("Right", AtomicString::ConstructFromLiteral));
FocusDirection retVal = FocusDirectionNone;
@@ -3092,53 +3019,14 @@ static FocusDirection focusDirectionForKey(const AtomicString& keyIdentifier)
return retVal;
}
-static void setInitialKeyboardSelection(Frame& frame, SelectionDirection direction)
-{
- Document* document = frame.document();
- if (!document)
- return;
-
- FrameSelection& selection = frame.selection();
-
- if (!selection.isNone())
- return;
-
- Element* focusedElement = document->focusedElement();
- VisiblePosition visiblePosition;
-
- switch (direction) {
- case DirectionBackward:
- case DirectionLeft:
- if (focusedElement)
- visiblePosition = VisiblePosition(positionBeforeNode(focusedElement));
- else
- visiblePosition = endOfDocument(document);
- break;
- case DirectionForward:
- case DirectionRight:
- if (focusedElement)
- visiblePosition = VisiblePosition(positionAfterNode(focusedElement));
- else
- visiblePosition = startOfDocument(document);
- break;
- }
-
- AXTextStateChangeIntent intent(AXTextStateChangeTypeSelectionMove, AXTextSelection { AXTextSelectionDirectionDiscontiguous, AXTextSelectionGranularityUnknown, false });
- selection.setSelection(visiblePosition, FrameSelection::defaultSetSelectionOptions(UserTriggered), intent);
-}
-
-static void handleKeyboardSelectionMovement(Frame& frame, KeyboardEvent* event)
+static void handleKeyboardSelectionMovement(FrameSelection& selection, KeyboardEvent* event)
{
if (!event)
return;
- FrameSelection& selection = frame.selection();
-
- bool isCommanded = event->getModifierState("Meta");
bool isOptioned = event->getModifierState("Alt");
- bool isSelection = !selection.isNone();
+ bool isCommanded = event->getModifierState("Meta");
- FrameSelection::EAlteration alternation = event->getModifierState("Shift") ? FrameSelection::AlterationExtend : FrameSelection::AlterationMove;
SelectionDirection direction = DirectionForward;
TextGranularity granularity = CharacterGranularity;
@@ -3167,11 +3055,8 @@ static void handleKeyboardSelectionMovement(Frame& frame, KeyboardEvent* event)
break;
}
- if (isSelection)
- selection.modify(alternation, direction, granularity, UserTriggered);
- else
- setInitialKeyboardSelection(frame, direction);
-
+ FrameSelection::EAlteration alternation = event->getModifierState("Shift") ? FrameSelection::AlterationExtend : FrameSelection::AlterationMove;
+ selection.modify(alternation, direction, granularity, UserTriggered);
event->setDefaultHandled();
}
@@ -3179,31 +3064,10 @@ void EventHandler::handleKeyboardSelectionMovementForAccessibility(KeyboardEvent
{
if (event->type() == eventNames().keydownEvent) {
if (AXObjectCache::accessibilityEnhancedUserInterfaceEnabled())
- handleKeyboardSelectionMovement(m_frame, event);
+ handleKeyboardSelectionMovement(m_frame.selection(), event);
}
}
-bool EventHandler::accessibilityPreventsEventPropogation(KeyboardEvent& event)
-{
-#if PLATFORM(COCOA)
- if (!AXObjectCache::accessibilityEnhancedUserInterfaceEnabled())
- return false;
-
- if (!m_frame.settings().preventKeyboardDOMEventDispatch())
- return false;
-
- // Check for key events that are relevant to accessibility: tab and arrows keys that change focus
- if (event.keyIdentifier() == "U+0009")
- return true;
- FocusDirection direction = focusDirectionForKey(event.keyIdentifier());
- if (direction != FocusDirectionNone)
- return true;
-#else
- UNUSED_PARAM(event);
-#endif
- return false;
-}
-
void EventHandler::defaultKeyboardEventHandler(KeyboardEvent* event)
{
if (event->type() == eventNames().keydownEvent) {
@@ -3240,15 +3104,18 @@ bool EventHandler::dragHysteresisExceeded(const IntPoint& floatDragViewportLocat
bool EventHandler::dragHysteresisExceeded(const FloatPoint& dragViewportLocation) const
{
+ FrameView* view = m_frame.view();
+ if (!view)
+ return false;
+ IntPoint dragLocation = view->windowToContents(flooredIntPoint(dragViewportLocation));
+ IntSize delta = dragLocation - m_mouseDownPos;
+
int threshold = GeneralDragHysteresis;
switch (dragState().type) {
case DragSourceActionSelection:
threshold = TextDragHysteresis;
break;
case DragSourceActionImage:
-#if ENABLE(ATTACHMENT_ELEMENT)
- case DragSourceActionAttachment:
-#endif
threshold = ImageDragHysteresis;
break;
case DragSourceActionLink:
@@ -3261,15 +3128,15 @@ bool EventHandler::dragHysteresisExceeded(const FloatPoint& dragViewportLocation
ASSERT_NOT_REACHED();
}
- return mouseMovementExceedsThreshold(dragViewportLocation, threshold);
+ return abs(delta.width()) >= threshold || abs(delta.height()) >= threshold;
}
-void EventHandler::freeDataTransfer()
+void EventHandler::freeClipboard()
{
- if (!dragState().dataTransfer)
+ if (!dragState().clipboard)
return;
- dragState().dataTransfer->setAccessPolicy(DataTransferAccessPolicy::Numb);
- dragState().dataTransfer = nullptr;
+ dragState().clipboard->setAccessPolicy(ClipboardNumb);
+ dragState().clipboard = 0;
}
void EventHandler::dragSourceEndedAt(const PlatformMouseEvent& event, DragOperation operation)
@@ -3279,12 +3146,12 @@ void EventHandler::dragSourceEndedAt(const PlatformMouseEvent& event, DragOperat
prepareMouseEvent(request, event);
if (dragState().source && dragState().shouldDispatchEvents) {
- dragState().dataTransfer->setDestinationOperation(operation);
+ dragState().clipboard->setDestinationOperation(operation);
// For now we don't care if event handler cancels default behavior, since there is no default behavior.
dispatchDragSrcEvent(eventNames().dragendEvent, event);
}
- freeDataTransfer();
- dragState().source = nullptr;
+ freeClipboard();
+ dragState().source = 0;
// In case the drag was ended due to an escape key press we need to ensure
// that consecutive mousemove events don't reinitiate the drag and drop.
m_mouseDownMayStartDrag = false;
@@ -3300,7 +3167,7 @@ void EventHandler::updateDragStateAfterEditDragIfNeeded(Element* rootEditableEle
// Return value indicates if we should continue "default processing", i.e., whether event handler canceled.
bool EventHandler::dispatchDragSrcEvent(const AtomicString& eventType, const PlatformMouseEvent& event)
{
- return !dispatchDragEvent(eventType, *dragState().source, event, dragState().dataTransfer.get());
+ return !dispatchDragEvent(eventType, *dragState().source, event, dragState().clipboard.get());
}
static bool ExactlyOneBitSet(DragSourceAction n)
@@ -3350,7 +3217,7 @@ bool EventHandler::handleDrag(const MouseEventWithHitTestResults& event, CheckDr
} else if (!(dragState().type & (DragSourceActionDHTML | DragSourceActionLink))) {
// ... but only bail if we're not over an unselectable element.
m_mouseDownMayStartDrag = false;
- dragState().source = nullptr;
+ dragState().source = 0;
// ... but if this was the first click in the window, we don't even want to start selection
if (eventActivatedView(event.event()))
m_mouseDownMayStartSelect = false;
@@ -3369,16 +3236,9 @@ bool EventHandler::handleDrag(const MouseEventWithHitTestResults& event, CheckDr
if (!ExactlyOneBitSet(dragState().type)) {
ASSERT((dragState().type & DragSourceActionSelection));
-#if ENABLE(ATTACHMENT_ELEMENT)
- ASSERT((dragState().type & ~DragSourceActionSelection) == DragSourceActionDHTML
- || (dragState().type & ~DragSourceActionSelection) == DragSourceActionImage
- || (dragState().type & ~DragSourceActionSelection) == DragSourceActionAttachment
- || (dragState().type & ~DragSourceActionSelection) == DragSourceActionLink);
-#else
ASSERT((dragState().type & ~DragSourceActionSelection) == DragSourceActionDHTML
|| (dragState().type & ~DragSourceActionSelection) == DragSourceActionImage
|| (dragState().type & ~DragSourceActionSelection) == DragSourceActionLink);
-#endif
dragState().type = DragSourceActionSelection;
}
@@ -3396,10 +3256,10 @@ bool EventHandler::handleDrag(const MouseEventWithHitTestResults& event, CheckDr
DragOperation srcOp = DragOperationNone;
- // This does work only if we missed a dragEnd. Do it anyway, just to make sure the old dataTransfer gets numbed.
- freeDataTransfer();
+ // This does work only if we missed a dragEnd. Do it anyway, just to make sure the old clipboard gets numbed.
+ freeClipboard();
- dragState().dataTransfer = createDraggingDataTransfer();
+ dragState().clipboard = createDraggingClipboard();
if (dragState().shouldDispatchEvents) {
// Check to see if the is a DOM based drag. If it is, get the DOM specified drag image and offset.
@@ -3408,7 +3268,7 @@ bool EventHandler::handleDrag(const MouseEventWithHitTestResults& event, CheckDr
// FIXME: This doesn't work correctly with transforms.
FloatPoint absPos = renderer->localToAbsolute();
IntSize delta = m_mouseDownPos - roundedIntPoint(absPos);
- dragState().dataTransfer->setDragImage(dragState().source.get(), delta.width(), delta.height());
+ dragState().clipboard->setDragImage(dragState().source.get(), delta.width(), delta.height());
} else {
// The renderer has disappeared, this can happen if the onStartDrag handler has hidden
// the element in some way. In this case we just kill the drag.
@@ -3418,20 +3278,20 @@ bool EventHandler::handleDrag(const MouseEventWithHitTestResults& event, CheckDr
}
m_mouseDownMayStartDrag = dispatchDragSrcEvent(eventNames().dragstartEvent, m_mouseDown)
- && !m_frame.selection().selection().isInPasswordField();
+ && !m_frame.selection().isInPasswordField();
- // Invalidate dataTransfer here against anymore pasteboard writing for security. The drag
+ // Invalidate clipboard here against anymore pasteboard writing for security. The drag
// image can still be changed as we drag, but not the pasteboard data.
- dragState().dataTransfer->setAccessPolicy(DataTransferAccessPolicy::ImageWritable);
+ dragState().clipboard->setAccessPolicy(ClipboardImageWritable);
if (m_mouseDownMayStartDrag) {
// Gather values from DHTML element, if it set any.
- srcOp = dragState().dataTransfer->sourceOperation();
+ srcOp = dragState().clipboard->sourceOperation();
// Yuck, a draggedImage:moveTo: message can be fired as a result of kicking off the
// drag with dragImage! Because of that dumb reentrancy, we may think we've not
// started the drag when that happens. So we have to assume it's started before we kick it off.
- dragState().dataTransfer->setDragHasStarted();
+ dragState().clipboard->setDragHasStarted();
}
}
@@ -3454,31 +3314,20 @@ bool EventHandler::handleDrag(const MouseEventWithHitTestResults& event, CheckDr
cleanupDrag:
if (!m_mouseDownMayStartDrag) {
// Something failed to start the drag, clean up.
- freeDataTransfer();
- dragState().source = nullptr;
+ freeClipboard();
+ dragState().source = 0;
}
// No more default handling (like selection), whether we're past the hysteresis bounds or not
return true;
}
#endif // ENABLE(DRAG_SUPPORT)
-
-bool EventHandler::mouseMovementExceedsThreshold(const FloatPoint& viewportLocation, int pointsThreshold) const
-{
- FrameView* view = m_frame.view();
- if (!view)
- return false;
- IntPoint location = view->windowToContents(flooredIntPoint(viewportLocation));
- IntSize delta = location - m_mouseDownPos;
-
- return abs(delta.width()) >= pointsThreshold || abs(delta.height()) >= pointsThreshold;
-}
-
+
bool EventHandler::handleTextInputEvent(const String& text, Event* underlyingEvent, TextEventInputType inputType)
{
// Platforms should differentiate real commands like selectAll from text input in disguise (like insertNewline),
// and avoid dispatching text input events from keydown default handlers.
- ASSERT(!is<KeyboardEvent>(underlyingEvent) || downcast<KeyboardEvent>(*underlyingEvent).type() == eventNames().keypressEvent);
+ ASSERT(!underlyingEvent || !underlyingEvent->isKeyboardEvent() || static_cast<KeyboardEvent*>(underlyingEvent)->type() == eventNames().keypressEvent);
EventTarget* target;
if (underlyingEvent)
@@ -3491,10 +3340,10 @@ bool EventHandler::handleTextInputEvent(const String& text, Event* underlyingEve
if (FrameView* view = m_frame.view())
view->disableLayerFlushThrottlingTemporarilyForInteraction();
- Ref<TextEvent> event = TextEvent::create(m_frame.document()->domWindow(), text, inputType);
+ RefPtr<TextEvent> event = TextEvent::create(m_frame.document()->domWindow(), text, inputType);
event->setUnderlyingEvent(underlyingEvent);
- target->dispatchEvent(event);
+ target->dispatchEvent(event, IGNORE_EXCEPTION);
return event->defaultHandled();
}
@@ -3508,7 +3357,7 @@ bool EventHandler::isKeyboardOptionTab(KeyboardEvent* event)
bool EventHandler::eventInvertsTabsToLinksClientCallResult(KeyboardEvent* event)
{
-#if PLATFORM(COCOA) || PLATFORM(EFL)
+#if PLATFORM(MAC) || PLATFORM(EFL)
return EventHandler::isKeyboardOptionTab(event);
#else
UNUSED_PARAM(event);
@@ -3632,6 +3481,17 @@ void EventHandler::defaultTabEventHandler(KeyboardEvent* event)
event->setDefaultHandled();
}
+void EventHandler::capsLockStateMayHaveChanged()
+{
+ Document* d = m_frame.document();
+ if (Element* element = d->focusedElement()) {
+ if (RenderObject* r = element->renderer()) {
+ if (r->isTextField())
+ toRenderTextControlSingleLine(r)->capsLockStateMayHaveChanged();
+ }
+ }
+}
+
void EventHandler::sendScrollEvent()
{
setFrameWasScrolledByUser();
@@ -3646,12 +3506,12 @@ void EventHandler::setFrameWasScrolledByUser()
v->setWasScrolledByUser(true);
}
-bool EventHandler::passMousePressEventToScrollbar(MouseEventWithHitTestResults& mouseEvent, Scrollbar* scrollbar)
+bool EventHandler::passMousePressEventToScrollbar(MouseEventWithHitTestResults& mev, Scrollbar* scrollbar)
{
if (!scrollbar || !scrollbar->enabled())
return false;
setFrameWasScrolledByUser();
- return scrollbar->mouseDown(mouseEvent.event());
+ return scrollbar->mouseDown(mev.event());
}
// If scrollbar (under mouse) is different from last, send a mouse exited. Set
@@ -3700,7 +3560,6 @@ static HitTestResult hitTestResultInFrame(Frame* frame, const LayoutPoint& point
if (!frame || !frame->contentRenderer())
return result;
-
if (frame->view()) {
IntRect rect = frame->view()->visibleContentRect();
if (!rect.contains(roundedIntPoint(point)))
@@ -3735,18 +3594,21 @@ bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event)
const Vector<PlatformTouchPoint>& points = event.touchPoints();
- UserGestureIndicator gestureIndicator(DefinitelyProcessingUserGesture, m_frame.document());
+ UserGestureIndicator gestureIndicator(DefinitelyProcessingUserGesture);
+ unsigned i;
bool freshTouchEvents = true;
bool allTouchReleased = true;
- for (auto& point : points) {
+ for (i = 0; i < points.size(); ++i) {
+ const PlatformTouchPoint& point = points[i];
if (point.state() != PlatformTouchPoint::TouchPressed)
freshTouchEvents = false;
if (point.state() != PlatformTouchPoint::TouchReleased && point.state() != PlatformTouchPoint::TouchCancelled)
allTouchReleased = false;
}
- for (auto& point : points) {
+ for (i = 0; i < points.size(); ++i) {
+ const PlatformTouchPoint& point = points[i];
PlatformTouchPoint::State pointState = point.state();
LayoutPoint pagePoint = documentPointForWindowPoint(m_frame, point.pos());
@@ -3798,7 +3660,7 @@ bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event)
Node* node = result.innerElement();
ASSERT(node);
- if (node && InspectorInstrumentation::handleTouchEvent(m_frame, *node))
+ if (InspectorInstrumentation::handleTouchEvent(m_frame.page(), node))
return true;
Document& doc = node->document();
@@ -3877,7 +3739,7 @@ bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event)
}
m_touchPressed = touches->length() > 0;
if (allTouchReleased)
- m_originatingTouchPointDocument = nullptr;
+ m_originatingTouchPointDocument.clear();
// Now iterate the changedTouches list and m_targets within it, sending events to the targets as required.
bool swallowedEvent = false;
@@ -3890,17 +3752,18 @@ bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event)
bool isTouchCancelEvent = (state == PlatformTouchPoint::TouchCancelled);
RefPtr<TouchList>& effectiveTouches(isTouchCancelEvent ? emptyList : touches);
const AtomicString& stateName(eventNameForTouchPointState(static_cast<PlatformTouchPoint::State>(state)));
+ const EventTargetSet& targetsForState = changedTouches[state].m_targets;
- for (auto& taget : changedTouches[state].m_targets) {
- EventTarget* touchEventTarget = taget.get();
+ for (EventTargetSet::const_iterator it = targetsForState.begin(); it != targetsForState.end(); ++it) {
+ EventTarget* touchEventTarget = it->get();
RefPtr<TouchList> targetTouches(isTouchCancelEvent ? emptyList : touchesByTarget.get(touchEventTarget));
ASSERT(targetTouches);
- Ref<TouchEvent> touchEvent =
+ RefPtr<TouchEvent> touchEvent =
TouchEvent::create(effectiveTouches.get(), targetTouches.get(), changedTouches[state].m_touches.get(),
stateName, touchEventTarget->toNode()->document().defaultView(),
0, 0, 0, 0, event.ctrlKey(), event.altKey(), event.shiftKey(), event.metaKey());
- touchEventTarget->toNode()->dispatchTouchEvent(touchEvent);
+ touchEventTarget->toNode()->dispatchTouchEvent(touchEvent.get());
swallowedEvent = swallowedEvent || touchEvent->defaultPrevented() || touchEvent->defaultHandled();
}
}
@@ -3910,29 +3773,29 @@ bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event)
#endif // ENABLE(TOUCH_EVENTS) && !ENABLE(IOS_TOUCH_EVENTS)
#if ENABLE(TOUCH_EVENTS)
-bool EventHandler::dispatchSyntheticTouchEventIfEnabled(const PlatformMouseEvent& platformMouseEvent)
+bool EventHandler::dispatchSyntheticTouchEventIfEnabled(const PlatformMouseEvent& event)
{
#if ENABLE(IOS_TOUCH_EVENTS)
- UNUSED_PARAM(platformMouseEvent);
+ UNUSED_PARAM(event);
return false;
#else
if (!m_frame.settings().isTouchEventEmulationEnabled())
return false;
- PlatformEvent::Type eventType = platformMouseEvent.type();
+ PlatformEvent::Type eventType = event.type();
if (eventType != PlatformEvent::MouseMoved && eventType != PlatformEvent::MousePressed && eventType != PlatformEvent::MouseReleased)
return false;
HitTestRequest request(HitTestRequest::Active | HitTestRequest::DisallowShadowContent);
- MouseEventWithHitTestResults mouseEvent = prepareMouseEvent(request, platformMouseEvent);
- if (mouseEvent.scrollbar() || subframeForHitTestResult(mouseEvent))
+ MouseEventWithHitTestResults mev = prepareMouseEvent(request, event);
+ if (mev.scrollbar() || subframeForHitTestResult(mev))
return false;
// The order is important. This check should follow the subframe test: http://webkit.org/b/111292.
if (eventType == PlatformEvent::MouseMoved && !m_touchPressed)
return true;
- SyntheticSingleTouchEvent touchEvent(platformMouseEvent);
+ SyntheticSingleTouchEvent touchEvent(event);
return handleTouchEvent(touchEvent);
#endif
}
@@ -3945,9 +3808,4 @@ void EventHandler::setLastKnownMousePosition(const PlatformMouseEvent& event)
m_lastKnownMouseGlobalPosition = event.globalPosition();
}
-void EventHandler::setImmediateActionStage(ImmediateActionStage stage)
-{
- m_immediateActionStage = stage;
-}
-
} // namespace WebCore
diff --git a/Source/WebCore/page/EventHandler.h b/Source/WebCore/page/EventHandler.h
index f666a1b40..387876f02 100644
--- a/Source/WebCore/page/EventHandler.h
+++ b/Source/WebCore/page/EventHandler.h
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -37,32 +37,39 @@
#include "TextEventInputType.h"
#include "TextGranularity.h"
#include "Timer.h"
-#include "WheelEventDeltaFilter.h"
-#include <memory>
+#include <wtf/Deque.h>
#include <wtf/Forward.h>
-#include <wtf/HashMap.h>
-#include <wtf/HashSet.h>
+#include <wtf/OwnPtr.h>
#include <wtf/RefPtr.h>
-#include <wtf/Vector.h>
#include <wtf/WeakPtr.h>
#if PLATFORM(IOS)
-OBJC_CLASS WebEvent;
-OBJC_CLASS WAKView;
#ifdef __OBJC__
+@class WebEvent;
+@class WAKView;
#include "WAKAppKitStubs.h"
+#else
+class WebEvent;
#endif
#endif // PLATFORM(IOS)
-#if PLATFORM(COCOA)
-OBJC_CLASS NSView;
+#if PLATFORM(MAC) && !defined(__OBJC__)
+class NSView;
+#endif
+
+#if ENABLE(TOUCH_EVENTS)
+#include <wtf/HashMap.h>
+#endif
+
+#if ENABLE(IOS_TOUCH_EVENTS)
+#include <wtf/HashSet.h>
+#include <wtf/Vector.h>
#endif
namespace WebCore {
class AutoscrollController;
-class ContainerNode;
-class DataTransfer;
+class Clipboard;
class Document;
class Element;
class Event;
@@ -77,7 +84,6 @@ class KeyboardEvent;
class MouseEventWithHitTestResults;
class Node;
class OptionalCursor;
-class PlatformGestureEvent;
class PlatformKeyboardEvent;
class PlatformTouchEvent;
class PlatformWheelEvent;
@@ -85,7 +91,7 @@ class RenderBox;
class RenderElement;
class RenderLayer;
class RenderWidget;
-class ScrollableArea;
+class SVGElementInstance;
class Scrollbar;
class TextEvent;
class Touch;
@@ -103,37 +109,29 @@ extern const int TextDragHysteresis;
extern const int GeneralDragHysteresis;
#endif // ENABLE(DRAG_SUPPORT)
-#if ENABLE(IOS_GESTURE_EVENTS) || ENABLE(MAC_GESTURE_EVENTS)
+#if ENABLE(IOS_GESTURE_EVENTS)
extern const float GestureUnknown;
-extern const unsigned InvalidTouchIdentifier;
#endif
enum AppendTrailingWhitespace { ShouldAppendTrailingWhitespace, DontAppendTrailingWhitespace };
enum CheckDragHysteresis { ShouldCheckDragHysteresis, DontCheckDragHysteresis };
-enum class ImmediateActionStage {
- None,
- PerformedHitTest,
- ActionUpdated,
- ActionCancelledWithoutUpdate,
- ActionCancelledAfterUpdate,
- ActionCompleted
-};
-
class EventHandler {
WTF_MAKE_NONCOPYABLE(EventHandler);
- WTF_MAKE_FAST_ALLOCATED;
public:
explicit EventHandler(Frame&);
~EventHandler();
void clear();
- void nodeWillBeRemoved(Node&);
+ void nodeWillBeRemoved(Node*);
#if ENABLE(DRAG_SUPPORT)
void updateSelectionForMouseDrag();
#endif
+ Node* mousePressNode() const;
+ void setMousePressNode(PassRefPtr<Node>);
+
#if ENABLE(PAN_SCROLLING)
void didPanScrollStart();
void didPanScrollStop();
@@ -147,22 +145,22 @@ public:
bool mouseDownWasInSubframe() const { return m_mouseDownWasInSubframe; }
bool panScrollInProgress() const;
- WEBCORE_EXPORT void dispatchFakeMouseMoveEventSoon();
+ void dispatchFakeMouseMoveEventSoon();
void dispatchFakeMouseMoveEventSoonInQuad(const FloatQuad&);
- WEBCORE_EXPORT HitTestResult hitTestResultAtPoint(const LayoutPoint&,
+ HitTestResult hitTestResultAtPoint(const LayoutPoint&,
HitTestRequest::HitTestRequestType hitType = HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::DisallowShadowContent,
const LayoutSize& padding = LayoutSize());
bool mousePressed() const { return m_mousePressed; }
- Node* mousePressNode() const { return m_mousePressNode.get(); }
+ void setMousePressed(bool pressed) { m_mousePressed = pressed; }
- WEBCORE_EXPORT void setCapturingMouseEventsElement(PassRefPtr<Element>); // A caller is responsible for resetting capturing element to 0.
+ void setCapturingMouseEventsElement(PassRefPtr<Element>); // A caller is responsible for resetting capturing element to 0.
#if ENABLE(DRAG_SUPPORT)
- bool updateDragAndDrop(const PlatformMouseEvent&, DataTransfer*);
- void cancelDragAndDrop(const PlatformMouseEvent&, DataTransfer*);
- bool performDragAndDrop(const PlatformMouseEvent&, DataTransfer*);
+ bool updateDragAndDrop(const PlatformMouseEvent&, Clipboard*);
+ void cancelDragAndDrop(const PlatformMouseEvent&, Clipboard*);
+ bool performDragAndDrop(const PlatformMouseEvent&, Clipboard*);
void updateDragStateAfterEditDragIfNeeded(Element* rootEditableElement);
#endif
@@ -176,57 +174,42 @@ public:
void resizeLayerDestroyed();
IntPoint lastKnownMousePosition() const;
- IntPoint lastKnownMouseGlobalPosition() const { return m_lastKnownMouseGlobalPosition; }
Cursor currentMouseCursor() const { return m_currentMouseCursor; }
static Frame* subframeForTargetNode(Node*);
static Frame* subframeForHitTestResult(const MouseEventWithHitTestResults&);
- WEBCORE_EXPORT bool scrollOverflow(ScrollDirection, ScrollGranularity, Node* startingNode = nullptr);
- WEBCORE_EXPORT bool scrollRecursively(ScrollDirection, ScrollGranularity, Node* startingNode = nullptr);
- WEBCORE_EXPORT bool logicalScrollRecursively(ScrollLogicalDirection, ScrollGranularity, Node* startingNode = nullptr);
+ bool scrollOverflow(ScrollDirection, ScrollGranularity, Node* startingNode = 0);
+ bool scrollRecursively(ScrollDirection, ScrollGranularity, Node* startingNode = 0);
+ bool logicalScrollRecursively(ScrollLogicalDirection, ScrollGranularity, Node* startingNode = 0);
bool tabsToLinks(KeyboardEvent*) const;
bool tabsToAllFormControls(KeyboardEvent*) const;
- WEBCORE_EXPORT bool mouseMoved(const PlatformMouseEvent&);
- WEBCORE_EXPORT bool passMouseMovedEventToScrollbars(const PlatformMouseEvent&);
+ bool mouseMoved(const PlatformMouseEvent&);
+ bool passMouseMovedEventToScrollbars(const PlatformMouseEvent&);
void lostMouseCapture();
- WEBCORE_EXPORT bool handleMousePressEvent(const PlatformMouseEvent&);
- bool handleMouseMoveEvent(const PlatformMouseEvent&, HitTestResult* hoveredNode = nullptr, bool onlyUpdateScrollbars = false);
- WEBCORE_EXPORT bool handleMouseReleaseEvent(const PlatformMouseEvent&);
- bool handleMouseForceEvent(const PlatformMouseEvent&);
- WEBCORE_EXPORT bool handleWheelEvent(const PlatformWheelEvent&);
+ bool handleMousePressEvent(const PlatformMouseEvent&);
+ bool handleMouseMoveEvent(const PlatformMouseEvent&, HitTestResult* hoveredNode = 0, bool onlyUpdateScrollbars = false);
+ bool handleMouseReleaseEvent(const PlatformMouseEvent&);
+ bool handleWheelEvent(const PlatformWheelEvent&);
void defaultWheelEventHandler(Node*, WheelEvent*);
bool handlePasteGlobalSelection(const PlatformMouseEvent&);
- void platformPrepareForWheelEvents(const PlatformWheelEvent&, const HitTestResult&, RefPtr<Element>& eventTarget, RefPtr<ContainerNode>& scrollableContainer, ScrollableArea*&, bool& isOverWidget);
- void platformRecordWheelEvent(const PlatformWheelEvent&);
- bool platformCompleteWheelEvent(const PlatformWheelEvent&, ContainerNode* scrollableContainer, ScrollableArea*);
- bool platformCompletePlatformWidgetWheelEvent(const PlatformWheelEvent&, const Widget&, ContainerNode* scrollableContainer);
- void platformNotifyIfEndGesture(const PlatformWheelEvent&, ScrollableArea*);
-
#if ENABLE(IOS_TOUCH_EVENTS) || ENABLE(IOS_GESTURE_EVENTS)
typedef Vector<RefPtr<Touch>> TouchArray;
typedef HashMap<EventTarget*, TouchArray*> EventTargetTouchMap;
-#endif
-
-#if ENABLE(IOS_TOUCH_EVENTS) || ENABLE(IOS_GESTURE_EVENTS) || ENABLE(MAC_GESTURE_EVENTS)
typedef HashSet<RefPtr<EventTarget>> EventTargetSet;
#endif
#if ENABLE(IOS_TOUCH_EVENTS)
bool dispatchTouchEvent(const PlatformTouchEvent&, const AtomicString&, const EventTargetTouchMap&, float, float);
- bool dispatchSimulatedTouchEvent(IntPoint location);
#endif
#if ENABLE(IOS_GESTURE_EVENTS)
bool dispatchGestureEvent(const PlatformTouchEvent&, const AtomicString&, const EventTargetSet&, float, float);
-#elif ENABLE(MAC_GESTURE_EVENTS)
- bool dispatchGestureEvent(const PlatformGestureEvent&, const AtomicString&, const EventTargetSet&, float, float);
- WEBCORE_EXPORT bool handleGestureEvent(const PlatformGestureEvent&);
#endif
#if PLATFORM(IOS)
@@ -234,7 +217,7 @@ public:
#endif
#if ENABLE(CONTEXT_MENUS)
- WEBCORE_EXPORT bool sendContextMenuEvent(const PlatformMouseEvent&);
+ bool sendContextMenuEvent(const PlatformMouseEvent&);
bool sendContextMenuEventForKey();
#endif
@@ -243,69 +226,68 @@ public:
bool needsKeyboardEventDisambiguationQuirks() const;
static unsigned accessKeyModifiers();
- WEBCORE_EXPORT bool handleAccessKey(const PlatformKeyboardEvent&);
- WEBCORE_EXPORT bool keyEvent(const PlatformKeyboardEvent&);
+ bool handleAccessKey(const PlatformKeyboardEvent&);
+ bool keyEvent(const PlatformKeyboardEvent&);
void defaultKeyboardEventHandler(KeyboardEvent*);
- bool accessibilityPreventsEventPropogation(KeyboardEvent&);
- WEBCORE_EXPORT void handleKeyboardSelectionMovementForAccessibility(KeyboardEvent*);
+ void handleKeyboardSelectionMovementForAccessibility(KeyboardEvent*);
- bool handleTextInputEvent(const String& text, Event* underlyingEvent = nullptr, TextEventInputType = TextEventInputKeyboard);
+ bool handleTextInputEvent(const String& text, Event* underlyingEvent = 0, TextEventInputType = TextEventInputKeyboard);
void defaultTextInputEventHandler(TextEvent*);
#if ENABLE(DRAG_SUPPORT)
- WEBCORE_EXPORT bool eventMayStartDrag(const PlatformMouseEvent&) const;
+ bool eventMayStartDrag(const PlatformMouseEvent&) const;
- WEBCORE_EXPORT void dragSourceEndedAt(const PlatformMouseEvent&, DragOperation);
+ void dragSourceEndedAt(const PlatformMouseEvent&, DragOperation);
#endif
void focusDocumentView();
+
+ void capsLockStateMayHaveChanged(); // Only called by FrameSelection
- WEBCORE_EXPORT void sendScrollEvent();
+ void sendScrollEvent(); // Ditto
-#if PLATFORM(COCOA) && defined(__OBJC__)
+#if PLATFORM(MAC) && defined(__OBJC__)
#if !PLATFORM(IOS)
- WEBCORE_EXPORT void mouseDown(NSEvent *, NSEvent *correspondingPressureEvent);
- WEBCORE_EXPORT void mouseDragged(NSEvent *, NSEvent *correspondingPressureEvent);
- WEBCORE_EXPORT void mouseUp(NSEvent *, NSEvent *correspondingPressureEvent);
- WEBCORE_EXPORT void mouseMoved(NSEvent *, NSEvent *correspondingPressureEvent);
- WEBCORE_EXPORT void pressureChange(NSEvent *, NSEvent* correspondingPressureEvent);
- WEBCORE_EXPORT bool keyEvent(NSEvent *);
- WEBCORE_EXPORT bool wheelEvent(NSEvent *);
+ void mouseDown(NSEvent *);
+ void mouseDragged(NSEvent *);
+ void mouseUp(NSEvent *);
+ void mouseMoved(NSEvent *);
+ bool keyEvent(NSEvent *);
+ bool wheelEvent(NSEvent *);
#else
- WEBCORE_EXPORT void mouseDown(WebEvent *);
- WEBCORE_EXPORT void mouseUp(WebEvent *);
- WEBCORE_EXPORT void mouseMoved(WebEvent *);
- WEBCORE_EXPORT bool keyEvent(WebEvent *);
- WEBCORE_EXPORT bool wheelEvent(WebEvent *);
+ void mouseDown(WebEvent *);
+ void mouseUp(WebEvent *);
+ void mouseMoved(WebEvent *);
+ bool keyEvent(WebEvent *);
+ bool wheelEvent(WebEvent *);
#endif
#if ENABLE(IOS_TOUCH_EVENTS)
- WEBCORE_EXPORT void touchEvent(WebEvent *);
+ void touchEvent(WebEvent *);
#endif
#if !PLATFORM(IOS)
- WEBCORE_EXPORT void passMouseMovedEventToScrollbars(NSEvent *, NSEvent* correspondingPressureEvent);
+ void passMouseMovedEventToScrollbars(NSEvent *);
- WEBCORE_EXPORT void sendFakeEventsAfterWidgetTracking(NSEvent *initiatingEvent);
+ void sendFakeEventsAfterWidgetTracking(NSEvent *initiatingEvent);
#endif
#if !PLATFORM(IOS)
void setActivationEventNumber(int num) { m_activationEventNumber = num; }
- WEBCORE_EXPORT static NSEvent *currentNSEvent();
- static NSEvent *correspondingPressureEvent();
+ static NSEvent *currentNSEvent();
#else
static WebEvent *currentEvent();
#endif // !PLATFORM(IOS)
-#endif // PLATFORM(COCOA) && defined(__OBJC__)
+#endif // PLATFORM(MAC) && defined(__OBJC__)
#if PLATFORM(IOS)
void invalidateClick();
#endif
#if ENABLE(TOUCH_EVENTS)
- WEBCORE_EXPORT bool handleTouchEvent(const PlatformTouchEvent&);
+ bool handleTouchEvent(const PlatformTouchEvent&);
#endif
bool useHandCursor(Node*, bool isOverLink, bool shiftKey);
@@ -313,56 +295,56 @@ public:
bool isHandlingWheelEvent() const { return m_isHandlingWheelEvent; }
- WEBCORE_EXPORT void setImmediateActionStage(ImmediateActionStage stage);
- ImmediateActionStage immediateActionStage() const { return m_immediateActionStage; }
-
private:
#if ENABLE(DRAG_SUPPORT)
static DragState& dragState();
static const double TextDragDelay;
- PassRefPtr<DataTransfer> createDraggingDataTransfer() const;
+ PassRefPtr<Clipboard> createDraggingClipboard() const;
#endif // ENABLE(DRAG_SUPPORT)
bool eventActivatedView(const PlatformMouseEvent&) const;
bool updateSelectionForMouseDownDispatchingSelectStart(Node*, const VisibleSelection&, TextGranularity);
void selectClosestWordFromHitTestResult(const HitTestResult&, AppendTrailingWhitespace);
- VisibleSelection selectClosestWordFromHitTestResultBasedOnLookup(const HitTestResult&);
void selectClosestWordFromMouseEvent(const MouseEventWithHitTestResults&);
- void selectClosestContextualWordFromMouseEvent(const MouseEventWithHitTestResults&);
- void selectClosestContextualWordOrLinkFromMouseEvent(const MouseEventWithHitTestResults&);
+ void selectClosestWordOrLinkFromMouseEvent(const MouseEventWithHitTestResults&);
bool handleMouseDoubleClickEvent(const PlatformMouseEvent&);
- WEBCORE_EXPORT bool handleMousePressEvent(const MouseEventWithHitTestResults&);
+ bool handleMousePressEvent(const MouseEventWithHitTestResults&);
bool handleMousePressEventSingleClick(const MouseEventWithHitTestResults&);
bool handleMousePressEventDoubleClick(const MouseEventWithHitTestResults&);
bool handleMousePressEventTripleClick(const MouseEventWithHitTestResults&);
#if ENABLE(DRAG_SUPPORT)
bool handleMouseDraggedEvent(const MouseEventWithHitTestResults&);
#endif
- WEBCORE_EXPORT bool handleMouseReleaseEvent(const MouseEventWithHitTestResults&);
+ bool handleMouseReleaseEvent(const MouseEventWithHitTestResults&);
OptionalCursor selectCursor(const HitTestResult&, bool shiftKey);
- void hoverTimerFired();
+ void hoverTimerFired(Timer<EventHandler>&);
#if ENABLE(CURSOR_SUPPORT)
- void cursorUpdateTimerFired();
+ void cursorUpdateTimerFired(Timer<EventHandler>&);
#endif
- bool logicalScrollOverflow(ScrollLogicalDirection, ScrollGranularity, Node* startingNode = nullptr);
+ bool logicalScrollOverflow(ScrollLogicalDirection, ScrollGranularity, Node* startingNode = 0);
bool shouldTurnVerticalTicksIntoHorizontal(const HitTestResult&, const PlatformWheelEvent&) const;
+ void recordWheelEventDelta(const PlatformWheelEvent&);
+ enum DominantScrollGestureDirection {
+ DominantScrollDirectionNone,
+ DominantScrollDirectionVertical,
+ DominantScrollDirectionHorizontal
+ };
+ DominantScrollGestureDirection dominantScrollGestureDirection() const;
bool mouseDownMayStartSelect() const { return m_mouseDownMayStartSelect; }
static bool isKeyboardOptionTab(KeyboardEvent*);
static bool eventInvertsTabsToLinksClientCallResult(KeyboardEvent*);
-#if !ENABLE(IOS_TOUCH_EVENTS)
- void fakeMouseMoveEventTimerFired();
+ void fakeMouseMoveEventTimerFired(Timer<EventHandler>&);
void cancelFakeMouseMoveEvent();
-#endif
bool isInsideScrollbar(const IntPoint&) const;
@@ -383,9 +365,9 @@ private:
bool dispatchMouseEvent(const AtomicString& eventType, Node* target, bool cancelable, int clickCount, const PlatformMouseEvent&, bool setUnder);
#if ENABLE(DRAG_SUPPORT)
- bool dispatchDragEvent(const AtomicString& eventType, Element& target, const PlatformMouseEvent&, DataTransfer*);
+ bool dispatchDragEvent(const AtomicString& eventType, Element& target, const PlatformMouseEvent&, Clipboard*);
- void freeDataTransfer();
+ void freeClipboard();
bool handleDrag(const MouseEventWithHitTestResults&, CheckDragHysteresis);
#endif
@@ -398,14 +380,12 @@ private:
bool dragHysteresisExceeded(const FloatPoint&) const;
bool dragHysteresisExceeded(const IntPoint&) const;
#endif // ENABLE(DRAG_SUPPORT)
-
- bool mouseMovementExceedsThreshold(const FloatPoint&, int pointsThreshold) const;
bool passMousePressEventToSubframe(MouseEventWithHitTestResults&, Frame* subframe);
- bool passMouseMoveEventToSubframe(MouseEventWithHitTestResults&, Frame* subframe, HitTestResult* hoveredNode = nullptr);
+ bool passMouseMoveEventToSubframe(MouseEventWithHitTestResults&, Frame* subframe, HitTestResult* hoveredNode = 0);
bool passMouseReleaseEventToSubframe(MouseEventWithHitTestResults&, Frame* subframe);
- bool passSubframeEventToSubframe(MouseEventWithHitTestResults&, Frame* subframe, HitTestResult* hoveredNode = nullptr);
+ bool passSubframeEventToSubframe(MouseEventWithHitTestResults&, Frame* subframe, HitTestResult* hoveredNode = 0);
bool passMousePressEventToScrollbar(MouseEventWithHitTestResults&, Scrollbar*);
@@ -413,7 +393,7 @@ private:
bool passWidgetMouseDownEventToWidget(RenderWidget*);
bool passMouseDownEventToWidget(Widget*);
- bool passWheelEventToWidget(const PlatformWheelEvent&, Widget&);
+ bool passWheelEventToWidget(const PlatformWheelEvent&, Widget*);
void defaultSpaceEventHandler(KeyboardEvent*);
void defaultBackspaceEventHandler(KeyboardEvent*);
@@ -441,7 +421,7 @@ private:
bool capturesDragging() const { return m_capturesDragging; }
-#if PLATFORM(COCOA) && defined(__OBJC__)
+#if PLATFORM(MAC) && defined(__OBJC__)
NSView *mouseDownViewIfStillGood();
PlatformMouseEvent currentPlatformMouseEvent() const;
@@ -456,51 +436,51 @@ private:
#if ENABLE(CURSOR_VISIBILITY)
void startAutoHideCursorTimer();
void cancelAutoHideCursorTimer();
- void autoHideCursorTimerFired();
+ void autoHideCursorTimerFired(Timer<EventHandler>&);
#endif
- void clearLatchedState();
-
Frame& m_frame;
- bool m_mousePressed { false };
- bool m_capturesDragging { false };
+ bool m_mousePressed;
+ bool m_capturesDragging;
RefPtr<Node> m_mousePressNode;
- bool m_mouseDownMayStartSelect { false };
+ bool m_mouseDownMayStartSelect;
#if ENABLE(DRAG_SUPPORT)
- bool m_mouseDownMayStartDrag { false };
- bool m_dragMayStartSelectionInstead { false };
+ bool m_mouseDownMayStartDrag;
+ bool m_dragMayStartSelectionInstead;
#endif
- bool m_mouseDownWasSingleClickInSelection { false };
+ bool m_mouseDownWasSingleClickInSelection;
enum SelectionInitiationState { HaveNotStartedSelection, PlacedCaret, ExtendedSelection };
- SelectionInitiationState m_selectionInitiationState { HaveNotStartedSelection };
+ SelectionInitiationState m_selectionInitiationState;
#if ENABLE(DRAG_SUPPORT)
LayoutPoint m_dragStartPos;
#endif
- bool m_panScrollButtonPressed { false };
+ bool m_panScrollButtonPressed;
- Timer m_hoverTimer;
+ Timer<EventHandler> m_hoverTimer;
#if ENABLE(CURSOR_SUPPORT)
- Timer m_cursorUpdateTimer;
+ Timer<EventHandler> m_cursorUpdateTimer;
#endif
- std::unique_ptr<AutoscrollController> m_autoscrollController;
- bool m_mouseDownMayStartAutoscroll { false };
- bool m_mouseDownWasInSubframe { false };
+ OwnPtr<AutoscrollController> m_autoscrollController;
+ bool m_mouseDownMayStartAutoscroll;
+ bool m_mouseDownWasInSubframe;
-#if !ENABLE(IOS_TOUCH_EVENTS)
- Timer m_fakeMouseMoveEventTimer;
-#endif
+ Timer<EventHandler> m_fakeMouseMoveEventTimer;
- bool m_svgPan { false };
+#if ENABLE(SVG)
+ bool m_svgPan;
+ RefPtr<SVGElementInstance> m_instanceUnderMouse;
+ RefPtr<SVGElementInstance> m_lastInstanceUnderMouse;
+#endif
- RenderLayer* m_resizeLayer { nullptr };
+ RenderLayer* m_resizeLayer;
RefPtr<Element> m_capturingMouseEventsElement;
- bool m_eventHandlerWillResetCapturingMouseEventsElement { false };
+ bool m_eventHandlerWillResetCapturingMouseEventsElement;
RefPtr<Element> m_elementUnderMouse;
RefPtr<Element> m_lastElementUnderMouse;
@@ -508,70 +488,71 @@ private:
WeakPtr<Scrollbar> m_lastScrollbarUnderMouse;
Cursor m_currentMouseCursor;
- int m_clickCount { 0 };
+ int m_clickCount;
RefPtr<Node> m_clickNode;
#if ENABLE(IOS_GESTURE_EVENTS)
- float m_gestureInitialRotation { GestureUnknown };
-#endif
-#if ENABLE(IOS_GESTURE_EVENTS) || ENABLE(MAC_GESTURE_EVENTS)
- float m_gestureInitialDiameter { GestureUnknown };
- float m_gestureLastDiameter { GestureUnknown };
- float m_gestureLastRotation { GestureUnknown };
- EventTargetSet m_gestureTargets;
-#endif
-#if ENABLE(MAC_GESTURE_EVENTS)
- bool m_hasActiveGesture { false };
+ float m_gestureInitialDiameter;
+ float m_gestureLastDiameter;
+ float m_gestureInitialRotation;
+ float m_gestureLastRotation;
#endif
#if ENABLE(IOS_TOUCH_EVENTS)
- unsigned m_firstTouchID { InvalidTouchIdentifier };
+ unsigned m_firstTouchID;
TouchArray m_touches;
+ EventTargetSet m_gestureTargets;
RefPtr<Frame> m_touchEventTargetSubframe;
#endif
#if ENABLE(DRAG_SUPPORT)
RefPtr<Element> m_dragTarget;
- bool m_shouldOnlyFireDragOverEvent { false };
+ bool m_shouldOnlyFireDragOverEvent;
#endif
RefPtr<HTMLFrameSetElement> m_frameSetBeingResized;
LayoutSize m_offsetFromResizeCorner; // In the coords of m_resizeLayer.
- bool m_mousePositionIsUnknown { true };
+ bool m_mousePositionIsUnknown;
IntPoint m_lastKnownMousePosition;
IntPoint m_lastKnownMouseGlobalPosition;
IntPoint m_mouseDownPos; // In our view's coords.
- double m_mouseDownTimestamp { 0 };
+ double m_mouseDownTimestamp;
PlatformMouseEvent m_mouseDown;
-#if PLATFORM(COCOA)
- NSView *m_mouseDownView { nullptr };
- bool m_sendingEventToSubview { false };
+ Deque<FloatSize> m_recentWheelEventDeltas;
+ RefPtr<Element> m_latchedWheelEventElement;
+ bool m_inTrackingScrollGesturePhase;
+ bool m_widgetIsLatched;
+
+ RefPtr<Element> m_previousWheelScrolledElement;
+
+#if PLATFORM(MAC) || PLATFORM(IOS)
+ NSView *m_mouseDownView;
+ bool m_sendingEventToSubview;
#if !PLATFORM(IOS)
- int m_activationEventNumber { -1 };
+ int m_activationEventNumber;
#endif
#endif
#if ENABLE(TOUCH_EVENTS) && !ENABLE(IOS_TOUCH_EVENTS)
typedef HashMap<int, RefPtr<EventTarget>> TouchTargetMap;
TouchTargetMap m_originatingTouchPointTargets;
RefPtr<Document> m_originatingTouchPointDocument;
- unsigned m_originatingTouchPointTargetKey { 0 };
- bool m_touchPressed { false };
+ unsigned m_originatingTouchPointTargetKey;
+ bool m_touchPressed;
#endif
- double m_maxMouseMovedDuration { 0 };
- PlatformEvent::Type m_baseEventType { PlatformEvent::NoType };
- bool m_didStartDrag { false };
- bool m_isHandlingWheelEvent { false };
+ double m_maxMouseMovedDuration;
+ PlatformEvent::Type m_baseEventType;
+ bool m_didStartDrag;
+ bool m_didLongPressInvokeContextMenu;
+ bool m_isHandlingWheelEvent;
#if ENABLE(CURSOR_VISIBILITY)
- Timer m_autoHideCursorTimer;
+ Timer<EventHandler> m_autoHideCursorTimer;
#endif
-
- ImmediateActionStage m_immediateActionStage { ImmediateActionStage::None };
};
} // namespace WebCore
diff --git a/Source/WebCore/page/EventSource.cpp b/Source/WebCore/page/EventSource.cpp
index 0f2ce3d93..4ccfbe380 100644
--- a/Source/WebCore/page/EventSource.cpp
+++ b/Source/WebCore/page/EventSource.cpp
@@ -38,20 +38,22 @@
#include "Dictionary.h"
#include "Document.h"
#include "Event.h"
+#include "EventException.h"
#include "ExceptionCode.h"
#include "Frame.h"
-#include "HTTPHeaderNames.h"
#include "MemoryCache.h"
#include "MessageEvent.h"
#include "ResourceError.h"
#include "ResourceRequest.h"
#include "ResourceResponse.h"
+#include "ScriptCallStack.h"
#include "ScriptController.h"
#include "ScriptExecutionContext.h"
#include "SecurityOrigin.h"
#include "SerializedScriptValue.h"
#include "TextResourceDecoder.h"
#include "ThreadableLoader.h"
+#include <wtf/text/StringBuilder.h>
namespace WebCore {
@@ -63,7 +65,7 @@ inline EventSource::EventSource(ScriptExecutionContext& context, const URL& url,
, m_withCredentials(false)
, m_state(CONNECTING)
, m_decoder(TextResourceDecoder::create("text/plain", "UTF-8"))
- , m_connectTimer(*this, &EventSource::connect)
+ , m_connectTimer(this, &EventSource::connectTimerFired)
, m_discardTrailingNewline(false)
, m_requestInFlight(false)
, m_reconnectDelay(defaultReconnectDelay)
@@ -71,24 +73,29 @@ inline EventSource::EventSource(ScriptExecutionContext& context, const URL& url,
eventSourceInit.get("withCredentials", m_withCredentials);
}
-RefPtr<EventSource> EventSource::create(ScriptExecutionContext& context, const String& url, const Dictionary& eventSourceInit, ExceptionCode& ec)
+PassRefPtr<EventSource> EventSource::create(ScriptExecutionContext& context, const String& url, const Dictionary& eventSourceInit, ExceptionCode& ec)
{
if (url.isEmpty()) {
ec = SYNTAX_ERR;
- return nullptr;
+ return 0;
}
URL fullURL = context.completeURL(url);
if (!fullURL.isValid()) {
ec = SYNTAX_ERR;
- return nullptr;
+ return 0;
}
// FIXME: Convert this to check the isolated world's Content Security Policy once webkit.org/b/104520 is solved.
- if (!context.contentSecurityPolicy()->allowConnectToSource(fullURL, context.shouldBypassMainWorldContentSecurityPolicy())) {
+ bool shouldBypassMainWorldContentSecurityPolicy = false;
+ if (context.isDocument()) {
+ Document& document = toDocument(context);
+ shouldBypassMainWorldContentSecurityPolicy = document.frame()->script().shouldBypassMainWorldContentSecurityPolicy();
+ }
+ if (!shouldBypassMainWorldContentSecurityPolicy && !context.contentSecurityPolicy()->allowConnectToSource(fullURL)) {
// FIXME: Should this be throwing an exception?
ec = SECURITY_ERR;
- return nullptr;
+ return 0;
}
RefPtr<EventSource> source = adoptRef(new EventSource(context, fullURL, eventSourceInit));
@@ -113,23 +120,21 @@ void EventSource::connect()
ResourceRequest request(m_url);
request.setHTTPMethod("GET");
- request.setHTTPHeaderField(HTTPHeaderName::Accept, "text/event-stream");
- request.setHTTPHeaderField(HTTPHeaderName::CacheControl, "no-cache");
+ request.setHTTPHeaderField("Accept", "text/event-stream");
+ request.setHTTPHeaderField("Cache-Control", "no-cache");
if (!m_lastEventId.isEmpty())
- request.setHTTPHeaderField(HTTPHeaderName::LastEventID, m_lastEventId);
+ request.setHTTPHeaderField("Last-Event-ID", m_lastEventId);
SecurityOrigin* origin = scriptExecutionContext()->securityOrigin();
ThreadableLoaderOptions options;
- options.setSendLoadCallbacks(SendCallbacks);
- options.setSniffContent(DoNotSniffContent);
- options.setAllowCredentials((origin->canRequest(m_url) || m_withCredentials) ? AllowStoredCredentials : DoNotAllowStoredCredentials);
- options.setCredentialRequest(m_withCredentials ? ClientRequestedCredentials : ClientDidNotRequestCredentials);
+ options.sendLoadCallbacks = SendCallbacks;
+ options.sniffContent = DoNotSniffContent;
+ options.allowCredentials = (origin->canRequest(m_url) || m_withCredentials) ? AllowStoredCredentials : DoNotAllowStoredCredentials;
options.preflightPolicy = PreventPreflight;
options.crossOriginRequestPolicy = UseAccessControl;
- options.setDataBufferingPolicy(DoNotBufferData);
+ options.dataBufferingPolicy = DoNotBufferData;
options.securityOrigin = origin;
- options.contentSecurityPolicyEnforcement = scriptExecutionContext()->shouldBypassMainWorldContentSecurityPolicy() ? ContentSecurityPolicyEnforcement::DoNotEnforce : ContentSecurityPolicyEnforcement::EnforceConnectSrcDirective;
m_loader = ThreadableLoader::create(scriptExecutionContext(), this, request, options);
@@ -165,6 +170,11 @@ void EventSource::scheduleReconnect()
dispatchEvent(Event::create(eventNames().errorEvent, false, false));
}
+void EventSource::connectTimerFired(Timer<EventSource>&)
+{
+ connect();
+}
+
String EventSource::url() const
{
return m_url.string();
@@ -211,18 +221,24 @@ void EventSource::didReceiveResponse(unsigned long, const ResourceResponse& resp
if (responseIsValid) {
const String& charset = response.textEncodingName();
// If we have a charset, the only allowed value is UTF-8 (case-insensitive).
- responseIsValid = charset.isEmpty() || equalLettersIgnoringASCIICase(charset, "utf-8");
+ responseIsValid = charset.isEmpty() || equalIgnoringCase(charset, "UTF-8");
if (!responseIsValid) {
- String message = makeString("EventSource's response has a charset (\"", charset, "\") that is not UTF-8. Aborting the connection.");
+ StringBuilder message;
+ message.appendLiteral("EventSource's response has a charset (\"");
+ message.append(charset);
+ message.appendLiteral("\") that is not UTF-8. Aborting the connection.");
// FIXME: We are missing the source line.
- scriptExecutionContext()->addConsoleMessage(MessageSource::JS, MessageLevel::Error, message);
+ scriptExecutionContext()->addConsoleMessage(JSMessageSource, ErrorMessageLevel, message.toString());
}
} else {
// To keep the signal-to-noise ratio low, we only log 200-response with an invalid MIME type.
if (statusCode == 200 && !mimeTypeIsValid) {
- String message = makeString("EventSource's response has a MIME type (\"", response.mimeType(), "\") that is not \"text/event-stream\". Aborting the connection.");
+ StringBuilder message;
+ message.appendLiteral("EventSource's response has a MIME type (\"");
+ message.append(response.mimeType());
+ message.appendLiteral("\") that is not \"text/event-stream\". Aborting the connection.");
// FIXME: We are missing the source line.
- scriptExecutionContext()->addConsoleMessage(MessageSource::JS, MessageLevel::Error, message);
+ scriptExecutionContext()->addConsoleMessage(JSMessageSource, ErrorMessageLevel, message.toString());
}
}
@@ -240,8 +256,7 @@ void EventSource::didReceiveData(const char* data, int length)
ASSERT(m_state == OPEN);
ASSERT(m_requestInFlight);
- // FIXME: Need to call flush at some point.
- append(m_receiveBuf, StringView(m_decoder->decode(data, length)));
+ append(m_receiveBuf, m_decoder->decode(data, length));
parseEventStream();
}
@@ -274,8 +289,8 @@ void EventSource::didFail(const ResourceError& error)
void EventSource::didFailAccessControlCheck(const ResourceError& error)
{
- String message = makeString("EventSource cannot load ", error.failingURL().string(), ". ", error.localizedDescription());
- scriptExecutionContext()->addConsoleMessage(MessageSource::JS, MessageLevel::Error, message);
+ String message = makeString("EventSource cannot load ", error.failingURL(), ". ", error.localizedDescription());
+ scriptExecutionContext()->addConsoleMessage(JSMessageSource, ErrorMessageLevel, message);
abortConnectionAttempt();
}
@@ -400,20 +415,11 @@ void EventSource::stop()
close();
}
-const char* EventSource::activeDOMObjectName() const
-{
- return "EventSource";
-}
-
-bool EventSource::canSuspendForDocumentSuspension() const
-{
- // FIXME: We should try and do better here.
- return false;
-}
-
-Ref<MessageEvent> EventSource::createMessageEvent()
+PassRefPtr<MessageEvent> EventSource::createMessageEvent()
{
- return MessageEvent::create(m_eventName.isEmpty() ? eventNames().messageEvent : AtomicString(m_eventName), false, false, SerializedScriptValue::create(String::adopt(m_data)), m_eventStreamOrigin, m_lastEventId);
+ RefPtr<MessageEvent> event = MessageEvent::create();
+ event->initMessageEvent(m_eventName.isEmpty() ? eventNames().messageEvent : AtomicString(m_eventName), false, false, SerializedScriptValue::create(String::adopt(m_data)), m_eventStreamOrigin, m_lastEventId, 0, 0);
+ return event.release();
}
} // namespace WebCore
diff --git a/Source/WebCore/page/EventSource.h b/Source/WebCore/page/EventSource.h
index 9e81a2af1..f2d1c1256 100644
--- a/Source/WebCore/page/EventSource.h
+++ b/Source/WebCore/page/EventSource.h
@@ -51,7 +51,7 @@ class ThreadableLoader;
class EventSource final : public RefCounted<EventSource>, public EventTargetWithInlineData, private ThreadableLoaderClient, public ActiveDOMObject {
WTF_MAKE_FAST_ALLOCATED;
public:
- static RefPtr<EventSource> create(ScriptExecutionContext&, const String& url, const Dictionary&, ExceptionCode&);
+ static PassRefPtr<EventSource> create(ScriptExecutionContext&, const String& url, const Dictionary&, ExceptionCode&);
virtual ~EventSource();
static const unsigned long long defaultReconnectDelay;
@@ -66,6 +66,10 @@ public:
State readyState() const;
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(open);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(message);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(error);
+
void close();
using RefCounted<EventSource>::ref;
@@ -87,19 +91,17 @@ private:
virtual void didFailAccessControlCheck(const ResourceError&) override;
virtual void didFailRedirectCheck() override;
- // ActiveDOMObject API.
- void stop() override;
- const char* activeDOMObjectName() const override;
- bool canSuspendForDocumentSuspension() const override;
+ virtual void stop() override;
void connect();
void networkRequestEnded();
void scheduleInitialConnect();
void scheduleReconnect();
+ void connectTimerFired(Timer<EventSource>&);
void abortConnectionAttempt();
void parseEventStream();
void parseEventStreamLine(unsigned pos, int fieldLength, int lineLength);
- Ref<MessageEvent> createMessageEvent();
+ PassRefPtr<MessageEvent> createMessageEvent();
URL m_url;
bool m_withCredentials;
@@ -107,7 +109,7 @@ private:
RefPtr<TextResourceDecoder> m_decoder;
RefPtr<ThreadableLoader> m_loader;
- Timer m_connectTimer;
+ Timer<EventSource> m_connectTimer;
Vector<UChar> m_receiveBuf;
bool m_discardTrailingNewline;
bool m_requestInFlight;
diff --git a/Source/WebCore/page/EventSource.idl b/Source/WebCore/page/EventSource.idl
index 36f8d8999..1c8adc977 100644
--- a/Source/WebCore/page/EventSource.idl
+++ b/Source/WebCore/page/EventSource.idl
@@ -35,7 +35,9 @@
Constructor(DOMString url, optional Dictionary eventSourceInit),
ConstructorCallWith=ScriptExecutionContext,
ConstructorRaisesException,
-] interface EventSource : EventTarget {
+ EventTarget,
+ JSNoStaticTables,
+] interface EventSource {
readonly attribute DOMString URL; // Lowercased .url is the one in the spec, but leaving .URL for compatibility reasons.
readonly attribute DOMString url;
@@ -48,8 +50,18 @@
readonly attribute unsigned short readyState;
// networking
- attribute EventHandler onopen;
- attribute EventHandler onmessage;
- attribute EventHandler onerror;
+ attribute EventListener onopen;
+ attribute EventListener onmessage;
+ attribute EventListener onerror;
void close();
+
+ // EventTarget interface
+ void addEventListener(DOMString type,
+ EventListener listener,
+ optional boolean useCapture);
+ void removeEventListener(DOMString type,
+ EventListener listener,
+ optional boolean useCapture);
+ [RaisesException] boolean dispatchEvent(Event evt);
+
};
diff --git a/Source/WebCore/page/csp/ContentSecurityPolicySourceListDirective.cpp b/Source/WebCore/page/FeatureObserver.cpp
index 89133d4eb..f5397abee 100644
--- a/Source/WebCore/page/csp/ContentSecurityPolicySourceListDirective.cpp
+++ b/Source/WebCore/page/FeatureObserver.cpp
@@ -1,6 +1,5 @@
/*
- * Copyright (C) 2011 Google, Inc. All rights reserved.
- * Copyright (C) 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2012 Google, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -14,7 +13,7 @@
* THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -25,26 +24,55 @@
*/
#include "config.h"
-#include "ContentSecurityPolicySourceListDirective.h"
+#include "FeatureObserver.h"
-#include "ContentSecurityPolicy.h"
-#include "URL.h"
+#include "DOMWindow.h"
+#include "Document.h"
+#include "HistogramSupport.h"
+#include "Page.h"
namespace WebCore {
-ContentSecurityPolicySourceListDirective::ContentSecurityPolicySourceListDirective(const String& name, const String& value, const ContentSecurityPolicy& policy)
- : ContentSecurityPolicyDirective(name, value, policy)
- , m_sourceList(policy, name)
+FeatureObserver::FeatureObserver()
{
- m_sourceList.parse(value);
}
-bool ContentSecurityPolicySourceListDirective::allows(const URL& url)
+FeatureObserver::~FeatureObserver()
{
- // FIXME: We should investigate returning false for an empty URL.
- if (url.isEmpty())
- return m_sourceList.allowSelf();
- return m_sourceList.matches(url);
+ updateMeasurements();
+}
+
+void FeatureObserver::updateMeasurements()
+{
+ if (!m_featureBits)
+ return;
+
+ // Clearing feature bits is timing sensitive. Ports other than chromium do not use HistogramSupport,
+ // and pull the results on certain navigation events instead.
+ m_featureBits->clearAll();
+}
+
+void FeatureObserver::didCommitLoad()
+{
+ updateMeasurements();
+}
+
+void FeatureObserver::observe(Document* document, Feature feature)
+{
+ if (!document)
+ return;
+
+ Page* page = document->page();
+ if (!page)
+ return;
+
+ page->featureObserver()->didObserve(feature);
+}
+
+void FeatureObserver::observe(DOMWindow* domWindow, Feature feature)
+{
+ ASSERT(domWindow);
+ observe(domWindow->document(), feature);
}
} // namespace WebCore
diff --git a/Source/WebCore/page/FeatureObserver.h b/Source/WebCore/page/FeatureObserver.h
new file mode 100644
index 000000000..d7f4e42f9
--- /dev/null
+++ b/Source/WebCore/page/FeatureObserver.h
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2012 Google, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef FeatureObserver_h
+#define FeatureObserver_h
+
+#include <wtf/BitVector.h>
+#include <wtf/Noncopyable.h>
+#include <wtf/OwnPtr.h>
+#include <wtf/PassOwnPtr.h>
+
+namespace WebCore {
+
+class DOMWindow;
+class Document;
+
+class FeatureObserver {
+ WTF_MAKE_NONCOPYABLE(FeatureObserver);
+public:
+ FeatureObserver();
+ ~FeatureObserver();
+
+ enum Feature {
+ PageDestruction,
+ LegacyNotifications,
+ MultipartMainResource,
+ PrefixedIndexedDB,
+ WorkerStart,
+ SharedWorkerStart,
+ LegacyWebAudio,
+ WebAudioStart,
+ PrefixedContentSecurityPolicy,
+ UnprefixedIndexedDB,
+ OpenWebDatabase,
+ UnusedSlot01, // We used this slot for LegacyHTMLNotifications.
+ LegacyTextNotifications,
+ UnprefixedRequestAnimationFrame,
+ PrefixedRequestAnimationFrame,
+ ContentSecurityPolicy,
+ ContentSecurityPolicyReportOnly,
+ PrefixedContentSecurityPolicyReportOnly,
+ PrefixedTransitionEndEvent,
+ UnprefixedTransitionEndEvent,
+ PrefixedAndUnprefixedTransitionEndEvent,
+ AutoFocusAttribute,
+ AutoSaveAttribute,
+ DataListElement,
+ FormAttribute,
+ IncrementalAttribute,
+ InputTypeColor,
+ InputTypeDate,
+ InputTypeDateTime,
+ InputTypeDateTimeFallback,
+ InputTypeDateTimeLocal,
+ InputTypeEmail,
+ InputTypeMonth,
+ InputTypeNumber,
+ InputTypeRange,
+ InputTypeSearch,
+ InputTypeTel,
+ InputTypeTime,
+ InputTypeURL,
+ InputTypeWeek,
+ InputTypeWeekFallback,
+ ListAttribute,
+ MaxAttribute,
+ MinAttribute,
+ PatternAttribute,
+ PlaceholderAttribute,
+ PrecisionAttribute,
+ PrefixedDirectoryAttribute,
+ PrefixedSpeechAttribute,
+ RequiredAttribute,
+ ResultsAttribute,
+ StepAttribute,
+ PageVisits,
+ HTMLMarqueeElement,
+ CSSOverflowMarquee,
+ Reflection,
+ CursorVisibility,
+ StorageInfo,
+ XFrameOptions,
+ XFrameOptionsSameOrigin,
+ XFrameOptionsSameOriginWithBadAncestorChain,
+ DeprecatedFlexboxWebContent,
+ DeprecatedFlexboxChrome,
+ DeprecatedFlexboxChromeExtension,
+ // Add new features above this line. Don't change assigned numbers of each items.
+ NumberOfFeatures, // This enum value must be last.
+ };
+
+ static void observe(Document*, Feature);
+ static void observe(DOMWindow*, Feature);
+ void didCommitLoad();
+
+ const BitVector* accumulatedFeatureBits() const { return m_featureBits.get(); }
+
+private:
+ void didObserve(Feature feature)
+ {
+ ASSERT(feature != PageDestruction); // PageDestruction is reserved as a scaling factor.
+ ASSERT(feature < NumberOfFeatures);
+ if (!m_featureBits) {
+ m_featureBits = adoptPtr(new BitVector(NumberOfFeatures));
+ m_featureBits->clearAll();
+ }
+ m_featureBits->quickSet(feature);
+ }
+
+ void updateMeasurements();
+
+ OwnPtr<BitVector> m_featureBits;
+};
+
+} // namespace WebCore
+
+#endif // FeatureObserver_h
diff --git a/Source/WebCore/page/FocusController.cpp b/Source/WebCore/page/FocusController.cpp
index 6459cf1bb..a52b0d720 100644
--- a/Source/WebCore/page/FocusController.cpp
+++ b/Source/WebCore/page/FocusController.cpp
@@ -11,10 +11,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -45,11 +45,11 @@
#include "HTMLImageElement.h"
#include "HTMLInputElement.h"
#include "HTMLNames.h"
-#include "HTMLPlugInElement.h"
#include "HTMLTextAreaElement.h"
#include "HitTestResult.h"
#include "KeyboardEvent.h"
#include "MainFrame.h"
+#include "NodeRenderingTraversal.h"
#include "Page.h"
#include "Range.h"
#include "RenderWidget.h"
@@ -60,64 +60,12 @@
#include "Widget.h"
#include "htmlediting.h" // For firstPositionInOrBeforeNode
#include <limits>
-#include <wtf/CurrentTime.h>
#include <wtf/Ref.h>
namespace WebCore {
using namespace HTMLNames;
-// FIXME: Focus navigation should work with shadow trees that have slots.
-static Node* firstChildInScope(const Node* node)
-{
- ASSERT(node);
- if (node->shadowRoot())
- return nullptr;
- return node->firstChild();
-}
-
-static Node* lastChildInScope(const Node* node)
-{
- ASSERT(node);
- if (node->shadowRoot())
- return nullptr;
- return node->lastChild();
-}
-
-static Node* parentInScope(const Node* node)
-{
- if (node->isShadowRoot())
- return nullptr;
-
- ContainerNode* parent = node->parentNode();
- if (parent && parent->shadowRoot())
- return nullptr;
-
- return parent;
-}
-
-static Node* nextInScope(const Node* node)
-{
- if (Node* next = firstChildInScope(node))
- return next;
- if (Node* next = node->nextSibling())
- return next;
- const Node* current = node;
- while (current && !current->nextSibling())
- current = parentInScope(current);
- return current ? current->nextSibling() : nullptr;
-}
-
-static Node* previousInScope(const Node* node)
-{
- if (Node* current = node->previousSibling()) {
- while (Node* child = lastChildInScope(current))
- current = child;
- return current;
- }
- return parentInScope(node);
-}
-
FocusNavigationScope::FocusNavigationScope(TreeScope* treeScope)
: m_rootTreeScope(treeScope)
{
@@ -126,24 +74,24 @@ FocusNavigationScope::FocusNavigationScope(TreeScope* treeScope)
ContainerNode* FocusNavigationScope::rootNode() const
{
- return &m_rootTreeScope->rootNode();
+ return m_rootTreeScope->rootNode();
}
Element* FocusNavigationScope::owner() const
{
ContainerNode* root = rootNode();
- if (is<ShadowRoot>(*root))
- return downcast<ShadowRoot>(*root).host();
+ if (root->isShadowRoot())
+ return toShadowRoot(root)->hostElement();
if (Frame* frame = root->document().frame())
return frame->ownerElement();
- return nullptr;
+ return 0;
}
FocusNavigationScope FocusNavigationScope::focusNavigationScopeOf(Node* node)
{
ASSERT(node);
Node* root = node;
- for (Node* n = node; n; n = parentInScope(n))
+ for (Node* n = node; n; n = NodeRenderingTraversal::parentInScope(n))
root = n;
// The result is not always a ShadowRoot nor a DocumentNode since
// a starting node is in an orphaned tree in composed shadow tree.
@@ -153,8 +101,8 @@ FocusNavigationScope FocusNavigationScope::focusNavigationScopeOf(Node* node)
FocusNavigationScope FocusNavigationScope::focusNavigationScopeOwnedByShadowHost(Node* node)
{
ASSERT(node);
- ASSERT(downcast<Element>(*node).shadowRoot());
- return FocusNavigationScope(downcast<Element>(*node).shadowRoot());
+ ASSERT(toElement(node)->shadowRoot());
+ return FocusNavigationScope(toElement(node)->shadowRoot());
}
FocusNavigationScope FocusNavigationScope::focusNavigationScopeOwnedByIFrame(HTMLFrameOwnerElement* frame)
@@ -177,15 +125,15 @@ static inline void dispatchEventsOnWindowAndFocusedElement(Document* document, b
}
if (!focused && document->focusedElement())
- document->focusedElement()->dispatchBlurEvent(nullptr);
+ document->focusedElement()->dispatchBlurEvent(0);
document->dispatchWindowEvent(Event::create(focused ? eventNames().focusEvent : eventNames().blurEvent, false, false));
if (focused && document->focusedElement())
- document->focusedElement()->dispatchFocusEvent(nullptr, FocusDirectionNone);
+ document->focusedElement()->dispatchFocusEvent(0, FocusDirectionNone);
}
static inline bool hasCustomFocusLogic(Element& element)
{
- return is<HTMLElement>(element) && downcast<HTMLElement>(element).hasCustomFocusLogic();
+ return element.isHTMLElement() && toHTMLElement(element).hasCustomFocusLogic();
}
static inline bool isNonFocusableShadowHost(Element& element, KeyboardEvent& event)
@@ -195,14 +143,14 @@ static inline bool isNonFocusableShadowHost(Element& element, KeyboardEvent& eve
static inline bool isFocusableShadowHost(Node& node, KeyboardEvent& event)
{
- return is<Element>(node) && downcast<Element>(node).isKeyboardFocusable(&event) && downcast<Element>(node).shadowRoot() && !hasCustomFocusLogic(downcast<Element>(node));
+ return node.isElementNode() && toElement(node).isKeyboardFocusable(&event) && toElement(node).shadowRoot() && !hasCustomFocusLogic(toElement(node));
}
static inline int adjustedTabIndex(Node& node, KeyboardEvent& event)
{
- if (!is<Element>(node))
+ if (!node.isElementNode())
return 0;
- return isNonFocusableShadowHost(downcast<Element>(node), event) ? 0 : downcast<Element>(node).tabIndex();
+ return isNonFocusableShadowHost(toElement(node), event) ? 0 : toElement(node).tabIndex();
}
static inline bool shouldVisit(Element& element, KeyboardEvent& event)
@@ -210,11 +158,12 @@ static inline bool shouldVisit(Element& element, KeyboardEvent& event)
return element.isKeyboardFocusable(&event) || isNonFocusableShadowHost(element, event);
}
-FocusController::FocusController(Page& page, ViewState::Flags viewState)
+FocusController::FocusController(Page& page)
: m_page(page)
+ , m_isActive(false)
+ , m_isFocused(false)
, m_isChangingFocusedFrame(false)
- , m_viewState(viewState)
- , m_focusRepaintTimer(*this, &FocusController::focusRepaintTimerFired)
+ , m_contentIsVisible(false)
{
}
@@ -256,12 +205,12 @@ Frame& FocusController::focusedOrMainFrame() const
void FocusController::setFocused(bool focused)
{
- m_page.setViewState(focused ? m_viewState | ViewState::IsFocused : m_viewState & ~ViewState::IsFocused);
-}
+ if (isFocused() == focused)
+ return;
+
+ m_isFocused = focused;
-void FocusController::setFocusedInternal(bool focused)
-{
- if (!isFocused())
+ if (!m_isFocused)
focusedOrMainFrame().eventHandler().stopAutoscrollTimer();
if (!m_focusedFrame)
@@ -278,8 +227,8 @@ Element* FocusController::findFocusableElementDescendingDownIntoFrameDocument(Fo
// The node we found might be a HTMLFrameOwnerElement, so descend down the tree until we find either:
// 1) a focusable node, or
// 2) the deepest-nested HTMLFrameOwnerElement.
- while (is<HTMLFrameOwnerElement>(element)) {
- HTMLFrameOwnerElement& owner = downcast<HTMLFrameOwnerElement>(*element);
+ while (element && element->isFrameOwnerElement()) {
+ HTMLFrameOwnerElement& owner = toHTMLFrameOwnerElement(*element);
if (!owner.contentFrame())
break;
Element* foundElement = findFocusableElement(direction, FocusNavigationScope::focusNavigationScopeOwnedByIFrame(&owner), 0, event);
@@ -332,7 +281,7 @@ bool FocusController::advanceFocusInDocumentOrder(FocusDirection direction, Keyb
bool caretBrowsing = frame.settings().caretBrowsingEnabled();
if (caretBrowsing && !currentNode)
- currentNode = frame.selection().selection().start().deprecatedNode();
+ currentNode = frame.selection().start().deprecatedNode();
document->updateLayoutIgnorePendingStylesheets();
@@ -341,8 +290,8 @@ bool FocusController::advanceFocusInDocumentOrder(FocusDirection direction, Keyb
if (!element) {
// We didn't find a node to focus, so we should try to pass focus to Chrome.
if (!initialFocus && m_page.chrome().canTakeFocus(direction)) {
- document->setFocusedElement(nullptr);
- setFocusedFrame(nullptr);
+ document->setFocusedElement(0);
+ setFocusedFrame(0);
m_page.chrome().takeFocus(direction);
return true;
}
@@ -362,10 +311,10 @@ bool FocusController::advanceFocusInDocumentOrder(FocusDirection direction, Keyb
return true;
}
- if (is<HTMLFrameOwnerElement>(*element) && (!is<HTMLPlugInElement>(*element) || !element->isKeyboardFocusable(event))) {
+ if (element->isFrameOwnerElement() && (!element->isPluginElement() || !element->isKeyboardFocusable(event))) {
// We focus frames rather than frame owners.
// FIXME: We should not focus frames that have no scrollbars, as focusing them isn't useful to the user.
- HTMLFrameOwnerElement& owner = downcast<HTMLFrameOwnerElement>(*element);
+ HTMLFrameOwnerElement& owner = toHTMLFrameOwnerElement(*element);
if (!owner.contentFrame())
return false;
@@ -390,10 +339,8 @@ bool FocusController::advanceFocusInDocumentOrder(FocusDirection direction, Keyb
if (caretBrowsing) {
Position position = firstPositionInOrBeforeNode(element.get());
VisibleSelection newSelection(position, position, DOWNSTREAM);
- if (frame.selection().shouldChangeSelection(newSelection)) {
- AXTextStateChangeIntent intent(AXTextStateChangeTypeSelectionMove, AXTextSelection { AXTextSelectionDirectionDiscontiguous, AXTextSelectionGranularityUnknown, true });
- frame.selection().setSelection(newSelection, FrameSelection::defaultSetSelectionOptions(UserTriggered), intent);
- }
+ if (frame.selection().shouldChangeSelection(newSelection))
+ frame.selection().setSelection(newSelection);
}
element->focus(false, direction);
@@ -402,7 +349,7 @@ bool FocusController::advanceFocusInDocumentOrder(FocusDirection direction, Keyb
Element* FocusController::findFocusableElementAcrossFocusScope(FocusDirection direction, FocusNavigationScope scope, Node* currentNode, KeyboardEvent* event)
{
- ASSERT(!is<Element>(currentNode) || !isNonFocusableShadowHost(*downcast<Element>(currentNode), *event));
+ ASSERT(!currentNode || !currentNode->isElementNode() || !isNonFocusableShadowHost(*toElement(currentNode), *event));
Element* found;
if (currentNode && direction == FocusDirectionForward && isFocusableShadowHost(*currentNode, *event)) {
Element* foundInInnerFocusScope = findFocusableElementRecursively(direction, FocusNavigationScope::focusNavigationScopeOwnedByShadowHost(currentNode), 0, event);
@@ -460,10 +407,11 @@ Element* FocusController::findFocusableElement(FocusDirection direction, FocusNa
Element* FocusController::findElementWithExactTabIndex(Node* start, int tabIndex, KeyboardEvent* event, FocusDirection direction)
{
// Search is inclusive of start
+ using namespace NodeRenderingTraversal;
for (Node* node = start; node; node = direction == FocusDirectionForward ? nextInScope(node) : previousInScope(node)) {
- if (!is<Element>(*node))
+ if (!node->isElementNode())
continue;
- Element& element = downcast<Element>(*node);
+ Element& element = toElement(*node);
if (shouldVisit(element, *event) && adjustedTabIndex(element, *event) == tabIndex)
return &element;
}
@@ -475,10 +423,10 @@ static Element* nextElementWithGreaterTabIndex(Node* start, int tabIndex, Keyboa
// Search is inclusive of start
int winningTabIndex = std::numeric_limits<short>::max() + 1;
Element* winner = nullptr;
- for (Node* node = start; node; node = nextInScope(node)) {
- if (!is<Element>(*node))
+ for (Node* node = start; node; node = NodeRenderingTraversal::nextInScope(node)) {
+ if (!node->isElementNode())
continue;
- Element& element = downcast<Element>(*node);
+ Element& element = toElement(*node);
if (shouldVisit(element, event) && element.tabIndex() > tabIndex && element.tabIndex() < winningTabIndex) {
winner = &element;
winningTabIndex = element.tabIndex();
@@ -493,10 +441,10 @@ static Element* previousElementWithLowerTabIndex(Node* start, int tabIndex, Keyb
// Search is inclusive of start
int winningTabIndex = 0;
Element* winner = nullptr;
- for (Node* node = start; node; node = previousInScope(node)) {
- if (!is<Element>(*node))
+ for (Node* node = start; node; node = NodeRenderingTraversal::previousInScope(node)) {
+ if (!node->isElementNode())
continue;
- Element& element = downcast<Element>(*node);
+ Element& element = toElement(*node);
int currentTabIndex = adjustedTabIndex(element, event);
if ((shouldVisit(element, event) || isNonFocusableShadowHost(element, event)) && currentTabIndex < tabIndex && currentTabIndex > winningTabIndex) {
winner = &element;
@@ -508,14 +456,16 @@ static Element* previousElementWithLowerTabIndex(Node* start, int tabIndex, Keyb
Element* FocusController::nextFocusableElement(FocusNavigationScope scope, Node* start, KeyboardEvent* event)
{
+ using namespace NodeRenderingTraversal;
+
if (start) {
int tabIndex = adjustedTabIndex(*start, *event);
// If a node is excluded from the normal tabbing cycle, the next focusable node is determined by tree order
if (tabIndex < 0) {
for (Node* node = nextInScope(start); node; node = nextInScope(node)) {
- if (!is<Element>(*node))
+ if (!node->isElementNode())
continue;
- Element& element = downcast<Element>(*node);
+ Element& element = toElement(*node);
if (shouldVisit(element, *event) && adjustedTabIndex(element, *event) >= 0)
return &element;
}
@@ -543,6 +493,8 @@ Element* FocusController::nextFocusableElement(FocusNavigationScope scope, Node*
Element* FocusController::previousFocusableElement(FocusNavigationScope scope, Node* start, KeyboardEvent* event)
{
+ using namespace NodeRenderingTraversal;
+
Node* last = nullptr;
for (Node* node = scope.rootNode(); node; node = lastChildInScope(node))
last = node;
@@ -563,9 +515,9 @@ Element* FocusController::previousFocusableElement(FocusNavigationScope scope, N
// However, if a node is excluded from the normal tabbing cycle, the previous focusable node is determined by tree order
if (startingTabIndex < 0) {
for (Node* node = startingNode; node; node = previousInScope(node)) {
- if (!is<Element>(*node))
+ if (!node->isElementNode())
continue;
- Element& element = downcast<Element>(*node);
+ Element& element = toElement(*node);
if (shouldVisit(element, *event) && adjustedTabIndex(element, *event) >= 0)
return &element;
}
@@ -591,7 +543,7 @@ static bool relinquishesEditingFocus(Node *node)
if (!frame || !root)
return false;
- return frame->editor().shouldEndEditing(rangeOfContents(*root).ptr());
+ return frame->editor().shouldEndEditing(rangeOfContents(*root).get());
}
static void clearSelectionIfNeeded(Frame* oldFocusedFrame, Frame* newFocusedFrame, Node* newFocusedNode)
@@ -601,8 +553,8 @@ static void clearSelectionIfNeeded(Frame* oldFocusedFrame, Frame* newFocusedFram
if (oldFocusedFrame->document() != newFocusedFrame->document())
return;
-
- const VisibleSelection& selection = oldFocusedFrame->selection().selection();
+
+ FrameSelection& selection = oldFocusedFrame->selection();
if (selection.isNone())
return;
@@ -610,7 +562,7 @@ static void clearSelectionIfNeeded(Frame* oldFocusedFrame, Frame* newFocusedFram
if (caretBrowsing)
return;
- Node* selectionStartNode = selection.start().deprecatedNode();
+ Node* selectionStartNode = selection.selection().start().deprecatedNode();
if (selectionStartNode == newFocusedNode || selectionStartNode->isDescendantOf(newFocusedNode) || selectionStartNode->deprecatedShadowAncestorNode() == newFocusedNode)
return;
@@ -622,21 +574,21 @@ static void clearSelectionIfNeeded(Frame* oldFocusedFrame, Frame* newFocusedFram
return;
if (Node* shadowAncestorNode = root->deprecatedShadowAncestorNode()) {
- if (!is<HTMLInputElement>(*shadowAncestorNode) && !is<HTMLTextAreaElement>(*shadowAncestorNode))
+ if (!isHTMLInputElement(shadowAncestorNode) && !isHTMLTextAreaElement(shadowAncestorNode))
return;
}
}
}
-
- oldFocusedFrame->selection().clear();
+
+ selection.clear();
}
bool FocusController::setFocusedElement(Element* element, PassRefPtr<Frame> newFocusedFrame, FocusDirection direction)
{
RefPtr<Frame> oldFocusedFrame = focusedFrame();
- RefPtr<Document> oldDocument = oldFocusedFrame ? oldFocusedFrame->document() : nullptr;
+ RefPtr<Document> oldDocument = oldFocusedFrame ? oldFocusedFrame->document() : 0;
- Element* oldFocusedElement = oldDocument ? oldDocument->focusedElement() : nullptr;
+ Element* oldFocusedElement = oldDocument ? oldDocument->focusedElement() : 0;
if (oldFocusedElement == element)
return true;
@@ -644,29 +596,29 @@ bool FocusController::setFocusedElement(Element* element, PassRefPtr<Frame> newF
if (oldFocusedElement && oldFocusedElement->isRootEditableElement() && !relinquishesEditingFocus(oldFocusedElement))
return false;
- m_page.editorClient().willSetInputMethodState();
+ m_page.editorClient()->willSetInputMethodState();
clearSelectionIfNeeded(oldFocusedFrame.get(), newFocusedFrame.get(), element);
if (!element) {
if (oldDocument)
- oldDocument->setFocusedElement(nullptr);
- m_page.editorClient().setInputMethodState(false);
+ oldDocument->setFocusedElement(0);
+ m_page.editorClient()->setInputMethodState(false);
return true;
}
Ref<Document> newDocument(element->document());
if (newDocument->focusedElement() == element) {
- m_page.editorClient().setInputMethodState(element->shouldUseInputMethod());
+ m_page.editorClient()->setInputMethodState(element->shouldUseInputMethod());
return true;
}
- if (oldDocument && oldDocument != newDocument.ptr())
- oldDocument->setFocusedElement(nullptr);
+ if (oldDocument && oldDocument != &newDocument.get())
+ oldDocument->setFocusedElement(0);
if (newFocusedFrame && !newFocusedFrame->page()) {
- setFocusedFrame(nullptr);
+ setFocusedFrame(0);
return false;
}
setFocusedFrame(newFocusedFrame);
@@ -678,35 +630,18 @@ bool FocusController::setFocusedElement(Element* element, PassRefPtr<Frame> newF
return false;
if (newDocument->focusedElement() == element)
- m_page.editorClient().setInputMethodState(element->shouldUseInputMethod());
-
- m_focusSetTime = monotonicallyIncreasingTime();
- m_focusRepaintTimer.stop();
+ m_page.editorClient()->setInputMethodState(element->shouldUseInputMethod());
return true;
}
-void FocusController::setViewState(ViewState::Flags viewState)
-{
- ViewState::Flags changed = m_viewState ^ viewState;
- m_viewState = viewState;
-
- if (changed & ViewState::IsFocused)
- setFocusedInternal(viewState & ViewState::IsFocused);
- if (changed & ViewState::WindowIsActive) {
- setActiveInternal(viewState & ViewState::WindowIsActive);
- if (changed & ViewState::IsVisible)
- setIsVisibleAndActiveInternal(viewState & ViewState::WindowIsActive);
- }
-}
-
void FocusController::setActive(bool active)
{
- m_page.setViewState(active ? m_viewState | ViewState::WindowIsActive : m_viewState & ~ViewState::WindowIsActive);
-}
+ if (m_isActive == active)
+ return;
+
+ m_isActive = active;
-void FocusController::setActiveInternal(bool active)
-{
if (FrameView* view = m_page.mainFrame().view()) {
if (!view->platformWidget()) {
view->updateLayoutAndStyleIfNeededRecursive();
@@ -728,8 +663,13 @@ static void contentAreaDidShowOrHide(ScrollableArea* scrollableArea, bool didSho
scrollableArea->contentAreaDidHide();
}
-void FocusController::setIsVisibleAndActiveInternal(bool contentIsVisible)
+void FocusController::setContentIsVisible(bool contentIsVisible)
{
+ if (m_contentIsVisible == contentIsVisible)
+ return;
+
+ m_contentIsVisible = contentIsVisible;
+
FrameView* view = m_page.mainFrame().view();
if (!view)
return;
@@ -745,7 +685,8 @@ void FocusController::setIsVisibleAndActiveInternal(bool contentIsVisible)
if (!scrollableAreas)
continue;
- for (auto& scrollableArea : *scrollableAreas) {
+ for (HashSet<ScrollableArea*>::const_iterator it = scrollableAreas->begin(), end = scrollableAreas->end(); it != end; ++it) {
+ ScrollableArea* scrollableArea = *it;
ASSERT(scrollableArea->scrollbarsCanBeActive() || m_page.shouldSuppressScrollbarAnimations());
contentAreaDidShowOrHide(scrollableArea, contentIsVisible);
@@ -802,8 +743,9 @@ static void updateFocusCandidateIfNeeded(FocusDirection direction, const FocusCa
closest = candidate;
}
-void FocusController::findFocusCandidateInContainer(Node& container, const LayoutRect& startingRect, FocusDirection direction, KeyboardEvent* event, FocusCandidate& closest)
+void FocusController::findFocusCandidateInContainer(Node* container, const LayoutRect& startingRect, FocusDirection direction, KeyboardEvent* event, FocusCandidate& closest)
{
+ ASSERT(container);
Node* focusedNode = (focusedFrame() && focusedFrame()->document()) ? focusedFrame()->document()->focusedElement() : 0;
Element* element = ElementTraversal::firstWithin(container);
@@ -814,8 +756,8 @@ void FocusController::findFocusCandidateInContainer(Node& container, const Layou
unsigned candidateCount = 0;
for (; element; element = (element->isFrameOwnerElement() || canScrollInDirection(element, direction))
- ? ElementTraversal::nextSkippingChildren(*element, &container)
- : ElementTraversal::next(*element, &container)) {
+ ? ElementTraversal::nextSkippingChildren(element, container)
+ : ElementTraversal::next(element, container)) {
if (element == focusedNode)
continue;
@@ -830,7 +772,7 @@ void FocusController::findFocusCandidateInContainer(Node& container, const Layou
continue;
candidateCount++;
- candidate.enclosingScrollableBox = &container;
+ candidate.enclosingScrollableBox = container;
updateFocusCandidateIfNeeded(direction, current, candidate, closest);
}
@@ -854,7 +796,7 @@ bool FocusController::advanceFocusDirectionallyInContainer(Node* container, cons
// Find the closest node within current container in the direction of the navigation.
FocusCandidate focusCandidate;
- findFocusCandidateInContainer(*container, newStartingRect, direction, event, focusCandidate);
+ findFocusCandidateInContainer(container, newStartingRect, direction, event, focusCandidate);
if (focusCandidate.isNull()) {
// Nothing to focus, scroll if possible.
@@ -905,7 +847,7 @@ bool FocusController::advanceFocusDirectionallyInContainer(Node* container, cons
}
// We found a new focus node, navigate to it.
- Element* element = downcast<Element>(focusCandidate.focusableNode);
+ Element* element = toElement(focusCandidate.focusableNode);
ASSERT(element);
element->focus(false, direction);
@@ -921,8 +863,8 @@ bool FocusController::advanceFocusDirectionally(FocusDirection direction, Keyboa
Element* focusedElement = focusedDocument->focusedElement();
Node* container = focusedDocument;
- if (is<Document>(*container))
- downcast<Document>(*container).updateLayoutIgnorePendingStylesheets();
+ if (container->isDocumentNode())
+ toDocument(container)->updateLayoutIgnorePendingStylesheets();
// Figure out the starting rect.
LayoutRect startingRect;
@@ -930,10 +872,10 @@ bool FocusController::advanceFocusDirectionally(FocusDirection direction, Keyboa
if (!hasOffscreenRect(focusedElement)) {
container = scrollableEnclosingBoxOrParentFrameForNodeInDirection(direction, focusedElement);
startingRect = nodeRectInAbsoluteCoordinates(focusedElement, true /* ignore border */);
- } else if (is<HTMLAreaElement>(*focusedElement)) {
- HTMLAreaElement& area = downcast<HTMLAreaElement>(*focusedElement);
- container = scrollableEnclosingBoxOrParentFrameForNodeInDirection(direction, area.imageElement());
- startingRect = virtualRectForAreaElementAndDirection(&area, direction);
+ } else if (isHTMLAreaElement(focusedElement)) {
+ HTMLAreaElement* area = toHTMLAreaElement(focusedElement);
+ container = scrollableEnclosingBoxOrParentFrameForNodeInDirection(direction, area->imageElement());
+ startingRect = virtualRectForAreaElementAndDirection(area, direction);
}
}
@@ -945,35 +887,11 @@ bool FocusController::advanceFocusDirectionally(FocusDirection direction, Keyboa
consumed = advanceFocusDirectionallyInContainer(container, startingRect, direction, event);
startingRect = nodeRectInAbsoluteCoordinates(container, true /* ignore border */);
container = scrollableEnclosingBoxOrParentFrameForNodeInDirection(direction, container);
- if (is<Document>(container))
- downcast<Document>(*container).updateLayoutIgnorePendingStylesheets();
+ if (container && container->isDocumentNode())
+ toDocument(container)->updateLayoutIgnorePendingStylesheets();
} while (!consumed && container);
return consumed;
}
-void FocusController::setFocusedElementNeedsRepaint()
-{
- m_focusRepaintTimer.startOneShot(0.033);
-}
-
-void FocusController::focusRepaintTimerFired()
-{
- Document* focusedDocument = focusedOrMainFrame().document();
- if (!focusedDocument)
- return;
-
- Element* focusedElement = focusedDocument->focusedElement();
- if (!focusedElement)
- return;
-
- if (focusedElement->renderer())
- focusedElement->renderer()->repaint();
-}
-
-double FocusController::timeSinceFocusWasSet() const
-{
- return monotonicallyIncreasingTime() - m_focusSetTime;
-}
-
} // namespace WebCore
diff --git a/Source/WebCore/page/FocusController.h b/Source/WebCore/page/FocusController.h
index f80dff4d4..b991130ae 100644
--- a/Source/WebCore/page/FocusController.h
+++ b/Source/WebCore/page/FocusController.h
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -28,8 +28,6 @@
#include "FocusDirection.h"
#include "LayoutRect.h"
-#include "Timer.h"
-#include "ViewState.h"
#include <wtf/Forward.h>
#include <wtf/Noncopyable.h>
#include <wtf/RefPtr.h>
@@ -52,7 +50,7 @@ class FocusNavigationScope {
public:
ContainerNode* rootNode() const;
Element* owner() const;
- WEBCORE_EXPORT static FocusNavigationScope focusNavigationScopeOf(Node*);
+ static FocusNavigationScope focusNavigationScopeOf(Node*);
static FocusNavigationScope focusNavigationScopeOwnedByShadowHost(Node*);
static FocusNavigationScope focusNavigationScopeOwnedByIFrame(HTMLFrameOwnerElement*);
@@ -64,39 +62,30 @@ private:
class FocusController {
WTF_MAKE_NONCOPYABLE(FocusController); WTF_MAKE_FAST_ALLOCATED;
public:
- explicit FocusController(Page&, ViewState::Flags);
+ explicit FocusController(Page&);
- WEBCORE_EXPORT void setFocusedFrame(PassRefPtr<Frame>);
+ void setFocusedFrame(PassRefPtr<Frame>);
Frame* focusedFrame() const { return m_focusedFrame.get(); }
- WEBCORE_EXPORT Frame& focusedOrMainFrame() const;
+ Frame& focusedOrMainFrame() const;
- WEBCORE_EXPORT bool setInitialFocus(FocusDirection, KeyboardEvent*);
+ bool setInitialFocus(FocusDirection, KeyboardEvent*);
bool advanceFocus(FocusDirection, KeyboardEvent*, bool initialFocus = false);
- WEBCORE_EXPORT bool setFocusedElement(Element*, PassRefPtr<Frame>, FocusDirection = FocusDirectionNone);
+ bool setFocusedElement(Element*, PassRefPtr<Frame>, FocusDirection = FocusDirectionNone);
- void setViewState(ViewState::Flags);
+ void setActive(bool);
+ bool isActive() const { return m_isActive; }
- WEBCORE_EXPORT void setActive(bool);
- bool isActive() const { return m_viewState & ViewState::WindowIsActive; }
+ void setFocused(bool);
+ bool isFocused() const { return m_isFocused; }
- WEBCORE_EXPORT void setFocused(bool);
- bool isFocused() const { return m_viewState & ViewState::IsFocused; }
-
- bool contentIsVisible() const { return m_viewState & ViewState::IsVisible; }
+ void setContentIsVisible(bool);
// These methods are used in WebCore/bindings/objc/DOM.mm.
- WEBCORE_EXPORT Element* nextFocusableElement(FocusNavigationScope, Node* start, KeyboardEvent*);
- WEBCORE_EXPORT Element* previousFocusableElement(FocusNavigationScope, Node* start, KeyboardEvent*);
-
- void setFocusedElementNeedsRepaint();
- double timeSinceFocusWasSet() const;
+ Element* nextFocusableElement(FocusNavigationScope, Node* start, KeyboardEvent*);
+ Element* previousFocusableElement(FocusNavigationScope, Node* start, KeyboardEvent*);
private:
- void setActiveInternal(bool);
- void setFocusedInternal(bool);
- void setIsVisibleAndActiveInternal(bool);
-
bool advanceFocusDirectionally(FocusDirection, KeyboardEvent*);
bool advanceFocusInDocumentOrder(FocusDirection, KeyboardEvent*, bool initialFocus);
@@ -118,17 +107,15 @@ private:
Element* findElementWithExactTabIndex(Node* start, int tabIndex, KeyboardEvent*, FocusDirection);
bool advanceFocusDirectionallyInContainer(Node* container, const LayoutRect& startingRect, FocusDirection, KeyboardEvent*);
- void findFocusCandidateInContainer(Node& container, const LayoutRect& startingRect, FocusDirection, KeyboardEvent*, FocusCandidate& closest);
-
- void focusRepaintTimerFired();
+ void findFocusCandidateInContainer(Node* container, const LayoutRect& startingRect, FocusDirection, KeyboardEvent*, FocusCandidate& closest);
Page& m_page;
RefPtr<Frame> m_focusedFrame;
+ bool m_isActive;
+ bool m_isFocused;
bool m_isChangingFocusedFrame;
- ViewState::Flags m_viewState;
+ bool m_contentIsVisible;
- Timer m_focusRepaintTimer;
- double m_focusSetTime;
};
} // namespace WebCore
diff --git a/Source/WebCore/page/FocusDirection.h b/Source/WebCore/page/FocusDirection.h
index b01a6fb1d..0645a6f9a 100644
--- a/Source/WebCore/page/FocusDirection.h
+++ b/Source/WebCore/page/FocusDirection.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006 Apple Inc. All rights reserved.
+ * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
diff --git a/Source/WebCore/page/Frame.cpp b/Source/WebCore/page/Frame.cpp
index c3b46c920..4456c0d5a 100644
--- a/Source/WebCore/page/Frame.cpp
+++ b/Source/WebCore/page/Frame.cpp
@@ -5,7 +5,7 @@
* 2000 Simon Hausmann <hausmann@kde.org>
* 2000 Stefan Schimanski <1Stein@gmx.de>
* 2001 George Staikos <staikos@kde.org>
- * Copyright (C) 2004-2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
* Copyright (C) 2005 Alexey Proskuryakov <ap@nypop.com>
* Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
* Copyright (C) 2008 Eric Seidel <eric@webkit.org>
@@ -61,7 +61,6 @@
#include "HTMLFrameElementBase.h"
#include "HTMLNames.h"
#include "HTMLTableCellElement.h"
-#include "HTMLTableRowElement.h"
#include "HitTestResult.h"
#include "ImageBuffer.h"
#include "InspectorInstrumentation.h"
@@ -76,7 +75,6 @@
#include "Page.h"
#include "PageCache.h"
#include "PageGroup.h"
-#include "RenderLayerCompositor.h"
#include "RenderTableCell.h"
#include "RenderText.h"
#include "RenderTextControl.h"
@@ -84,19 +82,17 @@
#include "RenderView.h"
#include "RenderWidget.h"
#include "RuntimeEnabledFeatures.h"
-#include "SVGDocument.h"
-#include "SVGDocumentExtensions.h"
#include "SVGNames.h"
#include "ScriptController.h"
#include "ScriptSourceCode.h"
#include "ScrollingCoordinator.h"
#include "Settings.h"
#include "StyleProperties.h"
+#include "TextIterator.h"
#include "TextNodeTraversal.h"
#include "TextResourceDecoder.h"
#include "UserContentController.h"
#include "UserContentURLPattern.h"
-#include "UserScript.h"
#include "UserTypingGestureIndicator.h"
#include "VisibleUnits.h"
#include "WebKitFontFamilyNames.h"
@@ -108,10 +104,24 @@
#include "npruntime_impl.h"
#include "runtime_root.h"
#include <bindings/ScriptValue.h>
+#include <wtf/PassOwnPtr.h>
#include <wtf/RefCountedLeakCounter.h>
#include <wtf/StdLibExtras.h>
#include <yarr/RegularExpression.h>
+#if USE(ACCELERATED_COMPOSITING)
+#include "RenderLayerCompositor.h"
+#endif
+
+#if ENABLE(SVG)
+#include "SVGDocument.h"
+#include "SVGDocumentExtensions.h"
+#endif
+
+#if USE(TILED_BACKING_STORE)
+#include "TiledBackingStore.h"
+#endif
+
#if PLATFORM(IOS)
#include "WKContentObservation.h"
#endif
@@ -158,17 +168,22 @@ Frame::Frame(Page& page, HTMLFrameOwnerElement* ownerElement, FrameLoaderClient&
, m_navigationScheduler(*this)
, m_ownerElement(ownerElement)
, m_script(std::make_unique<ScriptController>(*this))
- , m_editor(std::make_unique<Editor>(*this))
- , m_selection(std::make_unique<FrameSelection>(this))
+ , m_editor(Editor::create(*this))
+ , m_selection(adoptPtr(new FrameSelection(this)))
+ , m_eventHandler(adoptPtr(new EventHandler(*this)))
, m_animationController(std::make_unique<AnimationController>(*this))
#if PLATFORM(IOS)
- , m_overflowAutoScrollTimer(*this, &Frame::overflowAutoScrollTimerFired)
+ , m_overflowAutoScrollTimer(this, &Frame::overflowAutoScrollTimerFired)
, m_selectionChangeCallbacksDisabled(false)
+ , m_timersPausedCount(0)
#endif
, m_pageZoomFactor(parentPageZoomFactor(this))
, m_textZoomFactor(parentTextZoomFactor(this))
+#if ENABLE(ORIENTATION_EVENTS)
+ , m_orientation(0)
+#endif
+ , m_inViewSourceMode(false)
, m_activeDOMObjectsAndAnimationsSuspendedCount(0)
- , m_eventHandler(std::make_unique<EventHandler>(*this))
{
AtomicString::init();
HTMLNames::init();
@@ -181,7 +196,12 @@ Frame::Frame(Page& page, HTMLFrameOwnerElement* ownerElement, FrameLoaderClient&
XMLNames::init();
WebKitFontFamilyNames::init();
- if (ownerElement) {
+ if (!ownerElement) {
+#if USE(TILED_BACKING_STORE)
+ // Top level frame only for now.
+ setTiledBackingStoreEnabled(settings().tiledBackingStoreEnabled());
+#endif
+ } else {
m_mainFrame.selfOnlyRef();
page.incrementSubframeCount();
ownerElement->setContentFrame(this);
@@ -191,22 +211,29 @@ Frame::Frame(Page& page, HTMLFrameOwnerElement* ownerElement, FrameLoaderClient&
frameCounter.increment();
#endif
- // Pause future ActiveDOMObjects if this frame is being created while the page is in a paused state.
+ // FIXME: We should reconcile the iOS and OpenSource code below.
Frame* parent = parentFromOwnerElement(ownerElement);
+#if PLATFORM(IOS)
+ // Pause future timers if this frame is created when page is in pending state.
+ if (parent && parent->timersPaused())
+ setTimersPaused(true);
+#else
+ // Pause future ActiveDOMObjects if this frame is being created while the page is in a paused state.
if (parent && parent->activeDOMObjectsAndAnimationsSuspended())
suspendActiveDOMObjectsAndAnimations();
+#endif
}
-Ref<Frame> Frame::create(Page* page, HTMLFrameOwnerElement* ownerElement, FrameLoaderClient* client)
+PassRefPtr<Frame> Frame::create(Page* page, HTMLFrameOwnerElement* ownerElement, FrameLoaderClient* client)
{
ASSERT(page);
ASSERT(client);
- return adoptRef(*new Frame(*page, ownerElement, *client));
+ return adoptRef(new Frame(*page, ownerElement, *client));
}
Frame::~Frame()
{
- setView(nullptr);
+ setView(0);
loader().cancelAndClear();
// FIXME: We should not be doing all this work inside the destructor
@@ -234,7 +261,7 @@ void Frame::removeDestructionObserver(FrameDestructionObserver* observer)
m_destructionObservers.remove(observer);
}
-void Frame::setView(RefPtr<FrameView>&& view)
+void Frame::setView(PassRefPtr<FrameView> view)
{
// We the custom scroll bars as early as possible to prevent m_doc->detach()
// from messing with the view such that its scroll bars won't be torn down.
@@ -245,32 +272,35 @@ void Frame::setView(RefPtr<FrameView>&& view)
// Prepare for destruction now, so any unload event handlers get run and the DOMWindow is
// notified. If we wait until the view is destroyed, then things won't be hooked up enough for
// these calls to work.
- if (!view && m_doc && !m_doc->inPageCache())
+ if (!view && m_doc && m_doc->hasLivingRenderTree() && !m_doc->inPageCache())
m_doc->prepareForDestruction();
if (m_view)
m_view->unscheduleRelayout();
- // This may be called during destruction, so need to do a null check.
- if (m_eventHandler)
- m_eventHandler->clear();
+ eventHandler().clear();
- m_view = WTFMove(view);
+ m_view = view;
// Only one form submission is allowed per view of a part.
// Since this part may be getting reused as a result of being
// pulled from the back/forward cache, reset this flag.
loader().resetMultipleFormSubmissionProtection();
+
+#if USE(TILED_BACKING_STORE)
+ if (m_view && tiledBackingStore())
+ m_view->setPaintsEntireContents(true);
+#endif
}
-void Frame::setDocument(RefPtr<Document>&& newDocument)
+void Frame::setDocument(PassRefPtr<Document> newDocument)
{
ASSERT(!newDocument || newDocument->frame() == this);
- if (m_doc && !m_doc->inPageCache())
+ if (m_doc && m_doc->hasLivingRenderTree() && !m_doc->inPageCache())
m_doc->prepareForDestruction();
- m_doc = newDocument.copyRef();
+ m_doc = newDocument.get();
ASSERT(!m_doc || m_doc->domWindow());
ASSERT(!m_doc || m_doc->domWindow()->frame() == this);
@@ -278,39 +308,24 @@ void Frame::setDocument(RefPtr<Document>&& newDocument)
// that the document is not destroyed during this function call.
if (newDocument)
newDocument->didBecomeCurrentDocumentInFrame();
-
- InspectorInstrumentation::frameDocumentUpdated(this);
}
#if ENABLE(ORIENTATION_EVENTS)
-void Frame::orientationChanged()
+void Frame::sendOrientationChangeEvent(int orientation)
{
- Vector<Ref<Frame>> frames;
- for (Frame* frame = this; frame; frame = frame->tree().traverseNext())
- frames.append(*frame);
-
- for (auto& frame : frames) {
- if (Document* document = frame->document())
- document->dispatchWindowEvent(Event::create(eventNames().orientationchangeEvent, false, false));
- }
-}
-
-int Frame::orientation() const
-{
- if (m_page)
- return m_page->chrome().client().deviceOrientation();
- return 0;
+ m_orientation = orientation;
+ if (Document* doc = document())
+ doc->dispatchWindowEvent(Event::create(eventNames().orientationchangeEvent, false, false));
}
#endif // ENABLE(ORIENTATION_EVENTS)
-static JSC::Yarr::RegularExpression createRegExpForLabels(const Vector<String>& labels)
+static PassOwnPtr<JSC::Yarr::RegularExpression> createRegExpForLabels(const Vector<String>& labels)
{
// REVIEW- version of this call in FrameMac.mm caches based on the NSArray ptrs being
// the same across calls. We can't do that.
- static NeverDestroyed<JSC::Yarr::RegularExpression> wordRegExp("\\w", TextCaseSensitive);
- StringBuilder pattern;
- pattern.append('(');
+ DEFINE_STATIC_LOCAL(JSC::Yarr::RegularExpression, wordRegExp, ("\\w", TextCaseSensitive));
+ String pattern("(");
unsigned int numLabels = labels.size();
unsigned int i;
for (i = 0; i < numLabels; i++) {
@@ -319,41 +334,41 @@ static JSC::Yarr::RegularExpression createRegExpForLabels(const Vector<String>&
bool startsWithWordChar = false;
bool endsWithWordChar = false;
if (label.length()) {
- startsWithWordChar = wordRegExp.get().match(label.substring(0, 1)) >= 0;
- endsWithWordChar = wordRegExp.get().match(label.substring(label.length() - 1, 1)) >= 0;
+ startsWithWordChar = wordRegExp.match(label.substring(0, 1)) >= 0;
+ endsWithWordChar = wordRegExp.match(label.substring(label.length() - 1, 1)) >= 0;
}
if (i)
- pattern.append('|');
+ pattern.append("|");
// Search for word boundaries only if label starts/ends with "word characters".
// If we always searched for word boundaries, this wouldn't work for languages
// such as Japanese.
if (startsWithWordChar)
- pattern.appendLiteral("\\b");
+ pattern.append("\\b");
pattern.append(label);
if (endsWithWordChar)
- pattern.appendLiteral("\\b");
+ pattern.append("\\b");
}
- pattern.append(')');
- return JSC::Yarr::RegularExpression(pattern.toString(), TextCaseInsensitive);
+ pattern.append(")");
+ return adoptPtr(new JSC::Yarr::RegularExpression(pattern, TextCaseInsensitive));
}
-String Frame::searchForLabelsAboveCell(const JSC::Yarr::RegularExpression& regExp, HTMLTableCellElement* cell, size_t* resultDistanceFromStartOfCell)
+String Frame::searchForLabelsAboveCell(JSC::Yarr::RegularExpression* regExp, HTMLTableCellElement* cell, size_t* resultDistanceFromStartOfCell)
{
HTMLTableCellElement* aboveCell = cell->cellAbove();
if (aboveCell) {
// search within the above cell we found for a match
size_t lengthSearched = 0;
- for (Text* textNode = TextNodeTraversal::firstWithin(*aboveCell); textNode; textNode = TextNodeTraversal::next(*textNode, aboveCell)) {
+ for (Text* textNode = TextNodeTraversal::firstWithin(aboveCell); textNode; textNode = TextNodeTraversal::next(textNode, aboveCell)) {
if (!textNode->renderer() || textNode->renderer()->style().visibility() != VISIBLE)
continue;
// For each text chunk, run the regexp
String nodeString = textNode->data();
- int pos = regExp.searchRev(nodeString);
+ int pos = regExp->searchRev(nodeString);
if (pos >= 0) {
if (resultDistanceFromStartOfCell)
*resultDistanceFromStartOfCell = lengthSearched;
- return nodeString.substring(pos, regExp.matchedLength());
+ return nodeString.substring(pos, regExp->matchedLength());
}
lengthSearched += nodeString.length();
}
@@ -365,18 +380,16 @@ String Frame::searchForLabelsAboveCell(const JSC::Yarr::RegularExpression& regEx
return String();
}
-// FIXME: This should take an Element&.
String Frame::searchForLabelsBeforeElement(const Vector<String>& labels, Element* element, size_t* resultDistance, bool* resultIsInCellAbove)
{
- ASSERT(element);
- JSC::Yarr::RegularExpression regExp = createRegExpForLabels(labels);
+ OwnPtr<JSC::Yarr::RegularExpression> regExp(createRegExpForLabels(labels));
// We stop searching after we've seen this many chars
const unsigned int charsSearchedThreshold = 500;
// This is the absolute max we search. We allow a little more slop than
// charsSearchedThreshold, to make it more likely that we'll search whole nodes.
const unsigned int maxCharsSearched = 600;
// If the starting element is within a table, the cell that contains it
- HTMLTableCellElement* startingTableCell = nullptr;
+ HTMLTableCellElement* startingTableCell = 0;
bool searchedCellAbove = false;
if (resultDistance)
@@ -387,15 +400,15 @@ String Frame::searchForLabelsBeforeElement(const Vector<String>& labels, Element
// walk backwards in the node tree, until another element, or form, or end of tree
int unsigned lengthSearched = 0;
Node* n;
- for (n = NodeTraversal::previous(*element); n && lengthSearched < charsSearchedThreshold; n = NodeTraversal::previous(*n)) {
+ for (n = NodeTraversal::previous(element); n && lengthSearched < charsSearchedThreshold; n = NodeTraversal::previous(n)) {
// We hit another form element or the start of the form - bail out
- if (is<HTMLFormElement>(*n) || is<HTMLFormControlElement>(*n))
+ if (isHTMLFormElement(n) || (n->isHTMLElement() && toElement(n)->isFormControlElement()))
break;
- if (n->hasTagName(tdTag) && !startingTableCell)
- startingTableCell = downcast<HTMLTableCellElement>(n);
- else if (is<HTMLTableRowElement>(*n) && startingTableCell) {
- String result = searchForLabelsAboveCell(regExp, startingTableCell, resultDistance);
+ if (n->hasTagName(tdTag) && !startingTableCell) {
+ startingTableCell = toHTMLTableCellElement(n);
+ } else if (n->hasTagName(trTag) && startingTableCell) {
+ String result = searchForLabelsAboveCell(regExp.get(), startingTableCell, resultDistance);
if (!result.isEmpty()) {
if (resultIsInCellAbove)
*resultIsInCellAbove = true;
@@ -408,11 +421,11 @@ String Frame::searchForLabelsBeforeElement(const Vector<String>& labels, Element
// add 100 for slop, to make it more likely that we'll search whole nodes
if (lengthSearched + nodeString.length() > maxCharsSearched)
nodeString = nodeString.right(charsSearchedThreshold - lengthSearched);
- int pos = regExp.searchRev(nodeString);
+ int pos = regExp->searchRev(nodeString);
if (pos >= 0) {
if (resultDistance)
*resultDistance = lengthSearched;
- return nodeString.substring(pos, regExp.matchedLength());
+ return nodeString.substring(pos, regExp->matchedLength());
}
lengthSearched += nodeString.length();
}
@@ -421,7 +434,7 @@ String Frame::searchForLabelsBeforeElement(const Vector<String>& labels, Element
// If we started in a cell, but bailed because we found the start of the form or the
// previous element, we still might need to search the row above us for a label.
if (startingTableCell && !searchedCellAbove) {
- String result = searchForLabelsAboveCell(regExp, startingTableCell, resultDistance);
+ String result = searchForLabelsAboveCell(regExp.get(), startingTableCell, resultDistance);
if (!result.isEmpty()) {
if (resultIsInCellAbove)
*resultIsInCellAbove = true;
@@ -442,7 +455,7 @@ static String matchLabelsAgainstString(const Vector<String>& labels, const Strin
replace(mutableStringToMatch, JSC::Yarr::RegularExpression("\\d", TextCaseSensitive), " ");
mutableStringToMatch.replace('_', ' ');
- JSC::Yarr::RegularExpression regExp = createRegExpForLabels(labels);
+ OwnPtr<JSC::Yarr::RegularExpression> regExp(createRegExpForLabels(labels));
// Use the largest match we can find in the whole string
int pos;
int length;
@@ -450,9 +463,9 @@ static String matchLabelsAgainstString(const Vector<String>& labels, const Strin
int bestLength = -1;
int start = 0;
do {
- pos = regExp.match(mutableStringToMatch, start);
+ pos = regExp->match(mutableStringToMatch, start);
if (pos != -1) {
- length = regExp.matchedLength();
+ length = regExp->matchedLength();
if (length >= bestLength) {
bestPos = pos;
bestLength = length;
@@ -476,7 +489,7 @@ String Frame::matchLabelsAgainstElement(const Vector<String>& labels, Element* e
if (!resultFromNameAttribute.isEmpty())
return resultFromNameAttribute;
- return matchLabelsAgainstString(labels, element->fastGetAttribute(idAttr));
+ return matchLabelsAgainstString(labels, element->getAttribute(idAttr));
}
#if PLATFORM(IOS)
@@ -492,30 +505,30 @@ void Frame::scrollOverflowLayer(RenderLayer* layer, const IntRect& visibleRect,
if (visibleRect.intersects(exposeRect))
return;
- // FIXME: Why isn't this just calling RenderLayer::scrollRectToVisible()?
- ScrollOffset scrollOffset = layer->scrollOffset();
+ int x = layer->scrollXOffset();
int exposeLeft = exposeRect.x();
int exposeRight = exposeLeft + exposeRect.width();
- int clientWidth = roundToInt(box->clientWidth());
+ int clientWidth = box->clientWidth();
if (exposeLeft <= 0)
- scrollOffset.setX(std::max(0, scrollOffset.x() + exposeLeft - clientWidth / 2));
+ x = std::max(0, x + exposeLeft - clientWidth / 2);
else if (exposeRight >= clientWidth)
- scrollOffset.setX(std::min(box->scrollWidth() - clientWidth, scrollOffset.x() + clientWidth / 2));
+ x = std::min(box->scrollWidth() - clientWidth, x + clientWidth / 2);
+ int y = layer->scrollYOffset();
int exposeTop = exposeRect.y();
int exposeBottom = exposeTop + exposeRect.height();
- int clientHeight = roundToInt(box->clientHeight());
+ int clientHeight = box->clientHeight();
if (exposeTop <= 0)
- scrollOffset.setY(std::max(0, scrollOffset.y() + exposeTop - clientHeight / 2));
+ y = std::max(0, y + exposeTop - clientHeight / 2);
else if (exposeBottom >= clientHeight)
- scrollOffset.setY(std::min(box->scrollHeight() - clientHeight, scrollOffset.y() + clientHeight / 2));
+ y = std::min(box->scrollHeight() - clientHeight, y + clientHeight / 2);
- layer->scrollToOffset(scrollOffset);
+ layer->scrollToOffset(IntSize(x, y));
selection().setCaretRectNeedsUpdate();
selection().updateAppearance();
}
-void Frame::overflowAutoScrollTimerFired()
+void Frame::overflowAutoScrollTimerFired(Timer<Frame>*)
{
if (!eventHandler().mousePressed() || checkOverflowScroll(PerformOverflowScroll) == OverflowScrollNone) {
if (m_overflowAutoScrollTimer.isActive())
@@ -604,10 +617,10 @@ int Frame::checkOverflowScroll(OverflowScrollAction action)
}
if (action == PerformOverflowScroll && (deltaX || deltaY)) {
- layer->scrollToOffset(layer->scrollOffset() + IntSize(deltaX, deltaY));
+ layer->scrollToOffset(IntSize(layer->scrollXOffset() + deltaX, layer->scrollYOffset() + deltaY));
// Handle making selection.
- VisiblePosition visiblePosition(renderer->positionForPoint(selectionPosition, nullptr));
+ VisiblePosition visiblePosition(renderer->positionForPoint(selectionPosition));
if (visiblePosition.isNotNull()) {
VisibleSelection visibleSelection = selection().selection();
visibleSelection.setExtent(visiblePosition);
@@ -688,7 +701,7 @@ void Frame::injectUserScripts(UserScriptInjectionTime injectionTime)
if (!m_page)
return;
- if (loader().stateMachine().creatingInitialEmptyDocument() && !settings().shouldInjectUserScriptsInInitialEmptyDocument())
+ if (loader().stateMachine()->creatingInitialEmptyDocument() && !settings().shouldInjectUserScriptsInInitialEmptyDocument())
return;
const auto* userContentController = m_page->userContentController();
@@ -713,7 +726,10 @@ void Frame::injectUserScriptsForWorld(DOMWrapperWorld& world, const UserScriptVe
if (!doc)
return;
- for (auto& script : userScripts) {
+ Vector<ScriptSourceCode> sourceCode;
+ unsigned count = userScripts.size();
+ for (unsigned i = 0; i < count; ++i) {
+ UserScript* script = userScripts[i].get();
if (script->injectedFrames() == InjectInTopFrameOnly && ownerElement())
continue;
@@ -724,24 +740,24 @@ void Frame::injectUserScriptsForWorld(DOMWrapperWorld& world, const UserScriptVe
RenderView* Frame::contentRenderer() const
{
- return document() ? document()->renderView() : nullptr;
+ return document() ? document()->renderView() : 0;
}
RenderWidget* Frame::ownerRenderer() const
{
HTMLFrameOwnerElement* ownerElement = m_ownerElement;
if (!ownerElement)
- return nullptr;
- auto* object = ownerElement->renderer();
+ return 0;
+ auto object = ownerElement->renderer();
if (!object)
- return nullptr;
+ return 0;
// FIXME: If <object> is ever fixed to disassociate itself from frames
// that it has started but canceled, then this can turn into an ASSERT
// since m_ownerElement would be 0 when the load is canceled.
// https://bugs.webkit.org/show_bug.cgi?id=18585
- if (!is<RenderWidget>(*object))
- return nullptr;
- return downcast<RenderWidget>(object);
+ if (!object->isWidget())
+ return 0;
+ return toRenderWidget(object);
}
Frame* Frame::frameForWidget(const Widget* widget)
@@ -753,7 +769,8 @@ Frame* Frame::frameForWidget(const Widget* widget)
// Assume all widgets are either a FrameView or owned by a RenderWidget.
// FIXME: That assumption is not right for scroll bars!
- return &downcast<FrameView>(*widget).frame();
+ ASSERT_WITH_SECURITY_IMPLICATION(widget->isFrameView());
+ return &toFrameView(widget)->frame();
}
void Frame::clearTimers(FrameView *view, Document *document)
@@ -781,10 +798,10 @@ void Frame::willDetachPage()
// FIXME: It's unclear as to why this is called more than once, but it is,
// so page() could be NULL.
if (page() && page()->focusController().focusedFrame() == this)
- page()->focusController().setFocusedFrame(nullptr);
+ page()->focusController().setFocusedFrame(0);
if (page() && page()->scrollingCoordinator() && m_view)
- page()->scrollingCoordinator()->willDestroyScrollableArea(*m_view);
+ page()->scrollingCoordinator()->willDestroyScrollableArea(m_view.get());
#if PLATFORM(IOS)
if (WebThreadCountOfObservedContentModifiers() > 0 && m_page)
@@ -798,6 +815,18 @@ void Frame::willDetachPage()
void Frame::disconnectOwnerElement()
{
if (m_ownerElement) {
+ // We use the ownerElement's document to retrieve the cache, because the contentDocument for this
+ // frame is already detached (and can't access the top level AX cache).
+ // However, we pass in the current document to clearTextMarkerNodesInUse so we can identify the
+ // nodes inside this document that need to be removed from the cache.
+
+ // We don't clear the AXObjectCache here because we don't want to clear the top level cache
+ // when a sub-frame is removed.
+#if HAVE(ACCESSIBILITY)
+ if (AXObjectCache* cache = m_ownerElement->document().existingAXObjectCache())
+ cache->clearTextMarkerNodesInUse(document());
+#endif
+
m_ownerElement->clearContentFrame();
if (m_page)
m_page->decrementSubframeCount();
@@ -810,7 +839,7 @@ String Frame::displayStringModifiedByEncoding(const String& str) const
return document() ? document()->displayStringModifiedByEncoding(str) : str;
}
-VisiblePosition Frame::visiblePositionForPoint(const IntPoint& framePoint) const
+VisiblePosition Frame::visiblePositionForPoint(const IntPoint& framePoint)
{
HitTestResult result = eventHandler().hitTestResultAtPoint(framePoint, HitTestRequest::ReadOnly | HitTestRequest::Active);
Node* node = result.innerNonSharedNode();
@@ -819,7 +848,7 @@ VisiblePosition Frame::visiblePositionForPoint(const IntPoint& framePoint) const
auto renderer = node->renderer();
if (!renderer)
return VisiblePosition();
- VisiblePosition visiblePos = renderer->positionForPoint(result.localPoint(), nullptr);
+ VisiblePosition visiblePos = renderer->positionForPoint(result.localPoint());
if (visiblePos.isNull())
visiblePos = firstPositionInOrBeforeNode(node);
return visiblePos;
@@ -838,33 +867,28 @@ Document* Frame::documentAtPoint(const IntPoint& point)
return result.innerNode() ? &result.innerNode()->document() : 0;
}
-RefPtr<Range> Frame::rangeForPoint(const IntPoint& framePoint)
+PassRefPtr<Range> Frame::rangeForPoint(const IntPoint& framePoint)
{
VisiblePosition position = visiblePositionForPoint(framePoint);
if (position.isNull())
- return nullptr;
-
- Position deepPosition = position.deepEquivalent();
- Text* containerText = deepPosition.containerText();
- if (!containerText || !containerText->renderer() || containerText->renderer()->style().userSelect() == SELECT_NONE)
- return nullptr;
+ return 0;
VisiblePosition previous = position.previous();
if (previous.isNotNull()) {
RefPtr<Range> previousCharacterRange = makeRange(previous, position);
LayoutRect rect = editor().firstRectForRange(previousCharacterRange.get());
if (rect.contains(framePoint))
- return previousCharacterRange;
+ return previousCharacterRange.release();
}
VisiblePosition next = position.next();
if (RefPtr<Range> nextCharacterRange = makeRange(position, next)) {
LayoutRect rect = editor().firstRectForRange(nextCharacterRange.get());
if (rect.contains(framePoint))
- return nextCharacterRange;
+ return nextCharacterRange.release();
}
- return nullptr;
+ return 0;
}
void Frame::createView(const IntSize& viewportSize, const Color& backgroundColor, bool transparent,
@@ -872,6 +896,7 @@ void Frame::createView(const IntSize& viewportSize, const Color& backgroundColor
bool useFixedLayout, ScrollbarMode horizontalScrollbarMode, bool horizontalLock,
ScrollbarMode verticalScrollbarMode, bool verticalLock)
{
+ ASSERT(this);
ASSERT(m_page);
bool isMainFrame = this->isMainFrame();
@@ -879,13 +904,13 @@ void Frame::createView(const IntSize& viewportSize, const Color& backgroundColor
if (isMainFrame && view())
view()->setParentVisible(false);
- setView(nullptr);
+ setView(0);
RefPtr<FrameView> frameView;
if (isMainFrame) {
frameView = FrameView::create(*this, viewportSize);
frameView->setFixedLayoutSize(fixedLayoutSize);
-#if USE(COORDINATED_GRAPHICS)
+#if USE(TILED_BACKING_STORE)
frameView->setFixedVisibleContentRect(fixedVisibleContentRect);
#else
UNUSED_PARAM(fixedVisibleContentRect);
@@ -896,7 +921,7 @@ void Frame::createView(const IntSize& viewportSize, const Color& backgroundColor
frameView->setScrollbarModes(horizontalScrollbarMode, verticalScrollbarMode, horizontalLock, verticalLock);
- setView(frameView.copyRef());
+ setView(frameView);
if (backgroundColor.isValid())
frameView->updateBackgroundRecursively(backgroundColor, transparent);
@@ -911,14 +936,80 @@ void Frame::createView(const IntSize& viewportSize, const Color& backgroundColor
view()->setCanHaveScrollbars(owner->scrollingMode() != ScrollbarAlwaysOff);
}
+#if USE(TILED_BACKING_STORE)
+void Frame::setTiledBackingStoreEnabled(bool enabled)
+{
+ if (!enabled) {
+ m_tiledBackingStore.clear();
+ return;
+ }
+ if (m_tiledBackingStore)
+ return;
+ m_tiledBackingStore = adoptPtr(new TiledBackingStore(this));
+ m_tiledBackingStore->setCommitTileUpdatesOnIdleEventLoop(true);
+ if (m_view)
+ m_view->setPaintsEntireContents(true);
+}
+
+void Frame::tiledBackingStorePaintBegin()
+{
+ if (!m_view)
+ return;
+ m_view->updateLayoutAndStyleIfNeededRecursive();
+}
+
+void Frame::tiledBackingStorePaint(GraphicsContext* context, const IntRect& rect)
+{
+ if (!m_view)
+ return;
+ m_view->paintContents(context, rect);
+}
+
+void Frame::tiledBackingStorePaintEnd(const Vector<IntRect>& paintedArea)
+{
+ if (!m_page || !m_view)
+ return;
+ unsigned size = paintedArea.size();
+ // Request repaint from the system
+ for (unsigned n = 0; n < size; ++n)
+ m_page->chrome().invalidateContentsAndRootView(m_view->contentsToRootView(paintedArea[n]), false);
+}
+
+IntRect Frame::tiledBackingStoreContentsRect()
+{
+ if (!m_view)
+ return IntRect();
+ return IntRect(IntPoint(), m_view->contentsSize());
+}
+
+IntRect Frame::tiledBackingStoreVisibleRect()
+{
+ if (!m_page)
+ return IntRect();
+ return m_page->chrome().client().visibleRectForTiledBackingStore();
+}
+
+Color Frame::tiledBackingStoreBackgroundColor() const
+{
+ if (!m_view)
+ return Color();
+ return m_view->baseBackgroundColor();
+}
+#endif
+
String Frame::layerTreeAsText(LayerTreeFlags flags) const
{
+#if USE(ACCELERATED_COMPOSITING)
document()->updateLayout();
if (!contentRenderer())
return String();
return contentRenderer()->compositor().layerTreeAsText(flags);
+#else
+ UNUSED_PARAM(flags);
+ return String();
+#endif
}
String Frame::trackedRepaintRectsAsText() const
@@ -953,10 +1044,14 @@ void Frame::setPageAndTextZoomFactors(float pageZoomFactor, float textZoomFactor
m_editor->dismissCorrectionPanelAsIgnored();
+#if ENABLE(SVG)
// Respect SVGs zoomAndPan="disabled" property in standalone SVG documents.
// FIXME: How to handle compound documents + zoomAndPan="disabled"? Needs SVG WG clarification.
- if (is<SVGDocument>(*document) && !downcast<SVGDocument>(*document).zoomAndPanEnabled())
- return;
+ if (document->isSVGDocument()) {
+ if (!toSVGDocument(document)->zoomAndPanEnabled())
+ return;
+ }
+#endif
if (m_pageZoomFactor != pageZoomFactor) {
if (FrameView* view = this->view()) {
@@ -979,6 +1074,9 @@ void Frame::setPageAndTextZoomFactors(float pageZoomFactor, float textZoomFactor
if (document->renderView() && document->renderView()->needsLayout() && view->didFirstLayout())
view->layout();
}
+
+ if (isMainFrame())
+ pageCache()->markPagesForFullStyleRecalc(page);
}
float Frame::frameScaleFactor() const
@@ -1002,33 +1100,30 @@ void Frame::suspendActiveDOMObjectsAndAnimations()
return;
// FIXME: Suspend/resume calls will not match if the frame is navigated, and gets a new document.
- clearTimers(); // Suspends animations and pending relayouts.
- if (m_doc)
- m_doc->suspendScheduledTasks(ActiveDOMObject::PageWillBeSuspended);
+ if (document()) {
+ document()->suspendScriptedAnimationControllerCallbacks();
+ animation().suspendAnimationsForDocument(document());
+ document()->suspendActiveDOMObjects(ActiveDOMObject::PageWillBeSuspended);
+ }
}
void Frame::resumeActiveDOMObjectsAndAnimations()
{
- if (!activeDOMObjectsAndAnimationsSuspended())
- return;
+ ASSERT(activeDOMObjectsAndAnimationsSuspended());
m_activeDOMObjectsAndAnimationsSuspendedCount--;
if (activeDOMObjectsAndAnimationsSuspended())
return;
- if (!m_doc)
- return;
-
- // FIXME: Suspend/resume calls will not match if the frame is navigated, and gets a new document.
- m_doc->resumeScheduledTasks(ActiveDOMObject::PageWillBeSuspended);
-
- // Frame::clearTimers() suspended animations and pending relayouts.
- animation().resumeAnimationsForDocument(m_doc.get());
- if (m_view)
- m_view->scheduleRelayout();
+ if (document()) {
+ document()->resumeActiveDOMObjects(ActiveDOMObject::PageWillBeSuspended);
+ animation().resumeAnimationsForDocument(document());
+ document()->resumeScriptedAnimationControllerCallbacks();
+ }
}
+#if USE(ACCELERATED_COMPOSITING)
void Frame::deviceOrPageScaleFactorChanged()
{
for (RefPtr<Frame> child = tree().firstChild(); child; child = child->tree().nextSibling())
@@ -1037,6 +1132,7 @@ void Frame::deviceOrPageScaleFactorChanged()
if (RenderView* root = contentRenderer())
root->compositor().deviceOrPageScaleFactorChanged();
}
+#endif
bool Frame::isURLAllowed(const URL& url) const
{
diff --git a/Source/WebCore/page/Frame.h b/Source/WebCore/page/Frame.h
index d0e22ef4e..eff8e141d 100644
--- a/Source/WebCore/page/Frame.h
+++ b/Source/WebCore/page/Frame.h
@@ -5,7 +5,7 @@
* 2000-2001 Simon Hausmann <hausmann@kde.org>
* 2000-2001 Dirk Mueller <mueller@kde.org>
* 2000 Stefan Schimanski <1Stein@gmx.de>
- * Copyright (C) 2004-2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
* Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
* Copyright (C) 2008 Eric Seidel <eric@webkit.org>
*
@@ -35,8 +35,7 @@
#include "NavigationScheduler.h"
#include "ScrollTypes.h"
#include "UserScriptTypes.h"
-#include <memory>
-#include <wtf/ThreadSafeRefCounted.h>
+#include <wtf/RefCounted.h>
#if PLATFORM(IOS)
#include "ViewportArguments.h"
@@ -47,13 +46,14 @@
#include "FrameWin.h"
#endif
-#if PLATFORM(COCOA)
-OBJC_CLASS NSArray;
+#if USE(TILED_BACKING_STORE)
+#include "TiledBackingStoreClient.h"
#endif
#if PLATFORM(IOS)
OBJC_CLASS DOMCSSStyleDeclaration;
OBJC_CLASS DOMNode;
+OBJC_CLASS NSArray;
OBJC_CLASS NSString;
#endif
@@ -90,6 +90,7 @@ namespace WebCore {
class RenderWidget;
class ScriptController;
class Settings;
+ class TiledBackingStore;
class VisiblePosition;
class Widget;
@@ -106,6 +107,10 @@ namespace WebCore {
typedef Node* (*NodeQualifier)(const HitTestResult&, Node* terminationNode, IntRect* nodeBounds);
#endif
+#if !USE(TILED_BACKING_STORE)
+ class TiledBackingStoreClient { };
+#endif
+
enum {
LayerTreeFlagsIncludeDebugInfo = 1 << 0,
LayerTreeFlagsIncludeVisibleRects = 1 << 1,
@@ -116,22 +121,22 @@ namespace WebCore {
};
typedef unsigned LayerTreeFlags;
- class Frame : public ThreadSafeRefCounted<Frame> {
+ class Frame : public RefCounted<Frame>, public TiledBackingStoreClient {
public:
- WEBCORE_EXPORT static Ref<Frame> create(Page*, HTMLFrameOwnerElement*, FrameLoaderClient*);
+ static PassRefPtr<Frame> create(Page*, HTMLFrameOwnerElement*, FrameLoaderClient*);
void init();
#if PLATFORM(IOS)
// Creates <html><body style="..."></body></html> doing minimal amount of work.
- WEBCORE_EXPORT void initWithSimpleHTMLDocument(const String& style, const URL&);
+ void initWithSimpleHTMLDocument(const String& style, const URL&);
#endif
- WEBCORE_EXPORT void setView(RefPtr<FrameView>&&);
- WEBCORE_EXPORT void createView(const IntSize&, const Color&, bool,
+ void setView(PassRefPtr<FrameView>);
+ void createView(const IntSize&, const Color&, bool,
const IntSize& fixedLayoutSize = IntSize(), const IntRect& fixedVisibleContentRect = IntRect(),
bool useFixedLayout = false, ScrollbarMode = ScrollbarAuto, bool horizontalLock = false,
ScrollbarMode = ScrollbarAuto, bool verticalLock = false);
- WEBCORE_EXPORT virtual ~Frame();
+ virtual ~Frame();
void addDestructionObserver(FrameDestructionObserver*);
void removeDestructionObserver(FrameDestructionObserver*);
@@ -141,7 +146,7 @@ namespace WebCore {
void disconnectOwnerElement();
MainFrame& mainFrame() const;
- WEBCORE_EXPORT bool isMainFrame() const;
+ bool isMainFrame() const;
Page* page() const;
HTMLFrameOwnerElement* ownerElement() const;
@@ -151,7 +156,6 @@ namespace WebCore {
Editor& editor() const;
EventHandler& eventHandler() const;
- EventHandler* eventHandlerPtr() const;
FrameLoader& loader() const;
NavigationScheduler& navigationScheduler() const;
FrameSelection& selection() const;
@@ -159,114 +163,118 @@ namespace WebCore {
AnimationController& animation() const;
ScriptController& script();
- WEBCORE_EXPORT RenderView* contentRenderer() const; // Root of the render tree for the document contained in this frame.
- WEBCORE_EXPORT RenderWidget* ownerRenderer() const; // Renderer for the element that contains this frame.
+ RenderView* contentRenderer() const; // Root of the render tree for the document contained in this frame.
+ RenderWidget* ownerRenderer() const; // Renderer for the element that contains this frame.
// ======== All public functions below this point are candidates to move out of Frame into another class. ========
void injectUserScripts(UserScriptInjectionTime);
- WEBCORE_EXPORT String layerTreeAsText(LayerTreeFlags = 0) const;
- WEBCORE_EXPORT String trackedRepaintRectsAsText() const;
+ String layerTreeAsText(LayerTreeFlags = 0) const;
+ String trackedRepaintRectsAsText() const;
- WEBCORE_EXPORT static Frame* frameForWidget(const Widget*);
+ static Frame* frameForWidget(const Widget*);
Settings& settings() const { return *m_settings; }
void setPrinting(bool printing, const FloatSize& pageSize, const FloatSize& originalPageSize, float maximumShrinkRatio, AdjustViewSizeOrNot);
bool shouldUsePrintingLayout() const;
- WEBCORE_EXPORT FloatSize resizePageRectsKeepingRatio(const FloatSize& originalSize, const FloatSize& expectedSize);
+ FloatSize resizePageRectsKeepingRatio(const FloatSize& originalSize, const FloatSize& expectedSize);
+
+ bool inViewSourceMode() const;
+ void setInViewSourceMode(bool = true);
- void setDocument(RefPtr<Document>&&);
+ void setDocument(PassRefPtr<Document>);
- WEBCORE_EXPORT void setPageZoomFactor(float);
+ void setPageZoomFactor(float factor);
float pageZoomFactor() const { return m_pageZoomFactor; }
- WEBCORE_EXPORT void setTextZoomFactor(float);
+ void setTextZoomFactor(float factor);
float textZoomFactor() const { return m_textZoomFactor; }
- WEBCORE_EXPORT void setPageAndTextZoomFactors(float pageZoomFactor, float textZoomFactor);
+ void setPageAndTextZoomFactors(float pageZoomFactor, float textZoomFactor);
// Scale factor of this frame with respect to the container.
- WEBCORE_EXPORT float frameScaleFactor() const;
+ float frameScaleFactor() const;
+#if USE(ACCELERATED_COMPOSITING)
void deviceOrPageScaleFactorChanged();
-
-#if ENABLE(DATA_DETECTION)
- void setDataDetectionResults(NSArray *results) { m_dataDetectionResults = results; }
- NSArray *dataDetectionResults() const { return m_dataDetectionResults.get(); }
#endif
#if PLATFORM(IOS)
const ViewportArguments& viewportArguments() const;
- WEBCORE_EXPORT void setViewportArguments(const ViewportArguments&);
+ void setViewportArguments(const ViewportArguments&);
- WEBCORE_EXPORT Node* deepestNodeAtLocation(const FloatPoint& viewportLocation);
- WEBCORE_EXPORT Node* nodeRespondingToClickEvents(const FloatPoint& viewportLocation, FloatPoint& adjustedViewportLocation);
- WEBCORE_EXPORT Node* nodeRespondingToScrollWheelEvents(const FloatPoint& viewportLocation);
+ Node* deepestNodeAtLocation(const FloatPoint& viewportLocation);
+ Node* nodeRespondingToClickEvents(const FloatPoint& viewportLocation, FloatPoint& adjustedViewportLocation);
+ Node* nodeRespondingToScrollWheelEvents(const FloatPoint& viewportLocation);
int indexCountOfWordPrecedingSelection(NSString* word) const;
- WEBCORE_EXPORT NSArray* wordsInCurrentParagraph() const;
- WEBCORE_EXPORT CGRect renderRectForPoint(CGPoint, bool* isReplaced, float* fontSize) const;
+ NSArray* wordsInCurrentParagraph() const;
+ CGRect renderRectForPoint(CGPoint, bool* isReplaced, float* fontSize) const;
- WEBCORE_EXPORT void setSelectionChangeCallbacksDisabled(bool = true);
+ void setSelectionChangeCallbacksDisabled(bool = true);
bool selectionChangeCallbacksDisabled() const;
enum ViewportOffsetChangeType { IncrementalScrollOffset, CompletedScrollOffset };
- WEBCORE_EXPORT void viewportOffsetChanged(ViewportOffsetChangeType);
+ void viewportOffsetChanged(ViewportOffsetChangeType);
bool containsTiledBackingLayers() const;
- WEBCORE_EXPORT void overflowScrollPositionChangedForNode(const IntPoint&, Node*, bool isUserScroll);
+ void overflowScrollPositionChangedForNode(const IntPoint&, Node*, bool isUserScroll);
- WEBCORE_EXPORT void resetAllGeolocationPermission();
+ void resetAllGeolocationPermission();
#endif
#if ENABLE(ORIENTATION_EVENTS)
// Orientation is the interface orientation in degrees. Some examples are:
// 0 is straight up; -90 is when the device is rotated 90 clockwise;
// 90 is when rotated counter clockwise.
- WEBCORE_EXPORT void orientationChanged();
- int orientation() const;
+ void sendOrientationChangeEvent(int orientation);
+ int orientation() const { return m_orientation; }
#endif
void clearTimers();
static void clearTimers(FrameView*, Document*);
- WEBCORE_EXPORT String displayStringModifiedByEncoding(const String&) const;
+ String displayStringModifiedByEncoding(const String&) const;
- WEBCORE_EXPORT VisiblePosition visiblePositionForPoint(const IntPoint& framePoint) const;
+ VisiblePosition visiblePositionForPoint(const IntPoint& framePoint);
Document* documentAtPoint(const IntPoint& windowPoint);
- WEBCORE_EXPORT RefPtr<Range> rangeForPoint(const IntPoint& framePoint);
+ PassRefPtr<Range> rangeForPoint(const IntPoint& framePoint);
- WEBCORE_EXPORT String searchForLabelsAboveCell(const JSC::Yarr::RegularExpression&, HTMLTableCellElement*, size_t* resultDistanceFromStartOfCell);
+ String searchForLabelsAboveCell(JSC::Yarr::RegularExpression*, HTMLTableCellElement*, size_t* resultDistanceFromStartOfCell);
String searchForLabelsBeforeElement(const Vector<String>& labels, Element*, size_t* resultDistance, bool* resultIsInCellAbove);
String matchLabelsAgainstElement(const Vector<String>& labels, Element*);
+#if ENABLE(IOS_TEXT_AUTOSIZING)
+ void setTextAutosizingWidth(float);
+ float textAutosizingWidth() const;
+#endif
+
#if PLATFORM(IOS)
// Scroll the selection in an overflow layer on iOS.
void scrollOverflowLayer(RenderLayer* , const IntRect& visibleRect, const IntRect& exposeRect);
- WEBCORE_EXPORT int preferredHeight() const;
- WEBCORE_EXPORT int innerLineHeight(DOMNode*) const;
- WEBCORE_EXPORT void updateLayout() const;
- WEBCORE_EXPORT NSRect caretRect() const;
- WEBCORE_EXPORT NSRect rectForScrollToVisible() const;
- WEBCORE_EXPORT DOMCSSStyleDeclaration* styleAtSelectionStart() const;
- WEBCORE_EXPORT unsigned formElementsCharacterCount() const;
-
- // This function is used by Legacy WebKit.
- WEBCORE_EXPORT void setTimersPaused(bool);
-
- WEBCORE_EXPORT void dispatchPageHideEventBeforePause();
- WEBCORE_EXPORT void dispatchPageShowEventBeforeResume();
- WEBCORE_EXPORT void setRangedSelectionBaseToCurrentSelection();
- WEBCORE_EXPORT void setRangedSelectionBaseToCurrentSelectionStart();
- WEBCORE_EXPORT void setRangedSelectionBaseToCurrentSelectionEnd();
- WEBCORE_EXPORT void clearRangedSelectionInitialExtent();
- WEBCORE_EXPORT void setRangedSelectionInitialExtentToCurrentSelectionStart();
- WEBCORE_EXPORT void setRangedSelectionInitialExtentToCurrentSelectionEnd();
- WEBCORE_EXPORT VisibleSelection rangedSelectionBase() const;
- WEBCORE_EXPORT VisibleSelection rangedSelectionInitialExtent() const;
- WEBCORE_EXPORT void recursiveSetUpdateAppearanceEnabled(bool);
- WEBCORE_EXPORT NSArray* interpretationsForCurrentRoot() const;
+ int preferredHeight() const;
+ int innerLineHeight(DOMNode*) const;
+ void updateLayout() const;
+ NSRect caretRect() const;
+ NSRect rectForScrollToVisible() const;
+ NSRect rectForSelection(VisibleSelection&) const;
+ DOMCSSStyleDeclaration* styleAtSelectionStart() const;
+ unsigned formElementsCharacterCount() const;
+ void setTimersPaused(bool);
+ bool timersPaused() const { return m_timersPausedCount; }
+ void dispatchPageHideEventBeforePause();
+ void dispatchPageShowEventBeforeResume();
+ void setRangedSelectionBaseToCurrentSelection();
+ void setRangedSelectionBaseToCurrentSelectionStart();
+ void setRangedSelectionBaseToCurrentSelectionEnd();
+ void clearRangedSelectionInitialExtent();
+ void setRangedSelectionInitialExtentToCurrentSelectionStart();
+ void setRangedSelectionInitialExtentToCurrentSelectionEnd();
+ VisibleSelection rangedSelectionBase() const;
+ VisibleSelection rangedSelectionInitialExtent() const;
+ void recursiveSetUpdateAppearanceEnabled(bool);
+ NSArray* interpretationsForCurrentRoot() const;
#endif
void suspendActiveDOMObjectsAndAnimations();
void resumeActiveDOMObjectsAndAnimations();
@@ -278,7 +286,6 @@ namespace WebCore {
protected:
Frame(Page&, HTMLFrameOwnerElement*, FrameLoaderClient&);
- void setMainFrameWasDestroyed();
private:
void injectUserScriptsForWorld(DOMWrapperWorld&, const UserScriptVector&, UserScriptInjectionTime);
@@ -297,41 +304,65 @@ namespace WebCore {
RefPtr<Document> m_doc;
const std::unique_ptr<ScriptController> m_script;
- const std::unique_ptr<Editor> m_editor;
- const std::unique_ptr<FrameSelection> m_selection;
+ const OwnPtr<Editor> m_editor;
+ const OwnPtr<FrameSelection> m_selection;
+ const OwnPtr<EventHandler> m_eventHandler;
const std::unique_ptr<AnimationController> m_animationController;
-#if ENABLE(DATA_DETECTION)
- RetainPtr<NSArray> m_dataDetectionResults;
-#endif
#if PLATFORM(IOS)
void betterApproximateNode(const IntPoint& testPoint, NodeQualifier, Node*& best, Node* failedNode, IntPoint& bestPoint, IntRect& bestRect, const IntRect& testRect);
bool hitTestResultAtViewportLocation(const FloatPoint& viewportLocation, HitTestResult&, IntPoint& center);
Node* qualifyingNodeAtViewportLocation(const FloatPoint& viewportLocation, FloatPoint& adjustedViewportLocation, NodeQualifier, bool shouldApproximate);
- void overflowAutoScrollTimerFired();
+ void overflowAutoScrollTimerFired(Timer<Frame>*);
void startOverflowAutoScroll(const IntPoint&);
int checkOverflowScroll(OverflowScrollAction);
void setTimersPausedInternal(bool);
- Timer m_overflowAutoScrollTimer;
+ Timer<Frame> m_overflowAutoScrollTimer;
float m_overflowAutoScrollDelta;
IntPoint m_overflowAutoScrollPos;
ViewportArguments m_viewportArguments;
bool m_selectionChangeCallbacksDisabled;
+ int m_timersPausedCount;
VisibleSelection m_rangedSelectionBase;
VisibleSelection m_rangedSelectionInitialExtent;
#endif
+#if ENABLE(IOS_TEXT_AUTOSIZING)
+ float m_textAutosizingWidth;
+#endif
+
float m_pageZoomFactor;
float m_textZoomFactor;
- int m_activeDOMObjectsAndAnimationsSuspendedCount;
- bool m_mainFrameWasDestroyed { false };
+#if ENABLE(ORIENTATION_EVENTS)
+ int m_orientation;
+#endif
- protected:
- std::unique_ptr<EventHandler> m_eventHandler;
+ bool m_inViewSourceMode;
+
+#if USE(TILED_BACKING_STORE)
+ // FIXME: The tiled backing store belongs in FrameView, not Frame.
+
+ public:
+ TiledBackingStore* tiledBackingStore() const { return m_tiledBackingStore.get(); }
+ void setTiledBackingStoreEnabled(bool);
+
+ private:
+ // TiledBackingStoreClient interface
+ virtual void tiledBackingStorePaintBegin() override final;
+ virtual void tiledBackingStorePaint(GraphicsContext*, const IntRect&) override final;
+ virtual void tiledBackingStorePaintEnd(const Vector<IntRect>& paintedArea) override final;
+ virtual IntRect tiledBackingStoreContentsRect() override final;
+ virtual IntRect tiledBackingStoreVisibleRect() override final;
+ virtual Color tiledBackingStoreBackgroundColor() const override final;
+
+ OwnPtr<TiledBackingStore> m_tiledBackingStore;
+#endif
+
+ int m_activeDOMObjectsAndAnimationsSuspendedCount;
};
inline void Frame::init()
@@ -384,6 +415,16 @@ namespace WebCore {
return m_ownerElement;
}
+ inline bool Frame::inViewSourceMode() const
+ {
+ return m_inViewSourceMode;
+ }
+
+ inline void Frame::setInViewSourceMode(bool mode)
+ {
+ m_inViewSourceMode = mode;
+ }
+
inline FrameTree& Frame::tree() const
{
return m_treeNode;
@@ -396,7 +437,7 @@ namespace WebCore {
inline void Frame::detachFromPage()
{
- m_page = nullptr;
+ m_page = 0;
}
inline EventHandler& Frame::eventHandler() const
@@ -404,22 +445,11 @@ namespace WebCore {
return *m_eventHandler;
}
- inline EventHandler* Frame::eventHandlerPtr() const
- {
- return m_eventHandler.get();
- }
-
inline MainFrame& Frame::mainFrame() const
{
- ASSERT_WITH_SECURITY_IMPLICATION(!m_mainFrameWasDestroyed);
return m_mainFrame;
}
- inline void Frame::setMainFrameWasDestroyed()
- {
- m_mainFrameWasDestroyed = false;
- }
-
} // namespace WebCore
#endif // Frame_h
diff --git a/Source/WebCore/page/FrameDestructionObserver.cpp b/Source/WebCore/page/FrameDestructionObserver.cpp
index 6b0ae533b..94bf33687 100644
--- a/Source/WebCore/page/FrameDestructionObserver.cpp
+++ b/Source/WebCore/page/FrameDestructionObserver.cpp
@@ -31,14 +31,14 @@
namespace WebCore {
FrameDestructionObserver::FrameDestructionObserver(Frame* frame)
- : m_frame(nullptr)
+ : m_frame(0)
{
observeFrame(frame);
}
FrameDestructionObserver::~FrameDestructionObserver()
{
- observeFrame(nullptr);
+ observeFrame(0);
}
@@ -55,7 +55,7 @@ void FrameDestructionObserver::observeFrame(Frame* frame)
void FrameDestructionObserver::frameDestroyed()
{
- m_frame = nullptr;
+ m_frame = 0;
}
void FrameDestructionObserver::willDetachPage()
diff --git a/Source/WebCore/page/FrameDestructionObserver.h b/Source/WebCore/page/FrameDestructionObserver.h
index 90488d9e9..094b521f3 100644
--- a/Source/WebCore/page/FrameDestructionObserver.h
+++ b/Source/WebCore/page/FrameDestructionObserver.h
@@ -34,16 +34,16 @@ class Frame;
class FrameDestructionObserver {
public:
- WEBCORE_EXPORT explicit FrameDestructionObserver(Frame*);
+ WEBCORE_TESTING explicit FrameDestructionObserver(Frame*);
- WEBCORE_EXPORT virtual void frameDestroyed();
- WEBCORE_EXPORT virtual void willDetachPage();
+ WEBCORE_TESTING virtual void frameDestroyed();
+ WEBCORE_TESTING virtual void willDetachPage();
Frame* frame() const { return m_frame; }
protected:
- WEBCORE_EXPORT virtual ~FrameDestructionObserver();
- WEBCORE_EXPORT void observeFrame(Frame*);
+ WEBCORE_TESTING virtual ~FrameDestructionObserver();
+ WEBCORE_TESTING void observeFrame(Frame*);
Frame* m_frame;
};
diff --git a/Source/WebCore/page/FrameSnapshotting.cpp b/Source/WebCore/page/FrameSnapshotting.cpp
index 4714dc666..495406b82 100644
--- a/Source/WebCore/page/FrameSnapshotting.cpp
+++ b/Source/WebCore/page/FrameSnapshotting.cpp
@@ -35,11 +35,9 @@
#include "Frame.h"
#include "FrameSelection.h"
#include "FrameView.h"
-#include "GraphicsContext.h"
#include "ImageBuffer.h"
#include "Page.h"
#include "RenderObject.h"
-#include "Settings.h"
namespace WebCore {
@@ -88,21 +86,14 @@ std::unique_ptr<ImageBuffer> snapshotFrameRect(Frame& frame, const IntRect& imag
paintBehavior |= PaintBehaviorForceBlackText;
if (options & SnapshotOptionsPaintSelectionOnly)
paintBehavior |= PaintBehaviorSelectionOnly;
- if (options & SnapshotOptionsPaintSelectionAndBackgroundsOnly)
- paintBehavior |= PaintBehaviorSelectionAndBackgroundsOnly;
// Other paint behaviors are set by paintContentsForSnapshot.
frame.view()->setPaintBehavior(paintBehavior);
- float scaleFactor = frame.page()->deviceScaleFactor();
-
- if (frame.settings().delegatesPageScaling())
- scaleFactor *= frame.page()->pageScaleFactor();
-
- std::unique_ptr<ImageBuffer> buffer = ImageBuffer::create(imageRect.size(), Unaccelerated, scaleFactor);
+ std::unique_ptr<ImageBuffer> buffer = ImageBuffer::create(imageRect.size(), frame.page()->deviceScaleFactor(), ColorSpaceDeviceRGB);
if (!buffer)
return nullptr;
- buffer->context().translate(-imageRect.x(), -imageRect.y());
+ buffer->context()->translate(-imageRect.x(), -imageRect.y());
frame.view()->paintContentsForSnapshot(buffer->context(), imageRect, shouldIncludeSelection, coordinateSpace);
return buffer;
@@ -110,19 +101,11 @@ std::unique_ptr<ImageBuffer> snapshotFrameRect(Frame& frame, const IntRect& imag
std::unique_ptr<ImageBuffer> snapshotSelection(Frame& frame, SnapshotOptions options)
{
- auto& selection = frame.selection();
-
- if (!selection.isRange())
- return nullptr;
-
- FloatRect selectionBounds = selection.selectionBounds();
-
- // It is possible for the selection bounds to be empty; see https://bugs.webkit.org/show_bug.cgi?id=56645.
- if (selectionBounds.isEmpty())
+ if (!frame.selection().isRange())
return nullptr;
options |= SnapshotOptionsPaintSelectionOnly;
- return snapshotFrameRect(frame, enclosingIntRect(selectionBounds), options);
+ return snapshotFrameRect(frame, enclosingIntRect(frame.selection().bounds()), options);
}
std::unique_ptr<ImageBuffer> snapshotNode(Frame& frame, Node& node)
@@ -136,7 +119,7 @@ std::unique_ptr<ImageBuffer> snapshotNode(Frame& frame, Node& node)
frame.view()->setNodeToDraw(&node);
LayoutRect topLevelRect;
- return snapshotFrameRect(frame, snappedIntRect(node.renderer()->paintingRootRect(topLevelRect)));
+ return snapshotFrameRect(frame, pixelSnappedIntRect(node.renderer()->paintingRootRect(topLevelRect)));
}
} // namespace WebCore
diff --git a/Source/WebCore/page/FrameSnapshotting.h b/Source/WebCore/page/FrameSnapshotting.h
index 6f2d15e95..f74767b28 100644
--- a/Source/WebCore/page/FrameSnapshotting.h
+++ b/Source/WebCore/page/FrameSnapshotting.h
@@ -45,13 +45,12 @@ enum {
SnapshotOptionsPaintSelectionOnly = 1 << 1,
SnapshotOptionsInViewCoordinates = 1 << 2,
SnapshotOptionsForceBlackText = 1 << 3,
- SnapshotOptionsPaintSelectionAndBackgroundsOnly = 1 << 4,
};
typedef unsigned SnapshotOptions;
-WEBCORE_EXPORT std::unique_ptr<ImageBuffer> snapshotFrameRect(Frame&, const IntRect&, SnapshotOptions = SnapshotOptionsNone);
+std::unique_ptr<ImageBuffer> snapshotFrameRect(Frame&, const IntRect&, SnapshotOptions = SnapshotOptionsNone);
std::unique_ptr<ImageBuffer> snapshotNode(Frame&, Node&);
-WEBCORE_EXPORT std::unique_ptr<ImageBuffer> snapshotSelection(Frame&, SnapshotOptions = SnapshotOptionsNone);
+std::unique_ptr<ImageBuffer> snapshotSelection(Frame&, SnapshotOptions = SnapshotOptionsNone);
} // namespace WebCore
diff --git a/Source/WebCore/page/FrameTree.cpp b/Source/WebCore/page/FrameTree.cpp
index 3b1036983..2ef23b335 100644
--- a/Source/WebCore/page/FrameTree.cpp
+++ b/Source/WebCore/page/FrameTree.cpp
@@ -38,7 +38,7 @@ namespace WebCore {
FrameTree::~FrameTree()
{
for (Frame* child = firstChild(); child; child = child->tree().nextSibling())
- child->setView(nullptr);
+ child->setView(0);
}
void FrameTree::setName(const AtomicString& name)
@@ -82,19 +82,6 @@ bool FrameTree::transferChild(PassRefPtr<Frame> child)
return true;
}
-unsigned FrameTree::indexInParent() const
-{
- if (!m_parent)
- return 0;
- unsigned index = 0;
- for (Frame* frame = m_parent->tree().firstChild(); frame; frame = frame->tree().nextSibling()) {
- if (&frame->tree() == this)
- return index;
- ++index;
- }
- RELEASE_ASSERT_NOT_REACHED();
-}
-
void FrameTree::appendChild(PassRefPtr<Frame> child)
{
ASSERT(child->page() == m_thisFrame.page());
@@ -121,7 +108,7 @@ void FrameTree::actuallyAppendChild(PassRefPtr<Frame> child)
void FrameTree::removeChild(Frame* child)
{
- child->tree().m_parent = nullptr;
+ child->tree().m_parent = 0;
// Slightly tricky way to prevent deleting the child until we are done with it, w/o
// extra refs. These swaps leave the child in a circular list by itself. Clearing its
@@ -133,24 +120,23 @@ void FrameTree::removeChild(Frame* child)
// For some inexplicable reason, the following line does not compile without the explicit std:: namespace
std::swap(newLocationForPrevious, child->tree().m_previousSibling);
- child->tree().m_previousSibling = nullptr;
- child->tree().m_nextSibling = nullptr;
+ child->tree().m_previousSibling = 0;
+ child->tree().m_nextSibling = 0;
m_scopedChildCount = invalidCount;
}
AtomicString FrameTree::uniqueChildName(const AtomicString& requestedName) const
{
- // If the requested name (the frame's "name" attribute) is unique, just use that.
if (!requestedName.isEmpty() && !child(requestedName) && requestedName != "_blank")
return requestedName;
- // The "name" attribute was not unique or absent. Generate a name based on the
- // new frame's location in the frame tree. The name uses HTML comment syntax to
- // avoid collisions with author names.
-
- // An example path for the third child of the second child of the root frame:
- // <!--framePath //<!--frame1-->/<!--frame2-->-->
+ // Create a repeatable name for a child about to be added to us. The name must be
+ // unique within the frame tree. The string we generate includes a "path" of names
+ // from the root frame down to us. For this path to be unique, each set of siblings must
+ // contribute a unique name to the path, which can't collide with any HTML-assigned names.
+ // We generate this path component by index in the child list along with an unlikely
+ // frame name that can't be set in HTML because it collides with comment syntax.
const char framePathPrefix[] = "<!--framePath ";
const int framePathPrefixLength = 14;
@@ -173,11 +159,7 @@ AtomicString FrameTree::uniqueChildName(const AtomicString& requestedName) const
for (int i = chain.size() - 1; i >= 0; --i) {
frame = chain[i];
name.append('/');
- if (frame->tree().parent()) {
- name.appendLiteral("<!--frame");
- name.appendNumber(frame->tree().indexInParent());
- name.appendLiteral("-->");
- }
+ name.append(frame->tree().uniqueName());
}
name.appendLiteral("/<!--frame");
@@ -374,68 +356,6 @@ Frame* FrameTree::traverseNext(const Frame* stayWithin) const
return nullptr;
}
-Frame* FrameTree::firstRenderedChild() const
-{
- Frame* child = firstChild();
- if (!child)
- return nullptr;
-
- if (child->ownerRenderer())
- return child;
-
- while ((child = child->tree().nextSibling())) {
- if (child->ownerRenderer())
- return child;
- }
-
- return nullptr;
-}
-
-Frame* FrameTree::nextRenderedSibling() const
-{
- Frame* sibling = &m_thisFrame;
-
- while ((sibling = sibling->tree().nextSibling())) {
- if (sibling->ownerRenderer())
- return sibling;
- }
-
- return nullptr;
-}
-
-Frame* FrameTree::traverseNextRendered(const Frame* stayWithin) const
-{
- Frame* child = firstRenderedChild();
- if (child) {
- ASSERT(!stayWithin || child->tree().isDescendantOf(stayWithin));
- return child;
- }
-
- if (&m_thisFrame == stayWithin)
- return nullptr;
-
- Frame* sibling = nextRenderedSibling();
- if (sibling) {
- ASSERT(!stayWithin || sibling->tree().isDescendantOf(stayWithin));
- return sibling;
- }
-
- Frame* frame = &m_thisFrame;
- while (!sibling && (!stayWithin || frame->tree().parent() != stayWithin)) {
- frame = frame->tree().parent();
- if (!frame)
- return nullptr;
- sibling = frame->tree().nextRenderedSibling();
- }
-
- if (frame) {
- ASSERT(!stayWithin || !sibling || sibling->tree().isDescendantOf(stayWithin));
- return sibling;
- }
-
- return nullptr;
-}
-
Frame* FrameTree::traverseNextWithWrap(bool wrap) const
{
if (Frame* result = traverseNext())
@@ -504,15 +424,11 @@ static void printFrames(const WebCore::Frame& frame, const WebCore::Frame* targe
printIndent(indent);
printf(" ownerElement=%p\n", frame.ownerElement());
printIndent(indent);
- printf(" frameView=%p (needs layout %d)\n", view, view ? view->needsLayout() : false);
- printIndent(indent);
- printf(" renderView=%p\n", view ? view->renderView() : nullptr);
- printIndent(indent);
- printf(" ownerRenderer=%p\n", frame.ownerRenderer());
+ printf(" frameView=%p\n", view);
printIndent(indent);
- printf(" document=%p (needs style recalc %d)\n", frame.document(), frame.document() ? frame.document()->childNeedsStyleRecalc() : false);
+ printf(" document=%p\n", frame.document());
printIndent(indent);
- printf(" uri=%s\n", frame.document()->documentURI().utf8().data());
+ printf(" uri=%s\n\n", frame.document()->documentURI().utf8().data());
for (WebCore::Frame* child = frame.tree().firstChild(); child; child = child->tree().nextSibling())
printFrames(*child, targetFrame, indent + 1);
diff --git a/Source/WebCore/page/FrameTree.h b/Source/WebCore/page/FrameTree.h
index 099a5d12d..c6b5c0191 100644
--- a/Source/WebCore/page/FrameTree.h
+++ b/Source/WebCore/page/FrameTree.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006 Apple Inc.
+ * Copyright (C) 2006 Apple Computer, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -35,8 +35,8 @@ namespace WebCore {
FrameTree(Frame& thisFrame, Frame* parentFrame)
: m_thisFrame(thisFrame)
, m_parent(parentFrame)
- , m_previousSibling(nullptr)
- , m_lastChild(nullptr)
+ , m_previousSibling(0)
+ , m_lastChild(0)
, m_scopedChildCount(invalidCount)
{
}
@@ -45,9 +45,9 @@ namespace WebCore {
const AtomicString& name() const { return m_name; }
const AtomicString& uniqueName() const { return m_uniqueName; }
- WEBCORE_EXPORT void setName(const AtomicString&);
- WEBCORE_EXPORT void clearName();
- WEBCORE_EXPORT Frame* parent() const;
+ void setName(const AtomicString&);
+ void clearName();
+ Frame* parent() const;
void setParent(Frame* parent) { m_parent = parent; }
Frame* nextSibling() const { return m_nextSibling.get(); }
@@ -55,37 +55,29 @@ namespace WebCore {
Frame* firstChild() const { return m_firstChild.get(); }
Frame* lastChild() const { return m_lastChild; }
- Frame* firstRenderedChild() const;
- Frame* nextRenderedSibling() const;
-
- WEBCORE_EXPORT bool isDescendantOf(const Frame* ancestor) const;
-
- WEBCORE_EXPORT Frame* traverseNext(const Frame* stayWithin = nullptr) const;
- // Rendered means being the main frame or having an ownerRenderer. It may not have been parented in the Widget tree yet (see WidgetHierarchyUpdatesSuspensionScope).
- WEBCORE_EXPORT Frame* traverseNextRendered(const Frame* stayWithin = nullptr) const;
- WEBCORE_EXPORT Frame* traverseNextWithWrap(bool) const;
- WEBCORE_EXPORT Frame* traversePreviousWithWrap(bool) const;
+ bool isDescendantOf(const Frame* ancestor) const;
+ Frame* traverseNext(const Frame* stayWithin = 0) const;
+ Frame* traverseNextWithWrap(bool) const;
+ Frame* traversePreviousWithWrap(bool) const;
- WEBCORE_EXPORT void appendChild(PassRefPtr<Frame>);
+ void appendChild(PassRefPtr<Frame>);
bool transferChild(PassRefPtr<Frame>);
- void detachFromParent() { m_parent = nullptr; }
+ void detachFromParent() { m_parent = 0; }
void removeChild(Frame*);
Frame* child(unsigned index) const;
Frame* child(const AtomicString& name) const;
- WEBCORE_EXPORT Frame* find(const AtomicString& name) const;
- WEBCORE_EXPORT unsigned childCount() const;
+ Frame* find(const AtomicString& name) const;
+ unsigned childCount() const;
AtomicString uniqueChildName(const AtomicString& requestedName) const;
- WEBCORE_EXPORT Frame& top() const;
+ Frame& top() const;
Frame* scopedChild(unsigned index) const;
Frame* scopedChild(const AtomicString& name) const;
unsigned scopedChildCount() const;
- unsigned indexInParent() const;
-
private:
Frame* deepLastChild() const;
void actuallyAppendChild(PassRefPtr<Frame>);
@@ -112,7 +104,7 @@ namespace WebCore {
#ifndef NDEBUG
// Outside the WebCore namespace for ease of invocation from gdb.
-WEBCORE_EXPORT void showFrameTree(const WebCore::Frame*);
+void showFrameTree(const WebCore::Frame*);
#endif
#endif // FrameTree_h
diff --git a/Source/WebCore/page/FrameView.cpp b/Source/WebCore/page/FrameView.cpp
index e1dd28906..804c0420f 100644
--- a/Source/WebCore/page/FrameView.cpp
+++ b/Source/WebCore/page/FrameView.cpp
@@ -3,7 +3,7 @@
* 1999 Lars Knoll <knoll@kde.org>
* 1999 Antti Koivisto <koivisto@kde.org>
* 2000 Dirk Mueller <mueller@kde.org>
- * Copyright (C) 2004-2008, 2013-2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2013 Apple Inc. All rights reserved.
* (C) 2006 Graham Dennis (graham.dennis@gmail.com)
* (C) 2006 Alexey Proskuryakov (ap@nypop.com)
* Copyright (C) 2009 Google Inc. All rights reserved.
@@ -35,43 +35,33 @@
#include "Chrome.h"
#include "ChromeClient.h"
#include "DOMWindow.h"
-#include "DebugPageOverlays.h"
#include "DocumentMarkerController.h"
#include "EventHandler.h"
#include "FloatRect.h"
#include "FocusController.h"
+#include "FontCache.h"
#include "FontLoader.h"
#include "FrameLoader.h"
#include "FrameLoaderClient.h"
#include "FrameSelection.h"
#include "FrameTree.h"
#include "GraphicsContext.h"
-#include "HTMLBodyElement.h"
#include "HTMLDocument.h"
#include "HTMLFrameElement.h"
#include "HTMLFrameSetElement.h"
#include "HTMLNames.h"
#include "HTMLPlugInImageElement.h"
-#include "ImageDocument.h"
#include "InspectorClient.h"
#include "InspectorController.h"
#include "InspectorInstrumentation.h"
-#include "Logging.h"
#include "MainFrame.h"
-#include "MemoryCache.h"
-#include "MemoryPressureHandler.h"
#include "OverflowEvent.h"
-#include "PageCache.h"
-#include "PageOverlayController.h"
#include "ProgressTracker.h"
#include "RenderEmbeddedObject.h"
#include "RenderFullScreen.h"
#include "RenderIFrame.h"
-#include "RenderInline.h"
#include "RenderLayer.h"
#include "RenderLayerBacking.h"
-#include "RenderLayerCompositor.h"
-#include "RenderSVGRoot.h"
#include "RenderScrollbar.h"
#include "RenderScrollbarPart.h"
#include "RenderStyle.h"
@@ -79,24 +69,29 @@
#include "RenderTheme.h"
#include "RenderView.h"
#include "RenderWidget.h"
-#include "SVGDocument.h"
-#include "SVGSVGElement.h"
-#include "ScriptedAnimationController.h"
#include "ScrollAnimator.h"
#include "ScrollingCoordinator.h"
#include "Settings.h"
#include "StyleResolver.h"
#include "TextResourceDecoder.h"
#include "TextStream.h"
-#include "TiledBacking.h"
-#include "WheelEventTestTrigger.h"
#include <wtf/CurrentTime.h>
#include <wtf/Ref.h>
-#include <wtf/SystemTracing.h>
#include <wtf/TemporaryChange.h>
-#if USE(COORDINATED_GRAPHICS)
+#if USE(ACCELERATED_COMPOSITING)
+#include "RenderLayerCompositor.h"
+#include "TiledBacking.h"
+#endif
+
+#if ENABLE(SVG)
+#include "RenderSVGRoot.h"
+#include "SVGDocument.h"
+#include "SVGSVGElement.h"
+#endif
+
+#if USE(TILED_BACKING_STORE)
#include "TiledBackingStore.h"
#endif
@@ -104,13 +99,17 @@
#include "TextAutosizer.h"
#endif
-#if ENABLE(CSS_SCROLL_SNAP)
-#include "AxisScrollSnapOffsets.h"
-#endif
-
#if PLATFORM(IOS)
#include "DocumentLoader.h"
-#include "LegacyTileCache.h"
+#include "Logging.h"
+#include "MemoryCache.h"
+#include "MemoryPressureHandler.h"
+#include "SystemMemory.h"
+#include "TileCache.h"
+#endif
+
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+#include "HTMLMediaElement.h"
#endif
namespace WebCore {
@@ -129,7 +128,7 @@ static RenderLayer::UpdateLayerPositionsFlags updateLayerPositionFlags(RenderLay
flags &= ~RenderLayer::CheckForRepaint;
flags |= RenderLayer::NeedsFullRepaintInBacking;
}
- if (isRelayoutingSubtree && layer->enclosingPaginationLayer(RenderLayer::IncludeCompositedPaginatedLayers))
+ if (isRelayoutingSubtree && layer->isPaginated())
flags |= RenderLayer::UpdatePagination;
return flags;
}
@@ -161,63 +160,33 @@ Pagination::Mode paginationModeForRenderStyle(const RenderStyle& style)
return Pagination::BottomToTopPaginated;
}
-class SubtreeLayoutStateMaintainer {
-public:
- SubtreeLayoutStateMaintainer(RenderElement* subtreeLayoutRoot)
- : m_layoutRoot(subtreeLayoutRoot)
- {
- if (m_layoutRoot) {
- RenderView& view = m_layoutRoot->view();
- view.pushLayoutState(*m_layoutRoot);
- m_disableLayoutState = view.shouldDisableLayoutStateForSubtree(m_layoutRoot);
- if (m_disableLayoutState)
- view.disableLayoutState();
- }
- }
-
- ~SubtreeLayoutStateMaintainer()
- {
- if (m_layoutRoot) {
- RenderView& view = m_layoutRoot->view();
- view.popLayoutState(*m_layoutRoot);
- if (m_disableLayoutState)
- view.enableLayoutState();
- }
- }
-
-private:
- RenderElement* m_layoutRoot { nullptr };
- bool m_disableLayoutState { false };
-};
-
FrameView::FrameView(Frame& frame)
- : m_frame(frame)
+ : m_frame(&frame)
, m_canHaveScrollbars(true)
- , m_layoutTimer(*this, &FrameView::layoutTimerFired)
+ , m_layoutTimer(this, &FrameView::layoutTimerFired)
+ , m_layoutRoot(0)
, m_layoutPhase(OutsideLayout)
, m_inSynchronousPostLayout(false)
- , m_postLayoutTasksTimer(*this, &FrameView::performPostLayoutTasks)
- , m_updateEmbeddedObjectsTimer(*this, &FrameView::updateEmbeddedObjectsTimerFired)
+ , m_postLayoutTasksTimer(this, &FrameView::postLayoutTimerFired)
+ , m_updateEmbeddedObjectsTimer(this, &FrameView::updateEmbeddedObjectsTimerFired)
, m_isTransparent(false)
, m_baseBackgroundColor(Color::white)
, m_mediaType("screen")
, m_overflowStatusDirty(true)
+ , m_viewportRenderer(0)
, m_wasScrolledByUser(false)
, m_inProgrammaticScroll(false)
, m_safeToPropagateScrollToParent(true)
- , m_delayedScrollEventTimer(*this, &FrameView::sendScrollEvent)
, m_isTrackingRepaints(false)
, m_shouldUpdateWhileOffscreen(true)
, m_exposedRect(FloatRect::infiniteRect())
- , m_deferSetNeedsLayoutCount(0)
+ , m_deferSetNeedsLayouts(0)
, m_setNeedsLayoutWasDeferred(false)
, m_speculativeTilingEnabled(false)
- , m_speculativeTilingEnableTimer(*this, &FrameView::speculativeTilingEnableTimerFired)
+ , m_speculativeTilingEnableTimer(this, &FrameView::speculativeTilingEnableTimerFired)
#if PLATFORM(IOS)
, m_useCustomFixedPositionLayoutRect(false)
- , m_useCustomSizeForResizeEvent(false)
#endif
- , m_hasOverrideViewportSize(false)
, m_shouldAutoSize(false)
, m_inAutoSize(false)
, m_didRunAutosize(false)
@@ -226,40 +195,29 @@ FrameView::FrameView(Frame& frame)
, m_footerHeight(0)
, m_milestonesPendingPaint(0)
, m_visualUpdatesAllowedByClient(true)
- , m_hasFlippedBlockRenderers(false)
, m_scrollPinningBehavior(DoNotPin)
{
init();
-#if ENABLE(RUBBER_BANDING)
- ScrollElasticity verticalElasticity = ScrollElasticityNone;
- ScrollElasticity horizontalElasticity = ScrollElasticityNone;
- if (m_frame->isMainFrame()) {
- verticalElasticity = m_frame->page() ? m_frame->page()->verticalScrollElasticity() : ScrollElasticityAllowed;
- horizontalElasticity = m_frame->page() ? m_frame->page()->horizontalScrollElasticity() : ScrollElasticityAllowed;
- } else if (m_frame->settings().rubberBandingForSubScrollableRegionsEnabled()) {
- verticalElasticity = ScrollElasticityAutomatic;
- horizontalElasticity = ScrollElasticityAutomatic;
+ if (frame.isMainFrame()) {
+ ScrollableArea::setVerticalScrollElasticity(ScrollElasticityAllowed);
+ ScrollableArea::setHorizontalScrollElasticity(ScrollElasticityAutomatic);
}
-
- ScrollableArea::setVerticalScrollElasticity(verticalElasticity);
- ScrollableArea::setHorizontalScrollElasticity(horizontalElasticity);
-#endif
}
-Ref<FrameView> FrameView::create(Frame& frame)
+PassRefPtr<FrameView> FrameView::create(Frame& frame)
{
- Ref<FrameView> view = adoptRef(*new FrameView(frame));
+ RefPtr<FrameView> view = adoptRef(new FrameView(frame));
view->show();
- return view;
+ return view.release();
}
-Ref<FrameView> FrameView::create(Frame& frame, const IntSize& initialSize)
+PassRefPtr<FrameView> FrameView::create(Frame& frame, const IntSize& initialSize)
{
- Ref<FrameView> view = adoptRef(*new FrameView(frame));
+ RefPtr<FrameView> view = adoptRef(new FrameView(frame));
view->Widget::setFrameRect(IntRect(view->location(), initialSize));
view->show();
- return view;
+ return view.release();
}
FrameView::~FrameView()
@@ -287,8 +245,10 @@ void FrameView::reset()
m_cannotBlitToWindow = false;
m_isOverlapped = false;
m_contentIsOpaque = false;
+ m_borderX = 30;
+ m_borderY = 30;
m_layoutTimer.stop();
- m_layoutRoot = nullptr;
+ m_layoutRoot = 0;
m_delayedLayout = false;
m_needsFullRepaint = true;
m_layoutSchedulingEnabled = true;
@@ -302,7 +262,6 @@ void FrameView::reset()
m_firstLayoutCallbackPending = false;
m_wasScrolledByUser = false;
m_safeToPropagateScrollToParent = true;
- m_delayedScrollEventTimer.stop();
m_lastViewportSize = IntSize();
m_lastZoomFactor = 1.0f;
m_isTrackingRepaints = false;
@@ -314,17 +273,13 @@ void FrameView::reset()
m_visuallyNonEmptyPixelCount = 0;
m_isVisuallyNonEmpty = false;
m_firstVisuallyNonEmptyLayoutCallbackPending = true;
- m_viewportIsStable = true;
- m_maintainScrollPositionAnchor = nullptr;
+ m_maintainScrollPositionAnchor = 0;
}
void FrameView::removeFromAXObjectCache()
{
- if (AXObjectCache* cache = axObjectCache()) {
- if (HTMLFrameOwnerElement* owner = frame().ownerElement())
- cache->childrenChanged(owner->renderer());
+ if (AXObjectCache* cache = axObjectCache())
cache->remove(this);
- }
}
void FrameView::resetScrollbars()
@@ -357,12 +312,12 @@ void FrameView::init()
// Propagate the marginwidth/height and scrolling modes to the view.
Element* ownerElement = frame().ownerElement();
- if (is<HTMLFrameElementBase>(ownerElement)) {
- HTMLFrameElementBase& frameElement = downcast<HTMLFrameElementBase>(*ownerElement);
- if (frameElement.scrollingMode() == ScrollbarAlwaysOff)
+ if (ownerElement && (ownerElement->hasTagName(frameTag) || ownerElement->hasTagName(iframeTag))) {
+ HTMLFrameElementBase* frameElt = toHTMLFrameElementBase(ownerElement);
+ if (frameElt->scrollingMode() == ScrollbarAlwaysOff)
setCanHaveScrollbars(false);
- LayoutUnit marginWidth = frameElement.marginWidth();
- LayoutUnit marginHeight = frameElement.marginHeight();
+ LayoutUnit marginWidth = frameElt->marginWidth();
+ LayoutUnit marginHeight = frameElt->marginHeight();
if (marginWidth != -1)
setMarginWidth(marginWidth);
if (marginHeight != -1)
@@ -383,7 +338,7 @@ void FrameView::prepareForDetach()
if (frame().page()) {
if (ScrollingCoordinator* scrollingCoordinator = frame().page()->scrollingCoordinator())
- scrollingCoordinator->willDestroyScrollableArea(*this);
+ scrollingCoordinator->willDestroyScrollableArea(this);
}
}
@@ -403,14 +358,7 @@ void FrameView::detachCustomScrollbars()
void FrameView::recalculateScrollbarOverlayStyle()
{
ScrollbarOverlayStyle oldOverlayStyle = scrollbarOverlayStyle();
- WTF::Optional<ScrollbarOverlayStyle> clientOverlayStyle = frame().page() ? frame().page()->chrome().client().preferredScrollbarOverlayStyle() : ScrollbarOverlayStyleDefault;
- if (clientOverlayStyle) {
- if (clientOverlayStyle.value() != oldOverlayStyle)
- setScrollbarOverlayStyle(clientOverlayStyle.value());
- return;
- }
-
- ScrollbarOverlayStyle computedOverlayStyle = ScrollbarOverlayStyleDefault;
+ ScrollbarOverlayStyle overlayStyle = ScrollbarOverlayStyleDefault;
Color backgroundColor = documentBackgroundColor();
if (backgroundColor.isValid()) {
@@ -420,11 +368,11 @@ void FrameView::recalculateScrollbarOverlayStyle()
double hue, saturation, lightness;
backgroundColor.getHSL(hue, saturation, lightness);
if (lightness <= .5 && backgroundColor.alpha() > 0)
- computedOverlayStyle = ScrollbarOverlayStyleLight;
+ overlayStyle = ScrollbarOverlayStyleLight;
}
- if (oldOverlayStyle != computedOverlayStyle)
- setScrollbarOverlayStyle(computedOverlayStyle);
+ if (oldOverlayStyle != overlayStyle)
+ setScrollbarOverlayStyle(overlayStyle);
}
void FrameView::clear()
@@ -438,20 +386,11 @@ void FrameView::clear()
#if PLATFORM(IOS)
// To avoid flashes of white, disable tile updates immediately when view is cleared at the beginning of a page load.
// Tiling will be re-enabled from UIKit via [WAKWindow setTilingMode:] when we have content to draw.
- if (LegacyTileCache* tileCache = legacyTileCache())
- tileCache->setTilingMode(LegacyTileCache::Disabled);
+ if (TileCache* tileCache = this->tileCache())
+ tileCache->setTilingMode(TileCache::Disabled);
#endif
}
-#if PLATFORM(IOS)
-void FrameView::didReplaceMultipartContent()
-{
- // Re-enable tile updates that were disabled in clear().
- if (LegacyTileCache* tileCache = legacyTileCache())
- tileCache->setTilingMode(LegacyTileCache::Normal);
-}
-#endif
-
bool FrameView::didFirstLayout() const
{
return !m_firstLayout;
@@ -461,7 +400,7 @@ void FrameView::invalidateRect(const IntRect& rect)
{
if (!parent()) {
if (HostWindow* window = hostWindow())
- window->invalidateContentsAndRootView(rect);
+ window->invalidateContentsAndRootView(rect, false /*immediate*/);
return;
}
@@ -477,7 +416,6 @@ void FrameView::invalidateRect(const IntRect& rect)
void FrameView::setFrameRect(const IntRect& newRect)
{
- Ref<FrameView> protect(*this);
IntRect oldRect = frameRect();
if (newRect == oldRect)
return;
@@ -485,6 +423,7 @@ void FrameView::setFrameRect(const IntRect& newRect)
#if ENABLE(TEXT_AUTOSIZING)
// Autosized font sizes depend on the width of the viewing area.
if (newRect.width() != oldRect.width()) {
+ Page* page = frame().page();
if (frame().isMainFrame() && page->settings().textAutosizingEnabled()) {
for (Frame* frame = &page->mainFrame(); frame; frame = frame->tree().traverseNext())
frame().document()->textAutosizer()->recalculateMultipliers();
@@ -496,15 +435,15 @@ void FrameView::setFrameRect(const IntRect& newRect)
updateScrollableAreaSet();
+#if USE(ACCELERATED_COMPOSITING)
if (RenderView* renderView = this->renderView()) {
if (renderView->usesCompositing())
renderView->compositor().frameViewDidChangeSize();
}
+#endif
- if (frame().isMainFrame())
- frame().mainFrame().pageOverlayController().didChangeViewSize();
-
- viewportContentsChanged();
+ if (!frameFlatteningEnabled())
+ sendResizeEventIfNeeded();
}
#if ENABLE(REQUEST_ANIMATION_FRAME)
@@ -582,19 +521,19 @@ PassRefPtr<Scrollbar> FrameView::createScrollbar(ScrollbarOrientation orientatio
Document* doc = frame().document();
// Try the <body> element first as a scrollbar source.
- HTMLElement* body = doc ? doc->bodyOrFrameset() : nullptr;
+ Element* body = doc ? doc->body() : 0;
if (body && body->renderer() && body->renderer()->style().hasPseudoStyle(SCROLLBAR))
- return RenderScrollbar::createCustomScrollbar(*this, orientation, body);
+ return RenderScrollbar::createCustomScrollbar(this, orientation, body);
// If the <body> didn't have a custom style, then the root element might.
- Element* docElement = doc ? doc->documentElement() : nullptr;
+ Element* docElement = doc ? doc->documentElement() : 0;
if (docElement && docElement->renderer() && docElement->renderer()->style().hasPseudoStyle(SCROLLBAR))
- return RenderScrollbar::createCustomScrollbar(*this, orientation, docElement);
+ return RenderScrollbar::createCustomScrollbar(this, orientation, docElement);
// If we have an owning iframe/frame element, then it can set the custom scrollbar also.
RenderWidget* frameRenderer = frame().ownerRenderer();
if (frameRenderer && frameRenderer->style().hasPseudoStyle(SCROLLBAR))
- return RenderScrollbar::createCustomScrollbar(*this, orientation, nullptr, &frame());
+ return RenderScrollbar::createCustomScrollbar(this, orientation, 0, &frame());
// Nobody set a custom style, so we just use a native scrollbar.
return ScrollView::createScrollbar(orientation);
@@ -605,10 +544,10 @@ void FrameView::setContentsSize(const IntSize& size)
if (size == contentsSize())
return;
- m_deferSetNeedsLayoutCount++;
+ m_deferSetNeedsLayouts++;
ScrollView::setContentsSize(size);
- contentsResized();
+ ScrollView::contentsResized();
Page* page = frame().page();
if (!page)
@@ -618,15 +557,10 @@ void FrameView::setContentsSize(const IntSize& size)
page->chrome().contentsSizeChanged(&frame(), size); // Notify only.
- if (frame().isMainFrame()) {
- frame().mainFrame().pageOverlayController().didChangeDocumentSize();
- PageCache::singleton().markPagesForContentsSizeChanged(*page);
- }
-
- ASSERT(m_deferSetNeedsLayoutCount);
- m_deferSetNeedsLayoutCount--;
+ ASSERT(m_deferSetNeedsLayouts);
+ m_deferSetNeedsLayouts--;
- if (!m_deferSetNeedsLayoutCount)
+ if (!m_deferSetNeedsLayouts)
m_setNeedsLayoutWasDeferred = false; // FIXME: Find a way to make the deferred layout actually happen.
}
@@ -641,13 +575,11 @@ void FrameView::adjustViewSize()
const IntRect rect = renderView->documentRect();
const IntSize& size = rect.size();
ScrollView::setScrollOrigin(IntPoint(-rect.x(), -rect.y()), !frame().document()->printing(), size == contentsSize());
-
- LOG_WITH_STREAM(Layout, stream << "FrameView " << this << " adjustViewSize: unscaled document rect changed to " << renderView->unscaledDocumentRect() << " (scaled to " << size << ")");
-
+
setContentsSize(size);
}
-void FrameView::applyOverflowToViewport(const RenderElement& renderer, ScrollbarMode& hMode, ScrollbarMode& vMode)
+void FrameView::applyOverflowToViewport(RenderElement* o, ScrollbarMode& hMode, ScrollbarMode& vMode)
{
// Handle the overflow:hidden/scroll case for the body/html elements. WinIE treats
// overflow:hidden and overflow:scroll on <body> as applying to the document's
@@ -660,17 +592,18 @@ void FrameView::applyOverflowToViewport(const RenderElement& renderer, Scrollbar
bool overrideHidden = frame().isMainFrame() && ((frame().frameScaleFactor() > 1) || headerHeight() || footerHeight());
- EOverflow overflowX = renderer.style().overflowX();
- EOverflow overflowY = renderer.style().overflowY();
+ EOverflow overflowX = o->style().overflowX();
+ EOverflow overflowY = o->style().overflowY();
- if (is<RenderSVGRoot>(renderer)) {
- // FIXME: evaluate if we can allow overflow for these cases too.
- // Overflow is always hidden when stand-alone SVG documents are embedded.
- if (downcast<RenderSVGRoot>(renderer).isEmbeddedThroughFrameContainingSVGDocument()) {
- overflowX = OHIDDEN;
- overflowY = OHIDDEN;
- }
+#if ENABLE(SVG)
+ if (o->isSVGRoot()) {
+ // overflow is ignored in stand-alone SVG documents.
+ if (!toRenderSVGRoot(o)->isEmbeddedThroughFrameContainingSVGDocument())
+ return;
+ overflowX = OHIDDEN;
+ overflowY = OHIDDEN;
}
+#endif
switch (overflowX) {
case OHIDDEN:
@@ -707,17 +640,21 @@ void FrameView::applyOverflowToViewport(const RenderElement& renderer, Scrollbar
// Don't set it at all. Values of OPAGEDX and OPAGEDY are handled by applyPaginationToViewPort().
;
}
+
+ m_viewportRenderer = o;
}
void FrameView::applyPaginationToViewport()
{
Document* document = frame().document();
- auto* documentElement = document->documentElement();
+ auto documentElement = document->documentElement();
RenderElement* documentRenderer = documentElement ? documentElement->renderer() : nullptr;
RenderElement* documentOrBodyRenderer = documentRenderer;
- auto* body = document->body();
- if (body && body->renderer())
- documentOrBodyRenderer = documentRenderer->style().overflowX() == OVISIBLE && is<HTMLHtmlElement>(*documentElement) ? body->renderer() : documentRenderer;
+ auto body = document->body();
+ if (body && body->renderer()) {
+ if (body->hasTagName(bodyTag))
+ documentOrBodyRenderer = documentRenderer->style().overflowX() == OVISIBLE && documentElement->hasTagName(htmlTag) ? body->renderer() : documentRenderer;
+ }
Pagination pagination;
@@ -737,7 +674,7 @@ void FrameView::applyPaginationToViewport()
void FrameView::calculateScrollbarModesForLayout(ScrollbarMode& hMode, ScrollbarMode& vMode, ScrollbarModesCalculationStrategy strategy)
{
- m_viewportRendererType = ViewportRendererType::None;
+ m_viewportRenderer = 0;
const HTMLFrameOwnerElement* owner = frame().ownerElement();
if (owner && (owner->scrollingMode() == ScrollbarAlwaysOff)) {
@@ -748,75 +685,51 @@ void FrameView::calculateScrollbarModesForLayout(ScrollbarMode& hMode, Scrollbar
if (m_canHaveScrollbars || strategy == RulesFromWebContentOnly) {
hMode = ScrollbarAuto;
- vMode = ScrollbarAuto;
+ // Seamless documents begin with heights of 0; we special case that here
+ // to correctly render documents that don't need scrollbars.
+ IntSize fullVisibleSize = visibleContentRectIncludingScrollbars(LegacyIOSDocumentVisibleRect).size();
+ bool isSeamlessDocument = frame().document() && frame().document()->shouldDisplaySeamlesslyWithParent();
+ vMode = (isSeamlessDocument && !fullVisibleSize.height()) ? ScrollbarAlwaysOff : ScrollbarAuto;
} else {
hMode = ScrollbarAlwaysOff;
vMode = ScrollbarAlwaysOff;
}
- if (m_layoutRoot)
- return;
-
- auto* document = frame().document();
- if (!document)
- return;
-
- auto* documentElement = document->documentElement();
- if (!documentElement)
- return;
-
- auto* bodyOrFrameset = document->bodyOrFrameset();
- auto* rootRenderer = documentElement->renderer();
- if (!bodyOrFrameset || !bodyOrFrameset->renderer()) {
- if (rootRenderer) {
- applyOverflowToViewport(*rootRenderer, hMode, vMode);
- m_viewportRendererType = ViewportRendererType::Document;
- }
- return;
- }
-
- if (is<HTMLFrameSetElement>(*bodyOrFrameset) && !frameFlatteningEnabled()) {
- vMode = ScrollbarAlwaysOff;
- hMode = ScrollbarAlwaysOff;
- return;
- }
-
- if (is<HTMLBodyElement>(*bodyOrFrameset) && rootRenderer) {
- // It's sufficient to just check the X overflow,
- // since it's illegal to have visible in only one direction.
- if (rootRenderer->style().overflowX() == OVISIBLE && is<HTMLHtmlElement>(documentElement)) {
- auto* bodyRenderer = bodyOrFrameset->renderer();
- if (bodyRenderer) {
- applyOverflowToViewport(*bodyRenderer, hMode, vMode);
- m_viewportRendererType = ViewportRendererType::Body;
+ if (!m_layoutRoot) {
+ Document* document = frame().document();
+ auto documentElement = document->documentElement();
+ RenderElement* rootRenderer = documentElement ? documentElement->renderer() : nullptr;
+ auto body = document->body();
+ if (body && body->renderer()) {
+ if (body->hasTagName(framesetTag) && !frameFlatteningEnabled()) {
+ vMode = ScrollbarAlwaysOff;
+ hMode = ScrollbarAlwaysOff;
+ } else if (body->hasTagName(bodyTag)) {
+ // It's sufficient to just check the X overflow,
+ // since it's illegal to have visible in only one direction.
+ RenderElement* o = rootRenderer->style().overflowX() == OVISIBLE && document->documentElement()->hasTagName(htmlTag) ? body->renderer() : rootRenderer;
+ applyOverflowToViewport(o, hMode, vMode);
}
- } else {
- applyOverflowToViewport(*rootRenderer, hMode, vMode);
- m_viewportRendererType = ViewportRendererType::Document;
- }
- }
+ } else if (rootRenderer)
+ applyOverflowToViewport(rootRenderer, hMode, vMode);
+ }
}
-void FrameView::willRecalcStyle()
+#if USE(ACCELERATED_COMPOSITING)
+void FrameView::updateCompositingLayersAfterStyleChange()
{
RenderView* renderView = this->renderView();
if (!renderView)
return;
- renderView->compositor().willRecalcStyle();
-}
-
-bool FrameView::updateCompositingLayersAfterStyleChange()
-{
- RenderView* renderView = this->renderView();
- if (!renderView)
- return false;
-
// If we expect to update compositing after an incipient layout, don't do so here.
if (inPreLayoutStyleUpdate() || layoutPending() || renderView->needsLayout())
- return false;
+ return;
- return renderView->compositor().didRecalcStyleWithNoPendingLayout();
+ RenderLayerCompositor& compositor = renderView->compositor();
+ // This call will make sure the cached hasAcceleratedCompositing is updated from the pref
+ compositor.cacheAcceleratedCompositingFlags();
+ compositor.updateCompositingLayers(CompositingUpdateAfterStyleChange);
}
void FrameView::updateCompositingLayersAfterLayout()
@@ -853,11 +766,21 @@ void FrameView::restoreBackingStores()
compositor.updateCompositingLayers(CompositingUpdateAfterLayout);
}
+bool FrameView::usesCompositedScrolling() const
+{
+ RenderView* renderView = this->renderView();
+ if (!renderView)
+ return false;
+ if (frame().settings().compositedScrollingForFramesEnabled())
+ return renderView->compositor().inForcedCompositingMode();
+ return false;
+}
+
GraphicsLayer* FrameView::layerForScrolling() const
{
RenderView* renderView = this->renderView();
if (!renderView)
- return nullptr;
+ return 0;
return renderView->compositor().scrollLayer();
}
@@ -865,7 +788,7 @@ GraphicsLayer* FrameView::layerForHorizontalScrollbar() const
{
RenderView* renderView = this->renderView();
if (!renderView)
- return nullptr;
+ return 0;
return renderView->compositor().layerForHorizontalScrollbar();
}
@@ -873,7 +796,7 @@ GraphicsLayer* FrameView::layerForVerticalScrollbar() const
{
RenderView* renderView = this->renderView();
if (!renderView)
- return nullptr;
+ return 0;
return renderView->compositor().layerForVerticalScrollbar();
}
@@ -881,7 +804,7 @@ GraphicsLayer* FrameView::layerForScrollCorner() const
{
RenderView* renderView = this->renderView();
if (!renderView)
- return nullptr;
+ return 0;
return renderView->compositor().layerForScrollCorner();
}
@@ -889,11 +812,11 @@ TiledBacking* FrameView::tiledBacking() const
{
RenderView* renderView = this->renderView();
if (!renderView)
- return nullptr;
+ return 0;
RenderLayerBacking* backing = renderView->layer()->backing();
if (!backing)
- return nullptr;
+ return 0;
return backing->graphicsLayer()->tiledBacking();
}
@@ -908,16 +831,7 @@ uint64_t FrameView::scrollLayerID() const
if (!backing)
return 0;
- return backing->scrollingNodeIDForRole(Scrolling);
-}
-
-ScrollableArea* FrameView::scrollableAreaForScrollLayerID(uint64_t nodeID) const
-{
- RenderView* renderView = this->renderView();
- if (!renderView)
- return nullptr;
-
- return renderView->compositor().scrollableAreaForScrollLayerID(nodeID);
+ return backing->scrollLayerID();
}
#if ENABLE(RUBBER_BANDING)
@@ -925,7 +839,7 @@ GraphicsLayer* FrameView::layerForOverhangAreas() const
{
RenderView* renderView = this->renderView();
if (!renderView)
- return nullptr;
+ return 0;
return renderView->compositor().layerForOverhangAreas();
}
@@ -933,7 +847,7 @@ GraphicsLayer* FrameView::setWantsLayerForTopOverHangArea(bool wantsLayer) const
{
RenderView* renderView = this->renderView();
if (!renderView)
- return nullptr;
+ return 0;
return renderView->compositor().updateLayerForTopOverhangArea(wantsLayer);
}
@@ -942,56 +856,14 @@ GraphicsLayer* FrameView::setWantsLayerForBottomOverHangArea(bool wantsLayer) co
{
RenderView* renderView = this->renderView();
if (!renderView)
- return nullptr;
+ return 0;
return renderView->compositor().updateLayerForBottomOverhangArea(wantsLayer);
}
#endif // ENABLE(RUBBER_BANDING)
-#if ENABLE(CSS_SCROLL_SNAP)
-void FrameView::updateSnapOffsets()
-{
- if (!frame().document())
- return;
-
- // FIXME: Should we allow specifying snap points through <html> tags too?
- HTMLElement* body = frame().document()->bodyOrFrameset();
- if (!renderView() || !body || !body->renderer())
- return;
-
- updateSnapOffsetsForScrollableArea(*this, *body, *renderView(), body->renderer()->style());
-}
-
-bool FrameView::isScrollSnapInProgress() const
-{
- if (scrollbarsSuppressed())
- return false;
-
- // If the scrolling thread updates the scroll position for this FrameView, then we should return
- // ScrollingCoordinator::isScrollSnapInProgress().
- if (Page* page = frame().page()) {
- if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator()) {
- if (!scrollingCoordinator->shouldUpdateScrollLayerPositionSynchronously())
- return scrollingCoordinator->isScrollSnapInProgress();
- }
- }
-
- // If the main thread updates the scroll position for this FrameView, we should return
- // ScrollAnimator::isScrollSnapInProgress().
- if (ScrollAnimator* scrollAnimator = existingScrollAnimator())
- return scrollAnimator->isScrollSnapInProgress();
-
- return false;
-}
-
-void FrameView::updateScrollingCoordinatorScrollSnapProperties() const
-{
- renderView()->compositor().updateScrollSnapPropertiesWithFrameView(*this);
-}
-#endif
-
-bool FrameView::flushCompositingStateForThisFrame(const Frame& rootFrameForFlush)
+bool FrameView::flushCompositingStateForThisFrame(Frame* rootFrameForFlush)
{
RenderView* renderView = this->renderView();
if (!renderView)
@@ -1005,11 +877,12 @@ bool FrameView::flushCompositingStateForThisFrame(const Frame& rootFrameForFlush
return false;
#if PLATFORM(IOS)
- if (LegacyTileCache* tileCache = legacyTileCache())
+ if (TileCache* tileCache = this->tileCache())
tileCache->doPendingRepaints();
#endif
- renderView->compositor().flushPendingLayerChanges(&rootFrameForFlush == m_frame.ptr());
+ renderView->compositor().flushPendingLayerChanges(rootFrameForFlush == &frame());
+
return true;
}
@@ -1052,25 +925,7 @@ void FrameView::scheduleLayerFlushAllowingThrottling()
return;
view->compositor().scheduleLayerFlush(true /* canThrottle */);
}
-
-LayoutRect FrameView::fixedScrollableAreaBoundsInflatedForScrolling(const LayoutRect& uninflatedBounds) const
-{
- LayoutPoint scrollPosition = scrollPositionRespectingCustomFixedPosition();
-
- LayoutSize topLeftExpansion = scrollPosition - minimumScrollPosition();
- LayoutSize bottomRightExpansion = maximumScrollPosition() - scrollPosition;
-
- return LayoutRect(uninflatedBounds.location() - topLeftExpansion, uninflatedBounds.size() + topLeftExpansion + bottomRightExpansion);
-}
-
-LayoutPoint FrameView::scrollPositionRespectingCustomFixedPosition() const
-{
-#if PLATFORM(IOS)
- return useCustomFixedPositionLayoutRect() ? customFixedPositionLayoutRect().location() : scrollPosition();
-#else
- return scrollPositionForFixedPosition();
-#endif
-}
+#endif // USE(ACCELERATED_COMPOSITING)
void FrameView::setHeaderHeight(int headerHeight)
{
@@ -1092,84 +947,103 @@ void FrameView::setFooterHeight(int footerHeight)
renderView->setNeedsLayout();
}
-float FrameView::topContentInset(TopContentInsetType contentInsetTypeToReturn) const
+bool FrameView::hasCompositedContent() const
{
- if (platformWidget() && contentInsetTypeToReturn == TopContentInsetType::WebCoreOrPlatformContentInset)
- return platformTopContentInset();
-
- if (!frame().isMainFrame())
- return 0;
-
- Page* page = frame().page();
- return page ? page->topContentInset() : 0;
+#if USE(ACCELERATED_COMPOSITING)
+ if (RenderView* renderView = this->renderView())
+ return renderView->compositor().inCompositingMode();
+#endif
+ return false;
}
-
-void FrameView::topContentInsetDidChange(float newTopContentInset)
-{
- RenderView* renderView = this->renderView();
- if (!renderView)
- return;
- if (platformWidget())
- platformSetTopContentInset(newTopContentInset);
-
- layout();
-
- updateScrollbars(scrollPosition());
- if (renderView->usesCompositing())
- renderView->compositor().frameViewDidChangeSize();
+bool FrameView::hasCompositedContentIncludingDescendants() const
+{
+#if USE(ACCELERATED_COMPOSITING)
+ for (Frame* frame = m_frame.get(); frame; frame = frame->tree().traverseNext(m_frame.get())) {
+ RenderView* renderView = frame->contentRenderer();
+ if (RenderLayerCompositor* compositor = renderView ? &renderView->compositor() : 0) {
+ if (compositor->inCompositingMode())
+ return true;
- if (TiledBacking* tiledBacking = this->tiledBacking())
- tiledBacking->setTopContentInset(newTopContentInset);
+ if (!RenderLayerCompositor::allowsIndependentlyCompositedFrames(this))
+ break;
+ }
+ }
+#endif
+ return false;
}
-
-bool FrameView::hasCompositedContent() const
+
+bool FrameView::hasCompositingAncestor() const
{
- if (RenderView* renderView = this->renderView())
- return renderView->compositor().inCompositingMode();
+#if USE(ACCELERATED_COMPOSITING)
+ for (Frame* frame = this->frame().tree().parent(); frame; frame = frame->tree().parent()) {
+ if (FrameView* view = frame->view()) {
+ if (view->hasCompositedContent())
+ return true;
+ }
+ }
+#endif
return false;
}
// Sometimes (for plug-ins) we need to eagerly go into compositing mode.
void FrameView::enterCompositingMode()
{
+#if USE(ACCELERATED_COMPOSITING)
if (RenderView* renderView = this->renderView()) {
renderView->compositor().enableCompositingMode();
if (!needsLayout())
renderView->compositor().scheduleCompositingLayerUpdate();
}
+#endif
}
bool FrameView::isEnclosedInCompositingLayer() const
{
+#if USE(ACCELERATED_COMPOSITING)
auto frameOwnerRenderer = frame().ownerRenderer();
if (frameOwnerRenderer && frameOwnerRenderer->containerForRepaint())
return true;
if (FrameView* parentView = parentFrameView())
return parentView->isEnclosedInCompositingLayer();
+#endif
return false;
}
bool FrameView::flushCompositingStateIncludingSubframes()
{
- InspectorInstrumentation::willComposite(frame());
-
- bool allFramesFlushed = flushCompositingStateForThisFrame(frame());
-
- for (Frame* child = frame().tree().firstRenderedChild(); child; child = child->tree().traverseNextRendered(m_frame.ptr())) {
- if (!child->view())
- continue;
- bool flushed = child->view()->flushCompositingStateForThisFrame(frame());
+#if USE(ACCELERATED_COMPOSITING)
+ bool allFramesFlushed = flushCompositingStateForThisFrame(&frame());
+
+ for (Frame* child = frame().tree().firstChild(); child; child = child->tree().traverseNext(&frame())) {
+ bool flushed = child->view()->flushCompositingStateForThisFrame(&frame());
allFramesFlushed &= flushed;
}
return allFramesFlushed;
+#else // USE(ACCELERATED_COMPOSITING)
+ return true;
+#endif
}
bool FrameView::isSoftwareRenderable() const
{
+#if USE(ACCELERATED_COMPOSITING)
RenderView* renderView = this->renderView();
return !renderView || !renderView->compositor().has3DContent();
+#else
+ return true;
+#endif
+}
+
+void FrameView::didMoveOnscreen()
+{
+ contentAreaDidShow();
+}
+
+void FrameView::willMoveOffscreen()
+{
+ contentAreaDidHide();
}
void FrameView::setIsInWindow(bool isInWindow)
@@ -1178,8 +1052,14 @@ void FrameView::setIsInWindow(bool isInWindow)
renderView->setIsInWindow(isInWindow);
}
+RenderObject* FrameView::layoutRoot(bool onlyDuringLayout) const
+{
+ return onlyDuringLayout && layoutPending() ? 0 : m_layoutRoot;
+}
+
inline void FrameView::forceLayoutParentViewIfNeeded()
{
+#if ENABLE(SVG)
RenderWidget* ownerRenderer = frame().ownerRenderer();
if (!ownerRenderer)
return;
@@ -1188,44 +1068,39 @@ inline void FrameView::forceLayoutParentViewIfNeeded()
if (!contentBox)
return;
- auto& svgRoot = downcast<RenderSVGRoot>(*contentBox);
- if (svgRoot.everHadLayout() && !svgRoot.needsLayout())
+ RenderSVGRoot* svgRoot = toRenderSVGRoot(contentBox);
+ if (svgRoot->everHadLayout() && !svgRoot->needsLayout())
return;
- LOG(Layout, "FrameView %p forceLayoutParentViewIfNeeded scheduling layout on parent FrameView %p", this, &ownerRenderer->view().frameView());
-
// If the embedded SVG document appears the first time, the ownerRenderer has already finished
// layout without knowing about the existence of the embedded SVG document, because RenderReplaced
- // embeddedContentBox() returns nullptr, as long as the embedded document isn't loaded yet. Before
+ // embeddedContentBox() returns 0, as long as the embedded document isn't loaded yet. Before
// bothering to lay out the SVG document, mark the ownerRenderer needing layout and ask its
// FrameView for a layout. After that the RenderEmbeddedObject (ownerRenderer) carries the
// correct size, which RenderSVGRoot::computeReplacedLogicalWidth/Height rely on, when laying
// out for the first time, or when the RenderSVGRoot size has changed dynamically (eg. via <script>).
+ Ref<FrameView> frameView(ownerRenderer->view().frameView());
+ // Mark the owner renderer as needing layout.
ownerRenderer->setNeedsLayoutAndPrefWidthsRecalc();
- ownerRenderer->view().frameView().scheduleRelayout();
+
+ // Synchronously enter layout, to layout the view containing the host object/embed/iframe.
+ frameView->layout();
+#endif
}
void FrameView::layout(bool allowSubtree)
{
- LOG(Layout, "FrameView %p (%dx%d) layout, main frameview %d, allowSubtree=%d", this, size().width(), size().height(), frame().isMainFrame(), allowSubtree);
- if (isInRenderTreeLayout()) {
- LOG(Layout, " in layout, bailing");
- return;
- }
-
- if (layoutDisallowed()) {
- LOG(Layout, " layout is disallowed, bailing");
+ if (isInLayout())
return;
- }
-
- // Protect the view from being deleted during layout (in recalcStyle).
- Ref<FrameView> protect(*this);
// Many of the tasks performed during layout can cause this function to be re-entered,
// so save the layout phase now and restore it on exit.
TemporaryChange<LayoutPhase> layoutPhaseRestorer(m_layoutPhase, InPreLayout);
+ // Protect the view from being deleted during layout (in recalcStyle)
+ Ref<FrameView> protect(*this);
+
// Every scroll that happens during layout is programmatic.
TemporaryChange<bool> changeInProgrammaticScroll(m_inProgrammaticScroll, true);
@@ -1234,11 +1109,9 @@ void FrameView::layout(bool allowSubtree)
if (inChildFrameLayoutWithFrameFlattening) {
startLayoutAtMainFrameViewIfNeeded(allowSubtree);
RenderElement* root = m_layoutRoot ? m_layoutRoot : frame().document()->renderView();
- if (!root || !root->needsLayout())
+ if (!root->needsLayout())
return;
}
-
- TraceScope tracingScope(LayoutStart, LayoutEnd);
#if PLATFORM(IOS)
if (updateFixedPositionLayoutRect())
@@ -1254,11 +1127,12 @@ void FrameView::layout(bool allowSubtree)
if (isPainting())
return;
- InspectorInstrumentationCookie cookie = InspectorInstrumentation::willLayout(frame());
- AnimationUpdateBlock animationUpdateBlock(&frame().animation());
-
- if (!allowSubtree && m_layoutRoot)
- convertSubtreeLayoutToFullLayout();
+ InspectorInstrumentationCookie cookie = InspectorInstrumentation::willLayout(&frame());
+
+ if (!allowSubtree && m_layoutRoot) {
+ m_layoutRoot->markContainingBlocksForLayout(false);
+ m_layoutRoot = 0;
+ }
ASSERT(frame().view() == this);
ASSERT(frame().document());
@@ -1266,6 +1140,9 @@ void FrameView::layout(bool allowSubtree)
Document& document = *frame().document();
ASSERT(!document.inPageCache());
+ bool subtree;
+ RenderElement* root;
+
{
TemporaryChange<bool> changeSchedulingEnabled(m_layoutSchedulingEnabled, false);
@@ -1280,11 +1157,10 @@ void FrameView::layout(bool allowSubtree)
// Viewport-dependent media queries may cause us to need completely different style information.
StyleResolver* styleResolver = document.styleResolverIfExists();
- if (!styleResolver || styleResolver->hasMediaQueriesAffectedByViewportChange()) {
- LOG(Layout, " hasMediaQueriesAffectedByViewportChange, enqueueing style recalc");
+ if (!styleResolver || styleResolver->affectedByViewportChange()) {
document.styleResolverChanged(DeferRecalcStyle);
// FIXME: This instrumentation event is not strictly accurate since cached media query results do not persist across StyleResolver rebuilds.
- InspectorInstrumentation::mediaQueryResultChanged(document);
+ InspectorInstrumentation::mediaQueryResultChanged(&document);
} else
document.evaluateMediaQueryList();
@@ -1295,41 +1171,41 @@ void FrameView::layout(bool allowSubtree)
// Always ensure our style info is up-to-date. This can happen in situations where
// the layout beats any sort of style recalc update that needs to occur.
document.updateStyleIfNeeded();
- // If there is only one ref to this view left, then its going to be destroyed as soon as we exit,
+ m_layoutPhase = InPreLayout;
+
+ subtree = m_layoutRoot;
+
+ // If there is only one ref to this view left, then its going to be destroyed as soon as we exit,
// so there's no point to continuing to layout
if (hasOneRef())
return;
+ root = subtree ? m_layoutRoot : document.renderView();
+ if (!root) {
+ // FIXME: Do we need to set m_size here?
+ return;
+ }
+
// Close block here so we can set up the font cache purge preventer, which we will still
// want in scope even after we want m_layoutSchedulingEnabled to be restored again.
// The next block sets m_layoutSchedulingEnabled back to false once again.
}
- m_layoutPhase = InPreLayout;
-
- RenderLayer* layer = nullptr;
- bool subtree = false;
- RenderElement* root = nullptr;
+ FontCachePurgePreventer fontCachePurgePreventer;
+ RenderLayer* layer;
++m_nestedLayoutCount;
{
TemporaryChange<bool> changeSchedulingEnabled(m_layoutSchedulingEnabled, false);
- autoSizeIfEnabled();
-
- root = m_layoutRoot ? m_layoutRoot : document.renderView();
- if (!root)
- return;
- subtree = m_layoutRoot;
-
if (!m_layoutRoot) {
- auto* body = document.bodyOrFrameset();
+ HTMLElement* body = document.body();
if (body && body->renderer()) {
- if (is<HTMLFrameSetElement>(*body) && !frameFlatteningEnabled()) {
+ if (body->hasTagName(framesetTag) && !frameFlatteningEnabled()) {
body->renderer()->setChildNeedsLayout();
- } else if (is<HTMLBodyElement>(*body)) {
- if (!m_firstLayout && m_size.height() != layoutHeight() && body->renderer()->enclosingBox().stretchesToViewport())
+ } else if (body->hasTagName(bodyTag)) {
+ if (!m_firstLayout && m_size.height() != layoutHeight() && body->renderer()->enclosingBox()->stretchesToViewport())
body->renderer()->setChildNeedsLayout();
}
}
@@ -1337,10 +1213,12 @@ void FrameView::layout(bool allowSubtree)
#ifdef INSTRUMENT_LAYOUT_SCHEDULING
if (m_firstLayout && !frame().ownerElement())
printf("Elapsed time before first layout: %lld\n", document.elapsedTime().count());
-#endif
+#endif
}
- m_needsFullRepaint = !subtree && (m_firstLayout || downcast<RenderView>(*root).printing());
+ autoSizeIfEnabled();
+
+ m_needsFullRepaint = !subtree && (m_firstLayout || toRenderView(*root).printing());
if (!subtree) {
ScrollbarMode hMode;
@@ -1353,7 +1231,11 @@ void FrameView::layout(bool allowSubtree)
m_firstLayout = false;
m_firstLayoutCallbackPending = true;
- m_lastViewportSize = sizeForResizeEvent();
+ if (useFixedLayout() && !fixedLayoutSize().isEmpty() && delegatesScrolling())
+ m_lastViewportSize = fixedLayoutSize();
+ else
+ m_lastViewportSize = visibleContentRectIncludingScrollbars().size();
+
m_lastZoomFactor = root->style().zoom();
// Set the initial vMode to AlwaysOn if we're auto.
@@ -1362,9 +1244,7 @@ void FrameView::layout(bool allowSubtree)
// Set the initial hMode to AlwaysOff if we're auto.
if (hMode == ScrollbarAuto)
setHorizontalScrollbarMode(ScrollbarAlwaysOff); // This causes a horizontal scrollbar to disappear.
- Page* page = frame().page();
- if (page && page->expectsWheelEventTriggers())
- scrollAnimator().setWheelEventTestTrigger(page->testTrigger());
+
setScrollbarModes(hMode, vMode);
setScrollbarsSuppressed(false, true);
} else
@@ -1372,15 +1252,14 @@ void FrameView::layout(bool allowSubtree)
}
LayoutSize oldSize = m_size;
+
m_size = layoutSize();
if (oldSize != m_size) {
- LOG(Layout, " layout size changed from %.3fx%.3f to %.3fx%.3f", oldSize.width().toFloat(), oldSize.height().toFloat(), m_size.width().toFloat(), m_size.height().toFloat());
m_needsFullRepaint = true;
if (!m_firstLayout) {
- RenderBox* rootRenderer = document.documentElement() ? document.documentElement()->renderBox() : nullptr;
- auto* body = document.bodyOrFrameset();
- RenderBox* bodyRenderer = rootRenderer && body ? body->renderBox() : nullptr;
+ RenderBox* rootRenderer = document.documentElement() ? document.documentElement()->renderBox() : 0;
+ RenderBox* bodyRenderer = rootRenderer && document.body() ? document.body()->renderBox() : 0;
if (bodyRenderer && bodyRenderer->stretchesToViewport())
bodyRenderer->setChildNeedsLayout();
else if (rootRenderer && rootRenderer->stretchesToViewport())
@@ -1392,27 +1271,31 @@ void FrameView::layout(bool allowSubtree)
}
layer = root->enclosingLayer();
- SubtreeLayoutStateMaintainer subtreeLayoutStateMaintainer(m_layoutRoot);
+ bool disableLayoutState = false;
+ if (subtree) {
+ disableLayoutState = root->view().shouldDisableLayoutStateForSubtree(root);
+ root->view().pushLayoutState(*root);
+ }
+ LayoutStateDisabler layoutStateDisabler(disableLayoutState ? &root->view() : 0);
RenderView::RepaintRegionAccumulator repaintRegionAccumulator(&root->view());
ASSERT(m_layoutPhase == InPreLayout);
- m_layoutPhase = InRenderTreeLayout;
+ m_layoutPhase = InLayout;
forceLayoutParentViewIfNeeded();
- ASSERT(m_layoutPhase == InRenderTreeLayout);
+ ASSERT(m_layoutPhase == InLayout);
root->layout();
#if ENABLE(IOS_TEXT_AUTOSIZING)
- if (Page* page = frame().page()) {
- float minimumZoomFontSize = frame().settings().minimumZoomFontSize();
- float textAutosizingWidth = page->textAutosizingWidth();
- if (minimumZoomFontSize && textAutosizingWidth && !root->view().printing()) {
- root->adjustComputedFontSizesOnBlocks(minimumZoomFontSize, textAutosizingWidth);
- if (root->needsLayout())
- root->layout();
- }
+ float minZoomFontSize = frame().settings().minimumZoomFontSize();
+ float visWidth = frame().page()->mainFrame().textAutosizingWidth();
+ if (minZoomFontSize && visWidth && !root->view().printing()) {
+ root->adjustComputedFontSizesOnBlocks(minZoomFontSize, visWidth);
+ bool needsLayout = root->needsLayout();
+ if (needsLayout)
+ root->layout();
}
#endif
#if ENABLE(TEXT_AUTOSIZING)
@@ -1420,16 +1303,21 @@ void FrameView::layout(bool allowSubtree)
root->layout();
#endif
- ASSERT(m_layoutPhase == InRenderTreeLayout);
- m_layoutRoot = nullptr;
- // Close block here to end the scope of changeSchedulingEnabled and SubtreeLayoutStateMaintainer.
+ ASSERT(m_layoutPhase == InLayout);
+
+ if (subtree)
+ root->view().popLayoutState(*root);
+
+ m_layoutRoot = 0;
+
+ // Close block here to end the scope of changeSchedulingEnabled and layoutStateDisabler.
}
m_layoutPhase = InViewSizeAdjust;
bool neededFullRepaint = m_needsFullRepaint;
- if (!subtree && !downcast<RenderView>(*root).printing())
+ if (!subtree && !toRenderView(*root).printing())
adjustViewSize();
m_layoutPhase = InPostLayout;
@@ -1440,19 +1328,15 @@ void FrameView::layout(bool allowSubtree)
if (m_needsFullRepaint)
root->view().repaintRootContents();
- root->view().releaseProtectedRenderWidgets();
-
- ASSERT(!root->needsLayout());
-
layer->updateLayerPositionsAfterLayout(renderView()->layer(), updateLayerPositionFlags(layer, subtree, m_needsFullRepaint));
+#if USE(ACCELERATED_COMPOSITING)
updateCompositingLayersAfterLayout();
-
- m_layoutPhase = InPostLayerPositionsUpdatedAfterLayout;
-
+#endif
+
m_layoutCount++;
-#if PLATFORM(COCOA) || PLATFORM(WIN) || PLATFORM(GTK) || PLATFORM(EFL)
+#if PLATFORM(MAC) || PLATFORM(WIN) || PLATFORM(GTK) || PLATFORM(EFL)
if (AXObjectCache* cache = root->document().existingAXObjectCache())
cache->postNotification(root, AXObjectCache::AXLayoutComplete);
#endif
@@ -1465,15 +1349,13 @@ void FrameView::layout(bool allowSubtree)
document.dirtyTouchEventRects();
#endif
- updateCanBlitOnScrollRecursively();
+ ASSERT(!root->needsLayout());
- handleDeferredScrollUpdateAfterContentSizeChange();
+ updateCanBlitOnScrollRecursively();
if (document.hasListenerType(Document::OVERFLOWCHANGED_LISTENER))
updateOverflowStatus(layoutWidth() < contentsWidth(), layoutHeight() < contentsHeight());
- frame().document()->markers().invalidateRectsForAllMarkers();
-
if (!m_postLayoutTasksTimer.isActive()) {
if (!m_inSynchronousPostLayout) {
if (inChildFrameLayoutWithFrameFlattening)
@@ -1496,27 +1378,31 @@ void FrameView::layout(bool allowSubtree)
}
InspectorInstrumentation::didLayout(cookie, root);
- DebugPageOverlays::didLayout(frame());
--m_nestedLayoutCount;
-}
-bool FrameView::shouldDeferScrollUpdateAfterContentSizeChange()
-{
- return (m_layoutPhase < InPostLayout) && (m_layoutPhase != OutsideLayout);
+ if (m_nestedLayoutCount)
+ return;
+
+ if (Page* page = frame().page())
+ page->chrome().client().layoutUpdated(&frame());
}
RenderBox* FrameView::embeddedContentBox() const
{
+#if ENABLE(SVG)
RenderView* renderView = this->renderView();
if (!renderView)
return nullptr;
RenderObject* firstChild = renderView->firstChild();
+ if (!firstChild || !firstChild->isBox())
+ return nullptr;
// Curently only embedded SVG documents participate in the size-negotiation logic.
- if (is<RenderSVGRoot>(firstChild))
- return downcast<RenderSVGRoot>(firstChild);
+ if (toRenderBox(firstChild)->isSVGRoot())
+ return toRenderBox(firstChild);
+#endif
return nullptr;
}
@@ -1524,12 +1410,12 @@ RenderBox* FrameView::embeddedContentBox() const
void FrameView::addEmbeddedObjectToUpdate(RenderEmbeddedObject& embeddedObject)
{
if (!m_embeddedObjectsToUpdate)
- m_embeddedObjectsToUpdate = std::make_unique<ListHashSet<RenderEmbeddedObject*>>();
+ m_embeddedObjectsToUpdate = adoptPtr(new ListHashSet<RenderEmbeddedObject*>);
HTMLFrameOwnerElement& element = embeddedObject.frameOwnerElement();
- if (is<HTMLObjectElement>(element) || is<HTMLEmbedElement>(element)) {
+ if (isHTMLObjectElement(element) || isHTMLEmbedElement(element)) {
// Tell the DOM element that it needs a widget update.
- HTMLPlugInImageElement& pluginElement = downcast<HTMLPlugInImageElement>(element);
+ HTMLPlugInImageElement& pluginElement = toHTMLPlugInImageElement(element);
if (!pluginElement.needsCheckForSizeChange())
pluginElement.setNeedsWidgetUpdate(true);
}
@@ -1554,7 +1440,7 @@ String FrameView::mediaType() const
{
// See if we have an override type.
String overrideType = frame().loader().client().overrideMediaType();
- InspectorInstrumentation::applyEmulatedMedia(frame(), overrideType);
+ InspectorInstrumentation::applyEmulatedMedia(&frame(), &overrideType);
if (!overrideType.isNull())
return overrideType;
return m_mediaType;
@@ -1581,7 +1467,7 @@ bool FrameView::useSlowRepaints(bool considerOverlap) const
// m_contentIsOpaque, so don't take the fast path for composited layers
// if they are a platform widget in order to get painting correctness
// for transparent layers. See the comment in WidgetMac::paint.
- if (usesCompositedScrolling() && !platformWidget())
+ if (contentsInCompositedLayer() && !platformWidget())
return mustBeSlow;
bool isOverlapped = m_isOverlapped && considerOverlap;
@@ -1602,53 +1488,25 @@ bool FrameView::useSlowRepaintsIfNotOverlapped() const
void FrameView::updateCanBlitOnScrollRecursively()
{
- for (auto* frame = m_frame.ptr(); frame; frame = frame->tree().traverseNext(m_frame.ptr())) {
+ for (Frame* frame = m_frame.get(); frame; frame = frame->tree().traverseNext(m_frame.get())) {
if (FrameView* view = frame->view())
view->setCanBlitOnScroll(!view->useSlowRepaints());
}
}
-bool FrameView::usesCompositedScrolling() const
+bool FrameView::contentsInCompositedLayer() const
{
+#if USE(ACCELERATED_COMPOSITING)
RenderView* renderView = this->renderView();
if (renderView && renderView->isComposited()) {
GraphicsLayer* layer = renderView->layer()->backing()->graphicsLayer();
if (layer && layer->drawsContent())
return true;
}
-
- return false;
-}
-
-bool FrameView::usesAsyncScrolling() const
-{
-#if ENABLE(ASYNC_SCROLLING)
- if (Page* page = frame().page()) {
- if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
- return scrollingCoordinator->coordinatesScrollingForFrameView(*this);
- }
#endif
return false;
}
-bool FrameView::usesMockScrollAnimator() const
-{
- return Settings::usesMockScrollAnimator();
-}
-
-void FrameView::logMockScrollAnimatorMessage(const String& message) const
-{
- Document* document = frame().document();
- if (!document)
- return;
- StringBuilder builder;
- if (frame().isMainFrame())
- builder.appendLiteral("Main");
- builder.appendLiteral("FrameView: ");
- builder.append(message);
- document->addConsoleMessage(MessageSource::Other, MessageLevel::Debug, builder.toString());
-}
-
void FrameView::setCannotBlitToWindow()
{
m_cannotBlitToWindow = true;
@@ -1660,7 +1518,7 @@ void FrameView::addSlowRepaintObject(RenderElement* o)
bool hadSlowRepaintObjects = hasSlowRepaintObjects();
if (!m_slowRepaintObjects)
- m_slowRepaintObjects = std::make_unique<HashSet<const RenderElement*>>();
+ m_slowRepaintObjects = adoptPtr(new HashSet<RenderElement*>);
m_slowRepaintObjects->add(o);
@@ -1669,7 +1527,7 @@ void FrameView::addSlowRepaintObject(RenderElement* o)
if (Page* page = frame().page()) {
if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
- scrollingCoordinator->frameViewHasSlowRepaintObjectsDidChange(*this);
+ scrollingCoordinator->frameViewHasSlowRepaintObjectsDidChange(this);
}
}
}
@@ -1686,7 +1544,7 @@ void FrameView::removeSlowRepaintObject(RenderElement* o)
if (Page* page = frame().page()) {
if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
- scrollingCoordinator->frameViewHasSlowRepaintObjectsDidChange(*this);
+ scrollingCoordinator->frameViewHasSlowRepaintObjectsDidChange(this);
}
}
}
@@ -1694,7 +1552,7 @@ void FrameView::removeSlowRepaintObject(RenderElement* o)
void FrameView::addViewportConstrainedObject(RenderElement* object)
{
if (!m_viewportConstrainedObjects)
- m_viewportConstrainedObjects = std::make_unique<ViewportConstrainedObjectSet>();
+ m_viewportConstrainedObjects = adoptPtr(new ViewportConstrainedObjectSet);
if (!m_viewportConstrainedObjects->contains(object)) {
m_viewportConstrainedObjects->add(object);
@@ -1703,7 +1561,7 @@ void FrameView::addViewportConstrainedObject(RenderElement* object)
if (Page* page = frame().page()) {
if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
- scrollingCoordinator->frameViewFixedObjectsDidChange(*this);
+ scrollingCoordinator->frameViewFixedObjectsDidChange(this);
}
}
}
@@ -1713,7 +1571,7 @@ void FrameView::removeViewportConstrainedObject(RenderElement* object)
if (m_viewportConstrainedObjects && m_viewportConstrainedObjects->remove(object)) {
if (Page* page = frame().page()) {
if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
- scrollingCoordinator->frameViewFixedObjectsDidChange(*this);
+ scrollingCoordinator->frameViewFixedObjectsDidChange(this);
}
// FIXME: In addFixedObject() we only call this if there's a platform widget,
@@ -1729,19 +1587,13 @@ LayoutRect FrameView::viewportConstrainedVisibleContentRect() const
return customFixedPositionLayoutRect();
#endif
LayoutRect viewportRect = visibleContentRect();
-
- viewportRect.setLocation(scrollPositionForFixedPosition());
+ viewportRect.setLocation(toPoint(scrollOffsetForFixedPosition()));
return viewportRect;
}
-float FrameView::frameScaleFactor() const
-{
- return frame().frameScaleFactor();
-}
-
-LayoutPoint FrameView::scrollPositionForFixedPosition(const LayoutRect& visibleContentRect, const LayoutSize& totalContentsSize, const LayoutPoint& scrollPosition, const LayoutPoint& scrollOrigin, float frameScaleFactor, bool fixedElementsLayoutRelativeToFrame, ScrollBehaviorForFixedElements behaviorForFixed, int headerHeight, int footerHeight)
+IntSize FrameView::scrollOffsetForFixedPosition(const IntRect& visibleContentRect, const IntSize& totalContentsSize, const IntPoint& scrollPosition, const IntPoint& scrollOrigin, float frameScaleFactor, bool fixedElementsLayoutRelativeToFrame, ScrollBehaviorForFixedElements behaviorForFixed, int headerHeight, int footerHeight)
{
- LayoutPoint position;
+ IntPoint position;
if (behaviorForFixed == StickToDocumentBounds)
position = ScrollableArea::constrainScrollPositionForOverhang(visibleContentRect, totalContentsSize, scrollPosition, scrollOrigin, headerHeight, footerHeight);
else {
@@ -1749,110 +1601,28 @@ LayoutPoint FrameView::scrollPositionForFixedPosition(const LayoutRect& visibleC
position.setY(position.y() - headerHeight);
}
- LayoutSize maxSize = totalContentsSize - visibleContentRect.size();
+ IntSize maxSize = totalContentsSize - visibleContentRect.size();
float dragFactorX = (fixedElementsLayoutRelativeToFrame || !maxSize.width()) ? 1 : (totalContentsSize.width() - visibleContentRect.width() * frameScaleFactor) / maxSize.width();
float dragFactorY = (fixedElementsLayoutRelativeToFrame || !maxSize.height()) ? 1 : (totalContentsSize.height() - visibleContentRect.height() * frameScaleFactor) / maxSize.height();
- return LayoutPoint(position.x() * dragFactorX / frameScaleFactor, position.y() * dragFactorY / frameScaleFactor);
+ return IntSize(position.x() * dragFactorX / frameScaleFactor, position.y() * dragFactorY / frameScaleFactor);
}
-float FrameView::yPositionForInsetClipLayer(const FloatPoint& scrollPosition, float topContentInset)
-{
- if (!topContentInset)
- return 0;
-
- // The insetClipLayer should not move for negative scroll values.
- float scrollY = std::max<float>(0, scrollPosition.y());
-
- if (scrollY >= topContentInset)
- return 0;
-
- return topContentInset - scrollY;
-}
-
-float FrameView::yPositionForHeaderLayer(const FloatPoint& scrollPosition, float topContentInset)
-{
- if (!topContentInset)
- return 0;
-
- float scrollY = std::max<float>(0, scrollPosition.y());
-
- if (scrollY >= topContentInset)
- return topContentInset;
-
- return scrollY;
-}
-
-float FrameView::yPositionForFooterLayer(const FloatPoint& scrollPosition, float topContentInset, float totalContentsHeight, float footerHeight)
-{
- return yPositionForHeaderLayer(scrollPosition, topContentInset) + totalContentsHeight - footerHeight;
-}
-
-FloatPoint FrameView::positionForRootContentLayer(const FloatPoint& scrollPosition, const FloatPoint& scrollOrigin, float topContentInset, float headerHeight)
-{
- return FloatPoint(0, yPositionForHeaderLayer(scrollPosition, topContentInset) + headerHeight) - toFloatSize(scrollOrigin);
-}
-
-FloatPoint FrameView::positionForRootContentLayer() const
-{
- return positionForRootContentLayer(scrollPosition(), scrollOrigin(), topContentInset(), headerHeight());
-}
-
-#if PLATFORM(IOS)
-LayoutRect FrameView::rectForViewportConstrainedObjects(const LayoutRect& visibleContentRect, const LayoutSize& totalContentsSize, float frameScaleFactor, bool fixedElementsLayoutRelativeToFrame, ScrollBehaviorForFixedElements scrollBehavior)
-{
- if (fixedElementsLayoutRelativeToFrame)
- return visibleContentRect;
-
- if (totalContentsSize.isEmpty())
- return visibleContentRect;
-
- // We impose an lower limit on the size (so an upper limit on the scale) of
- // the rect used to position fixed objects so that they don't crowd into the
- // center of the screen at larger scales.
- const LayoutUnit maxContentWidthForZoomThreshold = LayoutUnit::fromPixel(1024);
- float zoomedOutScale = frameScaleFactor * visibleContentRect.width() / std::min(maxContentWidthForZoomThreshold, totalContentsSize.width());
- float constraintThresholdScale = 1.5 * zoomedOutScale;
- float maxPostionedObjectsRectScale = std::min(frameScaleFactor, constraintThresholdScale);
-
- LayoutRect viewportConstrainedObjectsRect = visibleContentRect;
-
- if (frameScaleFactor > constraintThresholdScale) {
- FloatRect contentRect(FloatPoint(), totalContentsSize);
- FloatRect viewportRect = visibleContentRect;
-
- // Scale the rect up from a point that is relative to its position in the viewport.
- FloatSize sizeDelta = contentRect.size() - viewportRect.size();
-
- FloatPoint scaleOrigin;
- scaleOrigin.setX(contentRect.x() + sizeDelta.width() > 0 ? contentRect.width() * (viewportRect.x() - contentRect.x()) / sizeDelta.width() : 0);
- scaleOrigin.setY(contentRect.y() + sizeDelta.height() > 0 ? contentRect.height() * (viewportRect.y() - contentRect.y()) / sizeDelta.height() : 0);
-
- AffineTransform rescaleTransform = AffineTransform::translation(scaleOrigin.x(), scaleOrigin.y());
- rescaleTransform.scale(frameScaleFactor / maxPostionedObjectsRectScale, frameScaleFactor / maxPostionedObjectsRectScale);
- rescaleTransform = CGAffineTransformTranslate(rescaleTransform, -scaleOrigin.x(), -scaleOrigin.y());
-
- viewportConstrainedObjectsRect = enclosingLayoutRect(rescaleTransform.mapRect(visibleContentRect));
- }
-
- if (scrollBehavior == StickToDocumentBounds) {
- LayoutRect documentBounds(LayoutPoint(), totalContentsSize);
- viewportConstrainedObjectsRect.intersect(documentBounds);
- }
-
- return viewportConstrainedObjectsRect;
-}
-
-LayoutRect FrameView::viewportConstrainedObjectsRect() const
+IntSize FrameView::scrollOffsetForFixedPosition() const
{
- return rectForViewportConstrainedObjects(visibleContentRect(), totalContentsSize(), frame().frameScaleFactor(), fixedElementsLayoutRelativeToFrame(), scrollBehaviorForFixedElements());
+ IntRect visibleContentRect = this->visibleContentRect();
+ IntSize totalContentsSize = this->totalContentsSize();
+ IntPoint scrollPosition = this->scrollPosition();
+ IntPoint scrollOrigin = this->scrollOrigin();
+ float frameScaleFactor = frame().frameScaleFactor();
+ ScrollBehaviorForFixedElements behaviorForFixed = scrollBehaviorForFixedElements();
+ return scrollOffsetForFixedPosition(visibleContentRect, totalContentsSize, scrollPosition, scrollOrigin, frameScaleFactor, fixedElementsLayoutRelativeToFrame(), behaviorForFixed, headerHeight(), footerHeight());
}
-#endif
-ScrollPosition FrameView::minimumScrollPosition() const
+IntPoint FrameView::minimumScrollPosition() const
{
- ScrollPosition minimumPosition = ScrollView::minimumScrollPosition();
+ IntPoint minimumPosition(ScrollView::minimumScrollPosition());
if (frame().isMainFrame() && m_scrollPinningBehavior == PinToBottom)
minimumPosition.setY(maximumScrollPosition().y());
@@ -1860,32 +1630,16 @@ ScrollPosition FrameView::minimumScrollPosition() const
return minimumPosition;
}
-ScrollPosition FrameView::maximumScrollPosition() const
+IntPoint FrameView::maximumScrollPosition() const
{
- ScrollPosition maximumPosition = ScrollView::maximumScrollPosition();
+ IntPoint maximumOffset(contentsWidth() - visibleWidth() - scrollOrigin().x(), totalContentsSize().height() - visibleHeight() - scrollOrigin().y());
+
+ maximumOffset.clampNegativeToZero();
if (frame().isMainFrame() && m_scrollPinningBehavior == PinToTop)
- maximumPosition.setY(minimumScrollPosition().y());
+ maximumOffset.setY(minimumScrollPosition().y());
- return maximumPosition;
-}
-
-void FrameView::viewportContentsChanged()
-{
- if (!frame().view()) {
- // The frame is being destroyed.
- return;
- }
-
- // When the viewport contents changes (scroll, resize, style recalc, layout, ...),
- // check if we should resume animated images or unthrottle DOM timers.
- applyRecursivelyWithVisibleRect([] (FrameView& frameView, const IntRect& visibleRect) {
- frameView.resumeVisibleImageAnimations(visibleRect);
- frameView.updateScriptedAnimationsAndTimersThrottlingState(visibleRect);
-
- if (auto* renderView = frameView.frame().contentRenderer())
- renderView->updateVisibleViewportRect(visibleRect);
- });
+ return maximumOffset;
}
bool FrameView::fixedElementsLayoutRelativeToFrame() const
@@ -1916,34 +1670,38 @@ bool FrameView::scrollContentsFastPath(const IntSize& scrollDelta, const IntRect
return true;
}
- const bool isCompositedContentLayer = usesCompositedScrolling();
+ const bool isCompositedContentLayer = contentsInCompositedLayer();
// Get the rects of the fixed objects visible in the rectToScroll
Region regionToUpdate;
for (auto& renderer : *m_viewportConstrainedObjects) {
if (!renderer->style().hasViewportConstrainedPosition())
continue;
+#if USE(ACCELERATED_COMPOSITING)
if (renderer->isComposited())
continue;
+#endif
// Fixed items should always have layers.
ASSERT(renderer->hasLayer());
- RenderLayer* layer = downcast<RenderBoxModelObject>(*renderer).layer();
+ RenderLayer* layer = toRenderBoxModelObject(renderer)->layer();
+#if USE(ACCELERATED_COMPOSITING)
if (layer->viewportConstrainedNotCompositedReason() == RenderLayer::NotCompositedForBoundsOutOfView
|| layer->viewportConstrainedNotCompositedReason() == RenderLayer::NotCompositedForNoVisibleContent) {
// Don't invalidate for invisible fixed layers.
continue;
}
+#endif
+#if ENABLE(CSS_FILTERS)
if (layer->hasAncestorWithFilterOutsets()) {
// If the fixed layer has a blur/drop-shadow filter applied on at least one of its parents, we cannot
// scroll using the fast path, otherwise the outsets of the filter will be moved around the page.
return false;
}
-
- // FIXME: use pixel snapping instead of enclosing when ScrollView has finished transitioning from IntRect to Float/LayoutRect.
- IntRect updateRect = enclosingIntRect(layer->repaintRectIncludingNonCompositingDescendants());
+#endif
+ IntRect updateRect = pixelSnappedIntRect(layer->repaintRectIncludingNonCompositingDescendants());
updateRect = contentsToRootView(updateRect);
if (!isCompositedContentLayer && clipsRepaints())
updateRect.intersect(rectToScroll);
@@ -1955,19 +1713,24 @@ bool FrameView::scrollContentsFastPath(const IntSize& scrollDelta, const IntRect
hostWindow()->scroll(scrollDelta, rectToScroll, clipRect);
// 2) update the area of fixed objects that has been invalidated
- for (auto& updateRect : regionToUpdate.rects()) {
+ Vector<IntRect> subRectsToUpdate = regionToUpdate.rects();
+ size_t viewportConstrainedObjectsCount = subRectsToUpdate.size();
+ for (size_t i = 0; i < viewportConstrainedObjectsCount; ++i) {
+ IntRect updateRect = subRectsToUpdate[i];
IntRect scrolledRect = updateRect;
scrolledRect.move(scrollDelta);
updateRect.unite(scrolledRect);
+#if USE(ACCELERATED_COMPOSITING)
if (isCompositedContentLayer) {
updateRect = rootViewToContents(updateRect);
ASSERT(renderView());
renderView()->layer()->setBackingNeedsRepaintInRect(updateRect);
continue;
}
+#endif
if (clipsRepaints())
updateRect.intersect(rectToScroll);
- hostWindow()->invalidateContentsAndRootView(updateRect);
+ hostWindow()->invalidateContentsAndRootView(updateRect, false);
}
return true;
@@ -1975,16 +1738,31 @@ bool FrameView::scrollContentsFastPath(const IntSize& scrollDelta, const IntRect
void FrameView::scrollContentsSlowPath(const IntRect& updateRect)
{
+#if USE(ACCELERATED_COMPOSITING)
+ if (contentsInCompositedLayer()) {
+ // FIXME: respect paintsEntireContents()?
+ IntRect updateRect = visibleContentRect(LegacyIOSDocumentVisibleRect);
+
+ // Make sure to "apply" the scale factor here since we're converting from frame view
+ // coordinates to layer backing coordinates.
+ updateRect.scale(1 / frame().frameScaleFactor());
+
+ ASSERT(renderView());
+ renderView()->layer()->setBackingNeedsRepaintInRect(updateRect);
+ }
+
repaintSlowRepaintObjects();
- if (!usesCompositedScrolling() && isEnclosedInCompositingLayer()) {
- if (RenderWidget* frameRenderer = frame().ownerRenderer()) {
- LayoutRect rect(frameRenderer->borderLeft() + frameRenderer->paddingLeft(), frameRenderer->borderTop() + frameRenderer->paddingTop(),
- visibleWidth(), visibleHeight());
+ if (RenderWidget* frameRenderer = frame().ownerRenderer()) {
+ if (isEnclosedInCompositingLayer()) {
+ LayoutRect rect(frameRenderer->borderLeft() + frameRenderer->paddingLeft(),
+ frameRenderer->borderTop() + frameRenderer->paddingTop(),
+ visibleWidth(), visibleHeight());
frameRenderer->repaintRectangle(rect);
return;
}
}
+#endif
ScrollView::scrollContentsSlowPath(updateRect);
}
@@ -1997,7 +1775,7 @@ void FrameView::repaintSlowRepaintObjects()
// Renderers with fixed backgrounds may be in compositing layers, so we need to explicitly
// repaint them after scrolling.
for (auto& renderer : *m_slowRepaintObjects)
- renderer->repaintSlowRepaintObject();
+ renderer->repaint();
}
// Note that this gets called at painting time.
@@ -2008,6 +1786,32 @@ void FrameView::setIsOverlapped(bool isOverlapped)
m_isOverlapped = isOverlapped;
updateCanBlitOnScrollRecursively();
+
+#if USE(ACCELERATED_COMPOSITING)
+ if (hasCompositedContentIncludingDescendants()) {
+ // Overlap can affect compositing tests, so if it changes, we need to trigger
+ // a layer update in the parent document.
+ if (Frame* parentFrame = frame().tree().parent()) {
+ if (RenderView* parentView = parentFrame->contentRenderer()) {
+ RenderLayerCompositor& compositor = parentView->compositor();
+ compositor.setCompositingLayersNeedRebuild();
+ compositor.scheduleCompositingLayerUpdate();
+ }
+ }
+
+ if (RenderLayerCompositor::allowsIndependentlyCompositedFrames(this)) {
+ // We also need to trigger reevaluation for this and all descendant frames,
+ // since a frame uses compositing if any ancestor is compositing.
+ for (Frame* frame = m_frame.get(); frame; frame = frame->tree().traverseNext(m_frame.get())) {
+ if (RenderView* view = frame->contentRenderer()) {
+ RenderLayerCompositor& compositor = view->compositor();
+ compositor.setCompositingLayersNeedRebuild();
+ compositor.scheduleCompositingLayerUpdate();
+ }
+ }
+ }
+ }
+#endif
}
bool FrameView::isOverlappedIncludingAncestors() const
@@ -2060,45 +1864,43 @@ bool FrameView::scrollToFragment(const URL& url)
bool FrameView::scrollToAnchor(const String& name)
{
ASSERT(frame().document());
- auto& document = *frame().document();
- if (!document.haveStylesheetsLoaded()) {
- document.setGotoAnchorNeededAfterStylesheetsLoad(true);
+ if (!frame().document()->haveStylesheetsLoaded()) {
+ frame().document()->setGotoAnchorNeededAfterStylesheetsLoad(true);
return false;
}
- document.setGotoAnchorNeededAfterStylesheetsLoad(false);
+ frame().document()->setGotoAnchorNeededAfterStylesheetsLoad(false);
- Element* anchorElement = document.findAnchor(name);
+ Element* anchorElement = frame().document()->findAnchor(name);
// Setting to null will clear the current target.
- document.setCSSTarget(anchorElement);
+ frame().document()->setCSSTarget(anchorElement);
- if (is<SVGDocument>(document)) {
- if (auto* rootElement = downcast<SVGDocument>(document).rootElement()) {
- rootElement->scrollToAnchor(name, anchorElement);
+#if ENABLE(SVG)
+ if (frame().document()->isSVGDocument()) {
+ if (SVGSVGElement* svg = toSVGDocument(frame().document())->rootElement()) {
+ svg->setupInitialView(name, anchorElement);
if (!anchorElement)
return true;
}
}
+#endif
// Implement the rule that "" and "top" both mean top of page as in other browsers.
- if (!anchorElement && !(name.isEmpty() || equalLettersIgnoringASCIICase(name, "top")))
+ if (!anchorElement && !(name.isEmpty() || equalIgnoringCase(name, "top")))
return false;
- ContainerNode* scrollPositionAnchor = anchorElement;
- if (!scrollPositionAnchor)
- scrollPositionAnchor = frame().document();
- maintainScrollPositionAtAnchor(scrollPositionAnchor);
+ maintainScrollPositionAtAnchor(anchorElement ? static_cast<Node*>(anchorElement) : frame().document());
// If the anchor accepts keyboard focus, move focus there to aid users relying on keyboard navigation.
if (anchorElement && anchorElement->isFocusable())
- document.setFocusedElement(anchorElement);
+ frame().document()->setFocusedElement(anchorElement);
return true;
}
-void FrameView::maintainScrollPositionAtAnchor(ContainerNode* anchorNode)
+void FrameView::maintainScrollPositionAtAnchor(Node* anchorNode)
{
m_maintainScrollPositionAnchor = anchorNode;
if (!m_maintainScrollPositionAnchor)
@@ -2115,36 +1917,33 @@ void FrameView::maintainScrollPositionAtAnchor(ContainerNode* anchorNode)
scrollToAnchor();
}
-void FrameView::scrollElementToRect(const Element& element, const IntRect& rect)
+void FrameView::scrollElementToRect(Element* element, const IntRect& rect)
{
frame().document()->updateLayoutIgnorePendingStylesheets();
- LayoutRect bounds;
- if (RenderElement* renderer = element.renderer())
- bounds = renderer->anchorRect();
+ LayoutRect bounds = element->boundingBox();
int centeringOffsetX = (rect.width() - bounds.width()) / 2;
int centeringOffsetY = (rect.height() - bounds.height()) / 2;
setScrollPosition(IntPoint(bounds.x() - centeringOffsetX - rect.x(), bounds.y() - centeringOffsetY - rect.y()));
}
-void FrameView::setScrollPosition(const ScrollPosition& scrollPosition)
+void FrameView::setScrollPosition(const IntPoint& scrollPoint)
{
TemporaryChange<bool> changeInProgrammaticScroll(m_inProgrammaticScroll, true);
- m_maintainScrollPositionAnchor = nullptr;
- Page* page = frame().page();
- if (page && page->expectsWheelEventTriggers())
- scrollAnimator().setWheelEventTestTrigger(page->testTrigger());
- ScrollView::setScrollPosition(scrollPosition);
+ m_maintainScrollPositionAnchor = 0;
+ ScrollView::setScrollPosition(scrollPoint);
}
void FrameView::delegatesScrollingDidChange()
{
+#if USE(ACCELERATED_COMPOSITING)
// When we switch to delgatesScrolling mode, we should destroy the scrolling/clipping layers in RenderLayerCompositor.
if (hasCompositedContent())
clearBackingStores();
+#endif
}
-#if USE(COORDINATED_GRAPHICS)
+#if USE(TILED_BACKING_STORE)
void FrameView::setFixedVisibleContentRect(const IntRect& visibleContentRect)
{
bool visibleContentSizeDidChange = false;
@@ -2155,21 +1954,20 @@ void FrameView::setFixedVisibleContentRect(const IntRect& visibleContentRect)
visibleContentSizeDidChange = true;
}
- IntPoint oldPosition = scrollPosition();
+ IntSize offset = scrollOffset();
ScrollView::setFixedVisibleContentRect(visibleContentRect);
- IntPoint newPosition = scrollPosition();
- if (oldPosition != newPosition) {
+ if (offset != scrollOffset()) {
updateLayerPositionsAfterScrolling();
- if (frame().settings().acceleratedCompositingForFixedPositionEnabled())
+ if (frame().page()->settings().acceleratedCompositingForFixedPositionEnabled())
updateCompositingLayersAfterScrolling();
- scrollAnimator().setCurrentPosition(newPosition);
- scrollPositionChanged(oldPosition, newPosition);
+ scrollAnimator()->setCurrentPosition(scrollPosition());
+ scrollPositionChanged();
}
if (visibleContentSizeDidChange) {
// Update the scroll-bars to calculate new page-step size.
- updateScrollbars(scrollPosition());
+ updateScrollbars(scrollOffset());
}
- didChangeScrollOffset();
+ frame().loader().client().didChangeScrollOffset();
}
#endif
@@ -2182,91 +1980,25 @@ void FrameView::setViewportConstrainedObjectsNeedLayout()
renderer->setNeedsLayout();
}
-void FrameView::didChangeScrollOffset()
-{
- frame().mainFrame().pageOverlayController().didScrollFrame(frame());
- frame().loader().client().didChangeScrollOffset();
-}
-
-void FrameView::scrollOffsetChangedViaPlatformWidgetImpl(const ScrollOffset& oldOffset, const ScrollOffset& newOffset)
+void FrameView::scrollPositionChangedViaPlatformWidget()
{
updateLayerPositionsAfterScrolling();
updateCompositingLayersAfterScrolling();
repaintSlowRepaintObjects();
- scrollPositionChanged(scrollPositionFromOffset(oldOffset), scrollPositionFromOffset(newOffset));
+ scrollPositionChanged();
}
-void FrameView::scrollPositionChanged(const ScrollPosition& oldPosition, const ScrollPosition& newPosition)
+void FrameView::scrollPositionChanged()
{
- Page* page = frame().page();
- auto throttlingDelay = page ? page->chrome().client().eventThrottlingDelay() : std::chrono::milliseconds::zero();
-
- if (throttlingDelay == std::chrono::milliseconds::zero()) {
- m_delayedScrollEventTimer.stop();
- sendScrollEvent();
- } else if (!m_delayedScrollEventTimer.isActive())
- m_delayedScrollEventTimer.startOneShot(throttlingDelay);
-
- if (Document* document = frame().document())
- document->sendWillRevealEdgeEventsIfNeeded(oldPosition, newPosition, visibleContentRect(), contentsSize());
+ frame().eventHandler().sendScrollEvent();
+ frame().eventHandler().dispatchFakeMouseMoveEventSoon();
+#if USE(ACCELERATED_COMPOSITING)
if (RenderView* renderView = this->renderView()) {
if (renderView->usesCompositing())
renderView->compositor().frameViewDidScroll();
}
-
- viewportContentsChanged();
-}
-
-void FrameView::applyRecursivelyWithVisibleRect(const std::function<void (FrameView& frameView, const IntRect& visibleRect)>& apply)
-{
- IntRect windowClipRect = this->windowClipRect();
- auto visibleRect = windowToContents(windowClipRect);
- apply(*this, visibleRect);
-
- // Recursive call for subframes. We cache the current FrameView's windowClipRect to avoid recomputing it for every subframe.
- TemporaryChange<IntRect*> windowClipRectCache(m_cachedWindowClipRect, &windowClipRect);
- for (Frame* childFrame = frame().tree().firstChild(); childFrame; childFrame = childFrame->tree().nextSibling()) {
- if (auto* childView = childFrame->view())
- childView->applyRecursivelyWithVisibleRect(apply);
- }
-}
-
-void FrameView::resumeVisibleImageAnimations(const IntRect& visibleRect)
-{
- if (visibleRect.isEmpty())
- return;
-
- if (auto* renderView = frame().contentRenderer())
- renderView->resumePausedImageAnimationsIfNeeded(visibleRect);
-}
-
-void FrameView::updateScriptedAnimationsAndTimersThrottlingState(const IntRect& visibleRect)
-{
- if (frame().isMainFrame())
- return;
-
- auto* document = frame().document();
- if (!document)
- return;
-
- // We don't throttle zero-size or display:none frames because those are usually utility frames.
- bool shouldThrottle = visibleRect.isEmpty() && !m_size.isEmpty() && frame().ownerRenderer();
-
-#if ENABLE(REQUEST_ANIMATION_FRAME)
- if (auto* scriptedAnimationController = document->scriptedAnimationController())
- scriptedAnimationController->setThrottled(shouldThrottle);
#endif
-
- document->setTimerThrottlingEnabled(shouldThrottle);
-}
-
-
-void FrameView::resumeVisibleImageAnimationsIncludingSubframes()
-{
- applyRecursivelyWithVisibleRect([] (FrameView& frameView, const IntRect& visibleRect) {
- frameView.resumeVisibleImageAnimations(visibleRect);
- });
}
void FrameView::updateLayerPositionsAfterScrolling()
@@ -2292,7 +2024,7 @@ bool FrameView::shouldUpdateCompositingLayersAfterScrolling() const
if (!page)
return true;
- if (&page->mainFrame() != m_frame.ptr())
+ if (&page->mainFrame() != &frame())
return true;
ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator();
@@ -2315,8 +2047,7 @@ bool FrameView::shouldUpdateCompositingLayersAfterScrolling() const
void FrameView::updateCompositingLayersAfterScrolling()
{
- ASSERT(m_layoutPhase >= InPostLayout || m_layoutPhase == OutsideLayout);
-
+#if USE(ACCELERATED_COMPOSITING)
if (!shouldUpdateCompositingLayersAfterScrolling())
return;
@@ -2324,6 +2055,7 @@ void FrameView::updateCompositingLayersAfterScrolling()
if (RenderView* renderView = this->renderView())
renderView->compositor().updateCompositingLayers(CompositingUpdateOnScroll);
}
+#endif
}
bool FrameView::isRubberBandInProgress() const
@@ -2348,19 +2080,18 @@ bool FrameView::isRubberBandInProgress() const
return false;
}
-bool FrameView::requestScrollPositionUpdate(const ScrollPosition& position)
+bool FrameView::requestScrollPositionUpdate(const IntPoint& position)
{
- LOG_WITH_STREAM(Scrolling, stream << "FrameView::requestScrollPositionUpdate " << position);
-
#if ENABLE(ASYNC_SCROLLING)
- if (TiledBacking* tiledBacking = this->tiledBacking())
- tiledBacking->prepopulateRect(FloatRect(position, visibleContentRect().size()));
-#endif
+ if (TiledBacking* tiledBacking = this->tiledBacking()) {
+ IntRect visibleRect = visibleContentRect();
+ visibleRect.setLocation(position);
+ tiledBacking->prepopulateRect(visibleRect);
+ }
-#if ENABLE(ASYNC_SCROLLING) || USE(COORDINATED_GRAPHICS)
if (Page* page = frame().page()) {
if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
- return scrollingCoordinator->requestScrollPositionUpdate(*this, position);
+ return scrollingCoordinator->requestScrollPositionUpdate(this, position);
}
#else
UNUSED_PARAM(position);
@@ -2373,64 +2104,72 @@ HostWindow* FrameView::hostWindow() const
{
if (Page* page = frame().page())
return &page->chrome();
- return nullptr;
+ return 0;
}
-void FrameView::addTrackedRepaintRect(const FloatRect& r)
+void FrameView::addTrackedRepaintRect(const IntRect& r)
{
if (!m_isTrackingRepaints || r.isEmpty())
return;
- FloatRect repaintRect = r;
- repaintRect.moveBy(-scrollPosition());
+ IntRect repaintRect = r;
+ repaintRect.move(-scrollOffset());
m_trackedRepaintRects.append(repaintRect);
}
-void FrameView::repaintContentRectangle(const IntRect& r)
+void FrameView::repaintContentRectangle(const IntRect& r, bool immediate)
{
ASSERT(!frame().ownerElement());
- if (!shouldUpdate())
+ if (!shouldUpdate(immediate))
return;
- ScrollView::repaintContentRectangle(r);
+#if USE(TILED_BACKING_STORE)
+ if (frame().tiledBackingStore()) {
+ frame().tiledBackingStore()->invalidate(r);
+ return;
+ }
+#endif
+ ScrollView::repaintContentRectangle(r, immediate);
}
-static unsigned countRenderedCharactersInRenderObjectWithThreshold(const RenderElement& renderer, unsigned threshold)
+static unsigned countRenderedCharactersInRenderObjectWithThreshold(const RenderObject& renderer, unsigned countSoFar, unsigned threshold)
{
- unsigned count = 0;
- for (const RenderObject* descendant = &renderer; descendant; descendant = descendant->nextInPreOrder()) {
- if (is<RenderText>(*descendant)) {
- count += downcast<RenderText>(*descendant).text()->length();
- if (count >= threshold)
- break;
- }
+ // FIXME: Consider writing this using RenderObject::nextInPreOrder() instead of using recursion.
+ if (renderer.isText())
+ countSoFar += toRenderText(renderer).text()->length();
+
+ for (RenderObject* child = renderer.firstChildSlow(); child; child = child->nextSibling()) {
+ if (countSoFar >= threshold)
+ break;
+ countSoFar = countRenderedCharactersInRenderObjectWithThreshold(*child, countSoFar, threshold);
}
- return count;
+ return countSoFar;
}
bool FrameView::renderedCharactersExceed(unsigned threshold)
{
- if (!frame().contentRenderer())
+ if (!m_frame->contentRenderer())
return false;
- return countRenderedCharactersInRenderObjectWithThreshold(*frame().contentRenderer(), threshold) >= threshold;
+ return countRenderedCharactersInRenderObjectWithThreshold(*m_frame->contentRenderer(), 0, threshold) >= threshold;
}
-void FrameView::availableContentSizeChanged(AvailableSizeChangeReason reason)
+void FrameView::contentsResized()
{
- if (Document* document = frame().document())
- document->updateViewportUnitsOnResize();
-
+ ScrollView::contentsResized();
setNeedsLayout();
- ScrollView::availableContentSizeChanged(reason);
}
-bool FrameView::shouldLayoutAfterContentsResized() const
+void FrameView::fixedLayoutSizeChanged()
{
- return !useFixedLayout() || useCustomFixedPositionLayoutRect();
+ // Can be triggered before the view is set, see comment in FrameView::visibleContentsResized().
+ // An ASSERT is triggered when a view schedules a layout before being attached to a frame.
+ if (!frame().view())
+ return;
+ ScrollView::fixedLayoutSizeChanged();
}
-void FrameView::updateContentsSize()
+void FrameView::visibleContentsResized()
{
// We check to make sure the view is attached to a frame() as this method can
// be triggered before the view is attached by Frame::createView(...) setting
@@ -2451,76 +2190,44 @@ void FrameView::updateContentsSize()
}
#endif
- if (shouldLayoutAfterContentsResized() && needsLayout())
+ if (!useFixedLayout() && needsLayout())
layout();
+#if USE(ACCELERATED_COMPOSITING)
if (RenderView* renderView = this->renderView()) {
if (renderView->usesCompositing())
renderView->compositor().frameViewDidChangeSize();
}
+#endif
}
void FrameView::addedOrRemovedScrollbar()
{
+#if USE(ACCELERATED_COMPOSITING)
if (RenderView* renderView = this->renderView()) {
if (renderView->usesCompositing())
renderView->compositor().frameViewDidAddOrRemoveScrollbars();
}
-}
-
-static LayerFlushThrottleState::Flags determineLayerFlushThrottleState(Page& page)
-{
- // We only throttle when constantly receiving new data during the inital page load.
- if (!page.progress().isMainLoadProgressing())
- return 0;
- // Scrolling during page loading disables throttling.
- if (page.mainFrame().view()->wasScrolledByUser())
- return 0;
- // Disable for image documents so large GIF animations don't get throttled during loading.
- auto* document = page.mainFrame().document();
- if (!document || is<ImageDocument>(*document))
- return 0;
- return LayerFlushThrottleState::Enabled;
+#endif
}
void FrameView::disableLayerFlushThrottlingTemporarilyForInteraction()
{
- if (!frame().page())
- return;
- auto& page = *frame().page();
-
- LayerFlushThrottleState::Flags flags = LayerFlushThrottleState::UserIsInteracting | determineLayerFlushThrottleState(page);
- if (page.chrome().client().adjustLayerFlushThrottling(flags))
- return;
-
+#if USE(ACCELERATED_COMPOSITING)
if (RenderView* view = renderView())
view->compositor().disableLayerFlushThrottlingTemporarilyForInteraction();
+#endif
}
-void FrameView::loadProgressingStatusChanged()
-{
- updateLayerFlushThrottling();
- adjustTiledBackingCoverage();
-}
-
-void FrameView::updateLayerFlushThrottling()
+void FrameView::updateLayerFlushThrottlingInAllFrames()
{
- Page* page = frame().page();
- if (!page)
- return;
-
- ASSERT(frame().isMainFrame());
-
- LayerFlushThrottleState::Flags flags = determineLayerFlushThrottleState(*page);
-
- // See if the client is handling throttling.
- if (page->chrome().client().adjustLayerFlushThrottling(flags))
- return;
-
- for (auto* frame = m_frame.ptr(); frame; frame = frame->tree().traverseNext(m_frame.ptr())) {
+#if USE(ACCELERATED_COMPOSITING)
+ bool isMainLoadProgressing = frame().page()->progress().isMainLoadProgressing();
+ for (Frame* frame = m_frame.get(); frame; frame = frame->tree().traverseNext(m_frame.get())) {
if (RenderView* renderView = frame->contentRenderer())
- renderView->compositor().setLayerFlushThrottlingEnabled(flags & LayerFlushThrottleState::Enabled);
+ renderView->compositor().setLayerFlushThrottlingEnabled(isMainLoadProgressing);
}
+#endif
}
void FrameView::adjustTiledBackingCoverage()
@@ -2528,19 +2235,20 @@ void FrameView::adjustTiledBackingCoverage()
if (!m_speculativeTilingEnabled)
enableSpeculativeTilingIfNeeded();
+#if USE(ACCELERATED_COMPOSITING)
RenderView* renderView = this->renderView();
if (renderView && renderView->layer()->backing())
renderView->layer()->backing()->adjustTiledBackingCoverage();
+#endif
#if PLATFORM(IOS)
- if (LegacyTileCache* tileCache = legacyTileCache())
+ if (TileCache* tileCache = this->tileCache())
tileCache->setSpeculativeTileCreationEnabled(m_speculativeTilingEnabled);
#endif
}
static bool shouldEnableSpeculativeTilingDuringLoading(const FrameView& view)
{
- Page* page = view.frame().page();
- return page && view.isVisuallyNonEmpty() && !page->progress().isMainLoadProgressing();
+ return view.isVisuallyNonEmpty() && !view.frame().page()->progress().isMainLoadProgressing();
}
void FrameView::enableSpeculativeTilingIfNeeded()
@@ -2559,7 +2267,7 @@ void FrameView::enableSpeculativeTilingIfNeeded()
m_speculativeTilingEnableTimer.startOneShot(speculativeTilingEnableDelay);
}
-void FrameView::speculativeTilingEnableTimerFired()
+void FrameView::speculativeTilingEnableTimerFired(Timer<FrameView>&)
{
if (m_speculativeTilingEnabled)
return;
@@ -2567,26 +2275,7 @@ void FrameView::speculativeTilingEnableTimerFired()
adjustTiledBackingCoverage();
}
-void FrameView::show()
-{
- ScrollView::show();
-
- if (frame().isMainFrame()) {
- // Turn off speculative tiling for a brief moment after a FrameView appears on screen.
- // Note that adjustTiledBackingCoverage() kicks the (500ms) timer to re-enable it.
- m_speculativeTilingEnabled = false;
- m_wasScrolledByUser = false;
- adjustTiledBackingCoverage();
- }
-}
-void FrameView::convertSubtreeLayoutToFullLayout()
-{
- ASSERT(m_layoutRoot);
- m_layoutRoot->markContainingBlocksForLayout(ScheduleRelayout::No);
- m_layoutRoot = nullptr;
-}
-
-void FrameView::layoutTimerFired()
+void FrameView::layoutTimerFired(Timer<FrameView>&)
{
#ifdef INSTRUMENT_LAYOUT_SCHEDULING
if (!frame().document()->ownerElement())
@@ -2601,15 +2290,17 @@ void FrameView::scheduleRelayout()
// too many false assertions. See <rdar://problem/7218118>.
ASSERT(frame().view() == this);
- if (m_layoutRoot)
- convertSubtreeLayoutToFullLayout();
+ if (m_layoutRoot) {
+ m_layoutRoot->markContainingBlocksForLayout(false);
+ m_layoutRoot = 0;
+ }
if (!m_layoutSchedulingEnabled)
return;
if (!needsLayout())
return;
if (!frame().document()->shouldScheduleLayout())
return;
- InspectorInstrumentation::didInvalidateLayout(frame());
+ InspectorInstrumentation::didInvalidateLayout(&frame());
// When frame flattening is enabled, the contents of the frame could affect the layout of the parent frames.
// Also invalidate parent frame starting from the owner element of this frame.
if (frame().ownerRenderer() && isInChildFrameWithFrameFlattening())
@@ -2643,15 +2334,14 @@ static bool isObjectAncestorContainerOf(RenderObject* ancestor, RenderObject* de
void FrameView::scheduleRelayoutOfSubtree(RenderElement& newRelayoutRoot)
{
ASSERT(renderView());
- const RenderView& renderView = *this->renderView();
+ RenderView& renderView = *this->renderView();
// Try to catch unnecessary work during render tree teardown.
ASSERT(!renderView.documentBeingDestroyed());
ASSERT(frame().view() == this);
if (renderView.needsLayout()) {
- m_layoutRoot = &newRelayoutRoot;
- convertSubtreeLayoutToFullLayout();
+ newRelayoutRoot.markContainingBlocksForLayout(false);
return;
}
@@ -2659,7 +2349,7 @@ void FrameView::scheduleRelayoutOfSubtree(RenderElement& newRelayoutRoot)
std::chrono::milliseconds delay = renderView.document().minimumLayoutDelay();
ASSERT(!newRelayoutRoot.container() || !newRelayoutRoot.container()->needsLayout());
m_layoutRoot = &newRelayoutRoot;
- InspectorInstrumentation::didInvalidateLayout(frame());
+ InspectorInstrumentation::didInvalidateLayout(&frame());
m_delayedLayout = delay.count();
m_layoutTimer.startOneShot(delay);
return;
@@ -2669,31 +2359,33 @@ void FrameView::scheduleRelayoutOfSubtree(RenderElement& newRelayoutRoot)
return;
if (!m_layoutRoot) {
- // We already have a pending (full) layout. Just mark the subtree for layout.
- newRelayoutRoot.markContainingBlocksForLayout(ScheduleRelayout::No);
- InspectorInstrumentation::didInvalidateLayout(frame());
+ // Just relayout the subtree.
+ newRelayoutRoot.markContainingBlocksForLayout(false);
+ InspectorInstrumentation::didInvalidateLayout(&frame());
return;
}
if (isObjectAncestorContainerOf(m_layoutRoot, &newRelayoutRoot)) {
// Keep the current root.
- newRelayoutRoot.markContainingBlocksForLayout(ScheduleRelayout::No, m_layoutRoot);
+ newRelayoutRoot.markContainingBlocksForLayout(false, m_layoutRoot);
ASSERT(!m_layoutRoot->container() || !m_layoutRoot->container()->needsLayout());
return;
}
if (isObjectAncestorContainerOf(&newRelayoutRoot, m_layoutRoot)) {
// Re-root at newRelayoutRoot.
- m_layoutRoot->markContainingBlocksForLayout(ScheduleRelayout::No, &newRelayoutRoot);
+ m_layoutRoot->markContainingBlocksForLayout(false, &newRelayoutRoot);
m_layoutRoot = &newRelayoutRoot;
ASSERT(!m_layoutRoot->container() || !m_layoutRoot->container()->needsLayout());
- InspectorInstrumentation::didInvalidateLayout(frame());
+ InspectorInstrumentation::didInvalidateLayout(&frame());
return;
}
- // Two disjoint subtrees need layout. Mark both of them and issue a full layout instead.
- convertSubtreeLayoutToFullLayout();
- newRelayoutRoot.markContainingBlocksForLayout(ScheduleRelayout::No);
- InspectorInstrumentation::didInvalidateLayout(frame());
+
+ // Just do a full relayout.
+ m_layoutRoot->markContainingBlocksForLayout(false);
+ m_layoutRoot = 0;
+ newRelayoutRoot.markContainingBlocksForLayout(false);
+ InspectorInstrumentation::didInvalidateLayout(&frame());
}
bool FrameView::layoutPending() const
@@ -2701,25 +2393,6 @@ bool FrameView::layoutPending() const
return m_layoutTimer.isActive();
}
-bool FrameView::needsStyleRecalcOrLayout(bool includeSubframes) const
-{
- if (frame().document() && frame().document()->childNeedsStyleRecalc())
- return true;
-
- if (needsLayout())
- return true;
-
- if (!includeSubframes)
- return false;
-
- for (auto& frameView : renderedChildFrameViews()) {
- if (frameView->needsStyleRecalcOrLayout())
- return true;
- }
-
- return false;
-}
-
bool FrameView::needsLayout() const
{
// This can return true in cases where the document does not have a body yet.
@@ -2729,12 +2402,12 @@ bool FrameView::needsLayout() const
return layoutPending()
|| (renderView && renderView->needsLayout())
|| m_layoutRoot
- || (m_deferSetNeedsLayoutCount && m_setNeedsLayoutWasDeferred);
+ || (m_deferSetNeedsLayouts && m_setNeedsLayoutWasDeferred);
}
void FrameView::setNeedsLayout()
{
- if (m_deferSetNeedsLayoutCount) {
+ if (m_deferSetNeedsLayouts) {
m_setNeedsLayoutWasDeferred = true;
return;
}
@@ -2745,9 +2418,6 @@ void FrameView::setNeedsLayout()
void FrameView::unscheduleRelayout()
{
- if (m_postLayoutTasksTimer.isActive())
- m_postLayoutTasksTimer.stop();
-
if (!m_layoutTimer.isActive())
return;
@@ -2763,17 +2433,17 @@ void FrameView::unscheduleRelayout()
#if ENABLE(REQUEST_ANIMATION_FRAME)
void FrameView::serviceScriptedAnimations(double monotonicAnimationStartTime)
{
- for (auto* frame = m_frame.ptr(); frame; frame = frame->tree().traverseNext()) {
+ for (Frame* frame = m_frame.get(); frame; frame = frame->tree().traverseNext()) {
frame->view()->serviceScrollAnimations();
frame->animation().serviceAnimations();
}
Vector<RefPtr<Document>> documents;
- for (auto* frame = m_frame.ptr(); frame; frame = frame->tree().traverseNext())
+ for (Frame* frame = m_frame.get(); frame; frame = frame->tree().traverseNext())
documents.append(frame->document());
- for (auto& document : documents)
- document->serviceScriptedAnimations(monotonicAnimationStartTime);
+ for (size_t i = 0; i < documents.size(); ++i)
+ documents[i]->serviceScriptedAnimations(monotonicAnimationStartTime);
}
#endif
@@ -2784,19 +2454,7 @@ bool FrameView::isTransparent() const
void FrameView::setTransparent(bool isTransparent)
{
- if (m_isTransparent == isTransparent)
- return;
-
m_isTransparent = isTransparent;
-
- // setTransparent can be called in the window between FrameView initialization
- // and switching in the new Document; this means that the RenderView that we
- // retrieve is actually attached to the previous Document, which is going away,
- // and must not update compositing layers.
- if (!isViewForDocumentInFrame())
- return;
-
- renderView()->compositor().rootBackgroundTransparencyChanged();
}
bool FrameView::hasOpaqueBackground() const
@@ -2811,25 +2469,17 @@ Color FrameView::baseBackgroundColor() const
void FrameView::setBaseBackgroundColor(const Color& backgroundColor)
{
- bool hadAlpha = m_baseBackgroundColor.hasAlpha();
-
if (!backgroundColor.isValid())
m_baseBackgroundColor = Color::white;
else
m_baseBackgroundColor = backgroundColor;
- if (!isViewForDocumentInFrame())
- return;
-
recalculateScrollbarOverlayStyle();
-
- if (m_baseBackgroundColor.hasAlpha() != hadAlpha)
- renderView()->compositor().rootBackgroundTransparencyChanged();
}
void FrameView::updateBackgroundRecursively(const Color& backgroundColor, bool transparent)
{
- for (auto* frame = m_frame.ptr(); frame; frame = frame->tree().traverseNext(m_frame.ptr())) {
+ for (Frame* frame = m_frame.get(); frame; frame = frame->tree().traverseNext(m_frame.get())) {
if (FrameView* view = frame->view()) {
view->setTransparent(transparent);
view->setBaseBackgroundColor(backgroundColor);
@@ -2837,8 +2487,9 @@ void FrameView::updateBackgroundRecursively(const Color& backgroundColor, bool t
}
}
-bool FrameView::hasExtendedBackgroundRectForPainting() const
+bool FrameView::hasExtendedBackground() const
{
+#if USE(ACCELERATED_COMPOSITING)
if (!frame().settings().backgroundShouldExtendBeyondPage())
return false;
@@ -2847,64 +2498,31 @@ bool FrameView::hasExtendedBackgroundRectForPainting() const
return false;
return tiledBacking->hasMargins();
+#else
+ return false;
+#endif
}
-void FrameView::updateExtendBackgroundIfNecessary()
-{
- ExtendedBackgroundMode mode = calculateExtendedBackgroundMode();
- if (mode == ExtendedBackgroundModeNone)
- return;
-
- updateTilesForExtendedBackgroundMode(mode);
-}
-
-FrameView::ExtendedBackgroundMode FrameView::calculateExtendedBackgroundMode() const
+IntRect FrameView::extendedBackgroundRect() const
{
- // Just because Settings::backgroundShouldExtendBeyondPage() is true does not necessarily mean
- // that the background rect needs to be extended for painting. Simple backgrounds can be extended
- // just with RenderLayerCompositor::setRootExtendedBackgroundColor(). More complicated backgrounds,
- // such as images, require extending the background rect to continue painting into the extended
- // region. This function finds out if it is necessary to extend the background rect for painting.
+#if USE(ACCELERATED_COMPOSITING)
+ TiledBacking* tiledBacking = this->tiledBacking();
+ if (!tiledBacking)
+ return IntRect();
-#if PLATFORM(IOS)
- // <rdar://problem/16201373>
- return ExtendedBackgroundModeNone;
+ return tiledBacking->bounds();
#else
- if (!frame().settings().backgroundShouldExtendBeyondPage())
- return ExtendedBackgroundModeNone;
-
- if (!frame().isMainFrame())
- return ExtendedBackgroundModeNone;
-
- Document* document = frame().document();
- if (!document)
- return ExtendedBackgroundModeNone;
-
- auto* documentElement = document->documentElement();
- auto* documentElementRenderer = documentElement ? documentElement->renderer() : nullptr;
- if (!documentElementRenderer)
- return ExtendedBackgroundModeNone;
-
- auto& renderer = documentElementRenderer->rendererForRootBackground();
- if (!renderer.style().hasBackgroundImage())
- return ExtendedBackgroundModeNone;
-
- ExtendedBackgroundMode mode = ExtendedBackgroundModeNone;
-
- if (renderer.style().backgroundRepeatX() == RepeatFill)
- mode |= ExtendedBackgroundModeHorizontal;
- if (renderer.style().backgroundRepeatY() == RepeatFill)
- mode |= ExtendedBackgroundModeVertical;
+ RenderView* renderView = this->renderView();
+ if (!renderView)
+ return IntRect();
- return mode;
+ return renderView->unscaledDocumentRect();
#endif
}
-void FrameView::updateTilesForExtendedBackgroundMode(ExtendedBackgroundMode mode)
+#if USE(ACCELERATED_COMPOSITING)
+void FrameView::setBackgroundExtendsBeyondPage(bool extendBackground)
{
- if (!frame().settings().backgroundShouldExtendBeyondPage())
- return;
-
RenderView* renderView = this->renderView();
if (!renderView)
return;
@@ -2913,41 +2531,9 @@ void FrameView::updateTilesForExtendedBackgroundMode(ExtendedBackgroundMode mode
if (!backing)
return;
- TiledBacking* tiledBacking = backing->graphicsLayer()->tiledBacking();
- if (!tiledBacking)
- return;
-
- ExtendedBackgroundMode existingMode = ExtendedBackgroundModeNone;
- if (tiledBacking->hasVerticalMargins())
- existingMode |= ExtendedBackgroundModeVertical;
- if (tiledBacking->hasHorizontalMargins())
- existingMode |= ExtendedBackgroundModeHorizontal;
-
- if (existingMode == mode)
- return;
-
- renderView->compositor().setRootExtendedBackgroundColor(mode == ExtendedBackgroundModeAll ? Color() : documentBackgroundColor());
- backing->setTiledBackingHasMargins(mode & ExtendedBackgroundModeHorizontal, mode & ExtendedBackgroundModeVertical);
-}
-
-IntRect FrameView::extendedBackgroundRectForPainting() const
-{
- TiledBacking* tiledBacking = this->tiledBacking();
- if (!tiledBacking)
- return IntRect();
-
- RenderView* renderView = this->renderView();
- if (!renderView)
- return IntRect();
-
- LayoutRect extendedRect = renderView->unextendedBackgroundRect();
- if (!tiledBacking->hasMargins())
- return snappedIntRect(extendedRect);
-
- extendedRect.moveBy(LayoutPoint(-tiledBacking->leftMarginWidth(), -tiledBacking->topMarginHeight()));
- extendedRect.expand(LayoutSize(tiledBacking->leftMarginWidth() + tiledBacking->rightMarginWidth(), tiledBacking->topMarginHeight() + tiledBacking->bottomMarginHeight()));
- return snappedIntRect(extendedRect);
+ backing->setTiledBackingHasMargins(extendBackground);
}
+#endif
bool FrameView::shouldUpdateWhileOffscreen() const
{
@@ -2959,16 +2545,16 @@ void FrameView::setShouldUpdateWhileOffscreen(bool shouldUpdateWhileOffscreen)
m_shouldUpdateWhileOffscreen = shouldUpdateWhileOffscreen;
}
-bool FrameView::shouldUpdate() const
+bool FrameView::shouldUpdate(bool immediateRequested) const
{
- if (isOffscreen() && !shouldUpdateWhileOffscreen())
+ if (!immediateRequested && isOffscreen() && !shouldUpdateWhileOffscreen())
return false;
return true;
}
void FrameView::scrollToAnchor()
{
- RefPtr<ContainerNode> anchorNode = m_maintainScrollPositionAnchor;
+ RefPtr<Node> anchorNode = m_maintainScrollPositionAnchor;
if (!anchorNode)
return;
@@ -2976,17 +2562,12 @@ void FrameView::scrollToAnchor()
return;
LayoutRect rect;
- if (anchorNode != frame().document() && anchorNode->renderer())
- rect = anchorNode->renderer()->anchorRect();
+ if (anchorNode != frame().document())
+ rect = anchorNode->boundingBox();
// Scroll nested layers and frames to reveal the anchor.
// Align to the top and to the closest side (this matches other browsers).
- if (anchorNode->renderer()->style().isHorizontalWritingMode())
- anchorNode->renderer()->scrollRectToVisible(rect, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignTopAlways);
- else if (anchorNode->renderer()->style().isFlippedBlocksWritingMode())
- anchorNode->renderer()->scrollRectToVisible(rect, ScrollAlignment::alignRightAlways, ScrollAlignment::alignToEdgeIfNeeded);
- else
- anchorNode->renderer()->scrollRectToVisible(rect, ScrollAlignment::alignLeftAlways, ScrollAlignment::alignToEdgeIfNeeded);
+ anchorNode->renderer()->scrollRectToVisible(rect, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignTopAlways);
if (AXObjectCache* cache = frame().document()->existingAXObjectCache())
cache->handleScrolledToAnchor(anchorNode.get());
@@ -3004,8 +2585,8 @@ void FrameView::updateEmbeddedObject(RenderEmbeddedObject& embeddedObject)
HTMLFrameOwnerElement& element = embeddedObject.frameOwnerElement();
if (embeddedObject.isSnapshottedPlugIn()) {
- if (is<HTMLObjectElement>(element) || is<HTMLEmbedElement>(element)) {
- HTMLPlugInImageElement& pluginElement = downcast<HTMLPlugInImageElement>(element);
+ if (isHTMLObjectElement(element) || isHTMLEmbedElement(element)) {
+ HTMLPlugInImageElement& pluginElement = toHTMLPlugInImageElement(element);
pluginElement.checkSnapshotStatus();
}
return;
@@ -3015,23 +2596,29 @@ void FrameView::updateEmbeddedObject(RenderEmbeddedObject& embeddedObject)
// FIXME: This could turn into a real virtual dispatch if we defined
// updateWidget(PluginCreationOption) on HTMLElement.
- if (is<HTMLPlugInImageElement>(element)) {
- HTMLPlugInImageElement& pluginElement = downcast<HTMLPlugInImageElement>(element);
+ if (isHTMLObjectElement(element) || isHTMLEmbedElement(element) || isHTMLAppletElement(element)) {
+ HTMLPlugInImageElement& pluginElement = toHTMLPlugInImageElement(element);
if (pluginElement.needsCheckForSizeChange()) {
pluginElement.checkSnapshotStatus();
return;
}
if (pluginElement.needsWidgetUpdate())
pluginElement.updateWidget(CreateAnyWidgetType);
- } else
+ }
+
+ // FIXME: It is not clear that Media elements need or want this updateWidget() call.
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+ else if (element.isMediaElement())
+ toHTMLMediaElement(element).updateWidget(CreateAnyWidgetType);
+#endif
+ else
ASSERT_NOT_REACHED();
// It's possible the renderer was destroyed below updateWidget() since loading a plugin may execute arbitrary JavaScript.
if (!weakRenderer)
return;
- auto ignoreWidgetState = embeddedObject.updateWidgetPosition();
- UNUSED_PARAM(ignoreWidgetState);
+ embeddedObject.updateWidgetPosition();
}
bool FrameView::updateEmbeddedObjects()
@@ -3055,7 +2642,7 @@ bool FrameView::updateEmbeddedObjects()
return m_embeddedObjectsToUpdate->isEmpty();
}
-void FrameView::updateEmbeddedObjectsTimerFired()
+void FrameView::updateEmbeddedObjectsTimerFired(Timer<FrameView>*)
{
RefPtr<FrameView> protect(this);
m_updateEmbeddedObjectsTimer.stop();
@@ -3070,56 +2657,57 @@ void FrameView::flushAnyPendingPostLayoutTasks()
if (m_postLayoutTasksTimer.isActive())
performPostLayoutTasks();
if (m_updateEmbeddedObjectsTimer.isActive())
- updateEmbeddedObjectsTimerFired();
-}
-
-void FrameView::queuePostLayoutCallback(std::function<void()> callback)
-{
- m_postLayoutCallbackQueue.append(callback);
-}
-
-void FrameView::flushPostLayoutTasksQueue()
-{
- if (m_nestedLayoutCount > 1)
- return;
-
- if (!m_postLayoutCallbackQueue.size())
- return;
-
- const auto queue = m_postLayoutCallbackQueue;
- m_postLayoutCallbackQueue.clear();
- for (size_t i = 0; i < queue.size(); ++i)
- queue[i]();
+ updateEmbeddedObjectsTimerFired(nullptr);
}
void FrameView::performPostLayoutTasks()
{
- LOG(Layout, "FrameView %p performPostLayoutTasks", this);
-
// FIXME: We should not run any JavaScript code in this function.
m_postLayoutTasksTimer.stop();
- frame().selection().updateAppearanceAfterLayout();
+ frame().selection().setCaretRectNeedsUpdate();
+ frame().selection().updateAppearance();
+
+ LayoutMilestones requestedMilestones = 0;
+ LayoutMilestones milestonesAchieved = 0;
+ Page* page = frame().page();
+ if (page)
+ requestedMilestones = page->requestedLayoutMilestones();
- flushPostLayoutTasksQueue();
+ if (m_nestedLayoutCount <= 1 && frame().document()->documentElement()) {
+ if (m_firstLayoutCallbackPending) {
+ m_firstLayoutCallbackPending = false;
+ frame().loader().didFirstLayout();
+ if (requestedMilestones & DidFirstLayout)
+ milestonesAchieved |= DidFirstLayout;
+ if (frame().isMainFrame())
+ page->startCountingRelevantRepaintedObjects();
+ }
+ updateIsVisuallyNonEmpty();
- if (m_nestedLayoutCount <= 1 && frame().document()->documentElement())
- fireLayoutRelatedMilestonesIfNeeded();
+ // If the layout was done with pending sheets, we are not in fact visually non-empty yet.
+ if (m_isVisuallyNonEmpty && !frame().document()->didLayoutWithPendingStylesheets() && m_firstVisuallyNonEmptyLayoutCallbackPending) {
+ m_firstVisuallyNonEmptyLayoutCallbackPending = false;
+ if (requestedMilestones & DidFirstVisuallyNonEmptyLayout)
+ milestonesAchieved |= DidFirstVisuallyNonEmptyLayout;
+ }
+ }
#if PLATFORM(IOS)
// Only send layout-related delegate callbacks synchronously for the main frame to
// avoid re-entering layout for the main frame while delivering a layout-related delegate
// callback for a subframe.
- if (frame().isMainFrame()) {
- if (Page* page = frame().page())
- page->chrome().client().didLayout();
- }
+ if (frame().isMainFrame())
+ page->chrome().client().didLayout();
#endif
+ if (milestonesAchieved && frame().isMainFrame())
+ frame().loader().didLayout(milestonesAchieved);
+
#if ENABLE(FONT_LOAD_EVENTS)
if (RuntimeEnabledFeatures::sharedFeatures().fontLoadEventsEnabled())
- frame().document()->fonts()->didLayout();
+ frame().document()->fontloader()->didLayout();
#endif
// FIXME: We should consider adding DidLayout as a LayoutMilestone. That would let us merge this
@@ -3127,68 +2715,51 @@ void FrameView::performPostLayoutTasks()
frame().loader().client().dispatchDidLayout();
updateWidgetPositions();
-
-#if ENABLE(CSS_SCROLL_SNAP)
- updateSnapOffsets();
-#endif
-
+
// layout() protects FrameView, but it still can get destroyed when updateEmbeddedObjects()
// is called through the post layout timer.
Ref<FrameView> protect(*this);
m_updateEmbeddedObjectsTimer.startOneShot(0);
- if (auto* page = frame().page()) {
- if (auto* scrollingCoordinator = page->scrollingCoordinator())
- scrollingCoordinator->frameViewLayoutUpdated(*this);
+ if (page) {
+ if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
+ scrollingCoordinator->frameViewLayoutUpdated(this);
}
+#if USE(ACCELERATED_COMPOSITING)
if (RenderView* renderView = this->renderView()) {
if (renderView->usesCompositing())
renderView->compositor().frameViewDidLayout();
}
+#endif
scrollToAnchor();
sendResizeEventIfNeeded();
- viewportContentsChanged();
-
- updateScrollSnapState();
-}
-
-IntSize FrameView::sizeForResizeEvent() const
-{
-#if PLATFORM(IOS)
- if (m_useCustomSizeForResizeEvent)
- return m_customSizeForResizeEvent;
-#endif
- if (useFixedLayout() && !fixedLayoutSize().isEmpty() && delegatesScrolling())
- return fixedLayoutSize();
- return visibleContentRectIncludingScrollbars().size();
}
void FrameView::sendResizeEventIfNeeded()
{
- if (isInRenderTreeLayout() || needsLayout())
- return;
-
RenderView* renderView = this->renderView();
if (!renderView || renderView->printing())
return;
-
if (frame().page() && frame().page()->chrome().client().isSVGImageChromeClient())
return;
- IntSize currentSize = sizeForResizeEvent();
- float currentZoomFactor = renderView->style().zoom();
+ IntSize currentSize;
+ if (useFixedLayout() && !fixedLayoutSize().isEmpty() && delegatesScrolling())
+ currentSize = fixedLayoutSize();
+ else
+ currentSize = visibleContentRectIncludingScrollbars().size();
- if (currentSize == m_lastViewportSize && currentZoomFactor == m_lastZoomFactor)
- return;
+ float currentZoomFactor = renderView->style().zoom();
+ bool shouldSendResizeEvent = !m_firstLayout && (currentSize != m_lastViewportSize || currentZoomFactor != m_lastZoomFactor);
m_lastViewportSize = currentSize;
m_lastZoomFactor = currentZoomFactor;
- if (m_firstLayout)
+ if (!shouldSendResizeEvent)
return;
#if PLATFORM(IOS)
@@ -3202,24 +2773,22 @@ void FrameView::sendResizeEventIfNeeded()
#endif
bool isMainFrame = frame().isMainFrame();
- bool canSendResizeEventSynchronously = isMainFrame && !m_shouldAutoSize;
+ bool canSendResizeEventSynchronously = !m_shouldAutoSize && isMainFrame && !isInLayout();
- Ref<Event> resizeEvent = Event::create(eventNames().resizeEvent, false, false);
+ // If we resized during layout, queue up a resize event for later, otherwise fire it right away.
+ RefPtr<Event> resizeEvent = Event::create(eventNames().resizeEvent, false, false);
if (canSendResizeEventSynchronously)
- frame().document()->dispatchWindowEvent(resizeEvent);
- else {
- // FIXME: Queueing this event for an unpredictable time in the future seems
- // intrinsically racy. By the time this resize event fires, the frame might
- // be resized again, so we could end up with two resize events for the same size.
- frame().document()->enqueueWindowEvent(WTFMove(resizeEvent));
- }
+ frame().document()->dispatchWindowEvent(resizeEvent.release(), frame().document()->domWindow());
+ else
+ frame().document()->enqueueWindowEvent(resizeEvent.release());
+#if ENABLE(INSPECTOR)
+ Page* page = frame().page();
if (InspectorInstrumentation::hasFrontends() && isMainFrame) {
- if (Page* page = frame().page()) {
- if (InspectorClient* inspectorClient = page->inspectorController().inspectorClient())
- inspectorClient->didResizeMainFrame(&frame());
- }
+ if (InspectorClient* inspectorClient = page ? page->inspectorController().inspectorClient() : nullptr)
+ inspectorClient->didResizeMainFrame(&frame());
}
+#endif
}
void FrameView::willStartLiveResize()
@@ -3234,6 +2803,11 @@ void FrameView::willEndLiveResize()
adjustTiledBackingCoverage();
}
+void FrameView::postLayoutTimerFired(Timer<FrameView>&)
+{
+ performPostLayoutTasks();
+}
+
void FrameView::autoSizeIfEnabled()
{
if (!m_shouldAutoSize)
@@ -3242,8 +2816,6 @@ void FrameView::autoSizeIfEnabled()
if (m_inAutoSize)
return;
- LOG(Layout, "FrameView %p autoSizeIfEnabled", this);
-
TemporaryChange<bool> changeInAutoSize(m_inAutoSize, true);
Document* document = frame().document();
@@ -3255,8 +2827,6 @@ void FrameView::autoSizeIfEnabled()
if (!documentView || !documentElement)
return;
- if (m_layoutRoot)
- convertSubtreeLayoutToFullLayout();
// Start from the minimum size and allow it to grow.
resize(m_minAutoSize.width(), m_minAutoSize.height());
@@ -3279,7 +2849,8 @@ void FrameView::autoSizeIfEnabled()
RefPtr<Scrollbar> localHorizontalScrollbar = horizontalScrollbar();
if (!localHorizontalScrollbar)
localHorizontalScrollbar = createScrollbar(HorizontalScrollbar);
- newSize.expand(0, localHorizontalScrollbar->occupiedHeight());
+ if (!localHorizontalScrollbar->isOverlayScrollbar())
+ newSize.setHeight(newSize.height() + localHorizontalScrollbar->height());
// Don't bother checking for a vertical scrollbar because the width is at
// already greater the maximum.
@@ -3287,7 +2858,8 @@ void FrameView::autoSizeIfEnabled()
RefPtr<Scrollbar> localVerticalScrollbar = verticalScrollbar();
if (!localVerticalScrollbar)
localVerticalScrollbar = createScrollbar(VerticalScrollbar);
- newSize.expand(localVerticalScrollbar->occupiedWidth(), 0);
+ if (!localVerticalScrollbar->isOverlayScrollbar())
+ newSize.setWidth(newSize.width() + localVerticalScrollbar->width());
// Don't bother checking for a horizontal scrollbar because the height is
// already greater the maximum.
@@ -3317,10 +2889,7 @@ void FrameView::autoSizeIfEnabled()
&& !frame().loader().isComplete() && (newSize.height() < size.height() || newSize.width() < size.width()))
break;
- // The first time around, resize to the minimum height again; otherwise,
- // on pages (e.g. quirks mode) where the body/document resize to the view size,
- // we'll end up not shrinking back down after resizing to the computed preferred width.
- resize(newSize.width(), i ? newSize.height() : m_minAutoSize.height());
+ resize(newSize.width(), newSize.height());
// Force the scrollbar state to avoid the scrollbar code adding them and causing them to be needed. For example,
// a vertical scrollbar may cause text to wrap and thus increase the height (which is the only reason the scollbar is needed).
setVerticalScrollbarLock(false);
@@ -3348,37 +2917,9 @@ void FrameView::setAutoSizeFixedMinimumHeight(int fixedMinimumHeight)
setNeedsLayout();
}
-RenderElement* FrameView::viewportRenderer() const
-{
- if (m_viewportRendererType == ViewportRendererType::None)
- return nullptr;
-
- auto* document = frame().document();
- if (!document)
- return nullptr;
-
- if (m_viewportRendererType == ViewportRendererType::Document) {
- auto* documentElement = document->documentElement();
- if (!documentElement)
- return nullptr;
- return documentElement->renderer();
- }
-
- if (m_viewportRendererType == ViewportRendererType::Body) {
- auto* body = document->body();
- if (!body)
- return nullptr;
- return body->renderer();
- }
-
- ASSERT_NOT_REACHED();
- return nullptr;
-}
-
void FrameView::updateOverflowStatus(bool horizontalOverflow, bool verticalOverflow)
{
- auto* viewportRenderer = this->viewportRenderer();
- if (!viewportRenderer)
+ if (!m_viewportRenderer)
return;
if (m_overflowStatusDirty) {
@@ -3395,12 +2936,13 @@ void FrameView::updateOverflowStatus(bool horizontalOverflow, bool verticalOverf
m_horizontalOverflow = horizontalOverflow;
m_verticalOverflow = verticalOverflow;
- Ref<OverflowEvent> overflowEvent = OverflowEvent::create(horizontalOverflowChanged, horizontalOverflow,
+ RefPtr<OverflowEvent> overflowEvent = OverflowEvent::create(horizontalOverflowChanged, horizontalOverflow,
verticalOverflowChanged, verticalOverflow);
- overflowEvent->setTarget(viewportRenderer->element());
+ overflowEvent->setTarget(m_viewportRenderer->element());
- frame().document()->enqueueOverflowEvent(WTFMove(overflowEvent));
+ frame().document()->enqueueOverflowEvent(overflowEvent.release());
}
+
}
const Pagination& FrameView::pagination() const
@@ -3408,10 +2950,8 @@ const Pagination& FrameView::pagination() const
if (m_pagination != Pagination())
return m_pagination;
- if (frame().isMainFrame()) {
- if (Page* page = frame().page())
- return page->pagination();
- }
+ if (frame().isMainFrame())
+ return frame().page()->pagination();
return m_pagination;
}
@@ -3426,19 +2966,19 @@ void FrameView::setPagination(const Pagination& pagination)
frame().document()->styleResolverChanged(DeferRecalcStyle);
}
-IntRect FrameView::windowClipRect() const
+IntRect FrameView::windowClipRect(bool clipToContents) const
{
ASSERT(frame().view() == this);
- if (m_cachedWindowClipRect)
- return *m_cachedWindowClipRect;
-
if (paintsEntireContents())
- return contentsToWindow(IntRect(IntPoint(), totalContentsSize()));
+ return IntRect(IntPoint(), totalContentsSize());
// Set our clip rect to be our contents.
- IntRect clipRect = contentsToWindow(visibleContentRect(LegacyIOSDocumentVisibleRect));
-
+ IntRect clipRect;
+ if (clipToContents)
+ clipRect = contentsToWindow(visibleContentRect(LegacyIOSDocumentVisibleRect));
+ else
+ clipRect = contentsToWindow(visibleContentRectIncludingScrollbars(LegacyIOSDocumentVisibleRect));
if (!frame().ownerElement())
return clipRect;
@@ -3464,9 +3004,9 @@ IntRect FrameView::windowClipRectForFrameOwner(const HTMLFrameOwnerElement* owne
// Apply the clip from the layer.
IntRect clipRect;
if (clipToLayerContents)
- clipRect = snappedIntRect(enclosingLayer->childrenClipRect());
+ clipRect = pixelSnappedIntRect(enclosingLayer->childrenClipRect());
else
- clipRect = snappedIntRect(enclosingLayer->selfClipRect());
+ clipRect = pixelSnappedIntRect(enclosingLayer->selfClipRect());
clipRect = contentsToWindow(clipRect);
return intersection(clipRect, windowClipRect());
}
@@ -3487,58 +3027,13 @@ bool FrameView::updatesScrollLayerPositionOnMainThread() const
return true;
}
-bool FrameView::forceUpdateScrollbarsOnMainThreadForPerformanceTesting() const
-{
- Page* page = frame().page();
- return page && page->settings().forceUpdateScrollbarsOnMainThreadForPerformanceTesting();
-}
-
-void FrameView::scrollTo(const ScrollPosition& newPosition)
-{
- IntPoint oldPosition = scrollPosition();
- ScrollView::scrollTo(newPosition);
- if (oldPosition != scrollPosition())
- scrollPositionChanged(oldPosition, scrollPosition());
- didChangeScrollOffset();
-}
-
-float FrameView::adjustScrollStepForFixedContent(float step, ScrollbarOrientation orientation, ScrollGranularity granularity)
+void FrameView::scrollTo(const IntSize& newOffset)
{
- if (granularity != ScrollByPage || orientation == HorizontalScrollbar)
- return step;
-
- TrackedRendererListHashSet* positionedObjects = nullptr;
- if (RenderView* root = frame().contentRenderer()) {
- if (!root->hasPositionedObjects())
- return step;
- positionedObjects = root->positionedObjects();
- }
-
- FloatRect unobscuredContentRect = this->unobscuredContentRect();
- float topObscuredArea = 0;
- float bottomObscuredArea = 0;
- for (const auto& positionedObject : *positionedObjects) {
- const RenderStyle& style = positionedObject->style();
- if (style.position() != FixedPosition || style.visibility() == HIDDEN || !style.opacity())
- continue;
-
- FloatQuad contentQuad = positionedObject->absoluteContentQuad();
- if (!contentQuad.isRectilinear())
- continue;
-
- FloatRect contentBoundingBox = contentQuad.boundingBox();
- FloatRect fixedRectInView = intersection(unobscuredContentRect, contentBoundingBox);
-
- if (fixedRectInView.width() < unobscuredContentRect.width())
- continue;
-
- if (fixedRectInView.y() == unobscuredContentRect.y())
- topObscuredArea = std::max(topObscuredArea, fixedRectInView.height());
- else if (fixedRectInView.maxY() == unobscuredContentRect.maxY())
- bottomObscuredArea = std::max(bottomObscuredArea, fixedRectInView.height());
- }
-
- return Scrollbar::pageStep(unobscuredContentRect.height(), unobscuredContentRect.height() - topObscuredArea - bottomObscuredArea);
+ LayoutSize offset = scrollOffset();
+ ScrollView::scrollTo(newOffset);
+ if (offset != scrollOffset())
+ scrollPositionChanged();
+ frame().loader().client().didChangeScrollOffset();
}
void FrameView::invalidateScrollbarRect(Scrollbar* scrollbar, const IntRect& rect)
@@ -3549,16 +3044,19 @@ void FrameView::invalidateScrollbarRect(Scrollbar* scrollbar, const IntRect& rec
invalidateRect(dirtyRect);
}
+IntRect FrameView::windowResizerRect() const
+{
+ if (Page* page = frame().page())
+ return page->chrome().windowResizerRect();
+ return IntRect();
+}
+
float FrameView::visibleContentScaleFactor() const
{
if (!frame().isMainFrame() || !frame().settings().delegatesPageScaling())
return 1;
- Page* page = frame().page();
- if (!page)
- return 1;
-
- return page->pageScaleFactor();
+ return frame().page()->pageScaleFactor();
}
void FrameView::setVisibleScrollerThumbRect(const IntRect& scrollerThumb)
@@ -3566,20 +3064,16 @@ void FrameView::setVisibleScrollerThumbRect(const IntRect& scrollerThumb)
if (!frame().isMainFrame())
return;
- Page* page = frame().page();
- if (!page)
- return;
-
- page->chrome().client().notifyScrollerThumbIsVisibleInRect(scrollerThumb);
+ frame().page()->chrome().client().notifyScrollerThumbIsVisibleInRect(scrollerThumb);
}
ScrollableArea* FrameView::enclosingScrollableArea() const
{
// FIXME: Walk up the frame tree and look for a scrollable parent frame or RenderLayer.
- return nullptr;
+ return 0;
}
-IntRect FrameView::scrollableAreaBoundingBox(bool*) const
+IntRect FrameView::scrollableAreaBoundingBox() const
{
RenderWidget* ownerRenderer = frame().ownerRenderer();
if (!ownerRenderer)
@@ -3588,7 +3082,7 @@ IntRect FrameView::scrollableAreaBoundingBox(bool*) const
return ownerRenderer->absoluteContentQuad().enclosingBoundingBox();
}
-bool FrameView::isScrollable(Scrollability definitionOfScrollable)
+bool FrameView::isScrollable()
{
// Check for:
// 1) If there an actual overflow.
@@ -3596,18 +3090,11 @@ bool FrameView::isScrollable(Scrollability definitionOfScrollable)
// 3) overflow{-x,-y}: hidden;
// 4) scrolling: no;
- bool requiresActualOverflowToBeConsideredScrollable = !frame().isMainFrame() || definitionOfScrollable != Scrollability::ScrollableOrRubberbandable;
-#if !ENABLE(RUBBER_BANDING)
- requiresActualOverflowToBeConsideredScrollable = true;
-#endif
-
// Covers #1
- if (requiresActualOverflowToBeConsideredScrollable) {
- IntSize totalContentsSize = this->totalContentsSize();
- IntSize visibleContentSize = visibleContentRect(LegacyIOSDocumentVisibleRect).size();
- if (totalContentsSize.height() <= visibleContentSize.height() && totalContentsSize.width() <= visibleContentSize.width())
- return false;
- }
+ IntSize totalContentsSize = this->totalContentsSize();
+ IntSize visibleContentSize = visibleContentRect(LegacyIOSDocumentVisibleRect).size();
+ if ((totalContentsSize.height() <= visibleContentSize.height() && totalContentsSize.width() <= visibleContentSize.width()))
+ return false;
// Covers #2.
HTMLFrameOwnerElement* owner = frame().ownerElement();
@@ -3624,25 +3111,6 @@ bool FrameView::isScrollable(Scrollability definitionOfScrollable)
return true;
}
-bool FrameView::isScrollableOrRubberbandable()
-{
- return isScrollable(Scrollability::ScrollableOrRubberbandable);
-}
-
-bool FrameView::hasScrollableOrRubberbandableAncestor()
-{
- if (frame().isMainFrame())
- return isScrollableOrRubberbandable();
-
- for (FrameView* parent = this->parentFrameView(); parent; parent = parent->parentFrameView()) {
- Scrollability frameScrollability = parent->frame().isMainFrame() ? Scrollability::ScrollableOrRubberbandable : Scrollability::Scrollable;
- if (parent->isScrollable(frameScrollability))
- return true;
- }
-
- return false;
-}
-
void FrameView::updateScrollableAreaSet()
{
// That ensures that only inner frames are cached.
@@ -3663,15 +3131,15 @@ bool FrameView::shouldSuspendScrollAnimations() const
return frame().loader().state() != FrameStateComplete;
}
-void FrameView::scrollbarStyleChanged(ScrollbarStyle newStyle, bool forceUpdate)
+void FrameView::scrollbarStyleChanged(int newStyle, bool forceUpdate)
{
if (!frame().isMainFrame())
return;
- if (Page* page = frame().page())
- page->chrome().client().recommendedScrollbarStyleDidChange(newStyle);
+ frame().page()->chrome().client().recommendedScrollbarStyleDidChange(newStyle);
- ScrollView::scrollbarStyleChanged(newStyle, forceUpdate);
+ if (forceUpdate)
+ ScrollView::scrollbarStyleChanged(newStyle, forceUpdate);
}
void FrameView::notifyPageThatContentAreaWillPaint() const
@@ -3719,14 +3187,14 @@ void FrameView::updateAnnotatedRegions()
void FrameView::updateScrollCorner()
{
- RenderElement* renderer = nullptr;
+ RenderElement* renderer = 0;
RefPtr<RenderStyle> cornerStyle;
IntRect cornerRect = scrollCornerRect();
if (!cornerRect.isEmpty()) {
// Try the <body> element first as a scroll corner source.
Document* doc = frame().document();
- Element* body = doc ? doc->bodyOrFrameset() : nullptr;
+ Element* body = doc ? doc->body() : 0;
if (body && body->renderer()) {
renderer = body->renderer();
cornerStyle = renderer->getUncachedPseudoStyle(PseudoStyleRequest(SCROLLBAR_CORNER), &renderer->style());
@@ -3734,7 +3202,7 @@ void FrameView::updateScrollCorner()
if (!cornerStyle) {
// If the <body> didn't have a custom style, then the root element might.
- Element* docElement = doc ? doc->documentElement() : nullptr;
+ Element* docElement = doc ? doc->documentElement() : 0;
if (docElement && docElement->renderer()) {
renderer = docElement->renderer();
cornerStyle = renderer->getUncachedPseudoStyle(PseudoStyleRequest(SCROLLBAR_CORNER), &renderer->style());
@@ -3762,16 +3230,16 @@ void FrameView::updateScrollCorner()
ScrollView::updateScrollCorner();
}
-void FrameView::paintScrollCorner(GraphicsContext& context, const IntRect& cornerRect)
+void FrameView::paintScrollCorner(GraphicsContext* context, const IntRect& cornerRect)
{
- if (context.updatingControlTints()) {
+ if (context->updatingControlTints()) {
updateScrollCorner();
return;
}
if (m_scrollCorner) {
if (frame().isMainFrame())
- context.fillRect(cornerRect, baseBackgroundColor());
+ context->fillRect(cornerRect, baseBackgroundColor(), ColorSpaceDeviceRGB);
m_scrollCorner->paintIntoRect(context, cornerRect.location(), cornerRect);
return;
}
@@ -3779,12 +3247,12 @@ void FrameView::paintScrollCorner(GraphicsContext& context, const IntRect& corne
ScrollView::paintScrollCorner(context, cornerRect);
}
-void FrameView::paintScrollbar(GraphicsContext& context, Scrollbar& bar, const IntRect& rect)
+void FrameView::paintScrollbar(GraphicsContext* context, Scrollbar* bar, const IntRect& rect)
{
- if (bar.isCustomScrollbar() && frame().isMainFrame()) {
- IntRect toFill = bar.frameRect();
+ if (bar->isCustomScrollbar() && frame().isMainFrame()) {
+ IntRect toFill = bar->frameRect();
toFill.intersect(rect);
- context.fillRect(toFill, baseBackgroundColor());
+ context->fillRect(toFill, baseBackgroundColor(), ColorSpaceDeviceRGB);
}
ScrollView::paintScrollbar(context, bar, rect);
@@ -3800,8 +3268,8 @@ Color FrameView::documentBackgroundColor() const
if (!frame().document())
return Color();
- auto* htmlElement = frame().document()->documentElement();
- auto* bodyElement = frame().document()->bodyOrFrameset();
+ Element* htmlElement = frame().document()->documentElement();
+ Element* bodyElement = frame().document()->body();
// Start with invalid colors.
Color htmlBackgroundColor;
@@ -3833,11 +3301,11 @@ Color FrameView::documentBackgroundColor() const
bool FrameView::hasCustomScrollbars() const
{
for (auto& widget : children()) {
- if (is<FrameView>(*widget)) {
- if (downcast<FrameView>(*widget).hasCustomScrollbars())
+ if (widget->isFrameView()) {
+ if (toFrameView(*widget).hasCustomScrollbars())
return true;
- } else if (is<Scrollbar>(*widget)) {
- if (downcast<Scrollbar>(*widget).isCustomScrollbar())
+ } else if (widget->isScrollbar()) {
+ if (toScrollbar(*widget).isCustomScrollbar())
return true;
}
}
@@ -3848,35 +3316,31 @@ bool FrameView::hasCustomScrollbars() const
FrameView* FrameView::parentFrameView() const
{
if (!parent())
- return nullptr;
+ return 0;
if (Frame* parentFrame = frame().tree().parent())
return parentFrame->view();
- return nullptr;
+ return 0;
}
bool FrameView::isInChildFrameWithFrameFlattening() const
{
- if (!frameFlatteningEnabled())
- return false;
-
- if (!parent())
- return false;
-
- HTMLFrameOwnerElement* ownerElement = frame().ownerElement();
- if (!ownerElement)
- return false;
-
- if (!ownerElement->renderWidget())
+ if (!parent() || !frame().ownerElement())
return false;
// Frame flattening applies when the owner element is either in a frameset or
// an iframe with flattening parameters.
- if (is<HTMLIFrameElement>(*ownerElement))
- return downcast<RenderIFrame>(*ownerElement->renderWidget()).flattenFrame();
+ if (frame().ownerElement()->hasTagName(iframeTag)) {
+ RenderIFrame* iframeRenderer = toRenderIFrame(frame().ownerElement()->renderWidget());
+ if (iframeRenderer->flattenFrame() || iframeRenderer->isSeamless())
+ return true;
+ }
+
+ if (!frameFlatteningEnabled())
+ return false;
- if (is<HTMLFrameElement>(*ownerElement))
+ if (frame().ownerElement()->hasTagName(frameTag))
return true;
return false;
@@ -3902,8 +3366,10 @@ void FrameView::startLayoutAtMainFrameViewIfNeeded(bool allowSubtree)
while (parentView->parentFrameView())
parentView = parentView->parentFrameView();
- LOG(Layout, " frame flattening, starting from root");
parentView->layout(allowSubtree);
+
+ RenderElement* root = m_layoutRoot ? m_layoutRoot : frame().document()->renderView();
+ ASSERT_UNUSED(root, !root->needsLayout());
}
void FrameView::updateControlTints()
@@ -3917,33 +3383,23 @@ void FrameView::updateControlTints()
if (frame().document()->url().isEmpty())
return;
- // As noted above, this is a "fake" paint, so we should pause counting relevant repainted objects.
- Page* page = frame().page();
- bool isCurrentlyCountingRelevantRepaintedObject = false;
- if (page) {
- isCurrentlyCountingRelevantRepaintedObject = page->isCountingRelevantRepaintedObjects();
- page->setIsCountingRelevantRepaintedObjects(false);
- }
-
RenderView* renderView = this->renderView();
if ((renderView && renderView->theme().supportsControlTints()) || hasCustomScrollbars())
paintControlTints();
-
- if (page)
- page->setIsCountingRelevantRepaintedObjects(isCurrentlyCountingRelevantRepaintedObject);
}
void FrameView::paintControlTints()
{
if (needsLayout())
layout();
-
- GraphicsContext context(GraphicsContext::NonPaintingReasons::UpdatingControlTints);
+ PlatformGraphicsContext* const noContext = 0;
+ GraphicsContext context(noContext);
+ context.setUpdatingControlTints(true);
if (platformWidget()) {
// FIXME: consult paintsEntireContents().
- paintContents(context, visibleContentRect(LegacyIOSDocumentVisibleRect));
+ paintContents(&context, visibleContentRect(LegacyIOSDocumentVisibleRect));
} else
- paint(context, frameRect());
+ paint(&context, frameRect());
}
bool FrameView::wasScrolledByUser() const
@@ -3955,143 +3411,134 @@ void FrameView::setWasScrolledByUser(bool wasScrolledByUser)
{
if (m_inProgrammaticScroll)
return;
- m_maintainScrollPositionAnchor = nullptr;
+ m_maintainScrollPositionAnchor = 0;
if (m_wasScrolledByUser == wasScrolledByUser)
return;
m_wasScrolledByUser = wasScrolledByUser;
- if (frame().isMainFrame())
- updateLayerFlushThrottling();
adjustTiledBackingCoverage();
}
-void FrameView::willPaintContents(GraphicsContext& context, const IntRect&, PaintingState& paintingState)
+void FrameView::paintContents(GraphicsContext* p, const IntRect& rect)
{
Document* document = frame().document();
- if (!context.paintingDisabled())
- InspectorInstrumentation::willPaint(renderView());
+#ifndef NDEBUG
+ bool fillWithRed;
+ if (document->printing())
+ fillWithRed = false; // Printing, don't fill with red (can't remember why).
+ else if (frame().ownerElement())
+ fillWithRed = false; // Subframe, don't fill with red.
+ else if (isTransparent())
+ fillWithRed = false; // Transparent, don't fill with red.
+ else if (m_paintBehavior & PaintBehaviorSelectionOnly)
+ fillWithRed = false; // Selections are transparent, don't fill with red.
+ else if (m_nodeToDraw)
+ fillWithRed = false; // Element images are transparent, don't fill with red.
+ else
+ fillWithRed = true;
+
+ if (fillWithRed)
+ p->fillRect(rect, Color(0xFF, 0, 0), ColorSpaceDeviceRGB);
+#endif
+
+ RenderView* renderView = this->renderView();
+ if (!renderView) {
+ LOG_ERROR("called FrameView::paint with nil renderer");
+ return;
+ }
+
+ ASSERT(!needsLayout());
+ if (needsLayout())
+ return;
- paintingState.isTopLevelPainter = !sCurrentPaintTimeStamp;
+ if (!p->paintingDisabled())
+ InspectorInstrumentation::willPaint(renderView);
- if (paintingState.isTopLevelPainter && MemoryPressureHandler::singleton().isUnderMemoryPressure()) {
- LOG(MemoryPressure, "Under memory pressure: %s", WTF_PRETTY_FUNCTION);
+ bool isTopLevelPainter = !sCurrentPaintTimeStamp;
+#if PLATFORM(IOS)
+ // FIXME: Remove PLATFORM(IOS)-guard once we upstream the iOS changes to MemoryPressureHandler.h.
+ if (isTopLevelPainter && memoryPressureHandler().hasReceivedMemoryPressure()) {
+ LOG(MemoryPressure, "Under memory pressure: %s", __PRETTY_FUNCTION__);
// To avoid unnecessary image decoding, we don't prune recently-decoded live resources here since
// we might need some live bitmaps on painting.
- MemoryCache::singleton().prune();
+ memoryCache()->prune();
}
-
- if (paintingState.isTopLevelPainter)
+#endif
+ if (isTopLevelPainter)
sCurrentPaintTimeStamp = monotonicallyIncreasingTime();
- paintingState.paintBehavior = m_paintBehavior;
+ FontCachePurgePreventer fontCachePurgePreventer;
+
+#if USE(ACCELERATED_COMPOSITING)
+ if (!p->paintingDisabled() && !document->printing())
+ flushCompositingStateForThisFrame(&frame());
+#endif
+
+ PaintBehavior oldPaintBehavior = m_paintBehavior;
if (FrameView* parentView = parentFrameView()) {
if (parentView->paintBehavior() & PaintBehaviorFlattenCompositingLayers)
m_paintBehavior |= PaintBehaviorFlattenCompositingLayers;
}
+
+ if (m_paintBehavior == PaintBehaviorNormal)
+ document->markers().invalidateRenderedRectsForMarkersInRect(rect);
if (document->printing())
m_paintBehavior |= PaintBehaviorFlattenCompositingLayers;
- paintingState.isFlatteningPaintOfRootFrame = (m_paintBehavior & PaintBehaviorFlattenCompositingLayers) && !frame().ownerElement();
- if (paintingState.isFlatteningPaintOfRootFrame)
+ bool flatteningPaint = m_paintBehavior & PaintBehaviorFlattenCompositingLayers;
+ bool isRootFrame = !frame().ownerElement();
+ if (flatteningPaint && isRootFrame)
notifyWidgetsInAllFrames(WillPaintFlattened);
ASSERT(!m_isPainting);
m_isPainting = true;
-}
-void FrameView::didPaintContents(GraphicsContext& context, const IntRect& dirtyRect, PaintingState& paintingState)
-{
+ // m_nodeToDraw is used to draw only one element (and its descendants)
+ RenderObject* eltRenderer = m_nodeToDraw ? m_nodeToDraw->renderer() : 0;
+ RenderLayer* rootLayer = renderView->layer();
+
+#ifndef NDEBUG
+ RenderElement::SetLayoutNeededForbiddenScope forbidSetNeedsLayout(&rootLayer->renderer());
+#endif
+
+ rootLayer->paint(p, rect, m_paintBehavior, eltRenderer);
+
+ if (rootLayer->containsDirtyOverlayScrollbars())
+ rootLayer->paintOverlayScrollbars(p, rect, m_paintBehavior, eltRenderer);
+
m_isPainting = false;
- if (paintingState.isFlatteningPaintOfRootFrame)
+ if (flatteningPaint && isRootFrame)
notifyWidgetsInAllFrames(DidPaintFlattened);
- m_paintBehavior = paintingState.paintBehavior;
+ m_paintBehavior = oldPaintBehavior;
m_lastPaintTime = monotonicallyIncreasingTime();
+#if PLATFORM(IOS)
// Painting can lead to decoding of large amounts of bitmaps
// If we are low on memory, wipe them out after the paint.
- if (paintingState.isTopLevelPainter && MemoryPressureHandler::singleton().isUnderMemoryPressure())
- MemoryCache::singleton().pruneLiveResources(true);
+ // FIXME: Remove PLATFORM(IOS)-guard once we upstream the iOS changes to MemoryPressureHandler.h.
+ if (isTopLevelPainter && memoryPressureHandler().hasReceivedMemoryPressure())
+ memoryCache()->pruneLiveResources(true);
+#endif
// Regions may have changed as a result of the visibility/z-index of element changing.
#if ENABLE(DASHBOARD_SUPPORT)
- if (frame().document()->annotatedRegionsDirty())
+ if (document->annotatedRegionsDirty())
updateAnnotatedRegions();
#endif
- if (paintingState.isTopLevelPainter)
+ if (isTopLevelPainter)
sCurrentPaintTimeStamp = 0;
- if (!context.paintingDisabled()) {
- InspectorInstrumentation::didPaint(renderView(), dirtyRect);
+ if (!p->paintingDisabled()) {
+ InspectorInstrumentation::didPaint(renderView, p, rect);
// FIXME: should probably not fire milestones for snapshot painting. https://bugs.webkit.org/show_bug.cgi?id=117623
- firePaintRelatedMilestonesIfNeeded();
- }
-}
-
-void FrameView::paintContents(GraphicsContext& context, const IntRect& dirtyRect)
-{
-#ifndef NDEBUG
- bool fillWithRed;
- if (frame().document()->printing())
- fillWithRed = false; // Printing, don't fill with red (can't remember why).
- else if (frame().ownerElement())
- fillWithRed = false; // Subframe, don't fill with red.
- else if (isTransparent())
- fillWithRed = false; // Transparent, don't fill with red.
- else if (m_paintBehavior & PaintBehaviorSelectionOnly)
- fillWithRed = false; // Selections are transparent, don't fill with red.
- else if (m_nodeToDraw)
- fillWithRed = false; // Element images are transparent, don't fill with red.
- else
- fillWithRed = true;
-
- if (fillWithRed)
- context.fillRect(dirtyRect, Color(0xFF, 0, 0));
-#endif
-
- if (m_layoutPhase == InViewSizeAdjust)
- return;
-
- TraceScope tracingScope(PaintViewStart, PaintViewEnd);
-
- ASSERT(m_layoutPhase == InPostLayerPositionsUpdatedAfterLayout || m_layoutPhase == OutsideLayout);
-
- RenderView* renderView = this->renderView();
- if (!renderView) {
- LOG_ERROR("called FrameView::paint with nil renderer");
- return;
+ firePaintRelatedMilestones();
}
-
- ASSERT(!needsLayout());
- if (needsLayout())
- return;
-
- PaintingState paintingState;
- willPaintContents(context, dirtyRect, paintingState);
-
- // m_nodeToDraw is used to draw only one element (and its descendants)
- RenderObject* renderer = m_nodeToDraw ? m_nodeToDraw->renderer() : nullptr;
- RenderLayer* rootLayer = renderView->layer();
-
-#ifndef NDEBUG
- RenderElement::SetLayoutNeededForbiddenScope forbidSetNeedsLayout(&rootLayer->renderer());
-#endif
-
- // To work around http://webkit.org/b/135106, ensure that the paint root isn't an inline with culled line boxes.
- // FIXME: This can cause additional content to be included in the snapshot, so remove this once that bug is fixed.
- while (is<RenderInline>(renderer) && !downcast<RenderInline>(*renderer).firstLineBox())
- renderer = renderer->parent();
-
- rootLayer->paint(context, dirtyRect, LayoutSize(), m_paintBehavior, renderer);
- if (rootLayer->containsDirtyOverlayScrollbars())
- rootLayer->paintOverlayScrollbars(context, dirtyRect, m_paintBehavior, renderer);
-
- didPaintContents(context, dirtyRect, paintingState);
}
void FrameView::setPaintBehavior(PaintBehavior behavior)
@@ -4115,7 +3562,7 @@ void FrameView::setNodeToDraw(Node* node)
m_nodeToDraw = node;
}
-void FrameView::paintContentsForSnapshot(GraphicsContext& context, const IntRect& imageRect, SelectionInSnapshot shouldPaintSelection, CoordinateSpaceForSnapshot coordinateSpace)
+void FrameView::paintContentsForSnapshot(GraphicsContext* context, const IntRect& imageRect, SelectionInSnapshot shouldPaintSelection, CoordinateSpaceForSnapshot coordinateSpace)
{
updateLayoutAndStyleIfNeededRecursive();
@@ -4127,7 +3574,7 @@ void FrameView::paintContentsForSnapshot(GraphicsContext& context, const IntRect
// in the render tree only. This will allow us to restore the selection from the DOM
// after we paint the snapshot.
if (shouldPaintSelection == ExcludeSelection) {
- for (auto* frame = m_frame.ptr(); frame; frame = frame->tree().traverseNext(m_frame.ptr())) {
+ for (Frame* frame = m_frame.get(); frame; frame = frame->tree().traverseNext(m_frame.get())) {
if (RenderView* root = frame->contentRenderer())
root->clearSelection();
}
@@ -4143,7 +3590,7 @@ void FrameView::paintContentsForSnapshot(GraphicsContext& context, const IntRect
// Restore selection.
if (shouldPaintSelection == ExcludeSelection) {
- for (auto* frame = m_frame.ptr(); frame; frame = frame->tree().traverseNext(m_frame.ptr()))
+ for (Frame* frame = m_frame.get(); frame; frame = frame->tree().traverseNext(m_frame.get()))
frame->selection().updateAppearance();
}
@@ -4151,9 +3598,9 @@ void FrameView::paintContentsForSnapshot(GraphicsContext& context, const IntRect
setPaintBehavior(oldBehavior);
}
-void FrameView::paintOverhangAreas(GraphicsContext& context, const IntRect& horizontalOverhangArea, const IntRect& verticalOverhangArea, const IntRect& dirtyRect)
+void FrameView::paintOverhangAreas(GraphicsContext* context, const IntRect& horizontalOverhangArea, const IntRect& verticalOverhangArea, const IntRect& dirtyRect)
{
- if (context.paintingDisabled())
+ if (context->paintingDisabled())
return;
if (frame().document()->printing())
@@ -4162,17 +3609,6 @@ void FrameView::paintOverhangAreas(GraphicsContext& context, const IntRect& hori
ScrollView::paintOverhangAreas(context, horizontalOverhangArea, verticalOverhangArea, dirtyRect);
}
-FrameView::FrameViewList FrameView::renderedChildFrameViews() const
-{
- FrameViewList childViews;
- for (Frame* frame = m_frame->tree().firstRenderedChild(); frame; frame = frame->tree().nextRenderedSibling()) {
- if (frame->view())
- childViews.append(*frame->view());
- }
-
- return childViews;
-}
-
void FrameView::updateLayoutAndStyleIfNeededRecursive()
{
// We have to crawl our entire tree looking for any FrameViews that need
@@ -4184,24 +3620,28 @@ void FrameView::updateLayoutAndStyleIfNeededRecursive()
// region but then become included later by the second frame adding rects to the dirty region
// when it lays out.
- AnimationUpdateBlock animationUpdateBlock(&frame().animation());
-
frame().document()->updateStyleIfNeeded();
if (needsLayout())
layout();
- // Grab a copy of the child views, as the list may be mutated by the following updateLayoutAndStyleIfNeededRecursive
- // calls, as they can potentially re-enter a layout of the parent frame view.
- for (auto& frameView : renderedChildFrameViews())
- frameView->updateLayoutAndStyleIfNeededRecursive();
+ // Grab a copy of the children() set, as it may be mutated by the following updateLayoutAndStyleIfNeededRecursive
+ // calls, as they can potentially re-enter a layout of the parent frame view, which may add/remove scrollbars
+ // and thus mutates the children() set.
+ Vector<Ref<FrameView>, 16> childViews;
+ childViews.reserveInitialCapacity(children().size());
+ for (auto& widget : children()) {
+ if (widget->isFrameView())
+ childViews.uncheckedAppend(toFrameView(*widget));
+ }
- // A child frame may have dirtied us during its layout.
- frame().document()->updateStyleIfNeeded();
- if (needsLayout())
- layout();
+ for (unsigned i = 0; i < childViews.size(); ++i)
+ childViews[i]->updateLayoutAndStyleIfNeededRecursive();
- ASSERT(!frame().isMainFrame() || !needsStyleRecalcOrLayout());
+ // When frame flattening is on, child frame can mark parent frame dirty. In such case, child frame
+ // needs to call layout on parent frame recursively.
+ // This assert ensures that parent frames are clean, when child frames finished updating layout and style.
+ ASSERT(!needsLayout());
}
bool FrameView::qualifiesAsVisuallyNonEmpty() const
@@ -4212,14 +3652,12 @@ bool FrameView::qualifiesAsVisuallyNonEmpty() const
return false;
// Ensure that we always get marked visually non-empty eventually.
- if (!frame().document()->parsing() && frame().loader().stateMachine().committedFirstRealDocumentLoad())
+ if (!frame().document()->parsing() && frame().loader().stateMachine()->committedFirstRealDocumentLoad())
return true;
// Require the document to grow a bit.
- // Using a value of 48 allows the header on Google's search page to render immediately before search results populate later.
- static const int documentHeightThreshold = 48;
- LayoutRect overflowRect = documentElement->renderBox()->layoutOverflowRect();
- if (snappedIntRect(overflowRect).height() < documentHeightThreshold)
+ static const int documentHeightThreshold = 200;
+ if (documentElement->renderBox()->layoutOverflowRect().pixelSnappedHeight() < documentHeightThreshold)
return false;
// The first few hundred characters rarely contain the interesting content of the page.
@@ -4241,15 +3679,6 @@ void FrameView::updateIsVisuallyNonEmpty()
adjustTiledBackingCoverage();
}
-bool FrameView::isViewForDocumentInFrame() const
-{
- RenderView* renderView = this->renderView();
- if (!renderView)
- return false;
-
- return &renderView->frameView() == this;
-}
-
void FrameView::enableAutoSizeMode(bool enable, const IntSize& minSize, const IntSize& maxSize)
{
ASSERT(!enable || !minSize.isEmpty());
@@ -4288,8 +3717,10 @@ void FrameView::forceLayoutForPagination(const FloatSize& pageSize, const FloatS
float pageLogicalWidth = renderView->style().isHorizontalWritingMode() ? pageSize.width() : pageSize.height();
float pageLogicalHeight = renderView->style().isHorizontalWritingMode() ? pageSize.height() : pageSize.width();
- renderView->setLogicalWidth(floor(pageLogicalWidth));
- renderView->setPageLogicalHeight(floor(pageLogicalHeight));
+ LayoutUnit flooredPageLogicalWidth = static_cast<LayoutUnit>(pageLogicalWidth);
+ LayoutUnit flooredPageLogicalHeight = static_cast<LayoutUnit>(pageLogicalHeight);
+ renderView->setLogicalWidth(flooredPageLogicalWidth);
+ renderView->setPageLogicalHeight(flooredPageLogicalHeight);
renderView->setNeedsLayoutAndPrefWidthsRecalc();
forceLayout();
@@ -4307,8 +3738,10 @@ void FrameView::forceLayoutForPagination(const FloatSize& pageSize, const FloatS
pageLogicalWidth = horizontalWritingMode ? maxPageSize.width() : maxPageSize.height();
pageLogicalHeight = horizontalWritingMode ? maxPageSize.height() : maxPageSize.width();
- renderView->setLogicalWidth(floor(pageLogicalWidth));
- renderView->setPageLogicalHeight(floor(pageLogicalHeight));
+ flooredPageLogicalWidth = static_cast<LayoutUnit>(pageLogicalWidth);
+ flooredPageLogicalHeight = static_cast<LayoutUnit>(pageLogicalHeight);
+ renderView->setLogicalWidth(flooredPageLogicalWidth);
+ renderView->setPageLogicalHeight(flooredPageLogicalHeight);
renderView->setNeedsLayoutAndPrefWidthsRecalc();
forceLayout();
@@ -4341,34 +3774,35 @@ void FrameView::adjustPageHeightDeprecated(float *newBottom, float oldTop, float
}
// Use a context with painting disabled.
- GraphicsContext context((PlatformGraphicsContext*)nullptr);
+ GraphicsContext context((PlatformGraphicsContext*)0);
renderView->setTruncatedAt(static_cast<int>(floorf(oldBottom)));
IntRect dirtyRect(0, static_cast<int>(floorf(oldTop)), renderView->layoutOverflowRect().maxX(), static_cast<int>(ceilf(oldBottom - oldTop)));
renderView->setPrintRect(dirtyRect);
- renderView->layer()->paint(context, dirtyRect);
+ renderView->layer()->paint(&context, dirtyRect);
*newBottom = renderView->bestTruncatedAt();
if (!*newBottom)
*newBottom = oldBottom;
renderView->setPrintRect(IntRect());
}
-IntRect FrameView::convertFromRendererToContainingView(const RenderElement* renderer, const IntRect& rendererRect) const
+IntRect FrameView::convertFromRenderer(const RenderElement* renderer, const IntRect& rendererRect) const
{
- IntRect rect = snappedIntRect(enclosingLayoutRect(renderer->localToAbsoluteQuad(FloatRect(rendererRect)).boundingBox()));
+ IntRect rect = pixelSnappedIntRect(enclosingLayoutRect(renderer->localToAbsoluteQuad(FloatRect(rendererRect)).boundingBox()));
+ // Convert from page ("absolute") to FrameView coordinates.
if (!delegatesScrolling())
- rect = contentsToView(rect);
+ rect.moveBy(-scrollPosition() + IntPoint(0, headerHeight()));
return rect;
}
-IntRect FrameView::convertFromContainingViewToRenderer(const RenderElement* renderer, const IntRect& viewRect) const
+IntRect FrameView::convertToRenderer(const RenderElement* renderer, const IntRect& viewRect) const
{
IntRect rect = viewRect;
// Convert from FrameView coords into page ("absolute") coordinates.
if (!delegatesScrolling())
- rect = viewToContents(rect);
+ rect.moveBy(scrollPositionRelativeToDocument());
// FIXME: we don't have a way to map an absolute rect down to a local quad, so just
// move the rect for now.
@@ -4376,24 +3810,23 @@ IntRect FrameView::convertFromContainingViewToRenderer(const RenderElement* rend
return rect;
}
-IntPoint FrameView::convertFromRendererToContainingView(const RenderElement* renderer, const IntPoint& rendererPoint) const
+IntPoint FrameView::convertFromRenderer(const RenderElement* renderer, const IntPoint& rendererPoint) const
{
IntPoint point = roundedIntPoint(renderer->localToAbsolute(rendererPoint, UseTransforms));
// Convert from page ("absolute") to FrameView coordinates.
if (!delegatesScrolling())
- point = contentsToView(point);
-
+ point.moveBy(-scrollPosition() + IntPoint(0, headerHeight()));
return point;
}
-IntPoint FrameView::convertFromContainingViewToRenderer(const RenderElement* renderer, const IntPoint& viewPoint) const
+IntPoint FrameView::convertToRenderer(const RenderElement* renderer, const IntPoint& viewPoint) const
{
IntPoint point = viewPoint;
// Convert from FrameView coords into page ("absolute") coordinates.
if (!delegatesScrolling())
- point = viewToContents(point);
+ point = point + scrollPositionRelativeToDocument();
return roundedIntPoint(renderer->absoluteToLocal(point, UseTransforms));
}
@@ -4401,8 +3834,8 @@ IntPoint FrameView::convertFromContainingViewToRenderer(const RenderElement* ren
IntRect FrameView::convertToContainingView(const IntRect& localRect) const
{
if (const ScrollView* parentScrollView = parent()) {
- if (is<FrameView>(*parentScrollView)) {
- const FrameView& parentView = downcast<FrameView>(*parentScrollView);
+ if (parentScrollView->isFrameView()) {
+ const FrameView* parentView = toFrameView(parentScrollView);
// Get our renderer in the parent view
RenderWidget* renderer = frame().ownerRenderer();
if (!renderer)
@@ -4412,7 +3845,7 @@ IntRect FrameView::convertToContainingView(const IntRect& localRect) const
// Add borders and padding??
rect.move(renderer->borderLeft() + renderer->paddingLeft(),
renderer->borderTop() + renderer->paddingTop());
- return parentView.convertFromRendererToContainingView(renderer, rect);
+ return parentView->convertFromRenderer(renderer, rect);
}
return Widget::convertToContainingView(localRect);
@@ -4424,15 +3857,15 @@ IntRect FrameView::convertToContainingView(const IntRect& localRect) const
IntRect FrameView::convertFromContainingView(const IntRect& parentRect) const
{
if (const ScrollView* parentScrollView = parent()) {
- if (is<FrameView>(*parentScrollView)) {
- const FrameView& parentView = downcast<FrameView>(*parentScrollView);
+ if (parentScrollView->isFrameView()) {
+ const FrameView* parentView = toFrameView(parentScrollView);
// Get our renderer in the parent view
RenderWidget* renderer = frame().ownerRenderer();
if (!renderer)
return parentRect;
- IntRect rect = parentView.convertFromContainingViewToRenderer(renderer, parentRect);
+ IntRect rect = parentView->convertToRenderer(renderer, parentRect);
// Subtract borders and padding
rect.move(-renderer->borderLeft() - renderer->paddingLeft(),
-renderer->borderTop() - renderer->paddingTop());
@@ -4448,8 +3881,8 @@ IntRect FrameView::convertFromContainingView(const IntRect& parentRect) const
IntPoint FrameView::convertToContainingView(const IntPoint& localPoint) const
{
if (const ScrollView* parentScrollView = parent()) {
- if (is<FrameView>(*parentScrollView)) {
- const FrameView& parentView = downcast<FrameView>(*parentScrollView);
+ if (parentScrollView->isFrameView()) {
+ const FrameView* parentView = toFrameView(parentScrollView);
// Get our renderer in the parent view
RenderWidget* renderer = frame().ownerRenderer();
@@ -4461,7 +3894,7 @@ IntPoint FrameView::convertToContainingView(const IntPoint& localPoint) const
// Add borders and padding
point.move(renderer->borderLeft() + renderer->paddingLeft(),
renderer->borderTop() + renderer->paddingTop());
- return parentView.convertFromRendererToContainingView(renderer, point);
+ return parentView->convertFromRenderer(renderer, point);
}
return Widget::convertToContainingView(localPoint);
@@ -4473,15 +3906,15 @@ IntPoint FrameView::convertToContainingView(const IntPoint& localPoint) const
IntPoint FrameView::convertFromContainingView(const IntPoint& parentPoint) const
{
if (const ScrollView* parentScrollView = parent()) {
- if (is<FrameView>(*parentScrollView)) {
- const FrameView& parentView = downcast<FrameView>(*parentScrollView);
+ if (parentScrollView->isFrameView()) {
+ const FrameView* parentView = toFrameView(parentScrollView);
// Get our renderer in the parent view
RenderWidget* renderer = frame().ownerRenderer();
if (!renderer)
return parentPoint;
- IntPoint point = parentView.convertFromContainingViewToRenderer(renderer, parentPoint);
+ IntPoint point = parentView->convertToRenderer(renderer, parentPoint);
// Subtract borders and padding
point.move(-renderer->borderLeft() - renderer->paddingLeft(),
-renderer->borderTop() - renderer->paddingTop());
@@ -4505,10 +3938,12 @@ void FrameView::setTracksRepaints(bool trackRepaints)
frame().document()->updateLayout();
}
+#if USE(ACCELERATED_COMPOSITING)
for (Frame* frame = &m_frame->tree().top(); frame; frame = frame->tree().traverseNext()) {
if (RenderView* renderView = frame->contentRenderer())
renderView->compositor().setTracksRepaints(trackRepaints);
}
+#endif
resetTrackedRepaints();
m_isTrackingRepaints = trackRepaints;
@@ -4517,8 +3952,10 @@ void FrameView::setTracksRepaints(bool trackRepaints)
void FrameView::resetTrackedRepaints()
{
m_trackedRepaintRects.clear();
+#if USE(ACCELERATED_COMPOSITING)
if (RenderView* renderView = this->renderView())
renderView->compositor().resetTrackedRepaintRects();
+#endif
}
String FrameView::trackedRepaintRectsAsText() const
@@ -4529,8 +3966,8 @@ String FrameView::trackedRepaintRectsAsText() const
TextStream ts;
if (!m_trackedRepaintRects.isEmpty()) {
ts << "(repaint rects\n";
- for (auto& rect : m_trackedRepaintRects)
- ts << " (rect " << LayoutUnit(rect.x()) << " " << LayoutUnit(rect.y()) << " " << LayoutUnit(rect.width()) << " " << LayoutUnit(rect.height()) << ")\n";
+ for (size_t i = 0; i < m_trackedRepaintRects.size(); ++i)
+ ts << " (rect " << m_trackedRepaintRects[i].x() << " " << m_trackedRepaintRects[i].y() << " " << m_trackedRepaintRects[i].width() << " " << m_trackedRepaintRects[i].height() << ")\n";
ts << ")\n";
}
return ts.release();
@@ -4539,23 +3976,13 @@ String FrameView::trackedRepaintRectsAsText() const
bool FrameView::addScrollableArea(ScrollableArea* scrollableArea)
{
if (!m_scrollableAreas)
- m_scrollableAreas = std::make_unique<ScrollableAreaSet>();
-
- if (m_scrollableAreas->add(scrollableArea).isNewEntry) {
- scrollableAreaSetChanged();
- return true;
- }
-
- return false;
+ m_scrollableAreas = adoptPtr(new ScrollableAreaSet);
+ return m_scrollableAreas->add(scrollableArea).isNewEntry;
}
bool FrameView::removeScrollableArea(ScrollableArea* scrollableArea)
{
- if (m_scrollableAreas && m_scrollableAreas->remove(scrollableArea)) {
- scrollableAreaSetChanged();
- return true;
- }
- return false;
+ return m_scrollableAreas && m_scrollableAreas->remove(scrollableArea);
}
bool FrameView::containsScrollableArea(ScrollableArea* scrollableArea) const
@@ -4563,27 +3990,10 @@ bool FrameView::containsScrollableArea(ScrollableArea* scrollableArea) const
return m_scrollableAreas && m_scrollableAreas->contains(scrollableArea);
}
-void FrameView::scrollableAreaSetChanged()
-{
- if (auto* page = frame().page()) {
- if (auto* scrollingCoordinator = page->scrollingCoordinator())
- scrollingCoordinator->frameViewNonFastScrollableRegionChanged(*this);
- }
-}
-
-void FrameView::sendScrollEvent()
+void FrameView::removeChild(Widget* widget)
{
- frame().eventHandler().sendScrollEvent();
- frame().eventHandler().dispatchFakeMouseMoveEventSoon();
-#if ENABLE(CSS_ANIMATIONS_LEVEL_2)
- frame().animation().scrollWasUpdated();
-#endif
-}
-
-void FrameView::removeChild(Widget& widget)
-{
- if (is<FrameView>(widget))
- removeScrollableArea(&downcast<FrameView>(widget));
+ if (widget->isFrameView())
+ removeScrollableArea(toFrameView(widget));
ScrollView::removeChild(widget);
}
@@ -4598,12 +4008,12 @@ bool FrameView::wheelEvent(const PlatformWheelEvent& wheelEvent)
#endif
if (delegatesScrolling()) {
- ScrollPosition oldPosition = scrollPosition();
- ScrollPosition newPosition = oldPosition - IntSize(wheelEvent.deltaX(), wheelEvent.deltaY());
- if (oldPosition != newPosition) {
- ScrollView::scrollTo(newPosition);
- scrollPositionChanged(oldPosition, scrollPosition());
- didChangeScrollOffset();
+ IntSize offset = scrollOffset();
+ IntSize newOffset = IntSize(offset.width() - wheelEvent.deltaX(), offset.height() - wheelEvent.deltaY());
+ if (offset != newOffset) {
+ ScrollView::scrollTo(newOffset);
+ scrollPositionChanged();
+ frame().loader().client().didChangeScrollOffset();
}
return true;
}
@@ -4618,8 +4028,8 @@ bool FrameView::wheelEvent(const PlatformWheelEvent& wheelEvent)
#if ENABLE(ASYNC_SCROLLING)
if (Page* page = frame().page()) {
if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator()) {
- if (scrollingCoordinator->coordinatesScrollingForFrameView(*this))
- return scrollingCoordinator->handleWheelEvent(*this, wheelEvent);
+ if (scrollingCoordinator->coordinatesScrollingForFrameView(this))
+ return scrollingCoordinator->handleWheelEvent(this, wheelEvent);
}
}
#endif
@@ -4648,7 +4058,7 @@ bool FrameView::isFlippedDocument() const
void FrameView::notifyWidgetsInAllFrames(WidgetNotification notification)
{
- for (auto* frame = m_frame.ptr(); frame; frame = frame->tree().traverseNext(m_frame.ptr())) {
+ for (Frame* frame = m_frame.get(); frame; frame = frame->tree().traverseNext(m_frame.get())) {
if (FrameView* view = frame->view())
view->notifyWidgets(notification);
}
@@ -4658,17 +4068,25 @@ AXObjectCache* FrameView::axObjectCache() const
{
if (frame().document())
return frame().document()->existingAXObjectCache();
- return nullptr;
+ return 0;
}
#if PLATFORM(IOS)
+void FrameView::setUseCustomFixedPositionLayoutRect(bool useCustomFixedPositionLayoutRect)
+{
+ if (m_useCustomFixedPositionLayoutRect == useCustomFixedPositionLayoutRect)
+ return;
+ m_useCustomFixedPositionLayoutRect = useCustomFixedPositionLayoutRect;
+ visibleContentsResized();
+}
+
void FrameView::setCustomFixedPositionLayoutRect(const IntRect& rect)
{
if (m_useCustomFixedPositionLayoutRect && m_customFixedPositionLayoutRect == rect)
return;
m_useCustomFixedPositionLayoutRect = true;
m_customFixedPositionLayoutRect = rect;
- updateContentsSize();
+ visibleContentsResized();
}
bool FrameView::updateFixedPositionLayoutRect()
@@ -4688,33 +4106,21 @@ bool FrameView::updateFixedPositionLayoutRect()
}
return false;
}
-
-void FrameView::setCustomSizeForResizeEvent(IntSize customSize)
-{
- m_useCustomSizeForResizeEvent = true;
- m_customSizeForResizeEvent = customSize;
- sendResizeEventIfNeeded();
-}
-
-void FrameView::setScrollVelocity(double horizontalVelocity, double verticalVelocity, double scaleChangeRate, double timestamp)
-{
- if (TiledBacking* tiledBacking = this->tiledBacking())
- tiledBacking->setVelocity(VelocityData(horizontalVelocity, verticalVelocity, scaleChangeRate, timestamp));
-}
#endif // PLATFORM(IOS)
void FrameView::setScrollingPerformanceLoggingEnabled(bool flag)
{
+#if USE(ACCELERATED_COMPOSITING)
if (TiledBacking* tiledBacking = this->tiledBacking())
tiledBacking->setScrollingPerformanceLoggingEnabled(flag);
+#else
+ UNUSED_PARAM(flag);
+#endif
}
void FrameView::didAddScrollbar(Scrollbar* scrollbar, ScrollbarOrientation orientation)
{
ScrollableArea::didAddScrollbar(scrollbar, orientation);
- Page* page = frame().page();
- if (page && page->expectsWheelEventTriggers())
- scrollAnimator().setWheelEventTestTrigger(page->testTrigger());
if (AXObjectCache* cache = axObjectCache())
cache->handleScrollbarUpdate(this);
}
@@ -4733,36 +4139,7 @@ void FrameView::addPaintPendingMilestones(LayoutMilestones milestones)
m_milestonesPendingPaint |= milestones;
}
-void FrameView::fireLayoutRelatedMilestonesIfNeeded()
-{
- LayoutMilestones requestedMilestones = 0;
- LayoutMilestones milestonesAchieved = 0;
- Page* page = frame().page();
- if (page)
- requestedMilestones = page->requestedLayoutMilestones();
-
- if (m_firstLayoutCallbackPending) {
- m_firstLayoutCallbackPending = false;
- frame().loader().didFirstLayout();
- if (requestedMilestones & DidFirstLayout)
- milestonesAchieved |= DidFirstLayout;
- if (frame().isMainFrame())
- page->startCountingRelevantRepaintedObjects();
- }
- updateIsVisuallyNonEmpty();
-
- // If the layout was done with pending sheets, we are not in fact visually non-empty yet.
- if (m_isVisuallyNonEmpty && !frame().document()->didLayoutWithPendingStylesheets() && m_firstVisuallyNonEmptyLayoutCallbackPending) {
- m_firstVisuallyNonEmptyLayoutCallbackPending = false;
- if (requestedMilestones & DidFirstVisuallyNonEmptyLayout)
- milestonesAchieved |= DidFirstVisuallyNonEmptyLayout;
- }
-
- if (milestonesAchieved && frame().isMainFrame())
- frame().loader().didLayout(milestonesAchieved);
-}
-
-void FrameView::firePaintRelatedMilestonesIfNeeded()
+void FrameView::firePaintRelatedMilestones()
{
Page* page = frame().page();
if (!page)
@@ -4801,12 +4178,10 @@ void FrameView::setScrollPinningBehavior(ScrollPinningBehavior pinning)
{
m_scrollPinningBehavior = pinning;
- if (Page* page = frame().page()) {
- if (auto* scrollingCoordinator = page->scrollingCoordinator())
- scrollingCoordinator->setScrollPinningBehavior(pinning);
- }
+ if (ScrollingCoordinator* scrollingCoordinator = frame().page()->scrollingCoordinator())
+ scrollingCoordinator->setScrollPinningBehavior(pinning);
- updateScrollbars(scrollPosition());
+ updateScrollbars(scrollOffset());
}
ScrollBehaviorForFixedElements FrameView::scrollBehaviorForFixedElements() const
@@ -4853,66 +4228,36 @@ void FrameView::updateWidgetPositions()
// updateWidgetPosition() can possibly cause layout to be re-entered (via plug-ins running
// scripts in response to NPP_SetWindow, for example), so we need to keep the Widgets
// alive during enumeration.
- for (auto& widget : collectAndProtectWidgets(m_widgetsInRenderTree)) {
- if (RenderWidget* renderWidget = RenderWidget::find(widget.get())) {
- auto ignoreWidgetState = renderWidget->updateWidgetPosition();
- UNUSED_PARAM(ignoreWidgetState);
- }
+ auto protectedWidgets = collectAndProtectWidgets(m_widgetsInRenderTree);
+
+ for (unsigned i = 0, size = protectedWidgets.size(); i < size; ++i) {
+ if (RenderWidget* renderWidget = RenderWidget::find(protectedWidgets[i].get()))
+ renderWidget->updateWidgetPosition();
}
}
void FrameView::notifyWidgets(WidgetNotification notification)
{
- for (auto& widget : collectAndProtectWidgets(m_widgetsInRenderTree))
- widget->notifyWidget(notification);
+ auto protectedWidgets = collectAndProtectWidgets(m_widgetsInRenderTree);
+
+ for (unsigned i = 0, size = protectedWidgets.size(); i < size; ++i)
+ protectedWidgets[i]->notifyWidget(notification);
}
void FrameView::setExposedRect(FloatRect exposedRect)
{
if (m_exposedRect == exposedRect)
return;
+
m_exposedRect = exposedRect;
+#if USE(ACCELERATED_COMPOSITING)
// FIXME: We should support clipping to the exposed rect for subframes as well.
- if (!frame().isMainFrame())
- return;
- if (TiledBacking* tiledBacking = this->tiledBacking()) {
- adjustTiledBackingCoverage();
- tiledBacking->setTiledScrollingIndicatorPosition(exposedRect.location());
- }
-
- if (auto* view = renderView())
- view->compositor().scheduleLayerFlush(false /* canThrottle */);
-
- frame().mainFrame().pageOverlayController().didChangeExposedRect();
-}
-
-void FrameView::setViewportSizeForCSSViewportUnits(IntSize size)
-{
- if (m_hasOverrideViewportSize && m_overrideViewportSize == size)
- return;
-
- m_overrideViewportSize = size;
- m_hasOverrideViewportSize = true;
-
- if (Document* document = frame().document()) {
- // FIXME: this should probably be updateViewportUnitsOnResize(), but synchronously
- // dirtying style here causes assertions on iOS (rdar://problem/19998166).
- document->styleResolverChanged(DeferRecalcStyle);
+ if (m_frame->isMainFrame()) {
+ if (TiledBacking* tiledBacking = this->tiledBacking())
+ tiledBacking->setExposedRect(exposedRect);
}
+#endif
}
-
-IntSize FrameView::viewportSizeForCSSViewportUnits() const
-{
- if (m_hasOverrideViewportSize)
- return m_overrideViewportSize;
- if (useFixedLayout())
- return fixedLayoutSize();
-
- // FIXME: the value returned should take into account the value of the overflow
- // property on the root element.
- return visibleContentRectIncludingScrollbars().size();
-}
-
} // namespace WebCore
diff --git a/Source/WebCore/page/FrameView.h b/Source/WebCore/page/FrameView.h
index b2735ad85..8ece6e51d 100644
--- a/Source/WebCore/page/FrameView.h
+++ b/Source/WebCore/page/FrameView.h
@@ -4,7 +4,7 @@
(C) 1998, 1999 Torben Weis (weis@kde.org)
(C) 1999 Lars Knoll (knoll@kde.org)
(C) 1999 Antti Koivisto (koivisto@kde.org)
- Copyright (C) 2004-2009, 2014-2015 Apple Inc. All rights reserved.
+ Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
@@ -27,17 +27,15 @@
#include "AdjustViewSizeOrNot.h"
#include "Color.h"
-#include "ContainerNode.h"
#include "LayoutMilestones.h"
#include "LayoutRect.h"
#include "Pagination.h"
#include "PaintPhase.h"
#include "RenderPtr.h"
#include "ScrollView.h"
-#include <memory>
#include <wtf/Forward.h>
-#include <wtf/HashSet.h>
#include <wtf/ListHashSet.h>
+#include <wtf/OwnPtr.h>
#include <wtf/text/WTFString.h>
namespace WebCore {
@@ -69,23 +67,23 @@ public:
friend class RenderView;
friend class Internals;
- WEBCORE_EXPORT static Ref<FrameView> create(Frame&);
- static Ref<FrameView> create(Frame&, const IntSize& initialSize);
+ static PassRefPtr<FrameView> create(Frame&);
+ static PassRefPtr<FrameView> create(Frame&, const IntSize& initialSize);
virtual ~FrameView();
virtual HostWindow* hostWindow() const override;
- WEBCORE_EXPORT virtual void invalidateRect(const IntRect&) override;
+ virtual void invalidateRect(const IntRect&) override;
virtual void setFrameRect(const IntRect&) override;
#if ENABLE(REQUEST_ANIMATION_FRAME)
virtual bool scheduleAnimation() override;
#endif
- Frame& frame() const { return const_cast<Frame&>(m_frame.get()); }
+ Frame& frame() const { return *m_frame; }
- WEBCORE_EXPORT RenderView* renderView() const;
+ RenderView* renderView() const;
int mapFromLayoutToCSSUnits(LayoutUnit) const;
LayoutUnit mapFromCSSToLayoutUnits(int) const;
@@ -95,66 +93,52 @@ public:
void setMarginWidth(LayoutUnit);
void setMarginHeight(LayoutUnit);
- WEBCORE_EXPORT virtual void setCanHaveScrollbars(bool) override;
- WEBCORE_EXPORT void updateCanHaveScrollbars();
+ virtual void setCanHaveScrollbars(bool) override;
+ void updateCanHaveScrollbars();
virtual PassRefPtr<Scrollbar> createScrollbar(ScrollbarOrientation) override;
virtual bool avoidScrollbarCreation() const override;
virtual void setContentsSize(const IntSize&) override;
- virtual void updateContentsSize() override;
void layout(bool allowSubtree = true);
- WEBCORE_EXPORT bool didFirstLayout() const;
- void layoutTimerFired();
+ bool didFirstLayout() const;
+ void layoutTimerFired(Timer<FrameView>&);
void scheduleRelayout();
void scheduleRelayoutOfSubtree(RenderElement&);
void unscheduleRelayout();
- void queuePostLayoutCallback(std::function<void()>);
bool layoutPending() const;
- bool isInLayout() const { return m_layoutPhase != OutsideLayout; }
- bool isInRenderTreeLayout() const { return m_layoutPhase == InRenderTreeLayout; }
- WEBCORE_EXPORT bool inPaintableState() { return m_layoutPhase != InRenderTreeLayout && m_layoutPhase != InViewSizeAdjust && m_layoutPhase != InPostLayout; }
+ bool isInLayout() const { return m_layoutPhase == InLayout; }
- RenderElement* layoutRoot() const { return m_layoutRoot; }
+ RenderObject* layoutRoot(bool onlyDuringLayout = false) const;
void clearLayoutRoot() { m_layoutRoot = nullptr; }
int layoutCount() const { return m_layoutCount; }
- WEBCORE_EXPORT bool needsLayout() const;
- WEBCORE_EXPORT void setNeedsLayout();
+ bool needsLayout() const;
+ void setNeedsLayout();
void setViewportConstrainedObjectsNeedLayout();
- bool needsStyleRecalcOrLayout(bool includeSubframes = true) const;
-
bool needsFullRepaint() const { return m_needsFullRepaint; }
- WEBCORE_EXPORT bool renderedCharactersExceed(unsigned threshold);
-
- WEBCORE_EXPORT void setViewportIsStable(bool stable) { m_viewportIsStable = stable; }
- bool viewportIsStable() const { return m_viewportIsStable; }
+ bool renderedCharactersExceed(unsigned threshold);
#if PLATFORM(IOS)
bool useCustomFixedPositionLayoutRect() const { return m_useCustomFixedPositionLayoutRect; }
+ void setUseCustomFixedPositionLayoutRect(bool);
IntRect customFixedPositionLayoutRect() const { return m_customFixedPositionLayoutRect; }
- WEBCORE_EXPORT void setCustomFixedPositionLayoutRect(const IntRect&);
+ void setCustomFixedPositionLayoutRect(const IntRect&);
bool updateFixedPositionLayoutRect();
-
- IntSize customSizeForResizeEvent() const { return m_customSizeForResizeEvent; }
- WEBCORE_EXPORT void setCustomSizeForResizeEvent(IntSize);
-
- WEBCORE_EXPORT void setScrollVelocity(double horizontalVelocity, double verticalVelocity, double scaleChangeRate, double timestamp);
-#else
- bool useCustomFixedPositionLayoutRect() const { return false; }
#endif
#if ENABLE(REQUEST_ANIMATION_FRAME)
- WEBCORE_EXPORT void serviceScriptedAnimations(double monotonicAnimationStartTime);
+ void serviceScriptedAnimations(double monotonicAnimationStartTime);
#endif
- void willRecalcStyle();
- bool updateCompositingLayersAfterStyleChange();
+#if USE(ACCELERATED_COMPOSITING)
+ void updateCompositingLayersAfterStyleChange();
void updateCompositingLayersAfterLayout();
+ bool flushCompositingStateForThisFrame(Frame* rootFrameForFlush);
void clearBackingStores();
void restoreBackingStores();
@@ -163,97 +147,91 @@ public:
// content rendered via the normal painting path.
void setNeedsOneShotDrawingSynchronization();
- WEBCORE_EXPORT GraphicsLayer* graphicsLayerForPlatformWidget(PlatformWidget);
- WEBCORE_EXPORT void scheduleLayerFlushAllowingThrottling();
+ GraphicsLayer* graphicsLayerForPlatformWidget(PlatformWidget);
+ void scheduleLayerFlushAllowingThrottling();
- WEBCORE_EXPORT virtual TiledBacking* tiledBacking() const override;
+ virtual TiledBacking* tiledBacking() const override;
// In the future when any ScrollableArea can have a node in th ScrollingTree, this should
// become a virtual function on ScrollableArea.
uint64_t scrollLayerID() const;
- ScrollableArea* scrollableAreaForScrollLayerID(uint64_t) const;
+#endif
bool hasCompositedContent() const;
- WEBCORE_EXPORT void enterCompositingMode();
- WEBCORE_EXPORT bool isEnclosedInCompositingLayer() const;
+ bool hasCompositedContentIncludingDescendants() const;
+ bool hasCompositingAncestor() const;
+ void enterCompositingMode();
+ bool isEnclosedInCompositingLayer() const;
// Only used with accelerated compositing, but outside the #ifdef to make linkage easier.
// Returns true if the flush was completed.
- WEBCORE_EXPORT bool flushCompositingStateIncludingSubframes();
+ bool flushCompositingStateIncludingSubframes();
// Returns true when a paint with the PaintBehaviorFlattenCompositingLayers flag set gives
// a faithful representation of the content.
- WEBCORE_EXPORT bool isSoftwareRenderable() const;
+ bool isSoftwareRenderable() const;
+ void didMoveOnscreen();
+ void willMoveOffscreen();
void setIsInWindow(bool);
void resetScrollbars();
void resetScrollbarsAndClearContentsSize();
void prepareForDetach();
void detachCustomScrollbars();
- WEBCORE_EXPORT void recalculateScrollbarOverlayStyle();
+ void recalculateScrollbarOverlayStyle();
void clear();
- WEBCORE_EXPORT bool isTransparent() const;
- WEBCORE_EXPORT void setTransparent(bool isTransparent);
+ bool isTransparent() const;
+ void setTransparent(bool isTransparent);
// True if the FrameView is not transparent, and the base background color is opaque.
bool hasOpaqueBackground() const;
- WEBCORE_EXPORT Color baseBackgroundColor() const;
- WEBCORE_EXPORT void setBaseBackgroundColor(const Color&);
+ Color baseBackgroundColor() const;
+ void setBaseBackgroundColor(const Color&);
void updateBackgroundRecursively(const Color&, bool);
- enum ExtendedBackgroundModeFlags {
- ExtendedBackgroundModeNone = 0,
- ExtendedBackgroundModeVertical = 1 << 0,
- ExtendedBackgroundModeHorizontal = 1 << 1,
- ExtendedBackgroundModeAll = ExtendedBackgroundModeVertical | ExtendedBackgroundModeHorizontal,
- };
- typedef unsigned ExtendedBackgroundMode;
-
- void updateExtendBackgroundIfNecessary();
- void updateTilesForExtendedBackgroundMode(ExtendedBackgroundMode);
- ExtendedBackgroundMode calculateExtendedBackgroundMode() const;
-
- bool hasExtendedBackgroundRectForPainting() const;
- IntRect extendedBackgroundRectForPainting() const;
+ // extendedBackgroundRect() is in the viewport's coordinate space.
+ bool hasExtendedBackground() const;
+ IntRect extendedBackgroundRect() const;
+
+#if USE(ACCELERATED_COMPOSITING)
+ void setBackgroundExtendsBeyondPage(bool);
+#endif
bool shouldUpdateWhileOffscreen() const;
- WEBCORE_EXPORT void setShouldUpdateWhileOffscreen(bool);
- bool shouldUpdate() const;
+ void setShouldUpdateWhileOffscreen(bool);
+ bool shouldUpdate(bool = false) const;
- WEBCORE_EXPORT void adjustViewSize();
-
- WEBCORE_EXPORT void setViewportSizeForCSSViewportUnits(IntSize);
- IntSize viewportSizeForCSSViewportUnits() const;
+ void adjustViewSize();
- virtual IntRect windowClipRect() const override;
- WEBCORE_EXPORT IntRect windowClipRectForFrameOwner(const HTMLFrameOwnerElement*, bool clipToLayerContents) const;
+ virtual IntRect windowClipRect(bool clipToContents = true) const override;
+ IntRect windowClipRectForFrameOwner(const HTMLFrameOwnerElement*, bool clipToLayerContents) const;
+
+ virtual IntRect windowResizerRect() const override;
virtual float visibleContentScaleFactor() const override;
-#if USE(COORDINATED_GRAPHICS)
+#if USE(TILED_BACKING_STORE)
virtual void setFixedVisibleContentRect(const IntRect&) override;
#endif
- WEBCORE_EXPORT virtual void setScrollPosition(const ScrollPosition&) override;
+ virtual void setScrollPosition(const IntPoint&) override;
+ void scrollPositionChangedViaPlatformWidget();
virtual void updateLayerPositionsAfterScrolling() override;
virtual void updateCompositingLayersAfterScrolling() override;
- virtual bool requestScrollPositionUpdate(const ScrollPosition&) override;
+ virtual bool requestScrollPositionUpdate(const IntPoint&) override;
virtual bool isRubberBandInProgress() const override;
- WEBCORE_EXPORT virtual ScrollPosition minimumScrollPosition() const override;
- WEBCORE_EXPORT virtual ScrollPosition maximumScrollPosition() const override;
-
- void viewportContentsChanged();
- WEBCORE_EXPORT void resumeVisibleImageAnimationsIncludingSubframes();
+ virtual IntPoint minimumScrollPosition() const override;
+ virtual IntPoint maximumScrollPosition() const override;
// This is different than visibleContentRect() in that it ignores negative (or overly positive)
// offsets from rubber-banding, and it takes zooming into account.
LayoutRect viewportConstrainedVisibleContentRect() const;
String mediaType() const;
- WEBCORE_EXPORT void setMediaType(const String&);
+ void setMediaType(const String&);
void adjustMediaTypeForPrinting(bool printing);
void setCannotBlitToWindow();
@@ -264,7 +242,7 @@ public:
void addSlowRepaintObject(RenderElement*);
void removeSlowRepaintObject(RenderElement*);
- bool hasSlowRepaintObject(const RenderElement& renderer) const { return m_slowRepaintObjects && m_slowRepaintObjects->contains(&renderer); }
+ bool hasSlowRepaintObject(RenderElement* o) const { return m_slowRepaintObjects && m_slowRepaintObjects->contains(o); }
bool hasSlowRepaintObjects() const { return m_slowRepaintObjects && m_slowRepaintObjects->size(); }
// Includes fixed- and sticky-position objects.
@@ -273,49 +251,31 @@ public:
void removeViewportConstrainedObject(RenderElement*);
const ViewportConstrainedObjectSet* viewportConstrainedObjects() const { return m_viewportConstrainedObjects.get(); }
bool hasViewportConstrainedObjects() const { return m_viewportConstrainedObjects && m_viewportConstrainedObjects->size() > 0; }
-
- float frameScaleFactor() const;
// Functions for querying the current scrolled position, negating the effects of overhang
// and adjusting for page scale.
- LayoutPoint scrollPositionForFixedPosition() const
- {
- return scrollPositionForFixedPosition(visibleContentRect(), totalContentsSize(), scrollPosition(), scrollOrigin(), frameScaleFactor(), fixedElementsLayoutRelativeToFrame(), scrollBehaviorForFixedElements(), headerHeight(), footerHeight());
- }
-
+ IntSize scrollOffsetForFixedPosition() const;
// Static function can be called from another thread.
- static LayoutPoint scrollPositionForFixedPosition(const LayoutRect& visibleContentRect, const LayoutSize& totalContentsSize, const LayoutPoint& scrollPosition, const LayoutPoint& scrollOrigin, float frameScaleFactor, bool fixedElementsLayoutRelativeToFrame, ScrollBehaviorForFixedElements, int headerHeight, int footerHeight);
-
- // These layers are positioned differently when there is a topContentInset, a header, or a footer. These value need to be computed
- // on both the main thread and the scrolling thread.
- static float yPositionForInsetClipLayer(const FloatPoint& scrollPosition, float topContentInset);
- WEBCORE_EXPORT static FloatPoint positionForRootContentLayer(const FloatPoint& scrollPosition, const FloatPoint& scrollOrigin, float topContentInset, float headerHeight);
- WEBCORE_EXPORT FloatPoint positionForRootContentLayer() const;
+ static IntSize scrollOffsetForFixedPosition(const IntRect& visibleContentRect, const IntSize& totalContentsSize, const IntPoint& scrollPosition, const IntPoint& scrollOrigin, float frameScaleFactor, bool fixedElementsLayoutRelativeToFrame, ScrollBehaviorForFixedElements, int headerHeight, int footerHeight);
- static float yPositionForHeaderLayer(const FloatPoint& scrollPosition, float topContentInset);
- static float yPositionForFooterLayer(const FloatPoint& scrollPosition, float topContentInset, float totalContentsHeight, float footerHeight);
-
-#if PLATFORM(IOS)
- WEBCORE_EXPORT LayoutRect viewportConstrainedObjectsRect() const;
- // Static function can be called from another thread.
- WEBCORE_EXPORT static LayoutRect rectForViewportConstrainedObjects(const LayoutRect& visibleContentRect, const LayoutSize& totalContentsSize, float frameScaleFactor, bool fixedElementsLayoutRelativeToFrame, ScrollBehaviorForFixedElements);
-#endif
-
bool fixedElementsLayoutRelativeToFrame() const;
- WEBCORE_EXPORT void disableLayerFlushThrottlingTemporarilyForInteraction();
+ void disableLayerFlushThrottlingTemporarilyForInteraction();
+ void updateLayerFlushThrottlingInAllFrames();
+ void adjustTiledBackingCoverage();
bool speculativeTilingEnabled() const { return m_speculativeTilingEnabled; }
- void loadProgressingStatusChanged();
#if ENABLE(DASHBOARD_SUPPORT)
void updateAnnotatedRegions();
#endif
- WEBCORE_EXPORT void updateControlTints();
+ void updateControlTints();
void restoreScrollbar();
- WEBCORE_EXPORT bool wasScrolledByUser() const;
- WEBCORE_EXPORT void setWasScrolledByUser(bool);
+ void postLayoutTimerFired(Timer<FrameView>&);
+
+ bool wasScrolledByUser() const;
+ void setWasScrolledByUser(bool);
bool safeToPropagateScrollToParent() const { return m_safeToPropagateScrollToParent; }
void setSafeToPropagateScrollToParent(bool isSafe) { m_safeToPropagateScrollToParent = isSafe; }
@@ -323,64 +283,40 @@ public:
void addEmbeddedObjectToUpdate(RenderEmbeddedObject&);
void removeEmbeddedObjectToUpdate(RenderEmbeddedObject&);
- WEBCORE_EXPORT virtual void paintContents(GraphicsContext&, const IntRect& dirtyRect) override;
-
- struct PaintingState {
- PaintBehavior paintBehavior;
- bool isTopLevelPainter;
- bool isFlatteningPaintOfRootFrame;
- PaintingState()
- : paintBehavior()
- , isTopLevelPainter(false)
- , isFlatteningPaintOfRootFrame(false)
- {
- }
- };
-
- void willPaintContents(GraphicsContext&, const IntRect& dirtyRect, PaintingState&);
- void didPaintContents(GraphicsContext&, const IntRect& dirtyRect, PaintingState&);
-
-#if PLATFORM(IOS)
- WEBCORE_EXPORT void didReplaceMultipartContent();
-#endif
-
- WEBCORE_EXPORT void setPaintBehavior(PaintBehavior);
- WEBCORE_EXPORT PaintBehavior paintBehavior() const;
+ virtual void paintContents(GraphicsContext*, const IntRect& damageRect) override;
+ void setPaintBehavior(PaintBehavior);
+ PaintBehavior paintBehavior() const;
bool isPainting() const;
bool hasEverPainted() const { return m_lastPaintTime; }
void setLastPaintTime(double lastPaintTime) { m_lastPaintTime = lastPaintTime; }
- WEBCORE_EXPORT void setNodeToDraw(Node*);
+ void setNodeToDraw(Node*);
enum SelectionInSnapshot { IncludeSelection, ExcludeSelection };
enum CoordinateSpaceForSnapshot { DocumentCoordinates, ViewCoordinates };
- WEBCORE_EXPORT void paintContentsForSnapshot(GraphicsContext&, const IntRect& imageRect, SelectionInSnapshot shouldPaintSelection, CoordinateSpaceForSnapshot);
+ void paintContentsForSnapshot(GraphicsContext*, const IntRect& imageRect, SelectionInSnapshot shouldPaintSelection, CoordinateSpaceForSnapshot);
- virtual void paintOverhangAreas(GraphicsContext&, const IntRect& horizontalOverhangArea, const IntRect& verticalOverhangArea, const IntRect& dirtyRect) override;
- virtual void paintScrollCorner(GraphicsContext&, const IntRect& cornerRect) override;
- virtual void paintScrollbar(GraphicsContext&, Scrollbar&, const IntRect&) override;
+ virtual void paintOverhangAreas(GraphicsContext*, const IntRect& horizontalOverhangArea, const IntRect& verticalOverhangArea, const IntRect& dirtyRect) override;
+ virtual void paintScrollCorner(GraphicsContext*, const IntRect& cornerRect) override;
+ virtual void paintScrollbar(GraphicsContext*, Scrollbar*, const IntRect&) override;
- WEBCORE_EXPORT Color documentBackgroundColor() const;
+ Color documentBackgroundColor() const;
bool isInChildFrameWithFrameFlattening() const;
- void startDisallowingLayout() { ++m_layoutDisallowed; }
- void endDisallowingLayout() { ASSERT(m_layoutDisallowed > 0); --m_layoutDisallowed; }
- bool layoutDisallowed() const { return m_layoutDisallowed; }
-
static double currentPaintTimeStamp() { return sCurrentPaintTimeStamp; } // returns 0 if not painting
- WEBCORE_EXPORT void updateLayoutAndStyleIfNeededRecursive();
+ void updateLayoutAndStyleIfNeededRecursive();
void incrementVisuallyNonEmptyCharacterCount(unsigned);
void incrementVisuallyNonEmptyPixelCount(const IntSize&);
void updateIsVisuallyNonEmpty();
bool isVisuallyNonEmpty() const { return m_isVisuallyNonEmpty; }
- WEBCORE_EXPORT void enableAutoSizeMode(bool enable, const IntSize& minSize, const IntSize& maxSize);
- WEBCORE_EXPORT void setAutoSizeFixedMinimumHeight(int);
+ void enableAutoSizeMode(bool enable, const IntSize& minSize, const IntSize& maxSize);
+ void setAutoSizeFixedMinimumHeight(int fixedMinimumHeight);
IntSize autoSizingIntrinsicContentSize() const { return m_autoSizeContentSize; }
- WEBCORE_EXPORT void forceLayout(bool allowSubtree = false);
- WEBCORE_EXPORT void forceLayoutForPagination(const FloatSize& pageSize, const FloatSize& originalPageSize, float maximumShrinkFactor, AdjustViewSizeOrNot);
+ void forceLayout(bool allowSubtree = false);
+ void forceLayoutForPagination(const FloatSize& pageSize, const FloatSize& originalPageSize, float maximumShrinkFactor, AdjustViewSizeOrNot);
// FIXME: This method is retained because of embedded WebViews in AppKit. When a WebView is embedded inside
// some enclosing view with auto-pagination, no call happens to resize the view. The new pagination model
@@ -398,37 +334,22 @@ public:
// but that doesn't solve the general problem of how other AppKit views could opt in to the better model.
//
// NO OTHER PLATFORM BESIDES MAC SHOULD USE THIS METHOD.
- WEBCORE_EXPORT void adjustPageHeightDeprecated(float* newBottom, float oldTop, float oldBottom, float bottomLimit);
+ void adjustPageHeightDeprecated(float* newBottom, float oldTop, float oldBottom, float bottomLimit);
bool scrollToFragment(const URL&);
bool scrollToAnchor(const String&);
- void maintainScrollPositionAtAnchor(ContainerNode*);
- WEBCORE_EXPORT void scrollElementToRect(const Element&, const IntRect&);
+ void maintainScrollPositionAtAnchor(Node*);
+ void scrollElementToRect(Element*, const IntRect&);
// Methods to convert points and rects between the coordinate space of the renderer, and this view.
- WEBCORE_EXPORT IntRect convertFromRendererToContainingView(const RenderElement*, const IntRect&) const;
- WEBCORE_EXPORT IntRect convertFromContainingViewToRenderer(const RenderElement*, const IntRect&) const;
- WEBCORE_EXPORT IntPoint convertFromRendererToContainingView(const RenderElement*, const IntPoint&) const;
- WEBCORE_EXPORT IntPoint convertFromContainingViewToRenderer(const RenderElement*, const IntPoint&) const;
-
- // Override ScrollView methods to do point conversion via renderers, in order to take transforms into account.
- virtual IntRect convertToContainingView(const IntRect&) const override;
- virtual IntRect convertFromContainingView(const IntRect&) const override;
- virtual IntPoint convertToContainingView(const IntPoint&) const override;
- virtual IntPoint convertFromContainingView(const IntPoint&) const override;
-
- bool isFrameViewScrollCorner(const RenderScrollbarPart& scrollCorner) const { return m_scrollCorner == &scrollCorner; }
+ IntRect convertFromRenderer(const RenderElement*, const IntRect&) const;
+ IntRect convertToRenderer(const RenderElement*, const IntRect&) const;
+ IntPoint convertFromRenderer(const RenderElement*, const IntPoint&) const;
+ IntPoint convertToRenderer(const RenderElement*, const IntPoint&) const;
- // isScrollable() takes an optional Scrollability parameter that allows the caller to define what they mean by 'scrollable.'
- // Most callers are interested in the default value, Scrollability::Scrollable, which means that there is actually content
- // to scroll to, and a scrollbar that will allow you to access it. In some cases, callers want to know if the FrameView is allowed
- // to rubber-band, which the main frame might be allowed to do even if there is no content to scroll to. In that case,
- // callers use Scrollability::ScrollableOrRubberbandable.
- enum class Scrollability { Scrollable, ScrollableOrRubberbandable };
- WEBCORE_EXPORT bool isScrollable(Scrollability definitionOfScrollable = Scrollability::Scrollable);
+ bool isFrameViewScrollCorner(RenderScrollbarPart* scrollCorner) const { return m_scrollCorner == scrollCorner; }
- virtual bool isScrollableOrRubberbandable() override;
- virtual bool hasScrollableOrRubberbandableAncestor() override;
+ bool isScrollable();
enum ScrollbarModesCalculationStrategy { RulesFromWebContentOnly, AnyRule };
void calculateScrollbarModesForLayout(ScrollbarMode& hMode, ScrollbarMode& vMode, ScrollbarModesCalculationStrategy = AnyRule);
@@ -441,32 +362,32 @@ public:
void flushAnyPendingPostLayoutTasks();
virtual bool shouldSuspendScrollAnimations() const override;
- virtual void scrollbarStyleChanged(ScrollbarStyle, bool forceUpdate) override;
+ virtual void scrollbarStyleChanged(int newStyle, bool forceUpdate) override;
RenderBox* embeddedContentBox() const;
- WEBCORE_EXPORT void setTracksRepaints(bool);
+ void setTracksRepaints(bool);
bool isTrackingRepaints() const { return m_isTrackingRepaints; }
- WEBCORE_EXPORT void resetTrackedRepaints();
- const Vector<FloatRect>& trackedRepaintRects() const { return m_trackedRepaintRects; }
+ void resetTrackedRepaints();
+ const Vector<IntRect>& trackedRepaintRects() const { return m_trackedRepaintRects; }
String trackedRepaintRectsAsText() const;
typedef HashSet<ScrollableArea*> ScrollableAreaSet;
// Returns whether the scrollable area has just been newly added.
- WEBCORE_EXPORT bool addScrollableArea(ScrollableArea*);
+ bool addScrollableArea(ScrollableArea*);
// Returns whether the scrollable area has just been removed.
- WEBCORE_EXPORT bool removeScrollableArea(ScrollableArea*);
+ bool removeScrollableArea(ScrollableArea*);
bool containsScrollableArea(ScrollableArea*) const;
const ScrollableAreaSet* scrollableAreas() const { return m_scrollableAreas.get(); }
- virtual void removeChild(Widget&) override;
+ virtual void removeChild(Widget*) override;
// This function exists for ports that need to handle wheel events manually.
// On Mac WebKit1 the underlying NSScrollView just does the scrolling, but on most other platforms
// we need this function in order to do the scroll ourselves.
bool wheelEvent(const PlatformWheelEvent&);
- WEBCORE_EXPORT void setScrollingPerformanceLoggingEnabled(bool);
+ void setScrollingPerformanceLoggingEnabled(bool);
// Page and FrameView both store a Pagination value. Page::pagination() is set only by API,
// and FrameView::pagination() is set only by CSS. Page::pagination() will affect all
@@ -477,7 +398,7 @@ public:
const Pagination& pagination() const;
void setPagination(const Pagination&);
- bool inProgrammaticScroll() const override { return m_inProgrammaticScroll; }
+ bool inProgrammaticScroll() const { return m_inProgrammaticScroll; }
void setInProgrammaticScroll(bool programmaticScroll) { m_inProgrammaticScroll = programmaticScroll; }
#if ENABLE(CSS_DEVICE_ADAPTATION)
@@ -487,74 +408,44 @@ public:
virtual bool isActive() const override;
virtual bool updatesScrollLayerPositionOnMainThread() const override;
- virtual bool forceUpdateScrollbarsOnMainThreadForPerformanceTesting() const override;
#if ENABLE(RUBBER_BANDING)
- WEBCORE_EXPORT GraphicsLayer* setWantsLayerForTopOverHangArea(bool) const;
- WEBCORE_EXPORT GraphicsLayer* setWantsLayerForBottomOverHangArea(bool) const;
+ GraphicsLayer* setWantsLayerForTopOverHangArea(bool) const;
+ GraphicsLayer* setWantsLayerForBottomOverHangArea(bool) const;
#endif
- LayoutRect fixedScrollableAreaBoundsInflatedForScrolling(const LayoutRect& uninflatedBounds) const;
- LayoutPoint scrollPositionRespectingCustomFixedPosition() const;
-
virtual int headerHeight() const override { return m_headerHeight; }
- WEBCORE_EXPORT void setHeaderHeight(int);
+ void setHeaderHeight(int);
virtual int footerHeight() const override { return m_footerHeight; }
- WEBCORE_EXPORT void setFooterHeight(int);
-
- WEBCORE_EXPORT virtual float topContentInset(TopContentInsetType = TopContentInsetType::WebCoreContentInset) const override;
- void topContentInsetDidChange(float newTopContentInset);
-
- WEBCORE_EXPORT virtual void willStartLiveResize() override;
- WEBCORE_EXPORT virtual void willEndLiveResize() override;
+ void setFooterHeight(int);
- WEBCORE_EXPORT virtual void availableContentSizeChanged(AvailableSizeChangeReason) override;
+ virtual void willStartLiveResize() override;
+ virtual void willEndLiveResize() override;
void addPaintPendingMilestones(LayoutMilestones);
- void firePaintRelatedMilestonesIfNeeded();
- void fireLayoutRelatedMilestonesIfNeeded();
+ void firePaintRelatedMilestones();
LayoutMilestones milestonesPendingPaint() const { return m_milestonesPendingPaint; }
bool visualUpdatesAllowedByClient() const { return m_visualUpdatesAllowedByClient; }
- WEBCORE_EXPORT void setVisualUpdatesAllowedByClient(bool);
+ void setVisualUpdatesAllowedByClient(bool);
- WEBCORE_EXPORT void setScrollPinningBehavior(ScrollPinningBehavior);
+ void setScrollPinningBehavior(ScrollPinningBehavior);
ScrollBehaviorForFixedElements scrollBehaviorForFixedElements() const;
- bool hasFlippedBlockRenderers() const { return m_hasFlippedBlockRenderers; }
- void setHasFlippedBlockRenderers(bool b) { m_hasFlippedBlockRenderers = b; }
-
void updateWidgetPositions();
void didAddWidgetToRenderTree(Widget&);
void willRemoveWidgetFromRenderTree(Widget&);
- const HashSet<Widget*>& widgetsInRenderTree() const { return m_widgetsInRenderTree; }
-
- typedef Vector<Ref<FrameView>, 16> FrameViewList;
- FrameViewList renderedChildFrameViews() const;
-
- void addTrackedRepaintRect(const FloatRect&);
+ void addTrackedRepaintRect(const IntRect&);
// exposedRect represents WebKit's understanding of what part
// of the view is actually exposed on screen (taking into account
// clipping by other UI elements), whereas visibleContentRect is
// internal to WebCore and doesn't respect those things.
- WEBCORE_EXPORT void setExposedRect(FloatRect);
+ void setExposedRect(FloatRect);
FloatRect exposedRect() const { return m_exposedRect; }
-#if ENABLE(CSS_SCROLL_SNAP)
- void updateSnapOffsets() override;
- bool isScrollSnapInProgress() const override;
- void updateScrollingCoordinatorScrollSnapProperties() const;
-#endif
-
- virtual float adjustScrollStepForFixedContent(float step, ScrollbarOrientation, ScrollGranularity) override;
-
- void didChangeScrollOffset();
-
- void show() override;
-
protected:
virtual bool scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect) override;
virtual void scrollContentsSlowPath(const IntRect& updateRect) override;
@@ -574,10 +465,9 @@ private:
OutsideLayout,
InPreLayout,
InPreLayoutStyleUpdate,
- InRenderTreeLayout,
+ InLayout,
InViewSizeAdjust,
InPostLayout,
- InPostLayerPositionsUpdatedAfterLayout,
};
LayoutPhase layoutPhase() const { return m_layoutPhase; }
@@ -589,46 +479,45 @@ private:
bool useSlowRepaints(bool considerOverlap = true) const;
bool useSlowRepaintsIfNotOverlapped() const;
void updateCanBlitOnScrollRecursively();
- bool shouldLayoutAfterContentsResized() const;
+ bool contentsInCompositedLayer() const;
bool shouldUpdateCompositingLayersAfterScrolling() const;
- bool flushCompositingStateForThisFrame(const Frame& rootFrameForFlush);
-
- virtual bool shouldDeferScrollUpdateAfterContentSizeChange() override;
- virtual void scrollOffsetChangedViaPlatformWidgetImpl(const ScrollOffset& oldOffset, const ScrollOffset& newOffset) override;
-
- void applyOverflowToViewport(const RenderElement&, ScrollbarMode& hMode, ScrollbarMode& vMode);
+ void applyOverflowToViewport(RenderElement*, ScrollbarMode& hMode, ScrollbarMode& vMode);
void applyPaginationToViewport();
void updateOverflowStatus(bool horizontalOverflow, bool verticalOverflow);
- WEBCORE_EXPORT void paintControlTints();
+ void paintControlTints();
void forceLayoutParentViewIfNeeded();
- void flushPostLayoutTasksQueue();
void performPostLayoutTasks();
void autoSizeIfEnabled();
- void applyRecursivelyWithVisibleRect(const std::function<void (FrameView& frameView, const IntRect& visibleRect)>&);
- void resumeVisibleImageAnimations(const IntRect& visibleRect);
- void updateScriptedAnimationsAndTimersThrottlingState(const IntRect& visibleRect);
-
- void updateLayerFlushThrottling();
- WEBCORE_EXPORT void adjustTiledBackingCoverage();
-
- virtual void repaintContentRectangle(const IntRect&) override;
+ virtual void repaintContentRectangle(const IntRect&, bool immediate) override;
+ virtual void contentsResized() override;
+ virtual void visibleContentsResized() override;
virtual void addedOrRemovedScrollbar() override;
+ virtual void fixedLayoutSizeChanged() override;
virtual void delegatesScrollingDidChange() override;
+ // Override ScrollView methods to do point conversion via renderers, in order to
+ // take transforms into account.
+ virtual IntRect convertToContainingView(const IntRect&) const override;
+ virtual IntRect convertFromContainingView(const IntRect&) const override;
+ virtual IntPoint convertToContainingView(const IntPoint&) const override;
+ virtual IntPoint convertFromContainingView(const IntPoint&) const override;
+
// ScrollableArea interface
virtual void invalidateScrollbarRect(Scrollbar*, const IntRect&) override;
- virtual void scrollTo(const ScrollPosition&) override;
+ virtual void scrollTo(const IntSize&) override;
virtual void setVisibleScrollerThumbRect(const IntRect&) override;
virtual ScrollableArea* enclosingScrollableArea() const override;
- virtual IntRect scrollableAreaBoundingBox(bool* = nullptr) const override;
+ virtual IntRect scrollableAreaBoundingBox() const override;
virtual bool scrollAnimatorEnabled() const override;
+#if USE(ACCELERATED_COMPOSITING)
+ virtual bool usesCompositedScrolling() const override;
virtual GraphicsLayer* layerForScrolling() const override;
virtual GraphicsLayer* layerForHorizontalScrollbar() const override;
virtual GraphicsLayer* layerForVerticalScrollbar() const override;
@@ -636,17 +525,12 @@ private:
#if ENABLE(RUBBER_BANDING)
virtual GraphicsLayer* layerForOverhangAreas() const override;
#endif
-
- virtual bool usesCompositedScrolling() const override;
- virtual bool usesAsyncScrolling() const override;
- bool usesMockScrollAnimator() const override;
- void logMockScrollAnimatorMessage(const String&) const override;
+#endif
// Override scrollbar notifications to update the AXObject cache.
virtual void didAddScrollbar(Scrollbar*, ScrollbarOrientation) override;
virtual void willRemoveScrollbar(Scrollbar*, ScrollbarOrientation) override;
- IntSize sizeForResizeEvent() const;
void sendResizeEventIfNeeded();
void updateScrollableAreaSet();
@@ -654,15 +538,13 @@ private:
virtual void notifyPageThatContentAreaWillPaint() const override;
void enableSpeculativeTilingIfNeeded();
- void speculativeTilingEnableTimerFired();
+ void speculativeTilingEnableTimerFired(Timer<FrameView>&);
- void updateEmbeddedObjectsTimerFired();
+ void updateEmbeddedObjectsTimerFired(Timer<FrameView>*);
bool updateEmbeddedObjects();
void updateEmbeddedObject(RenderEmbeddedObject&);
void scrollToAnchor();
- void scrollPositionChanged(const ScrollPosition& oldPosition, const ScrollPosition& newPosition);
- void scrollableAreaSetChanged();
- void sendScrollEvent();
+ void scrollPositionChanged();
bool hasCustomScrollbars() const;
@@ -675,17 +557,12 @@ private:
bool isFrameFlatteningValidForThisFrame() const;
bool qualifiesAsVisuallyNonEmpty() const;
- bool isViewForDocumentInFrame() const;
AXObjectCache* axObjectCache() const;
void notifyWidgetsInAllFrames(WidgetNotification);
void removeFromAXObjectCache();
void notifyWidgets(WidgetNotification);
- void convertSubtreeLayoutToFullLayout();
-
- RenderElement* viewportRenderer() const;
-
HashSet<Widget*> m_widgetsInRenderTree;
static double sCurrentPaintTimeStamp; // used for detecting decoded resource thrash in the cache
@@ -693,10 +570,10 @@ private:
LayoutSize m_size;
LayoutSize m_margins;
- std::unique_ptr<ListHashSet<RenderEmbeddedObject*>> m_embeddedObjectsToUpdate;
- const Ref<Frame> m_frame;
+ OwnPtr<ListHashSet<RenderEmbeddedObject*>> m_embeddedObjectsToUpdate;
+ const RefPtr<Frame> m_frame;
- std::unique_ptr<HashSet<const RenderElement*>> m_slowRepaintObjects;
+ OwnPtr<HashSet<RenderElement*>> m_slowRepaintObjects;
bool m_needsFullRepaint;
@@ -705,17 +582,20 @@ private:
bool m_isOverlapped;
bool m_contentIsOpaque;
- Timer m_layoutTimer;
+ int m_borderX;
+ int m_borderY;
+
+ Timer<FrameView> m_layoutTimer;
bool m_delayedLayout;
- RenderElement* m_layoutRoot { nullptr };
+ RenderElement* m_layoutRoot;
LayoutPhase m_layoutPhase;
bool m_layoutSchedulingEnabled;
bool m_inSynchronousPostLayout;
int m_layoutCount;
unsigned m_nestedLayoutCount;
- Timer m_postLayoutTasksTimer;
- Timer m_updateEmbeddedObjectsTimer;
+ Timer<FrameView> m_postLayoutTasksTimer;
+ Timer<FrameView> m_updateEmbeddedObjectsTimer;
bool m_firstLayoutCallbackPending;
bool m_firstLayout;
@@ -729,29 +609,26 @@ private:
bool m_overflowStatusDirty;
bool m_horizontalOverflow;
- bool m_verticalOverflow;
- enum class ViewportRendererType { None, Document, Body };
- ViewportRendererType m_viewportRendererType { ViewportRendererType::None };
+ bool m_verticalOverflow;
+ RenderElement* m_viewportRenderer;
Pagination m_pagination;
bool m_wasScrolledByUser;
bool m_inProgrammaticScroll;
bool m_safeToPropagateScrollToParent;
- Timer m_delayedScrollEventTimer;
double m_lastPaintTime;
bool m_isTrackingRepaints; // Used for testing.
- Vector<FloatRect> m_trackedRepaintRects;
+ Vector<IntRect> m_trackedRepaintRects;
bool m_shouldUpdateWhileOffscreen;
FloatRect m_exposedRect;
- unsigned m_deferSetNeedsLayoutCount;
+ unsigned m_deferSetNeedsLayouts;
bool m_setNeedsLayoutWasDeferred;
- int m_layoutDisallowed { 0 };
RefPtr<Node> m_nodeToDraw;
PaintBehavior m_paintBehavior;
@@ -762,27 +639,19 @@ private:
bool m_isVisuallyNonEmpty;
bool m_firstVisuallyNonEmptyLayoutCallbackPending;
- bool m_viewportIsStable { true };
-
- RefPtr<ContainerNode> m_maintainScrollPositionAnchor;
+ RefPtr<Node> m_maintainScrollPositionAnchor;
// Renderer to hold our custom scroll corner.
RenderPtr<RenderScrollbarPart> m_scrollCorner;
bool m_speculativeTilingEnabled;
- Timer m_speculativeTilingEnableTimer;
+ Timer<FrameView> m_speculativeTilingEnableTimer;
#if PLATFORM(IOS)
bool m_useCustomFixedPositionLayoutRect;
IntRect m_customFixedPositionLayoutRect;
-
- bool m_useCustomSizeForResizeEvent;
- IntSize m_customSizeForResizeEvent;
#endif
- IntSize m_overrideViewportSize;
- bool m_hasOverrideViewportSize;
-
// If true, automatically resize the frame view around its content.
bool m_shouldAutoSize;
bool m_inAutoSize;
@@ -797,8 +666,8 @@ private:
// The intrinsic content size decided by autosizing.
IntSize m_autoSizeContentSize;
- std::unique_ptr<ScrollableAreaSet> m_scrollableAreas;
- std::unique_ptr<ViewportConstrainedObjectSet> m_viewportConstrainedObjects;
+ OwnPtr<ScrollableAreaSet> m_scrollableAreas;
+ OwnPtr<ViewportConstrainedObjectSet> m_viewportConstrainedObjects;
int m_headerHeight;
int m_footerHeight;
@@ -815,12 +684,8 @@ private:
#endif
bool m_visualUpdatesAllowedByClient;
- bool m_hasFlippedBlockRenderers;
-
+
ScrollPinningBehavior m_scrollPinningBehavior;
-
- IntRect* m_cachedWindowClipRect { nullptr };
- Vector<std::function<void()>> m_postLayoutCallbackQueue;
};
inline void FrameView::incrementVisuallyNonEmptyCharacterCount(unsigned count)
@@ -843,8 +708,8 @@ inline void FrameView::incrementVisuallyNonEmptyPixelCount(const IntSize& size)
updateIsVisuallyNonEmpty();
}
-} // namespace WebCore
+WIDGET_TYPE_CASTS(FrameView, isFrameView());
-SPECIALIZE_TYPE_TRAITS_WIDGET(FrameView, isFrameView())
+} // namespace WebCore
#endif // FrameView_h
diff --git a/Source/WebCore/page/GestureTapHighlighter.cpp b/Source/WebCore/page/GestureTapHighlighter.cpp
new file mode 100644
index 000000000..7b1c0abb5
--- /dev/null
+++ b/Source/WebCore/page/GestureTapHighlighter.cpp
@@ -0,0 +1,272 @@
+/*
+ * Copyright (C) 2011 Google Inc. All rights reserved.
+ * Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "GestureTapHighlighter.h"
+
+#include "Element.h"
+#include "FrameView.h"
+#include "GraphicsContext.h"
+#include "GraphicsTypes.h"
+#include "MainFrame.h"
+#include "Node.h"
+#include "Page.h"
+#include "RenderBoxModelObject.h"
+#include "RenderInline.h"
+#include "RenderLayer.h"
+#include "RenderObject.h"
+#include "RenderView.h"
+
+namespace WebCore {
+
+namespace {
+
+inline LayoutPoint ownerFrameToMainFrameOffset(const RenderObject* o)
+{
+ ASSERT(o->node());
+ Frame& containingFrame = o->frame();
+
+ Frame& mainFrame = containingFrame.page()->mainFrame();
+
+ LayoutPoint mainFramePoint = mainFrame.view()->windowToContents(containingFrame.view()->contentsToWindow(IntPoint()));
+ return mainFramePoint;
+}
+
+AffineTransform localToAbsoluteTransform(const RenderObject* o)
+{
+ AffineTransform transform;
+ LayoutPoint referencePoint;
+
+ while (o) {
+ RenderObject* nextContainer = o->container();
+ if (!nextContainer)
+ break;
+
+ LayoutSize containerOffset = o->offsetFromContainer(nextContainer, referencePoint);
+ TransformationMatrix t;
+ o->getTransformFromContainer(nextContainer, containerOffset, t);
+
+ transform = t.toAffineTransform() * transform;
+ referencePoint.move(containerOffset);
+ o = nextContainer;
+ }
+
+ return transform;
+}
+
+inline bool contains(const LayoutRect& rect, int x)
+{
+ return !rect.isEmpty() && x >= rect.x() && x <= rect.maxX();
+}
+
+inline bool strikes(const LayoutRect& a, const LayoutRect& b)
+{
+ return !a.isEmpty() && !b.isEmpty()
+ && a.x() <= b.maxX() && b.x() <= a.maxX()
+ && a.y() <= b.maxY() && b.y() <= a.maxY();
+}
+
+inline void shiftXEdgesToContainIfStrikes(LayoutRect& rect, LayoutRect& other, bool isFirst)
+{
+ if (rect.isEmpty())
+ return;
+
+ if (other.isEmpty() || !strikes(rect, other))
+ return;
+
+ LayoutUnit leftSide = std::min(rect.x(), other.x());
+ LayoutUnit rightSide = std::max(rect.maxX(), other.maxX());
+
+ rect.shiftXEdgeTo(leftSide);
+ rect.shiftMaxXEdgeTo(rightSide);
+
+ if (isFirst)
+ other.shiftMaxXEdgeTo(rightSide);
+ else
+ other.shiftXEdgeTo(leftSide);
+}
+
+inline void addHighlightRect(Path& path, const LayoutRect& rect, const LayoutRect& prev, const LayoutRect& next)
+{
+ // The rounding check depends on the rects not intersecting eachother,
+ // or being contained for that matter.
+ ASSERT(!rect.intersects(prev));
+ ASSERT(!rect.intersects(next));
+
+ if (rect.isEmpty())
+ return;
+
+ const int rounding = 4;
+
+ FloatRect copy(rect);
+ copy.inflateX(rounding);
+ copy.inflateY(rounding / 2);
+
+ FloatSize rounded(rounding * 1.8, rounding * 1.8);
+ FloatSize squared(0, 0);
+
+ path.addBeziersForRoundedRect(copy,
+ contains(prev, rect.x()) ? squared : rounded,
+ contains(prev, rect.maxX()) ? squared : rounded,
+ contains(next, rect.x()) ? squared : rounded,
+ contains(next, rect.maxX()) ? squared : rounded);
+}
+
+Path absolutePathForRenderer(RenderObject* const o)
+{
+ ASSERT(o);
+
+ Vector<IntRect> rects;
+ LayoutPoint frameOffset = ownerFrameToMainFrameOffset(o);
+ o->addFocusRingRects(rects, frameOffset);
+
+ if (rects.isEmpty())
+ return Path();
+
+ // The basic idea is to allow up to three different boxes in order to highlight
+ // text with line breaks more nicer than using a bounding box.
+
+ // Merge all center boxes (all but the first and the last).
+ LayoutRect mid;
+
+ // Set the end value to integer. It ensures that no unsigned int overflow occurs
+ // in the test expression, in case of empty rects vector.
+ int end = rects.size() - 1;
+ for (int i = 1; i < end; ++i)
+ mid.uniteIfNonZero(rects.at(i));
+
+ LayoutRect first;
+ LayoutRect last;
+
+ // Add the first box, but merge it with the center boxes if it intersects or if the center box is empty.
+ if (rects.size() && !rects.first().isEmpty()) {
+ // If the mid box is empty at this point, unite it with the first box. This allows the first box to be
+ // united with the last box if they intersect in the following check for last. Not uniting them would
+ // trigger in assert in addHighlighRect due to the first and the last box intersecting, but being passed
+ // as two separate boxes.
+ if (mid.isEmpty() || mid.intersects(rects.first()))
+ mid.unite(rects.first());
+ else {
+ first = rects.first();
+ shiftXEdgesToContainIfStrikes(mid, first, /* isFirst */ true);
+ }
+ }
+
+ // Add the last box, but merge it with the center boxes if it intersects.
+ if (rects.size() > 1 && !rects.last().isEmpty()) {
+ // Adjust center boxes to boundary of last
+ if (mid.intersects(rects.last()))
+ mid.unite(rects.last());
+ else {
+ last = rects.last();
+ shiftXEdgesToContainIfStrikes(mid, last, /* isFirst */ false);
+ }
+ }
+
+ Vector<LayoutRect> drawableRects;
+ if (!first.isEmpty())
+ drawableRects.append(first);
+ if (!mid.isEmpty())
+ drawableRects.append(mid);
+ if (!last.isEmpty())
+ drawableRects.append(last);
+
+ // Clip the overflow rects if needed, before the ring path is formed to
+ // ensure rounded highlight rects.
+ for (int i = drawableRects.size() - 1; i >= 0; --i) {
+ LayoutRect& ringRect = drawableRects.at(i);
+ LayoutPoint ringRectLocation = ringRect.location();
+
+ ringRect.moveBy(-frameOffset);
+
+ RenderLayer* layer = o->enclosingLayer();
+ RenderObject* currentRenderer = o;
+
+ // Check ancestor layers for overflow clip and intersect them.
+ for (; layer; layer = layer->parent()) {
+ RenderLayerModelObject* layerRenderer = &layer->renderer();
+
+ if (layerRenderer->hasOverflowClip() && layerRenderer != currentRenderer) {
+ bool containerSkipped = false;
+ // Skip ancestor layers that are not containers for the current renderer.
+ currentRenderer->container(layerRenderer, &containerSkipped);
+ if (containerSkipped)
+ continue;
+ FloatQuad ringQuad = currentRenderer->localToContainerQuad(FloatQuad(ringRect), layerRenderer);
+ // Ignore quads that are not rectangular, since we can not currently highlight them nicely.
+ if (ringQuad.isRectilinear())
+ ringRect = ringQuad.enclosingBoundingBox();
+ else
+ ringRect = LayoutRect();
+ currentRenderer = layerRenderer;
+
+ ASSERT(layerRenderer->isBox());
+ ringRect.intersect(toRenderBox(layerRenderer)->borderBoxRect());
+
+ if (ringRect.isEmpty())
+ break;
+ }
+ }
+
+ if (ringRect.isEmpty()) {
+ drawableRects.remove(i);
+ continue;
+ }
+ // After clipping, reset the original position so that parents' transforms apply correctly.
+ ringRect.setLocation(ringRectLocation);
+ }
+
+ Path path;
+ for (size_t i = 0; i < drawableRects.size(); ++i) {
+ LayoutRect prev = i ? drawableRects.at(i - 1) : LayoutRect();
+ LayoutRect next = i < (drawableRects.size() - 1) ? drawableRects.at(i + 1) : LayoutRect();
+ addHighlightRect(path, drawableRects.at(i), prev, next);
+ }
+
+ path.transform(localToAbsoluteTransform(o));
+ return path;
+}
+
+} // anonymous namespace
+
+namespace GestureTapHighlighter {
+
+Path pathForNodeHighlight(const Node* node)
+{
+ RenderObject* renderer = node->renderer();
+
+ if (!renderer || (!renderer->isBox() && !renderer->isRenderInline()))
+ return Path();
+
+ return absolutePathForRenderer(renderer);
+}
+
+} // namespace GestureTapHighlighter
+
+} // namespace WebCore
diff --git a/Source/WebCore/page/WheelEventTestTrigger.h b/Source/WebCore/page/GestureTapHighlighter.h
index b8c9b9d61..e8015fe5c 100644
--- a/Source/WebCore/page/WheelEventTestTrigger.h
+++ b/Source/WebCore/page/GestureTapHighlighter.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Inc. ("Apple") nor the names of
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
@@ -26,44 +26,21 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef WheelEventTestTrigger_h
-#define WheelEventTestTrigger_h
-
-#include <set>
-#include <wtf/HashMap.h>
-#include <wtf/Lock.h>
-#include <wtf/RefPtr.h>
-#include <wtf/RunLoop.h>
-#include <wtf/ThreadSafeRefCounted.h>
+#ifndef GestureTapHighlighter_h
+#define GestureTapHighlighter_h
namespace WebCore {
-class WheelEventTestTrigger : public ThreadSafeRefCounted<WheelEventTestTrigger> {
- WTF_MAKE_NONCOPYABLE(WheelEventTestTrigger); WTF_MAKE_FAST_ALLOCATED;
-public:
- WheelEventTestTrigger();
+class AffineTransform;
+class Path;
+class Node;
+
+namespace GestureTapHighlighter {
- WEBCORE_EXPORT void setTestCallbackAndStartNotificationTimer(std::function<void()>);
- WEBCORE_EXPORT void clearAllTestDeferrals();
-
- enum DeferTestTriggerReason {
- RubberbandInProgress,
- ScrollSnapInProgress,
- ScrollingThreadSyncNeeded,
- ContentScrollInProgress
- };
- typedef const void* ScrollableAreaIdentifier;
- void WEBCORE_EXPORT deferTestsForReason(ScrollableAreaIdentifier, DeferTestTriggerReason);
- void WEBCORE_EXPORT removeTestDeferralForReason(ScrollableAreaIdentifier, DeferTestTriggerReason);
- void triggerTestTimerFired();
+Path pathForNodeHighlight(const Node*);
-private:
- std::function<void()> m_testNotificationCallback;
- RunLoop::Timer<WheelEventTestTrigger> m_testTriggerTimer;
- mutable Lock m_testTriggerMutex;
- WTF::HashMap<ScrollableAreaIdentifier, std::set<DeferTestTriggerReason>> m_deferTestTriggerReasons;
-};
+} // namespace GestureTapHighlighter
-}
+} // namespace WebCore
-#endif
+#endif // GestureTapHighlighter__h
diff --git a/Source/WebCore/page/GroupSettings.cpp b/Source/WebCore/page/GroupSettings.cpp
new file mode 100644
index 000000000..0762861e4
--- /dev/null
+++ b/Source/WebCore/page/GroupSettings.cpp
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "GroupSettings.h"
+
+namespace WebCore {
+
+GroupSettings::GroupSettings()
+ : m_localStorageQuotaBytes(5 * 1024 * 1024) // Suggested by the HTML5 spec.
+ , m_indexedDBQuotaBytes(5 * 1024 * 1024)
+{
+}
+
+void GroupSettings::setLocalStorageQuotaBytes(unsigned quota)
+{
+ m_localStorageQuotaBytes = quota;
+}
+
+void GroupSettings::setIndexedDBDatabasePath(const String& path)
+{
+ m_indexedDBDatabasePath = path;
+}
+
+void GroupSettings::setIndexedDBQuotaBytes(int64_t quota)
+{
+ m_indexedDBQuotaBytes = quota;
+}
+
+
+} // namespace WebCore
diff --git a/Source/WebCore/page/GroupSettings.h b/Source/WebCore/page/GroupSettings.h
new file mode 100644
index 000000000..e094f09c2
--- /dev/null
+++ b/Source/WebCore/page/GroupSettings.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GroupSettings_h
+#define GroupSettings_h
+
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+class PageGroup;
+
+class GroupSettings {
+ WTF_MAKE_NONCOPYABLE(GroupSettings); WTF_MAKE_FAST_ALLOCATED;
+public:
+ GroupSettings();
+
+ void setLocalStorageQuotaBytes(unsigned);
+ unsigned localStorageQuotaBytes() const { return m_localStorageQuotaBytes; }
+
+ void setIndexedDBQuotaBytes(int64_t);
+ int64_t indexedDBQuotaBytes() const { return m_indexedDBQuotaBytes; }
+
+ void setIndexedDBDatabasePath(const String&);
+ const String& indexedDBDatabasePath() const { return m_indexedDBDatabasePath; }
+
+private:
+ unsigned m_localStorageQuotaBytes;
+ String m_indexedDBDatabasePath;
+ int64_t m_indexedDBQuotaBytes;
+};
+
+} // namespace WebCore
+
+#endif // GroupSettings_h
diff --git a/Source/WebCore/page/History.cpp b/Source/WebCore/page/History.cpp
index b9571c1d4..5b5539cb5 100644
--- a/Source/WebCore/page/History.cpp
+++ b/Source/WebCore/page/History.cpp
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -34,19 +34,16 @@
#include "FrameLoaderClient.h"
#include "HistoryController.h"
#include "HistoryItem.h"
-#include "MainFrame.h"
#include "Page.h"
-#include "ScriptController.h"
#include "SecurityOrigin.h"
#include "SerializedScriptValue.h"
-#include <wtf/CheckedArithmetic.h>
#include <wtf/MainThread.h>
namespace WebCore {
History::History(Frame* frame)
: DOMWindowProperty(frame)
- , m_lastStateObjectRequested(nullptr)
+ , m_lastStateObjectRequested(0)
{
}
@@ -120,7 +117,7 @@ void History::go(ScriptExecutionContext* context, int distance)
return;
ASSERT(isMainThread());
- Document* activeDocument = downcast<Document>(context);
+ Document* activeDocument = toDocument(context);
if (!activeDocument)
return;
@@ -139,101 +136,29 @@ URL History::urlForState(const String& urlString)
return URL(baseURL, urlString);
}
-void History::stateObjectAdded(PassRefPtr<SerializedScriptValue> data, const String& title, const String& urlString, StateObjectType stateObjectType, ExceptionCodeWithMessage& ec)
+void History::stateObjectAdded(PassRefPtr<SerializedScriptValue> data, const String& title, const String& urlString, StateObjectType stateObjectType, ExceptionCode& ec)
{
- // Each unique main-frame document is only allowed to send 64mb of state object payload to the UI client/process.
- static uint32_t totalStateObjectPayloadLimit = 0x4000000;
- static unsigned perUserGestureStateObjectLimit = 100;
-
if (!m_frame || !m_frame->page())
return;
-
+
URL fullURL = urlForState(urlString);
if (!fullURL.isValid() || !m_frame->document()->securityOrigin()->canRequest(fullURL)) {
- ec.code = SECURITY_ERR;
- return;
- }
-
- Document* mainDocument = m_frame->page()->mainFrame().document();
- History* mainHistory = nullptr;
- if (mainDocument) {
- if (auto* mainDOMWindow = mainDocument->domWindow())
- mainHistory = mainDOMWindow->history();
- }
-
- if (!mainHistory)
- return;
-
- bool processingUserGesture = ScriptController::processingUserGesture();
- if (!processingUserGesture && mainHistory->m_nonUserGestureObjectsAdded >= perUserGestureStateObjectLimit) {
- ec.code = SECURITY_ERR;
- if (stateObjectType == StateObjectType::Replace)
- ec.message = String::format("Attempt to use history.replaceState() more than %u times without a user gesture", perUserGestureStateObjectLimit);
- else
- ec.message = String::format("Attempt to use history.pushState() more than %u times without a user gesture", perUserGestureStateObjectLimit);
- return;
- }
-
- double userGestureTimestamp = mainDocument->lastHandledUserGestureTimestamp();
- if (processingUserGesture) {
- if (mainHistory->m_currentUserGestureTimestamp < userGestureTimestamp) {
- mainHistory->m_currentUserGestureTimestamp = userGestureTimestamp;
- mainHistory->m_currentUserGestureObjectsAdded = 0;
- }
-
- if (mainHistory->m_currentUserGestureObjectsAdded >= perUserGestureStateObjectLimit) {
- ec.code = SECURITY_ERR;
- if (stateObjectType == StateObjectType::Replace)
- ec.message = String::format("Attempt to use history.replaceState() more than %u times per gesture", perUserGestureStateObjectLimit);
- else
- ec.message = String::format("Attempt to use history.pushState() more than %u times per user gesture", perUserGestureStateObjectLimit);
- return;
- }
- }
-
- Checked<unsigned> titleSize = title.length();
- titleSize *= 2;
-
- Checked<unsigned> urlSize = fullURL.string().length();
- urlSize *= 2;
-
- Checked<uint64_t> payloadSize = titleSize;
- payloadSize += urlSize;
- payloadSize += data ? data->data().size() : 0;
-
- Checked<uint64_t> newTotalUsage = mainHistory->m_totalStateObjectUsage;
-
- if (stateObjectType == StateObjectType::Replace)
- newTotalUsage -= m_mostRecentStateObjectUsage;
- newTotalUsage += payloadSize;
-
- if (newTotalUsage > totalStateObjectPayloadLimit) {
- ec.code = QUOTA_EXCEEDED_ERR;
- if (stateObjectType == StateObjectType::Replace)
- ec.message = ASCIILiteral("Attempt to store more data than allowed using history.replaceState()");
- else
- ec.message = ASCIILiteral("Attempt to store more data than allowed using history.pushState()");
+ ec = SECURITY_ERR;
return;
}
- m_mostRecentStateObjectUsage = payloadSize.unsafeGet();
-
- mainHistory->m_totalStateObjectUsage = newTotalUsage.unsafeGet();
- if (processingUserGesture)
- ++mainHistory->m_currentUserGestureObjectsAdded;
- else
- ++mainHistory->m_nonUserGestureObjectsAdded;
-
+ if (stateObjectType == StateObjectType::Push)
+ m_frame->loader().history().pushState(data, title, fullURL.string());
+ else if (stateObjectType == StateObjectType::Replace)
+ m_frame->loader().history().replaceState(data, title, fullURL.string());
+
if (!urlString.isEmpty())
m_frame->document()->updateURLForPushOrReplaceState(fullURL);
- if (stateObjectType == StateObjectType::Push) {
- m_frame->loader().history().pushState(data, title, fullURL.string());
+ if (stateObjectType == StateObjectType::Push)
m_frame->loader().client().dispatchDidPushStateWithinPage();
- } else if (stateObjectType == StateObjectType::Replace) {
- m_frame->loader().history().replaceState(data, title, fullURL.string());
+ else if (stateObjectType == StateObjectType::Replace)
m_frame->loader().client().dispatchDidReplaceStateWithinPage();
- }
}
} // namespace WebCore
diff --git a/Source/WebCore/page/History.h b/Source/WebCore/page/History.h
index ae37fc387..1e8568594 100644
--- a/Source/WebCore/page/History.h
+++ b/Source/WebCore/page/History.h
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -38,12 +38,11 @@ namespace WebCore {
class Frame;
class ScriptExecutionContext;
-struct ExceptionCodeWithMessage;
typedef int ExceptionCode;
class History : public ScriptWrappable, public RefCounted<History>, public DOMWindowProperty {
public:
- static Ref<History> create(Frame* frame) { return adoptRef(*new History(frame)); }
+ static PassRefPtr<History> create(Frame* frame) { return adoptRef(new History(frame)); }
unsigned length() const;
PassRefPtr<SerializedScriptValue> state();
@@ -62,7 +61,7 @@ public:
Push,
Replace
};
- void stateObjectAdded(PassRefPtr<SerializedScriptValue>, const String& title, const String& url, StateObjectType, ExceptionCodeWithMessage&);
+ void stateObjectAdded(PassRefPtr<SerializedScriptValue>, const String& title, const String& url, StateObjectType, ExceptionCode&);
private:
explicit History(Frame*);
@@ -72,16 +71,6 @@ private:
PassRefPtr<SerializedScriptValue> stateInternal() const;
RefPtr<SerializedScriptValue> m_lastStateObjectRequested;
-
- unsigned m_nonUserGestureObjectsAdded { 0 };
- unsigned m_currentUserGestureObjectsAdded { 0 };
- double m_currentUserGestureTimestamp { 0 };
-
- // For the main frame's History object to keep track of all state object usage.
- uint64_t m_totalStateObjectUsage { 0 };
-
- // For each individual History object to keep track of the most recent state object added.
- uint64_t m_mostRecentStateObjectUsage { 0 };
};
} // namespace WebCore
diff --git a/Source/WebCore/page/History.idl b/Source/WebCore/page/History.idl
index 0b7b2eeb6..2fc8c07f0 100644
--- a/Source/WebCore/page/History.idl
+++ b/Source/WebCore/page/History.idl
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -24,14 +24,18 @@
*/
[
+ JSCustomGetOwnPropertySlotAndDescriptor,
+ CustomNamedSetter,
GenerateIsReachable=ImplFrame,
+ CustomDeleteProperty,
+ CustomEnumerateProperty,
] interface History {
readonly attribute unsigned long length;
[CachedAttribute, Custom] readonly attribute SerializedScriptValue state;
- [CallWith=ScriptExecutionContext, ForwardDeclareInHeader] void back();
- [CallWith=ScriptExecutionContext, ForwardDeclareInHeader] void forward();
- [CallWith=ScriptExecutionContext, ForwardDeclareInHeader] void go([Default=Undefined] optional long distance);
+ [DoNotCheckSecurity, CallWith=ScriptExecutionContext] void back();
+ [DoNotCheckSecurity, CallWith=ScriptExecutionContext] void forward();
+ [DoNotCheckSecurity, CallWith=ScriptExecutionContext] void go([Default=Undefined] optional long distance);
[Custom, RaisesException] void pushState(any data, DOMString title, optional DOMString url);
[Custom, RaisesException] void replaceState(any data, DOMString title, optional DOMString url);
diff --git a/Source/WebCore/page/LayoutMilestones.h b/Source/WebCore/page/LayoutMilestones.h
index b125bc4ea..7007434bf 100644
--- a/Source/WebCore/page/LayoutMilestones.h
+++ b/Source/WebCore/page/LayoutMilestones.h
@@ -37,8 +37,7 @@ enum LayoutMilestoneFlag {
DidHitRelevantRepaintedObjectsAreaThreshold = 1 << 2,
DidFirstFlushForHeaderLayer = 1 << 3,
DidFirstLayoutAfterSuppressedIncrementalRendering = 1 << 4,
- DidFirstPaintAfterSuppressedIncrementalRendering = 1 << 5,
- ReachedSessionRestorationRenderTreeSizeThreshold = 1 << 6 // FIXME: only implemented by WK2 currently.
+ DidFirstPaintAfterSuppressedIncrementalRendering = 1 << 5
};
typedef unsigned LayoutMilestones;
diff --git a/Source/WebCore/page/Location.cpp b/Source/WebCore/page/Location.cpp
index fea54e4af..6ae9af0bf 100644
--- a/Source/WebCore/page/Location.cpp
+++ b/Source/WebCore/page/Location.cpp
@@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Inc. ("Apple") nor the names of
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
@@ -143,14 +143,14 @@ String Location::hash() const
return fragmentIdentifier.isEmpty() ? emptyString() : "#" + fragmentIdentifier;
}
-void Location::setHref(DOMWindow& activeWindow, DOMWindow& firstWindow, const String& url)
+void Location::setHref(const String& url, DOMWindow& activeWindow, DOMWindow& firstWindow)
{
if (!m_frame)
return;
- setLocation(activeWindow, firstWindow, url);
+ setLocation(url, activeWindow, firstWindow);
}
-void Location::setProtocol(DOMWindow& activeWindow, DOMWindow& firstWindow, const String& protocol, ExceptionCode& ec)
+void Location::setProtocol(const String& protocol, DOMWindow& activeWindow, DOMWindow& firstWindow, ExceptionCode& ec)
{
if (!m_frame)
return;
@@ -159,28 +159,28 @@ void Location::setProtocol(DOMWindow& activeWindow, DOMWindow& firstWindow, cons
ec = SYNTAX_ERR;
return;
}
- setLocation(activeWindow, firstWindow, url.string());
+ setLocation(url.string(), activeWindow, firstWindow);
}
-void Location::setHost(DOMWindow& activeWindow, DOMWindow& firstWindow, const String& host)
+void Location::setHost(const String& host, DOMWindow& activeWindow, DOMWindow& firstWindow)
{
if (!m_frame)
return;
URL url = m_frame->document()->url();
url.setHostAndPort(host);
- setLocation(activeWindow, firstWindow, url.string());
+ setLocation(url.string(), activeWindow, firstWindow);
}
-void Location::setHostname(DOMWindow& activeWindow, DOMWindow& firstWindow, const String& hostname)
+void Location::setHostname(const String& hostname, DOMWindow& activeWindow, DOMWindow& firstWindow)
{
if (!m_frame)
return;
URL url = m_frame->document()->url();
url.setHost(hostname);
- setLocation(activeWindow, firstWindow, url.string());
+ setLocation(url.string(), activeWindow, firstWindow);
}
-void Location::setPort(DOMWindow& activeWindow, DOMWindow& firstWindow, const String& portString)
+void Location::setPort(const String& portString, DOMWindow& activeWindow, DOMWindow& firstWindow)
{
if (!m_frame)
return;
@@ -190,28 +190,28 @@ void Location::setPort(DOMWindow& activeWindow, DOMWindow& firstWindow, const St
url.removePort();
else
url.setPort(port);
- setLocation(activeWindow, firstWindow, url.string());
+ setLocation(url.string(), activeWindow, firstWindow);
}
-void Location::setPathname(DOMWindow& activeWindow, DOMWindow& firstWindow, const String& pathname)
+void Location::setPathname(const String& pathname, DOMWindow& activeWindow, DOMWindow& firstWindow)
{
if (!m_frame)
return;
URL url = m_frame->document()->url();
url.setPath(pathname);
- setLocation(activeWindow, firstWindow, url.string());
+ setLocation(url.string(), activeWindow, firstWindow);
}
-void Location::setSearch(DOMWindow& activeWindow, DOMWindow& firstWindow, const String& search)
+void Location::setSearch(const String& search, DOMWindow& activeWindow, DOMWindow& firstWindow)
{
if (!m_frame)
return;
URL url = m_frame->document()->url();
url.setQuery(search);
- setLocation(activeWindow, firstWindow, url.string());
+ setLocation(url.string(), activeWindow, firstWindow);
}
-void Location::setHash(DOMWindow& activeWindow, DOMWindow& firstWindow, const String& hash)
+void Location::setHash(const String& hash, DOMWindow& activeWindow, DOMWindow& firstWindow)
{
if (!m_frame)
return;
@@ -226,22 +226,22 @@ void Location::setHash(DOMWindow& activeWindow, DOMWindow& firstWindow, const St
// cases where fragment identifiers are ignored or invalid.
if (equalIgnoringNullity(oldFragmentIdentifier, url.fragmentIdentifier()))
return;
- setLocation(activeWindow, firstWindow, url.string());
+ setLocation(url.string(), activeWindow, firstWindow);
}
-void Location::assign(DOMWindow& activeWindow, DOMWindow& firstWindow, const String& url)
+void Location::assign(const String& url, DOMWindow& activeWindow, DOMWindow& firstWindow)
{
if (!m_frame)
return;
- setLocation(activeWindow, firstWindow, url);
+ setLocation(url, activeWindow, firstWindow);
}
-void Location::replace(DOMWindow& activeWindow, DOMWindow& firstWindow, const String& url)
+void Location::replace(const String& url, DOMWindow& activeWindow, DOMWindow& firstWindow)
{
if (!m_frame)
return;
// Note: We call DOMWindow::setLocation directly here because replace() always operates on the current frame.
- m_frame->document()->domWindow()->setLocation(activeWindow, firstWindow, url, LockHistoryAndBackForwardList);
+ m_frame->document()->domWindow()->setLocation(url, activeWindow, firstWindow, LockHistoryAndBackForwardList);
}
void Location::reload(DOMWindow& activeWindow)
@@ -258,16 +258,17 @@ void Location::reload(DOMWindow& activeWindow)
}
if (protocolIsJavaScript(m_frame->document()->url()))
return;
- m_frame->navigationScheduler().scheduleRefresh(activeWindow.document());
+ m_frame->navigationScheduler().scheduleRefresh();
}
-void Location::setLocation(DOMWindow& activeWindow, DOMWindow& firstWindow, const String& url)
+void Location::setLocation(const String& url, DOMWindow& activeWindow, DOMWindow& firstWindow)
{
ASSERT(m_frame);
+ // We call findFrameForNavigation to handle the case of a seamless iframe correctly.
Frame* frame = m_frame->loader().findFrameForNavigation(String(), activeWindow.document());
if (!frame)
return;
- frame->document()->domWindow()->setLocation(activeWindow, firstWindow, url);
+ frame->document()->domWindow()->setLocation(url, activeWindow, firstWindow);
}
} // namespace WebCore
diff --git a/Source/WebCore/page/Location.h b/Source/WebCore/page/Location.h
index 204aebeee..b55c5a8f0 100644
--- a/Source/WebCore/page/Location.h
+++ b/Source/WebCore/page/Location.h
@@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Inc. ("Apple") nor the names of
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
@@ -46,28 +46,28 @@ typedef int ExceptionCode;
class Location : public ScriptWrappable, public RefCounted<Location>, public DOMWindowProperty {
public:
- static Ref<Location> create(Frame* frame) { return adoptRef(*new Location(frame)); }
+ static PassRefPtr<Location> create(Frame* frame) { return adoptRef(new Location(frame)); }
- void setHref(DOMWindow& activeWindow, DOMWindow& firstWindow, const String&);
+ void setHref(const String&, DOMWindow& activeWindow, DOMWindow& firstWindow);
String href() const;
- void assign(DOMWindow& activeWindow, DOMWindow& firstWindow, const String&);
- void replace(DOMWindow& activeWindow, DOMWindow& firstWindow, const String&);
+ void assign(const String&, DOMWindow& activeWindow, DOMWindow& firstWindow);
+ void replace(const String&, DOMWindow& activeWindow, DOMWindow& firstWindow);
void reload(DOMWindow& activeWindow);
- void setProtocol(DOMWindow& activeWindow, DOMWindow& firstWindow, const String&, ExceptionCode&);
+ void setProtocol(const String&, DOMWindow& activeWindow, DOMWindow& firstWindow, ExceptionCode&);
String protocol() const;
- void setHost(DOMWindow& activeWindow, DOMWindow& firstWindow, const String&);
+ void setHost(const String&, DOMWindow& activeWindow, DOMWindow& firstWindow);
String host() const;
- void setHostname(DOMWindow& activeWindow, DOMWindow& firstWindow, const String&);
+ void setHostname(const String&, DOMWindow& activeWindow, DOMWindow& firstWindow);
String hostname() const;
- void setPort(DOMWindow& activeWindow, DOMWindow& firstWindow, const String&);
+ void setPort(const String&, DOMWindow& activeWindow, DOMWindow& firstWindow);
String port() const;
- void setPathname(DOMWindow& activeWindow, DOMWindow& firstWindow, const String&);
+ void setPathname(const String&, DOMWindow& activeWindow, DOMWindow& firstWindow);
String pathname() const;
- void setSearch(DOMWindow& activeWindow, DOMWindow& firstWindow, const String&);
+ void setSearch(const String&, DOMWindow& activeWindow, DOMWindow& firstWindow);
String search() const;
- void setHash(DOMWindow& activeWindow, DOMWindow& firstWindow, const String&);
+ void setHash(const String&, DOMWindow& activeWindow, DOMWindow& firstWindow);
String hash() const;
String origin() const;
@@ -78,7 +78,7 @@ public:
private:
explicit Location(Frame*);
- void setLocation(DOMWindow& activeWindow, DOMWindow& firstWindow, const String&);
+ void setLocation(const String&, DOMWindow& activeWindow, DOMWindow& firstWindow);
const URL& url() const;
};
diff --git a/Source/WebCore/page/Location.idl b/Source/WebCore/page/Location.idl
index 6bd2da3a7..7eeb6be92 100644
--- a/Source/WebCore/page/Location.idl
+++ b/Source/WebCore/page/Location.idl
@@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Inc. ("Apple") nor the names of
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
@@ -35,24 +35,28 @@
JSCustomDefineOwnProperty,
JSCustomNamedGetterOnPrototype,
JSCustomDefineOwnPropertyOnPrototype,
- Unforgeable
+ OperationsNotDeletable
] interface Location {
- [SetterCallWith=ActiveWindow&FirstWindow] attribute DOMString href;
+#if !defined(LANGUAGE_CPP) || !LANGUAGE_CPP
+ [DoNotCheckSecurityOnSetter, CustomSetter] attribute DOMString href;
+#endif
- [CallWith=ActiveWindow&FirstWindow, ForwardDeclareInHeader] void assign(DOMString url);
- [CallWith=ActiveWindow&FirstWindow, ForwardDeclareInHeader] void replace(DOMString url);
- [CallWith=ActiveWindow, ForwardDeclareInHeader] void reload();
+ [Custom] void assign([Default=Undefined] optional DOMString url);
+ [Custom] void replace([Default=Undefined] optional DOMString url);
+ [Custom] void reload();
// URI decomposition attributes
- [SetterCallWith=ActiveWindow&FirstWindow, SetterRaisesException] attribute DOMString protocol;
- [SetterCallWith=ActiveWindow&FirstWindow] attribute DOMString host;
- [SetterCallWith=ActiveWindow&FirstWindow] attribute DOMString hostname;
- [SetterCallWith=ActiveWindow&FirstWindow] attribute DOMString port;
- [SetterCallWith=ActiveWindow&FirstWindow] attribute DOMString pathname;
- [SetterCallWith=ActiveWindow&FirstWindow] attribute DOMString search;
- [SetterCallWith=ActiveWindow&FirstWindow] attribute DOMString hash;
+#if !defined(LANGUAGE_CPP) || !LANGUAGE_CPP
+ [CustomSetter] attribute DOMString protocol;
+ [CustomSetter] attribute DOMString host;
+ [CustomSetter] attribute DOMString hostname;
+ [CustomSetter] attribute DOMString port;
+ [CustomSetter] attribute DOMString pathname;
+ [CustomSetter] attribute DOMString search;
+ [CustomSetter] attribute DOMString hash;
- readonly attribute DOMString origin;
+ readonly attribute DOMString origin;
+#endif
readonly attribute DOMStringList ancestorOrigins;
diff --git a/Source/WebCore/page/MainFrame.cpp b/Source/WebCore/page/MainFrame.cpp
index 48ab95de6..054a0625c 100644
--- a/Source/WebCore/page/MainFrame.cpp
+++ b/Source/WebCore/page/MainFrame.cpp
@@ -1,82 +1,43 @@
/*
- * Copyright (C) 2013-2016 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
+
+Copyright (C) 2013 Apple Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
#include "config.h"
#include "MainFrame.h"
-#include "Element.h"
-#include "EmptyClients.h"
-#include "EventHandler.h"
-#include "PageConfiguration.h"
-#include "PageOverlayController.h"
-#include "ScrollLatchingState.h"
-#include "Settings.h"
-#include "WheelEventDeltaFilter.h"
-#include <wtf/NeverDestroyed.h>
-
-#if PLATFORM(MAC)
-#include "ServicesOverlayController.h"
-#endif /* PLATFORM(MAC) */
-
-#if USE(APPLE_INTERNAL_SDK)
-#include <WebKitAdditions/MainFrameIncludes.h>
-#endif
-
namespace WebCore {
-inline MainFrame::MainFrame(Page& page, PageConfiguration& configuration)
- : Frame(page, nullptr, *configuration.loaderClientForMainFrame)
+inline MainFrame::MainFrame(Page& page, FrameLoaderClient& client)
+ : Frame(page, nullptr, client)
, m_selfOnlyRefCount(0)
-#if PLATFORM(MAC)
-#if ENABLE(SERVICE_CONTROLS) || ENABLE(TELEPHONE_NUMBER_DETECTION)
- , m_servicesOverlayController(std::make_unique<ServicesOverlayController>(*this))
-#endif
-#endif
- , m_recentWheelEventDeltaFilter(WheelEventDeltaFilter::create())
- , m_pageOverlayController(std::make_unique<PageOverlayController>(*this))
- , m_diagnosticLoggingClient(configuration.diagnosticLoggingClient)
{
-#if USE(APPLE_INTERNAL_SDK)
-#include <WebKitAdditions/MainFrameInitialization.cpp>
-#endif
-}
-
-MainFrame::~MainFrame()
-{
- if (m_diagnosticLoggingClient)
- m_diagnosticLoggingClient->mainFrameDestroyed();
-
- m_recentWheelEventDeltaFilter = nullptr;
- m_eventHandler = nullptr;
-
- setMainFrameWasDestroyed();
}
-Ref<MainFrame> MainFrame::create(Page& page, PageConfiguration& configuration)
+RefPtr<MainFrame> MainFrame::create(Page& page, FrameLoaderClient& client)
{
- return adoptRef(*new MainFrame(page, configuration));
+ return adoptRef(new MainFrame(page, client));
}
void MainFrame::selfOnlyRef()
@@ -99,58 +60,10 @@ void MainFrame::selfOnlyDeref()
deref();
}
-DiagnosticLoggingClient& MainFrame::diagnosticLoggingClient() const
-{
- static NeverDestroyed<EmptyDiagnosticLoggingClient> dummyClient;
- if (!settings().diagnosticLoggingEnabled() || !m_diagnosticLoggingClient)
- return dummyClient;
-
- return *m_diagnosticLoggingClient;
-}
-
void MainFrame::dropChildren()
{
while (Frame* child = tree().firstChild())
tree().removeChild(child);
}
-#if PLATFORM(MAC)
-ScrollLatchingState* MainFrame::latchingState()
-{
- if (m_latchingState.isEmpty())
- return nullptr;
-
- return &m_latchingState.last();
-}
-
-void MainFrame::pushNewLatchingState()
-{
- m_latchingState.append(ScrollLatchingState());
-}
-
-void MainFrame::resetLatchingState()
-{
- m_latchingState.clear();
-}
-
-void MainFrame::popLatchingState()
-{
- m_latchingState.removeLast();
-}
-
-void MainFrame::removeLatchingStateForTarget(Element& targetNode)
-{
- if (m_latchingState.isEmpty())
- return;
-
- m_latchingState.removeAllMatching([&targetNode] (ScrollLatchingState& state) {
- auto* wheelElement = state.wheelEventElement();
- if (!wheelElement)
- return false;
-
- return targetNode.isEqualNode(wheelElement);
- });
-}
-#endif
-
}
diff --git a/Source/WebCore/page/MainFrame.h b/Source/WebCore/page/MainFrame.h
index 45c1f1c43..2e7828a71 100644
--- a/Source/WebCore/page/MainFrame.h
+++ b/Source/WebCore/page/MainFrame.h
@@ -1,94 +1,49 @@
/*
- * Copyright (C) 2013-2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
+
+Copyright (C) 2013 Apple Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
#ifndef MainFrame_h
#define MainFrame_h
#include "Frame.h"
-#include <wtf/Vector.h>
-
-#if USE(APPLE_INTERNAL_SDK)
-#include <WebKitAdditions/MainFrameIncludes.h>
-#endif
namespace WebCore {
-class DiagnosticLoggingClient;
-class PageConfiguration;
-class PageOverlayController;
-class ScrollLatchingState;
-class ServicesOverlayController;
-class WheelEventDeltaFilter;
-
class MainFrame final : public Frame {
public:
- static Ref<MainFrame> create(Page&, PageConfiguration&);
-
- virtual ~MainFrame();
+ static RefPtr<MainFrame> create(Page&, FrameLoaderClient&);
void selfOnlyRef();
void selfOnlyDeref();
- WheelEventDeltaFilter* wheelEventDeltaFilter() { return m_recentWheelEventDeltaFilter.get(); }
- PageOverlayController& pageOverlayController() { return *m_pageOverlayController; }
-
-#if PLATFORM(MAC)
-#if ENABLE(SERVICE_CONTROLS) || ENABLE(TELEPHONE_NUMBER_DETECTION)
- ServicesOverlayController& servicesOverlayController() { return *m_servicesOverlayController; }
-#endif // ENABLE(SERVICE_CONTROLS) || ENABLE(TELEPHONE_NUMBER_DETECTION)
-
- ScrollLatchingState* latchingState();
- void pushNewLatchingState();
- void popLatchingState();
- void resetLatchingState();
- void removeLatchingStateForTarget(Element&);
-#endif // PLATFORM(MAC)
-
- WEBCORE_EXPORT DiagnosticLoggingClient& diagnosticLoggingClient() const;
-
-#if USE(APPLE_INTERNAL_SDK)
-#include <WebKitAdditions/MainFrameMembers.h>
-#endif
-
private:
- MainFrame(Page&, PageConfiguration&);
+ MainFrame(Page&, FrameLoaderClient&);
void dropChildren();
unsigned m_selfOnlyRefCount;
-
-#if PLATFORM(MAC)
- Vector<ScrollLatchingState> m_latchingState;
-#if ENABLE(SERVICE_CONTROLS) || ENABLE(TELEPHONE_NUMBER_DETECTION)
- std::unique_ptr<ServicesOverlayController> m_servicesOverlayController;
-#endif
-#endif
-
- std::unique_ptr<WheelEventDeltaFilter> m_recentWheelEventDeltaFilter;
- std::unique_ptr<PageOverlayController> m_pageOverlayController;
- DiagnosticLoggingClient* m_diagnosticLoggingClient;
};
inline bool Frame::isMainFrame() const
diff --git a/Source/WebCore/page/MediaProducer.h b/Source/WebCore/page/MediaProducer.h
deleted file mode 100644
index 1fbb791ea..000000000
--- a/Source/WebCore/page/MediaProducer.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef MediaProducer_h
-#define MediaProducer_h
-
-namespace WebCore {
-
-class MediaProducer {
-public:
- enum MediaState {
- IsNotPlaying = 0,
- IsPlayingAudio = 1 << 0,
- IsPlayingVideo = 1 << 1,
- IsPlayingToExternalDevice = 1 << 2,
- RequiresPlaybackTargetMonitoring = 1 << 3,
- ExternalDeviceAutoPlayCandidate = 1 << 4,
- DidPlayToEnd = 1 << 5,
- IsSourceElementPlaying = 1 << 6,
- IsNextTrackControlEnabled = 1 << 7,
- IsPreviousTrackControlEnabled = 1 << 8,
- HasPlaybackTargetAvailabilityListener = 1 << 9,
- HasAudioOrVideo = 1 << 10,
- };
- typedef unsigned MediaStateFlags;
-
- virtual MediaStateFlags mediaState() const = 0;
- virtual void pageMutedStateDidChange() = 0;
-
-protected:
- virtual ~MediaProducer() { }
-};
-
-}
-
-#endif
diff --git a/Source/WebCore/page/MouseEventWithHitTestResults.cpp b/Source/WebCore/page/MouseEventWithHitTestResults.cpp
index b93ac71b4..e0305687d 100644
--- a/Source/WebCore/page/MouseEventWithHitTestResults.cpp
+++ b/Source/WebCore/page/MouseEventWithHitTestResults.cpp
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2006 Apple Inc.
+ Copyright (C) 2006 Apple Computer, Inc.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
diff --git a/Source/WebCore/page/MouseEventWithHitTestResults.h b/Source/WebCore/page/MouseEventWithHitTestResults.h
index 6d6d6f739..e20790032 100644
--- a/Source/WebCore/page/MouseEventWithHitTestResults.h
+++ b/Source/WebCore/page/MouseEventWithHitTestResults.h
@@ -1,6 +1,6 @@
/*
Copyright (C) 2000 Simon Hausmann <hausmann@kde.org>
- Copyright (C) 2006 Apple Inc.
+ Copyright (C) 2006 Apple Computer, Inc.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
diff --git a/Source/WebCore/page/Navigator.cpp b/Source/WebCore/page/Navigator.cpp
index 25895bf54..b88015b79 100644
--- a/Source/WebCore/page/Navigator.cpp
+++ b/Source/WebCore/page/Navigator.cpp
@@ -2,7 +2,7 @@
* Copyright (C) 2000 Harri Porten (porten@kde.org)
* Copyright (c) 2000 Daniel Molkentin (molkentin@kde.org)
* Copyright (c) 2000 Stefan Schimanski (schimmi@kde.org)
- * Copyright (C) 2003, 2004, 2005, 2006 Apple Inc.
+ * Copyright (C) 2003, 2004, 2005, 2006 Apple Computer, Inc.
* Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
*
* This library is free software; you can redistribute it and/or
@@ -37,12 +37,10 @@
#include "ScriptController.h"
#include "SecurityOrigin.h"
#include "Settings.h"
+#include "StorageNamespace.h"
#include <wtf/HashSet.h>
-#include <wtf/NumberOfCores.h>
#include <wtf/StdLibExtras.h>
-using namespace WTF;
-
namespace WebCore {
Navigator::Navigator(Frame* frame)
@@ -134,28 +132,6 @@ bool Navigator::javaEnabled() const
return true;
}
-#if defined(ENABLE_NAVIGATOR_HWCONCURRENCY)
-int Navigator::hardwareConcurrency() const
-{
- // Enforce a maximum for the number of cores reported to mitigate
- // fingerprinting for the minority of machines with large numbers of cores.
- // If machines with more than 8 cores become commonplace, we should bump this number.
- // see https://bugs.webkit.org/show_bug.cgi?id=132588 for the
- // rationale behind this decision.
-#if PLATFORM(IOS)
- const int maxCoresToReport = 2;
-#else
- const int maxCoresToReport = 8;
-#endif
- int hardwareConcurrency = numberOfProcessorCores();
-
- if (hardwareConcurrency > maxCoresToReport)
- return maxCoresToReport;
-
- return hardwareConcurrency;
-}
-#endif
-
#if PLATFORM(IOS)
bool Navigator::standalone() const
{
diff --git a/Source/WebCore/page/Navigator.h b/Source/WebCore/page/Navigator.h
index 16abdd867..044485e44 100644
--- a/Source/WebCore/page/Navigator.h
+++ b/Source/WebCore/page/Navigator.h
@@ -41,7 +41,7 @@ typedef int ExceptionCode;
class Navigator : public NavigatorBase, public ScriptWrappable, public RefCounted<Navigator>, public DOMWindowProperty, public Supplementable<Navigator> {
public:
- static Ref<Navigator> create(Frame* frame) { return adoptRef(*new Navigator(frame)); }
+ static PassRefPtr<Navigator> create(Frame* frame) { return adoptRef(new Navigator(frame)); }
virtual ~Navigator();
String appVersion() const;
@@ -50,9 +50,7 @@ public:
DOMMimeTypeArray* mimeTypes() const;
bool cookieEnabled() const;
bool javaEnabled() const;
-#if defined(ENABLE_NAVIGATOR_HWCONCURRENCY)
- int hardwareConcurrency() const;
-#endif
+
virtual String userAgent() const;
#if PLATFORM(IOS)
diff --git a/Source/WebCore/page/Navigator.idl b/Source/WebCore/page/Navigator.idl
index bdce4f24f..638d5a56c 100644
--- a/Source/WebCore/page/Navigator.idl
+++ b/Source/WebCore/page/Navigator.idl
@@ -20,27 +20,23 @@
[
GenerateIsReachable=ImplFrame,
] interface Navigator {
- [Nondeterministic] readonly attribute DOMString appCodeName;
- [Nondeterministic] readonly attribute DOMString appName;
- [Nondeterministic] readonly attribute DOMString appVersion;
- [Nondeterministic] readonly attribute DOMString language;
- [Nondeterministic] readonly attribute DOMString userAgent;
- [Nondeterministic] readonly attribute DOMString platform;
+ readonly attribute DOMString appCodeName;
+ readonly attribute DOMString appName;
+ readonly attribute DOMString appVersion;
+ readonly attribute DOMString language;
+ readonly attribute DOMString userAgent;
+ readonly attribute DOMString platform;
readonly attribute DOMPluginArray plugins;
readonly attribute DOMMimeTypeArray mimeTypes;
- [Nondeterministic] readonly attribute DOMString product;
- [Nondeterministic] readonly attribute DOMString productSub;
- [Nondeterministic] readonly attribute DOMString vendor;
- [Nondeterministic] readonly attribute DOMString vendorSub;
- [Nondeterministic] readonly attribute boolean cookieEnabled;
- [Nondeterministic] boolean javaEnabled();
+ readonly attribute DOMString product;
+ readonly attribute DOMString productSub;
+ readonly attribute DOMString vendor;
+ readonly attribute DOMString vendorSub;
+ readonly attribute boolean cookieEnabled;
+ boolean javaEnabled();
readonly attribute boolean onLine;
-#if defined(ENABLE_NAVIGATOR_HWCONCURRENCY)
- readonly attribute long hardwareConcurrency;
-#endif
-
// FIXME: Convert this #if'def to an IDL conditional attribute.
#if defined(WTF_PLATFORM_IOS) && WTF_PLATFORM_IOS
readonly attribute boolean standalone;
diff --git a/Source/WebCore/page/NavigatorBase.cpp b/Source/WebCore/page/NavigatorBase.cpp
index 0be2e1fb8..eb2f8f7cc 100644
--- a/Source/WebCore/page/NavigatorBase.cpp
+++ b/Source/WebCore/page/NavigatorBase.cpp
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -28,7 +28,6 @@
#include "NavigatorBase.h"
#include "NetworkStateNotifier.h"
-#include <wtf/NeverDestroyed.h>
#include <wtf/text/WTFString.h>
#if OS(LINUX)
@@ -37,12 +36,12 @@
#endif
#if PLATFORM(IOS)
-#include "Device.h"
+#include "WebCoreSystemInterface.h"
#endif
#ifndef WEBCORE_NAVIGATOR_PLATFORM
#if PLATFORM(IOS)
-#define WEBCORE_NAVIGATOR_PLATFORM deviceName()
+#define WEBCORE_NAVIGATOR_PLATFORM ""
#elif OS(MAC_OS_X) && (CPU(PPC) || CPU(PPC64))
#define WEBCORE_NAVIGATOR_PLATFORM "MacPPC"
#elif OS(MAC_OS_X) && (CPU(X86) || CPU(X86_64))
@@ -70,6 +69,7 @@
#define WEBCORE_NAVIGATOR_VENDOR_SUB ""
#endif // ifndef WEBCORE_NAVIGATOR_VENDOR_SUB
+
namespace WebCore {
NavigatorBase::~NavigatorBase()
@@ -94,7 +94,7 @@ String NavigatorBase::platform() const
if (!String(WEBCORE_NAVIGATOR_PLATFORM).isEmpty())
return WEBCORE_NAVIGATOR_PLATFORM;
struct utsname osname;
- static NeverDestroyed<String> platformName(uname(&osname) >= 0 ? String(osname.sysname) + String(" ") + String(osname.machine) : emptyString());
+ DEFINE_STATIC_LOCAL(String, platformName, (uname(&osname) >= 0 ? String(osname.sysname) + String(" ") + String(osname.machine) : emptyString()));
return platformName;
#else
return WEBCORE_NAVIGATOR_PLATFORM;
diff --git a/Source/WebCore/page/NavigatorBase.h b/Source/WebCore/page/NavigatorBase.h
index 5283f5698..8f576e387 100644
--- a/Source/WebCore/page/NavigatorBase.h
+++ b/Source/WebCore/page/NavigatorBase.h
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
diff --git a/Source/WebCore/page/OriginAccessEntry.cpp b/Source/WebCore/page/OriginAccessEntry.cpp
index 8c123ae26..7ff67cc46 100644
--- a/Source/WebCore/page/OriginAccessEntry.cpp
+++ b/Source/WebCore/page/OriginAccessEntry.cpp
@@ -36,8 +36,8 @@
namespace WebCore {
OriginAccessEntry::OriginAccessEntry(const String& protocol, const String& host, SubdomainSetting subdomainSetting)
- : m_protocol(protocol.convertToASCIILowercase())
- , m_host(host.convertToASCIILowercase())
+ : m_protocol(protocol.lower())
+ , m_host(host.lower())
, m_subdomainSettings(subdomainSetting)
{
ASSERT(subdomainSetting == AllowSubdomains || subdomainSetting == DisallowSubdomains);
@@ -48,8 +48,8 @@ OriginAccessEntry::OriginAccessEntry(const String& protocol, const String& host,
bool OriginAccessEntry::matchesOrigin(const SecurityOrigin& origin) const
{
- ASSERT(origin.host() == origin.host().convertToASCIILowercase());
- ASSERT(origin.protocol() == origin.protocol().convertToASCIILowercase());
+ ASSERT(origin.host() == origin.host().lower());
+ ASSERT(origin.protocol() == origin.protocol().lower());
if (m_protocol != origin.protocol())
return false;
diff --git a/Source/WebCore/page/OriginAccessEntry.h b/Source/WebCore/page/OriginAccessEntry.h
index 06614e12d..183600bde 100644
--- a/Source/WebCore/page/OriginAccessEntry.h
+++ b/Source/WebCore/page/OriginAccessEntry.h
@@ -61,7 +61,7 @@ private:
inline bool operator==(const OriginAccessEntry& a, const OriginAccessEntry& b)
{
- return equalIgnoringASCIICase(a.protocol(), b.protocol()) && equalIgnoringASCIICase(a.host(), b.host()) && a.subdomainSettings() == b.subdomainSettings();
+ return equalIgnoringCase(a.protocol(), b.protocol()) && equalIgnoringCase(a.host(), b.host()) && a.subdomainSettings() == b.subdomainSettings();
}
inline bool operator!=(const OriginAccessEntry& a, const OriginAccessEntry& b)
diff --git a/Source/WebCore/page/Page.cpp b/Source/WebCore/page/Page.cpp
index c895df184..d5d994919 100644
--- a/Source/WebCore/page/Page.cpp
+++ b/Source/WebCore/page/Page.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006-2015 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All Rights Reserved.
* Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
*
* This library is free software; you can redistribute it and/or
@@ -22,7 +22,6 @@
#include "AlternativeTextClient.h"
#include "AnimationController.h"
-#include "ApplicationCacheStorage.h"
#include "BackForwardClient.h"
#include "BackForwardController.h"
#include "Chrome.h"
@@ -30,9 +29,9 @@
#include "ClientRectList.h"
#include "ContextMenuClient.h"
#include "ContextMenuController.h"
-#include "DatabaseProvider.h"
-#include "DocumentLoader.h"
+#include "DOMWindow.h"
#include "DocumentMarkerController.h"
+#include "DocumentStyleSheetCollection.h"
#include "DragController.h"
#include "Editor.h"
#include "EditorClient.h"
@@ -40,7 +39,6 @@
#include "EventNames.h"
#include "ExceptionCode.h"
#include "ExceptionCodePlaceholder.h"
-#include "ExtensionStyleSheets.h"
#include "FileSystem.h"
#include "FocusController.h"
#include "FrameLoader.h"
@@ -58,23 +56,21 @@
#include "MediaCanStartListener.h"
#include "Navigator.h"
#include "NetworkStateNotifier.h"
+#include "PageActivityAssertionToken.h"
#include "PageCache.h"
-#include "PageConfiguration.h"
-#include "PageConsoleClient.h"
+#include "PageConsole.h"
#include "PageDebuggable.h"
#include "PageGroup.h"
-#include "PageOverlayController.h"
#include "PageThrottler.h"
#include "PlugInClient.h"
#include "PluginData.h"
-#include "PluginViewBase.h"
+#include "PluginView.h"
#include "PointerLockController.h"
#include "ProgressTracker.h"
#include "RenderLayerCompositor.h"
#include "RenderTheme.h"
#include "RenderView.h"
#include "RenderWidget.h"
-#include "ResourceUsageOverlay.h"
#include "RuntimeEnabledFeatures.h"
#include "SchemeRegistry.h"
#include "ScriptController.h"
@@ -83,105 +79,75 @@
#include "SharedBuffer.h"
#include "StorageArea.h"
#include "StorageNamespace.h"
-#include "StorageNamespaceProvider.h"
#include "StyleResolver.h"
#include "SubframeLoader.h"
#include "TextResourceDecoder.h"
#include "UserContentController.h"
-#include "UserInputBridge.h"
-#include "ViewStateChangeObserver.h"
#include "VisitedLinkState.h"
-#include "VisitedLinkStore.h"
#include "VoidCallback.h"
#include "Widget.h"
-#include <JavaScriptCore/Profile.h>
#include <wtf/HashMap.h>
#include <wtf/RefCountedLeakCounter.h>
#include <wtf/StdLibExtras.h>
#include <wtf/text/Base64.h>
#include <wtf/text/StringHash.h>
-#if ENABLE(WEB_REPLAY)
-#include "ReplayController.h"
-#include <replay/InputCursor.h>
-#endif
-
-#if ENABLE(WIRELESS_PLAYBACK_TARGET)
-#include "HTMLVideoElement.h"
-#include "MediaPlaybackTarget.h"
-#endif
-
-#if ENABLE(MEDIA_SESSION)
-#include "MediaSessionManager.h"
-#endif
-
-#if ENABLE(INDEXED_DATABASE)
-#include "IDBConnectionToServer.h"
-#include "InProcessIDBServer.h"
-#endif
-
namespace WebCore {
static HashSet<Page*>* allPages;
DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, pageCounter, ("Page"));
-void Page::forEachPage(std::function<void(Page&)> function)
-{
- if (!allPages)
- return;
- for (Page* page : *allPages)
- function(*page);
-}
-
static void networkStateChanged(bool isOnLine)
{
Vector<Ref<Frame>> frames;
// Get all the frames of all the pages in all the page groups
- for (auto& page : *allPages) {
- for (Frame* frame = &page->mainFrame(); frame; frame = frame->tree().traverseNext())
+ for (auto it = allPages->begin(), end = allPages->end(); it != end; ++it) {
+ for (Frame* frame = &(*it)->mainFrame(); frame; frame = frame->tree().traverseNext())
frames.append(*frame);
- InspectorInstrumentation::networkStateChanged(page);
+ InspectorInstrumentation::networkStateChanged(*it);
}
AtomicString eventName = isOnLine ? eventNames().onlineEvent : eventNames().offlineEvent;
- for (auto& frame : frames) {
- if (!frame->document())
- continue;
- frame->document()->dispatchWindowEvent(Event::create(eventName, false, false));
- }
+ for (unsigned i = 0; i < frames.size(); i++)
+ frames[i]->document()->dispatchWindowEvent(Event::create(eventName, false, false));
}
-static const ViewState::Flags PageInitialViewState = ViewState::IsVisible | ViewState::IsInWindow;
-bool Page::s_tabSuspensionIsEnabled = false;
+float deviceScaleFactor(Frame* frame)
+{
+ if (!frame)
+ return 1;
+ Page* page = frame->page();
+ if (!page)
+ return 1;
+ return page->deviceScaleFactor();
+}
-Page::Page(PageConfiguration& pageConfiguration)
- : m_chrome(std::make_unique<Chrome>(*this, *pageConfiguration.chromeClient))
+Page::Page(PageClients& pageClients)
+ : m_chrome(std::make_unique<Chrome>(*this, *pageClients.chromeClient))
, m_dragCaretController(std::make_unique<DragCaretController>())
#if ENABLE(DRAG_SUPPORT)
- , m_dragController(std::make_unique<DragController>(*this, *pageConfiguration.dragClient))
+ , m_dragController(std::make_unique<DragController>(*this, *pageClients.dragClient))
#endif
- , m_focusController(std::make_unique<FocusController>(*this, PageInitialViewState))
+ , m_focusController(std::make_unique<FocusController>(*this))
#if ENABLE(CONTEXT_MENUS)
- , m_contextMenuController(std::make_unique<ContextMenuController>(*this, *pageConfiguration.contextMenuClient))
+ , m_contextMenuController(std::make_unique<ContextMenuController>(*this, *pageClients.contextMenuClient))
#endif
- , m_userInputBridge(std::make_unique<UserInputBridge>(*this))
-#if ENABLE(WEB_REPLAY)
- , m_replayController(std::make_unique<ReplayController>(*this))
+#if ENABLE(INSPECTOR)
+ , m_inspectorController(std::make_unique<InspectorController>(*this, pageClients.inspectorClient))
#endif
- , m_inspectorController(std::make_unique<InspectorController>(*this, pageConfiguration.inspectorClient))
#if ENABLE(POINTER_LOCK)
- , m_pointerLockController(std::make_unique<PointerLockController>(*this))
+ , m_pointerLockController(PointerLockController::create(this))
#endif
, m_settings(Settings::create(this))
- , m_progress(std::make_unique<ProgressTracker>(*pageConfiguration.progressTrackerClient))
- , m_backForwardController(std::make_unique<BackForwardController>(*this, WTFMove(pageConfiguration.backForwardClient)))
- , m_mainFrame(MainFrame::create(*this, pageConfiguration))
+ , m_progress(std::make_unique<ProgressTracker>(*pageClients.progressTrackerClient))
+ , m_backForwardController(std::make_unique<BackForwardController>(*this, pageClients.backForwardClient))
+ , m_mainFrame(MainFrame::create(*this, *pageClients.loaderClientForMainFrame))
, m_theme(RenderTheme::themeForPage(this))
- , m_editorClient(*pageConfiguration.editorClient)
- , m_plugInClient(pageConfiguration.plugInClient)
- , m_validationMessageClient(pageConfiguration.validationMessageClient)
+ , m_editorClient(pageClients.editorClient)
+ , m_plugInClient(pageClients.plugInClient)
+ , m_validationMessageClient(pageClients.validationMessageClient)
, m_subframeCount(0)
, m_openedByDOM(false)
, m_tabKeyCyclesThroughElements(true)
@@ -190,29 +156,25 @@ Page::Page(PageConfiguration& pageConfiguration)
, m_inLowQualityInterpolationMode(false)
, m_areMemoryCacheClientCallsEnabled(true)
, m_mediaVolume(1)
- , m_muted(false)
, m_pageScaleFactor(1)
- , m_zoomedOutPageScaleFactor(0)
- , m_topContentInset(0)
-#if ENABLE(IOS_TEXT_AUTOSIZING)
- , m_textAutosizingWidth(0)
-#endif
+ , m_deviceScaleFactor(1)
, m_suppressScrollbarAnimations(false)
- , m_verticalScrollElasticity(ScrollElasticityAllowed)
- , m_horizontalScrollElasticity(ScrollElasticityAllowed)
, m_didLoadUserStyleSheet(false)
, m_userStyleSheetModificationTime(0)
- , m_group(nullptr)
- , m_debugger(nullptr)
+ , m_group(0)
+ , m_debugger(0)
+ , m_customHTMLTokenizerTimeDelay(-1)
+ , m_customHTMLTokenizerChunkSize(-1)
, m_canStartMedia(true)
#if ENABLE(VIEW_MODE_CSS_MEDIA)
, m_viewMode(ViewModeWindowed)
#endif // ENABLE(VIEW_MODE_CSS_MEDIA)
- , m_timerThrottlingEnabled(false)
- , m_timerAlignmentInterval(DOMTimer::defaultAlignmentInterval())
+ , m_minimumTimerInterval(Settings::defaultMinDOMTimerInterval())
+ , m_timerAlignmentInterval(Settings::defaultDOMTimerAlignmentInterval())
, m_isEditable(false)
+ , m_isInWindow(true)
+ , m_isVisible(true)
, m_isPrerender(false)
- , m_viewState(PageInitialViewState)
, m_requestedLayoutMilestones(0)
, m_headerHeight(0)
, m_footerHeight(0)
@@ -220,32 +182,17 @@ Page::Page(PageConfiguration& pageConfiguration)
#ifndef NDEBUG
, m_isPainting(false)
#endif
- , m_alternativeTextClient(pageConfiguration.alternativeTextClient)
+ , m_alternativeTextClient(pageClients.alternativeTextClient)
, m_scriptedAnimationsSuspended(false)
- , m_pageThrottler(*this)
- , m_consoleClient(std::make_unique<PageConsoleClient>(*this))
+ , m_pageThrottler(std::make_unique<PageThrottler>(*this))
+ , m_console(std::make_unique<PageConsole>(*this))
#if ENABLE(REMOTE_INSPECTOR)
, m_inspectorDebuggable(std::make_unique<PageDebuggable>(*this))
#endif
, m_lastSpatialNavigationCandidatesCount(0) // NOTE: Only called from Internals for Spatial Navigation testing.
- , m_forbidPromptsDepth(0)
- , m_applicationCacheStorage(pageConfiguration.applicationCacheStorage ? *WTFMove(pageConfiguration.applicationCacheStorage) : ApplicationCacheStorage::singleton())
- , m_databaseProvider(*WTFMove(pageConfiguration.databaseProvider))
- , m_storageNamespaceProvider(*WTFMove(pageConfiguration.storageNamespaceProvider))
- , m_userContentController(WTFMove(pageConfiguration.userContentController))
- , m_visitedLinkStore(*WTFMove(pageConfiguration.visitedLinkStore))
- , m_sessionID(SessionID::defaultSessionID())
- , m_isClosing(false)
- , m_tabSuspensionTimer(*this, &Page::tabSuspensionTimerFired)
+ , m_framesHandlingBeforeUnloadEvent(0)
{
- setTimerThrottlingEnabled(m_viewState & ViewState::IsVisuallyIdle);
-
- m_storageNamespaceProvider->addPage(*this);
-
- if (m_userContentController)
- m_userContentController->addPage(*this);
-
- m_visitedLinkStore->addPage(*this);
+ ASSERT(m_editorClient);
if (!allPages) {
allPages = new HashSet<Page*>;
@@ -263,33 +210,31 @@ Page::Page(PageConfiguration& pageConfiguration)
#if ENABLE(REMOTE_INSPECTOR)
m_inspectorDebuggable->init();
#endif
-
-#if PLATFORM(COCOA)
- platformInitialize();
-#endif
}
Page::~Page()
{
- m_mainFrame->setView(nullptr);
+ m_mainFrame->setView(0);
setGroupName(String());
allPages->remove(this);
m_settings->pageDestroyed();
- m_inspectorController->inspectedPageDestroyed();
-
for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
frame->willDetachPage();
frame->detachFromPage();
}
- m_editorClient.pageDestroyed();
+ m_editorClient->pageDestroyed();
if (m_plugInClient)
m_plugInClient->pageDestroyed();
if (m_alternativeTextClient)
m_alternativeTextClient->pageDestroyed();
+#if ENABLE(INSPECTOR)
+ m_inspectorController->inspectedPageDestroyed();
+#endif
+
if (m_scrollingCoordinator)
m_scrollingCoordinator->pageDestroyed();
@@ -299,25 +244,8 @@ Page::~Page()
pageCounter.decrement();
#endif
- m_storageNamespaceProvider->removePage(*this);
-
if (m_userContentController)
m_userContentController->removePage(*this);
- m_visitedLinkStore->removePage(*this);
-}
-
-void Page::clearPreviousItemFromAllPages(HistoryItem* item)
-{
- if (!allPages)
- return;
-
- for (auto& page : *allPages) {
- HistoryController& controller = page->mainFrame().loader().history();
- if (item == controller.previousItem()) {
- controller.clearPreviousItem();
- return;
- }
- }
}
uint64_t Page::renderTreeSize() const
@@ -369,19 +297,18 @@ String Page::synchronousScrollingReasonsAsText()
return String();
}
-Ref<ClientRectList> Page::nonFastScrollableRects()
+PassRefPtr<ClientRectList> Page::nonFastScrollableRects(const Frame* frame)
{
if (Document* document = m_mainFrame->document())
document->updateLayout();
Vector<IntRect> rects;
if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
- rects = scrollingCoordinator->absoluteNonFastScrollableRegion().rects();
+ rects = scrollingCoordinator->computeNonFastScrollableRegion(frame, IntPoint()).rects();
Vector<FloatQuad> quads(rects.size());
for (size_t i = 0; i < rects.size(); ++i)
quads[i] = FloatRect(rects[i]);
-
return ClientRectList::create(quads);
}
@@ -391,7 +318,7 @@ struct ViewModeInfo {
Page::ViewMode type;
};
static const int viewModeMapSize = 5;
-static const ViewModeInfo viewModeMap[viewModeMapSize] = {
+static ViewModeInfo viewModeMap[viewModeMapSize] = {
{"windowed", Page::ViewModeWindowed},
{"floating", Page::ViewModeFloating},
{"fullscreen", Page::ViewModeFullscreen},
@@ -401,9 +328,9 @@ static const ViewModeInfo viewModeMap[viewModeMapSize] = {
Page::ViewMode Page::stringToViewMode(const String& text)
{
- for (auto& mode : viewModeMap) {
- if (text == mode.name)
- return mode.type;
+ for (int i = 0; i < viewModeMapSize; ++i) {
+ if (text == viewModeMap[i].name)
+ return viewModeMap[i].type;
}
return Page::ViewModeInvalid;
}
@@ -436,11 +363,11 @@ void Page::setOpenedByDOM()
m_openedByDOM = true;
}
-void Page::goToItem(HistoryItem& item, FrameLoadType type)
+void Page::goToItem(HistoryItem* item, FrameLoadType type)
{
// stopAllLoaders may end up running onload handlers, which could cause further history traversals that may lead to the passed in HistoryItem
// being deref()-ed. Make sure we can still use it with HistoryController::goToItem later.
- Ref<HistoryItem> protector(item);
+ RefPtr<HistoryItem> protector(item);
if (m_mainFrame->loader().history().shouldStopLoadingForHistoryItem(item))
m_mainFrame->loader().stopAllLoaders();
@@ -482,18 +409,16 @@ void Page::updateStyleForAllPagesAfterGlobalChangeInEnvironment()
{
if (!allPages)
return;
- for (auto& page : *allPages) {
- for (Frame* frame = &page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
+ HashSet<Page*>::iterator end = allPages->end();
+ for (HashSet<Page*>::iterator it = allPages->begin(); it != end; ++it)
+ for (Frame* frame = &(*it)->mainFrame(); frame; frame = frame->tree().traverseNext()) {
// If a change in the global environment has occurred, we need to
// make sure all the properties a recomputed, therefore we invalidate
// the properties cache.
- if (!frame->document())
- continue;
if (StyleResolver* styleResolver = frame->document()->styleResolverIfExists())
styleResolver->invalidateMatchedPropertiesCache();
frame->document()->scheduleForcedStyleRecalc();
}
- }
}
void Page::setNeedsRecalcStyleInAllFrames()
@@ -504,6 +429,20 @@ void Page::setNeedsRecalcStyleInAllFrames()
}
}
+void Page::jettisonStyleResolversInAllDocuments()
+{
+ if (!allPages)
+ return;
+
+ for (auto it = allPages->begin(), end = allPages->end(); it != end; ++it) {
+ Page& page = **it;
+ for (Frame* frame = &page.mainFrame(); frame; frame = frame->tree().traverseNext()) {
+ if (Document* document = frame->document())
+ document->clearStyleResolver();
+ }
+ }
+}
+
void Page::refreshPlugins(bool reload)
{
if (!allPages)
@@ -513,20 +452,21 @@ void Page::refreshPlugins(bool reload)
Vector<Ref<Frame>> framesNeedingReload;
- for (auto& page : *allPages) {
- page->m_pluginData = nullptr;
+ for (auto it = allPages->begin(), end = allPages->end(); it != end; ++it) {
+ Page& page = **it;
+ page.m_pluginData.clear();
if (!reload)
continue;
- for (Frame* frame = &page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
+ for (Frame* frame = &page.mainFrame(); frame; frame = frame->tree().traverseNext()) {
if (frame->loader().subframeLoader().containsPlugins())
framesNeedingReload.append(*frame);
}
}
- for (auto& frame : framesNeedingReload)
- frame->loader().reload();
+ for (size_t i = 0; i < framesNeedingReload.size(); ++i)
+ framesNeedingReload[i]->loader().reload();
}
PluginData& Page::pluginData() const
@@ -536,24 +476,9 @@ PluginData& Page::pluginData() const
return *m_pluginData;
}
-bool Page::showAllPlugins() const
-{
- if (m_showAllPlugins)
- return true;
-
- if (Document* document = mainFrame().document()) {
- if (SecurityOrigin* securityOrigin = document->securityOrigin())
- return securityOrigin->isLocal();
- }
-
- return false;
-}
-
inline MediaCanStartListener* Page::takeAnyMediaCanStartListener()
{
for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
- if (!frame->document())
- continue;
if (MediaCanStartListener* listener = frame->document()->takeAnyMediaCanStartListener())
return listener;
}
@@ -575,12 +500,6 @@ void Page::setCanStartMedia(bool canStartMedia)
}
}
-bool Page::inPageCache() const
-{
- auto* document = mainFrame().document();
- return document && document->inPageCache();
-}
-
static Frame* incrementFrame(Frame* curr, bool forward, bool wrapFlag)
{
return forward
@@ -617,35 +536,35 @@ bool Page::findString(const String& target, FindOptions options)
return false;
}
-void Page::findStringMatchingRanges(const String& target, FindOptions options, int limit, Vector<RefPtr<Range>>& matchRanges, int& indexForSelection)
+void Page::findStringMatchingRanges(const String& target, FindOptions options, int limit, Vector<RefPtr<Range>>* matchRanges, int& indexForSelection)
{
indexForSelection = 0;
Frame* frame = &mainFrame();
- Frame* frameWithSelection = nullptr;
+ Frame* frameWithSelection = 0;
do {
- frame->editor().countMatchesForText(target, 0, options, limit ? (limit - matchRanges.size()) : 0, true, &matchRanges);
+ frame->editor().countMatchesForText(target, 0, options, limit ? (limit - matchRanges->size()) : 0, true, matchRanges);
if (frame->selection().isRange())
frameWithSelection = frame;
frame = incrementFrame(frame, true, false);
} while (frame);
- if (matchRanges.isEmpty())
+ if (matchRanges->isEmpty())
return;
if (frameWithSelection) {
indexForSelection = NoMatchAfterUserSelection;
RefPtr<Range> selectedRange = frameWithSelection->selection().selection().firstRange();
if (options & Backwards) {
- for (size_t i = matchRanges.size(); i > 0; --i) {
- if (selectedRange->compareBoundaryPoints(Range::END_TO_START, matchRanges[i - 1].get(), IGNORE_EXCEPTION) > 0) {
+ for (size_t i = matchRanges->size(); i > 0; --i) {
+ if (selectedRange->compareBoundaryPoints(Range::END_TO_START, matchRanges->at(i - 1).get(), IGNORE_EXCEPTION) > 0) {
indexForSelection = i - 1;
break;
}
}
} else {
- for (size_t i = 0, size = matchRanges.size(); i < size; ++i) {
- if (selectedRange->compareBoundaryPoints(Range::START_TO_END, matchRanges[i].get(), IGNORE_EXCEPTION) < 0) {
+ for (size_t i = 0; i < matchRanges->size(); ++i) {
+ if (selectedRange->compareBoundaryPoints(Range::START_TO_END, matchRanges->at(i).get(), IGNORE_EXCEPTION) < 0) {
indexForSelection = i;
break;
}
@@ -653,26 +572,26 @@ void Page::findStringMatchingRanges(const String& target, FindOptions options, i
}
} else {
if (options & Backwards)
- indexForSelection = matchRanges.size() - 1;
+ indexForSelection = matchRanges->size() - 1;
else
indexForSelection = 0;
}
}
-RefPtr<Range> Page::rangeOfString(const String& target, Range* referenceRange, FindOptions options)
+PassRefPtr<Range> Page::rangeOfString(const String& target, Range* referenceRange, FindOptions options)
{
if (target.isEmpty())
- return nullptr;
+ return 0;
if (referenceRange && referenceRange->ownerDocument().page() != this)
- return nullptr;
+ return 0;
bool shouldWrap = options & WrapAround;
Frame* frame = referenceRange ? referenceRange->ownerDocument().frame() : &mainFrame();
Frame* startFrame = frame;
do {
if (RefPtr<Range> resultRange = frame->editor().rangeOfString(target, frame == startFrame ? referenceRange : 0, options & ~WrapAround))
- return resultRange;
+ return resultRange.release();
frame = incrementFrame(frame, !(options & Backwards), shouldWrap);
} while (frame && frame != startFrame);
@@ -681,10 +600,10 @@ RefPtr<Range> Page::rangeOfString(const String& target, Range* referenceRange, F
// We cheat a bit and just search again with wrap on.
if (shouldWrap && referenceRange) {
if (RefPtr<Range> resultRange = startFrame->editor().rangeOfString(target, referenceRange, options | WrapAround | StartInSelection))
- return resultRange;
+ return resultRange.release();
}
- return nullptr;
+ return 0;
}
unsigned Page::findMatchesForText(const String& target, FindOptions options, unsigned maxMatchCount, ShouldHighlightMatches shouldHighlightMatches, ShouldMarkMatches shouldMarkMatches)
@@ -753,7 +672,7 @@ void Page::setDefersLoading(bool defers)
void Page::clearUndoRedoOperations()
{
- m_editorClient.clearUndoRedoOperations();
+ m_editorClient->clearUndoRedoOperations();
}
bool Page::inLowQualityImageInterpolationMode() const
@@ -776,47 +695,21 @@ void Page::setMediaVolume(float volume)
m_mediaVolume = volume;
for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
- if (!frame->document())
- continue;
frame->document()->mediaVolumeDidChange();
}
}
-void Page::setZoomedOutPageScaleFactor(float scale)
-{
- if (m_zoomedOutPageScaleFactor == scale)
- return;
- m_zoomedOutPageScaleFactor = scale;
-
- mainFrame().deviceOrPageScaleFactorChanged();
-}
-
-void Page::setPageScaleFactor(float scale, const IntPoint& origin, bool inStableState)
+void Page::setPageScaleFactor(float scale, const IntPoint& origin)
{
Document* document = mainFrame().document();
FrameView* view = document->view();
if (scale == m_pageScaleFactor) {
- if (view && view->scrollPosition() != origin) {
+ if (view && (view->scrollPosition() != origin || view->delegatesScrolling())) {
if (!m_settings->delegatesPageScaling())
document->updateLayoutIgnorePendingStylesheets();
-
- if (!view->delegatesScrolling())
- view->setScrollPosition(origin);
-#if USE(COORDINATED_GRAPHICS)
- else
- view->requestScrollPositionUpdate(origin);
-#endif
- }
-#if ENABLE(MEDIA_CONTROLS_SCRIPT)
- if (inStableState) {
- for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
- if (!frame->document())
- continue;
- frame->document()->pageScaleFactorChangedAndStable();
- }
+ view->setScrollPosition(origin);
}
-#endif
return;
}
@@ -832,7 +725,9 @@ void Page::setPageScaleFactor(float scale, const IntPoint& origin, bool inStable
mainFrame().view()->invalidateRect(IntRect(LayoutRect::infiniteRect()));
}
+#if USE(ACCELERATED_COMPOSITING)
mainFrame().deviceOrPageScaleFactorChanged();
+#endif
if (view && view->fixedElementsLayoutRelativeToFrame())
view->setViewportConstrainedObjectsNeedLayout();
@@ -840,66 +735,29 @@ void Page::setPageScaleFactor(float scale, const IntPoint& origin, bool inStable
if (view && view->scrollPosition() != origin) {
if (!m_settings->delegatesPageScaling() && document->renderView() && document->renderView()->needsLayout() && view->didFirstLayout())
view->layout();
-
- if (!view->delegatesScrolling())
- view->setScrollPosition(origin);
-#if USE(COORDINATED_GRAPHICS)
- else
- view->requestScrollPositionUpdate(origin);
-#endif
+ view->setScrollPosition(origin);
}
-
-#if ENABLE(MEDIA_CONTROLS_SCRIPT)
- if (inStableState) {
- for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
- if (!frame->document())
- continue;
- frame->document()->pageScaleFactorChangedAndStable();
- }
- }
-#else
- UNUSED_PARAM(inStableState);
-#endif
}
-void Page::setViewScaleFactor(float scale)
-{
- if (m_viewScaleFactor == scale)
- return;
-
- m_viewScaleFactor = scale;
- PageCache::singleton().markPagesForDeviceOrPageScaleChanged(*this);
-}
void Page::setDeviceScaleFactor(float scaleFactor)
{
- ASSERT(scaleFactor > 0);
- if (scaleFactor <= 0)
- return;
-
if (m_deviceScaleFactor == scaleFactor)
return;
m_deviceScaleFactor = scaleFactor;
setNeedsRecalcStyleInAllFrames();
+#if USE(ACCELERATED_COMPOSITING)
mainFrame().deviceOrPageScaleFactorChanged();
- PageCache::singleton().markPagesForDeviceOrPageScaleChanged(*this);
-
- GraphicsContext::updateDocumentMarkerResources();
+ pageCache()->markPagesForDeviceScaleChanged(this);
+#endif
- mainFrame().pageOverlayController().didChangeDeviceScaleFactor();
-}
+ for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext())
+ frame->editor().deviceScaleFactorChanged();
-void Page::setTopContentInset(float contentInset)
-{
- if (m_topContentInset == contentInset)
- return;
-
- m_topContentInset = contentInset;
-
- if (FrameView* view = mainFrame().view())
- view->topContentInsetDidChange(m_topContentInset);
+ pageCache()->markPagesForFullStyleRecalc(this);
+ GraphicsContext::updateDocumentMarkerResources();
}
void Page::setShouldSuppressScrollbarAnimations(bool suppressAnimations)
@@ -928,32 +786,12 @@ void Page::lockAllOverlayScrollbarsToHidden(bool lockOverlayScrollbars)
if (!scrollableAreas)
continue;
- for (auto& scrollableArea : *scrollableAreas)
+ for (HashSet<ScrollableArea*>::const_iterator it = scrollableAreas->begin(), end = scrollableAreas->end(); it != end; ++it) {
+ ScrollableArea* scrollableArea = *it;
scrollableArea->lockOverlayScrollbarStateToHidden(lockOverlayScrollbars);
+ }
}
}
-
-void Page::setVerticalScrollElasticity(ScrollElasticity elasticity)
-{
- if (m_verticalScrollElasticity == elasticity)
- return;
-
- m_verticalScrollElasticity = elasticity;
-
- if (FrameView* view = mainFrame().view())
- view->setVerticalScrollElasticity(elasticity);
-}
-
-void Page::setHorizontalScrollElasticity(ScrollElasticity elasticity)
-{
- if (m_horizontalScrollElasticity == elasticity)
- return;
-
- m_horizontalScrollElasticity = elasticity;
-
- if (FrameView* view = mainFrame().view())
- view->setHorizontalScrollElasticity(elasticity);
-}
void Page::setPagination(const Pagination& pagination)
{
@@ -963,16 +801,7 @@ void Page::setPagination(const Pagination& pagination)
m_pagination = pagination;
setNeedsRecalcStyleInAllFrames();
-}
-
-void Page::setPaginationLineGridEnabled(bool enabled)
-{
- if (m_paginationLineGridEnabled == enabled)
- return;
-
- m_paginationLineGridEnabled = enabled;
-
- setNeedsRecalcStyleInAllFrames();
+ pageCache()->markPagesForFullStyleRecalc(this);
}
unsigned Page::pageCount() const
@@ -984,16 +813,16 @@ unsigned Page::pageCount() const
document->updateLayoutIgnorePendingStylesheets();
RenderView* contentRenderer = mainFrame().contentRenderer();
- return contentRenderer ? contentRenderer->pageCount() : 0;
+ return contentRenderer ? contentRenderer->columnCount(contentRenderer->columnInfo()) : 0;
}
void Page::setIsInWindow(bool isInWindow)
{
- setViewState(isInWindow ? m_viewState | ViewState::IsInWindow : m_viewState & ~ViewState::IsInWindow);
-}
+ if (m_isInWindow == isInWindow)
+ return;
+
+ m_isInWindow = isInWindow;
-void Page::setIsInWindowInternal(bool isInWindow)
-{
for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
if (FrameView* frameView = frame->view())
frameView->setIsInWindow(isInWindow);
@@ -1003,16 +832,6 @@ void Page::setIsInWindowInternal(bool isInWindow)
resumeAnimatingImages();
}
-void Page::addViewStateChangeObserver(ViewStateChangeObserver& observer)
-{
- m_viewStateChangeObservers.add(&observer);
-}
-
-void Page::removeViewStateChangeObserver(ViewStateChangeObserver& observer)
-{
- m_viewStateChangeObservers.remove(&observer);
-}
-
void Page::suspendScriptedAnimations()
{
m_scriptedAnimationsSuspended = true;
@@ -1031,14 +850,9 @@ void Page::resumeScriptedAnimations()
}
}
-void Page::setIsVisuallyIdleInternal(bool isVisuallyIdle)
+void Page::setIsVisuallyIdle(bool isVisuallyIdle)
{
- setTimerThrottlingEnabled(isVisuallyIdle);
-
- for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
- if (frame->document())
- frame->document()->scriptedAnimationControllerSetThrottled(isVisuallyIdle);
- }
+ m_pageThrottler->setIsVisuallyIdle(isVisuallyIdle);
}
void Page::userStyleSheetLocationChanged()
@@ -1063,13 +877,13 @@ void Page::userStyleSheetLocationChanged()
m_didLoadUserStyleSheet = true;
Vector<char> styleSheetAsUTF8;
- if (base64Decode(decodeURLEscapeSequences(url.string().substring(35)), styleSheetAsUTF8, Base64IgnoreSpacesAndNewLines))
+ if (base64Decode(decodeURLEscapeSequences(url.string().substring(35)), styleSheetAsUTF8, Base64IgnoreWhitespace))
m_userStyleSheet = String::fromUTF8(styleSheetAsUTF8.data(), styleSheetAsUTF8.size());
}
for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
if (frame->document())
- frame->document()->extensionStyleSheets().updatePageUserSheet();
+ frame->document()->styleSheetCollection().updatePageUserSheet();
}
}
@@ -1107,26 +921,57 @@ const String& Page::userStyleSheet() const
if (!data)
return m_userStyleSheet;
- m_userStyleSheet = TextResourceDecoder::create("text/css")->decodeAndFlush(data->data(), data->size());
+ RefPtr<TextResourceDecoder> decoder = TextResourceDecoder::create("text/css");
+ m_userStyleSheet = decoder->decode(data->data(), data->size());
+ m_userStyleSheet.append(decoder->flush());
return m_userStyleSheet;
}
-void Page::invalidateStylesForAllLinks()
+void Page::removeAllVisitedLinks()
{
- for (Frame* frame = m_mainFrame.get(); frame; frame = frame->tree().traverseNext()) {
- if (!frame->document())
+ if (!allPages)
+ return;
+ HashSet<PageGroup*> groups;
+ HashSet<Page*>::iterator pagesEnd = allPages->end();
+ for (HashSet<Page*>::iterator it = allPages->begin(); it != pagesEnd; ++it) {
+ if (PageGroup* group = (*it)->groupPtr())
+ groups.add(group);
+ }
+ HashSet<PageGroup*>::iterator groupsEnd = groups.end();
+ for (HashSet<PageGroup*>::iterator it = groups.begin(); it != groupsEnd; ++it)
+ (*it)->removeVisitedLinks();
+}
+
+void Page::allVisitedStateChanged(PageGroup* group)
+{
+ ASSERT(group);
+ if (!allPages)
+ return;
+
+ HashSet<Page*>::iterator pagesEnd = allPages->end();
+ for (HashSet<Page*>::iterator it = allPages->begin(); it != pagesEnd; ++it) {
+ Page* page = *it;
+ if (page->m_group != group)
continue;
- frame->document()->visitedLinkState().invalidateStyleForAllLinks();
+ for (Frame* frame = page->m_mainFrame.get(); frame; frame = frame->tree().traverseNext())
+ frame->document()->visitedLinkState().invalidateStyleForAllLinks();
}
}
-void Page::invalidateStylesForLink(LinkHash linkHash)
+void Page::visitedStateChanged(PageGroup* group, LinkHash linkHash)
{
- for (Frame* frame = m_mainFrame.get(); frame; frame = frame->tree().traverseNext()) {
- if (!frame->document())
+ ASSERT(group);
+ if (!allPages)
+ return;
+
+ HashSet<Page*>::iterator pagesEnd = allPages->end();
+ for (HashSet<Page*>::iterator it = allPages->begin(); it != pagesEnd; ++it) {
+ Page* page = *it;
+ if (page->m_group != group)
continue;
- frame->document()->visitedLinkState().invalidateStyleForLink(linkHash);
+ for (Frame* frame = page->m_mainFrame.get(); frame; frame = frame->tree().traverseNext())
+ frame->document()->visitedLinkState().invalidateStyleForLink(linkHash);
}
}
@@ -1144,25 +989,32 @@ void Page::setDebugger(JSC::Debugger* debugger)
StorageNamespace* Page::sessionStorage(bool optionalCreate)
{
if (!m_sessionStorage && optionalCreate)
- m_sessionStorage = m_storageNamespaceProvider->createSessionStorageNamespace(*this, m_settings->sessionStorageQuota());
+ m_sessionStorage = StorageNamespace::sessionStorageNamespace(this);
return m_sessionStorage.get();
}
-void Page::setSessionStorage(RefPtr<StorageNamespace>&& newStorage)
+void Page::setSessionStorage(PassRefPtr<StorageNamespace> newStorage)
{
- m_sessionStorage = WTFMove(newStorage);
+ m_sessionStorage = newStorage;
}
-bool Page::hasCustomHTMLTokenizerTimeDelay() const
+void Page::setCustomHTMLTokenizerTimeDelay(double customHTMLTokenizerTimeDelay)
{
- return m_settings->maxParseDuration() != -1;
+ if (customHTMLTokenizerTimeDelay < 0) {
+ m_customHTMLTokenizerTimeDelay = -1;
+ return;
+ }
+ m_customHTMLTokenizerTimeDelay = customHTMLTokenizerTimeDelay;
}
-double Page::customHTMLTokenizerTimeDelay() const
+void Page::setCustomHTMLTokenizerChunkSize(int customHTMLTokenizerChunkSize)
{
- ASSERT(m_settings->maxParseDuration() != -1);
- return m_settings->maxParseDuration();
+ if (customHTMLTokenizerChunkSize < 0) {
+ m_customHTMLTokenizerChunkSize = -1;
+ return;
+ }
+ m_customHTMLTokenizerChunkSize = customHTMLTokenizerChunkSize;
}
void Page::setMemoryCacheClientCallsEnabled(bool enabled)
@@ -1178,42 +1030,42 @@ void Page::setMemoryCacheClientCallsEnabled(bool enabled)
frame->loader().tellClientAboutPastMemoryCacheLoads();
}
-void Page::hiddenPageDOMTimerThrottlingStateChanged()
+void Page::setMinimumTimerInterval(double minimumTimerInterval)
{
- setTimerThrottlingEnabled(m_viewState & ViewState::IsVisuallyIdle);
+ double oldTimerInterval = m_minimumTimerInterval;
+ m_minimumTimerInterval = minimumTimerInterval;
+ for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNextWithWrap(false)) {
+ if (frame->document())
+ frame->document()->adjustMinimumTimerInterval(oldTimerInterval);
+ }
}
-void Page::setTimerThrottlingEnabled(bool enabled)
+double Page::minimumTimerInterval() const
{
-#if ENABLE(HIDDEN_PAGE_DOM_TIMER_THROTTLING)
- if (!m_settings->hiddenPageDOMTimerThrottlingEnabled())
- enabled = false;
-#endif
-
- if (enabled == m_timerThrottlingEnabled)
- return;
-
- m_timerThrottlingEnabled = enabled;
- setDOMTimerAlignmentInterval(enabled ? DOMTimer::hiddenPageAlignmentInterval() : DOMTimer::defaultAlignmentInterval());
+ return m_minimumTimerInterval;
}
-void Page::setDOMTimerAlignmentInterval(double alignmentInterval)
+void Page::setTimerAlignmentInterval(double interval)
{
- m_timerAlignmentInterval = alignmentInterval;
-
- for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
+ if (interval == m_timerAlignmentInterval)
+ return;
+
+ m_timerAlignmentInterval = interval;
+ for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNextWithWrap(false)) {
if (frame->document())
frame->document()->didChangeTimerAlignmentInterval();
}
}
+double Page::timerAlignmentInterval() const
+{
+ return m_timerAlignmentInterval;
+}
+
void Page::dnsPrefetchingStateChanged()
{
- for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
- if (!frame->document())
- continue;
+ for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext())
frame->document()->initDNSPrefetch();
- }
}
Vector<Ref<PluginViewBase>> Page::pluginViews()
@@ -1225,9 +1077,10 @@ Vector<Ref<PluginViewBase>> Page::pluginViews()
if (!view)
break;
- for (auto& widget : view->children()) {
- if (is<PluginViewBase>(*widget))
- views.append(downcast<PluginViewBase>(*widget));
+ for (auto it = view->children().begin(), end = view->children().end(); it != end; ++it) {
+ Widget* widget = (*it).get();
+ if (widget->isPluginViewBase())
+ views.append(*toPluginViewBase(widget));
}
}
@@ -1236,78 +1089,31 @@ Vector<Ref<PluginViewBase>> Page::pluginViews()
void Page::storageBlockingStateChanged()
{
- for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
- if (!frame->document())
- continue;
+ for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext())
frame->document()->storageBlockingStateDidChange();
- }
// Collect the PluginViews in to a vector to ensure that action the plug-in takes
// from below storageBlockingStateChanged does not affect their lifetime.
- for (auto& view : pluginViews())
- view->storageBlockingStateChanged();
-}
-
-void Page::enableLegacyPrivateBrowsing(bool privateBrowsingEnabled)
-{
- // Don't allow changing the legacy private browsing state if we have set a session ID.
- ASSERT(m_sessionID == SessionID::defaultSessionID() || m_sessionID == SessionID::legacyPrivateSessionID());
+ auto views = pluginViews();
- setSessionID(privateBrowsingEnabled ? SessionID::legacyPrivateSessionID() : SessionID::defaultSessionID());
+ for (unsigned i = 0; i < views.size(); ++i)
+ views[i]->storageBlockingStateChanged();
}
-void Page::updateIsPlayingMedia(uint64_t sourceElementID)
+void Page::privateBrowsingStateChanged()
{
- MediaProducer::MediaStateFlags state = MediaProducer::IsNotPlaying;
- for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
- if (Document* document = frame->document())
- state |= document->mediaState();
- }
+ bool privateBrowsingEnabled = m_settings->privateBrowsingEnabled();
- if (state == m_mediaState)
- return;
-
- m_mediaState = state;
-
- chrome().client().isPlayingMediaDidChange(state, sourceElementID);
-}
-
-void Page::setMuted(bool muted)
-{
- if (m_muted == muted)
- return;
-
- m_muted = muted;
-
- for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
- if (!frame->document())
- continue;
- frame->document()->pageMutedStateDidChange();
- }
-}
+ for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext())
+ frame->document()->privateBrowsingStateDidChange();
-#if ENABLE(MEDIA_SESSION)
-void Page::handleMediaEvent(MediaEventType eventType)
-{
- switch (eventType) {
- case MediaEventType::PlayPause:
- MediaSessionManager::singleton().togglePlayback();
- break;
- case MediaEventType::TrackNext:
- MediaSessionManager::singleton().skipToNextTrack();
- break;
- case MediaEventType::TrackPrevious:
- MediaSessionManager::singleton().skipToPreviousTrack();
- break;
- }
-}
+ // Collect the PluginViews in to a vector to ensure that action the plug-in takes
+ // from below privateBrowsingStateChanged does not affect their lifetime.
+ auto views = pluginViews();
-void Page::setVolumeOfMediaElement(double volume, uint64_t elementID)
-{
- if (HTMLMediaElement* element = HTMLMediaElement::elementWithID(elementID))
- element->setVolume(volume, ASSERT_NO_EXCEPTION);
+ for (unsigned i = 0; i < views.size(); ++i)
+ views[i]->privateBrowsingStateChanged(privateBrowsingEnabled);
}
-#endif
#if !ASSERT_DISABLED
void Page::checkSubframeCountConsistency() const
@@ -1322,94 +1128,91 @@ void Page::checkSubframeCountConsistency() const
}
#endif
-void Page::resumeAnimatingImages()
+void Page::throttleTimers()
{
- // Drawing models which cache painted content while out-of-window (WebKit2's composited drawing areas, etc.)
- // require that we repaint animated images to kickstart the animation loop.
- if (FrameView* view = mainFrame().view())
- view->resumeVisibleImageAnimationsIncludingSubframes();
+#if ENABLE(HIDDEN_PAGE_DOM_TIMER_THROTTLING)
+ if (m_settings->hiddenPageDOMTimerThrottlingEnabled())
+ setTimerAlignmentInterval(Settings::hiddenPageDOMTimerAlignmentInterval());
+#endif
}
-void Page::setViewState(ViewState::Flags viewState)
+void Page::unthrottleTimers()
{
- ViewState::Flags changed = m_viewState ^ viewState;
- if (!changed)
- return;
-
- ViewState::Flags oldViewState = m_viewState;
-
- m_viewState = viewState;
- m_focusController->setViewState(viewState);
-
- if (changed & ViewState::IsVisible)
- setIsVisibleInternal(viewState & ViewState::IsVisible);
- if (changed & ViewState::IsInWindow)
- setIsInWindowInternal(viewState & ViewState::IsInWindow);
- if (changed & ViewState::IsVisuallyIdle)
- setIsVisuallyIdleInternal(viewState & ViewState::IsVisuallyIdle);
-
- for (auto* observer : m_viewStateChangeObservers)
- observer->viewStateDidChange(oldViewState, m_viewState);
+#if ENABLE(HIDDEN_PAGE_DOM_TIMER_THROTTLING)
+ if (m_settings->hiddenPageDOMTimerThrottlingEnabled())
+ setTimerAlignmentInterval(Settings::defaultDOMTimerAlignmentInterval());
+#endif
}
-void Page::setPageActivityState(PageActivityState::Flags activityState)
+void Page::resumeAnimatingImages()
{
- chrome().client().setPageActivityState(activityState);
-
- updateTabSuspensionState();
-}
+ // Drawing models which cache painted content while out-of-window (WebKit2's composited drawing areas, etc.)
+ // require that we repaint animated images to kickstart the animation loop.
-void Page::setIsVisible(bool isVisible)
-{
- if (isVisible)
- setViewState((m_viewState & ~ViewState::IsVisuallyIdle) | ViewState::IsVisible | ViewState::IsVisibleOrOccluded);
- else
- setViewState((m_viewState & ~(ViewState::IsVisible | ViewState::IsVisibleOrOccluded)) | ViewState::IsVisuallyIdle);
+ for (Frame* frame = m_mainFrame.get(); frame; frame = frame->tree().traverseNext())
+ CachedImage::resumeAnimatingImagesForLoader(frame->document()->cachedResourceLoader());
}
-void Page::setIsVisibleInternal(bool isVisible)
+void Page::setIsVisible(bool isVisible, bool isInitialState)
{
// FIXME: The visibility state should be stored on the top-level document.
// https://bugs.webkit.org/show_bug.cgi?id=116769
+ if (m_isVisible == isVisible)
+ return;
+ m_isVisible = isVisible;
+
if (isVisible) {
m_isPrerender = false;
+ for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
+ if (FrameView* frameView = frame->view())
+ frameView->didMoveOnscreen();
+ }
+
resumeScriptedAnimations();
-#if PLATFORM(IOS)
- resumeDeviceMotionAndOrientationUpdates();
-#endif
if (FrameView* view = mainFrame().view())
view->show();
+ unthrottleTimers();
+
if (m_settings->hiddenPageCSSAnimationSuspensionEnabled())
mainFrame().animation().resumeAnimations();
resumeAnimatingImages();
}
- Vector<Ref<Document>> documents;
- for (Frame* frame = m_mainFrame.get(); frame; frame = frame->tree().traverseNext())
- documents.append(*frame->document());
+#if ENABLE(PAGE_VISIBILITY_API)
+ if (!isInitialState) {
+ Vector<Ref<Document>> documents;
+ for (Frame* frame = m_mainFrame.get(); frame; frame = frame->tree().traverseNext())
+ documents.append(*frame->document());
- for (auto& document : documents)
- document->visibilityStateChanged();
+ for (size_t i = 0, size = documents.size(); i < size; ++i)
+ documents[i]->visibilityStateChanged();
+ }
+#else
+ UNUSED_PARAM(isInitialState);
+#endif
if (!isVisible) {
+ if (m_pageThrottler->shouldThrottleTimers())
+ throttleTimers();
+
if (m_settings->hiddenPageCSSAnimationSuspensionEnabled())
mainFrame().animation().suspendAnimations();
-#if PLATFORM(IOS)
- suspendDeviceMotionAndOrientationUpdates();
-#endif
+ for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
+ if (FrameView* frameView = frame->view())
+ frameView->willMoveOffscreen();
+ }
+
suspendScriptedAnimations();
if (FrameView* view = mainFrame().view())
view->hide();
}
-
- updateTabSuspensionState();
}
void Page::setIsPrerender()
@@ -1417,14 +1220,16 @@ void Page::setIsPrerender()
m_isPrerender = true;
}
+#if ENABLE(PAGE_VISIBILITY_API)
PageVisibilityState Page::visibilityState() const
{
- if (isVisible())
+ if (m_isVisible)
return PageVisibilityStateVisible;
if (m_isPrerender)
return PageVisibilityStatePrerender;
return PageVisibilityStateHidden;
}
+#endif
#if ENABLE(RUBBER_BANDING)
void Page::addHeaderWithHeight(int headerHeight)
@@ -1471,16 +1276,6 @@ void Page::setRemoteInspectionAllowed(bool allowed)
m_inspectorDebuggable->setRemoteDebuggingAllowed(allowed);
}
-String Page::remoteInspectionNameOverride() const
-{
- return m_inspectorDebuggable->nameOverride();
-}
-
-void Page::setRemoteInspectionNameOverride(const String& name)
-{
- m_inspectorDebuggable->setNameOverride(name);
-}
-
void Page::remoteInspectorInformationDidChange() const
{
m_inspectorDebuggable->update();
@@ -1498,22 +1293,9 @@ void Page::removeLayoutMilestones(LayoutMilestones milestones)
m_requestedLayoutMilestones &= ~milestones;
}
-Color Page::pageExtendedBackgroundColor() const
-{
- FrameView* frameView = mainFrame().view();
- if (!frameView)
- return Color();
-
- RenderView* renderView = frameView->renderView();
- if (!renderView)
- return Color();
-
- return renderView->compositor().rootExtendedBackgroundColor();
-}
-
// These are magical constants that might be tweaked over time.
-static const double gMinimumPaintedAreaRatio = 0.1;
-static const double gMaximumUnpaintedAreaRatio = 0.04;
+static double gMinimumPaintedAreaRatio = 0.1;
+static double gMaximumUnpaintedAreaRatio = 0.04;
bool Page::isCountingRelevantRepaintedObjects() const
{
@@ -1566,10 +1348,10 @@ void Page::addRelevantRepaintedObject(RenderObject* object, const LayoutRect& ob
LayoutRect relevantRect = relevantViewRect(&object->view());
// The objects are only relevant if they are being painted within the viewRect().
- if (!objectPaintRect.intersects(snappedIntRect(relevantRect)))
+ if (!objectPaintRect.intersects(pixelSnappedIntRect(relevantRect)))
return;
- IntRect snappedPaintRect = snappedIntRect(objectPaintRect);
+ IntRect snappedPaintRect = pixelSnappedIntRect(objectPaintRect);
// If this object was previously counted as an unpainted object, remove it from that HashSet
// and corresponding Region. FIXME: This doesn't do the right thing if the objects overlap.
@@ -1587,11 +1369,11 @@ void Page::addRelevantRepaintedObject(RenderObject* object, const LayoutRect& ob
// If the rect straddles both Regions, split it appropriately.
if (topRelevantRect.intersects(snappedPaintRect) && bottomRelevantRect.intersects(snappedPaintRect)) {
IntRect topIntersection = snappedPaintRect;
- topIntersection.intersect(snappedIntRect(topRelevantRect));
+ topIntersection.intersect(pixelSnappedIntRect(topRelevantRect));
m_topRelevantPaintedRegion.unite(topIntersection);
IntRect bottomIntersection = snappedPaintRect;
- bottomIntersection.intersect(snappedIntRect(bottomRelevantRect));
+ bottomIntersection.intersect(pixelSnappedIntRect(bottomRelevantRect));
m_bottomRelevantPaintedRegion.unite(bottomIntersection);
} else if (topRelevantRect.intersects(snappedPaintRect))
m_topRelevantPaintedRegion.unite(snappedPaintRect);
@@ -1621,27 +1403,11 @@ void Page::addRelevantUnpaintedObject(RenderObject* object, const LayoutRect& ob
return;
// The objects are only relevant if they are being painted within the relevantViewRect().
- if (!objectPaintRect.intersects(snappedIntRect(relevantViewRect(&object->view()))))
+ if (!objectPaintRect.intersects(pixelSnappedIntRect(relevantViewRect(&object->view()))))
return;
m_relevantUnpaintedRenderObjects.add(object);
- m_relevantUnpaintedRegion.unite(snappedIntRect(objectPaintRect));
-}
-
-void Page::suspendDeviceMotionAndOrientationUpdates()
-{
- for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
- if (Document* document = frame->document())
- document->suspendDeviceMotionAndOrientationUpdates();
- }
-}
-
-void Page::resumeDeviceMotionAndOrientationUpdates()
-{
- for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
- if (Document* document = frame->document())
- document->resumeDeviceMotionAndOrientationUpdates();
- }
+ m_relevantUnpaintedRegion.unite(pixelSnappedIntRect(objectPaintRect));
}
void Page::suspendActiveDOMObjectsAndAnimations()
@@ -1698,41 +1464,58 @@ void Page::resetSeenMediaEngines()
m_seenMediaEngines.clear();
}
+std::unique_ptr<PageActivityAssertionToken> Page::createActivityToken()
+{
+ return m_pageThrottler->createActivityToken();
+}
+
+#if ENABLE(HIDDEN_PAGE_DOM_TIMER_THROTTLING)
+void Page::hiddenPageDOMTimerThrottlingStateChanged()
+{
+ if (m_settings->hiddenPageDOMTimerThrottlingEnabled()) {
+#if ENABLE(PAGE_VISIBILITY_API)
+ if (m_pageThrottler->shouldThrottleTimers())
+ setTimerAlignmentInterval(Settings::hiddenPageDOMTimerAlignmentInterval());
+#endif
+ } else
+ setTimerAlignmentInterval(Settings::defaultDOMTimerAlignmentInterval());
+}
+#endif
+
+#if (ENABLE_PAGE_VISIBILITY_API)
void Page::hiddenPageCSSAnimationSuspensionStateChanged()
{
- if (!isVisible()) {
+ if (!m_isVisible) {
if (m_settings->hiddenPageCSSAnimationSuspensionEnabled())
mainFrame().animation().suspendAnimations();
else
mainFrame().animation().resumeAnimations();
}
}
+#endif
#if ENABLE(VIDEO_TRACK)
void Page::captionPreferencesChanged()
{
- for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
- if (!frame->document())
- continue;
+ for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext())
frame->document()->captionPreferencesChanged();
- }
}
#endif
-void Page::forbidPrompts()
+void Page::incrementFrameHandlingBeforeUnloadEventCount()
{
- ++m_forbidPromptsDepth;
+ ++m_framesHandlingBeforeUnloadEvent;
}
-void Page::allowPrompts()
+void Page::decrementFrameHandlingBeforeUnloadEventCount()
{
- ASSERT(m_forbidPromptsDepth);
- --m_forbidPromptsDepth;
+ ASSERT(m_framesHandlingBeforeUnloadEvent);
+ --m_framesHandlingBeforeUnloadEvent;
}
-bool Page::arePromptsAllowed()
+bool Page::isAnyFrameHandlingBeforeUnloadEvent()
{
- return !m_forbidPromptsDepth;
+ return m_framesHandlingBeforeUnloadEvent;
}
void Page::setUserContentController(UserContentController* userContentController)
@@ -1744,243 +1527,26 @@ void Page::setUserContentController(UserContentController* userContentController
if (m_userContentController)
m_userContentController->addPage(*this);
-
- for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
- if (Document *document = frame->document()) {
- document->extensionStyleSheets().invalidateInjectedStyleSheetCache();
- document->styleResolverChanged(DeferRecalcStyle);
- }
- }
}
-void Page::setStorageNamespaceProvider(Ref<StorageNamespaceProvider>&& storageNamespaceProvider)
-{
- m_storageNamespaceProvider->removePage(*this);
- m_storageNamespaceProvider = WTFMove(storageNamespaceProvider);
- m_storageNamespaceProvider->addPage(*this);
-
- // This needs to reset all the local storage namespaces of all the pages.
-}
-
-VisitedLinkStore& Page::visitedLinkStore()
-{
- return m_visitedLinkStore;
-}
-
-void Page::setVisitedLinkStore(Ref<VisitedLinkStore>&& visitedLinkStore)
-{
- m_visitedLinkStore->removePage(*this);
- m_visitedLinkStore = WTFMove(visitedLinkStore);
- m_visitedLinkStore->addPage(*this);
-
- invalidateStylesForAllLinks();
-}
-
-SessionID Page::sessionID() const
-{
- return m_sessionID;
-}
-
-void Page::setSessionID(SessionID sessionID)
-{
- ASSERT(sessionID.isValid());
-
-#if ENABLE(INDEXED_DATABASE)
- if (sessionID != m_sessionID)
- m_idbIDBConnectionToServer = nullptr;
-#endif
-
- bool privateBrowsingStateChanged = (sessionID.isEphemeral() != m_sessionID.isEphemeral());
-
- m_sessionID = sessionID;
-
- if (!privateBrowsingStateChanged)
- return;
-
- for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
- if (!frame->document())
- continue;
- frame->document()->privateBrowsingStateDidChange();
- }
-
- // Collect the PluginViews in to a vector to ensure that action the plug-in takes
- // from below privateBrowsingStateChanged does not affect their lifetime.
-
- for (auto& view : pluginViews())
- view->privateBrowsingStateChanged(sessionID.isEphemeral());
-}
-
-#if ENABLE(WIRELESS_PLAYBACK_TARGET)
-void Page::addPlaybackTargetPickerClient(uint64_t contextId)
-{
- chrome().client().addPlaybackTargetPickerClient(contextId);
-}
-
-void Page::removePlaybackTargetPickerClient(uint64_t contextId)
-{
- chrome().client().removePlaybackTargetPickerClient(contextId);
-}
-
-void Page::showPlaybackTargetPicker(uint64_t contextId, const WebCore::IntPoint& location, bool isVideo)
-{
-#if PLATFORM(IOS)
- // FIXME: refactor iOS implementation.
- UNUSED_PARAM(contextId);
- UNUSED_PARAM(location);
- chrome().client().showPlaybackTargetPicker(isVideo);
-#else
- chrome().client().showPlaybackTargetPicker(contextId, location, isVideo);
-#endif
-}
-
-void Page::playbackTargetPickerClientStateDidChange(uint64_t contextId, MediaProducer::MediaStateFlags state)
-{
- chrome().client().playbackTargetPickerClientStateDidChange(contextId, state);
-}
-
-void Page::setMockMediaPlaybackTargetPickerEnabled(bool enabled)
-{
- chrome().client().setMockMediaPlaybackTargetPickerEnabled(enabled);
-}
-
-void Page::setMockMediaPlaybackTargetPickerState(const String& name, MediaPlaybackTargetContext::State state)
-{
- chrome().client().setMockMediaPlaybackTargetPickerState(name, state);
-}
-
-void Page::setPlaybackTarget(uint64_t contextId, Ref<MediaPlaybackTarget>&& target)
-{
- for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
- if (!frame->document())
- continue;
- frame->document()->setPlaybackTarget(contextId, target.copyRef());
- }
-}
-
-void Page::playbackTargetAvailabilityDidChange(uint64_t contextId, bool available)
-{
- for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
- if (!frame->document())
- continue;
- frame->document()->playbackTargetAvailabilityDidChange(contextId, available);
- }
-}
-
-void Page::setShouldPlayToPlaybackTarget(uint64_t clientId, bool shouldPlay)
-{
- for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
- if (!frame->document())
- continue;
- frame->document()->setShouldPlayToPlaybackTarget(clientId, shouldPlay);
- }
-}
-#endif
-
-WheelEventTestTrigger& Page::ensureTestTrigger()
-{
- if (!m_testTrigger)
- m_testTrigger = adoptRef(new WheelEventTestTrigger());
-
- return *m_testTrigger;
-}
-
-#if ENABLE(VIDEO)
-void Page::setAllowsMediaDocumentInlinePlayback(bool flag)
-{
- if (m_allowsMediaDocumentInlinePlayback == flag)
- return;
- m_allowsMediaDocumentInlinePlayback = flag;
-
- Vector<Ref<Document>> documents;
- for (Frame* frame = m_mainFrame.get(); frame; frame = frame->tree().traverseNext())
- documents.append(*frame->document());
-
- for (auto& document : documents)
- document->allowsMediaDocumentInlinePlaybackChanged();
-}
-#endif
-
-#if ENABLE(INDEXED_DATABASE)
-IDBClient::IDBConnectionToServer& Page::idbConnection()
-{
- if (!m_idbIDBConnectionToServer)
- m_idbIDBConnectionToServer = &databaseProvider().idbConnectionToServerForSession(m_sessionID);
-
- return *m_idbIDBConnectionToServer;
-}
-#endif
-
-#if ENABLE(RESOURCE_USAGE)
-void Page::setResourceUsageOverlayVisible(bool visible)
-{
- if (!visible) {
- m_resourceUsageOverlay = nullptr;
- return;
- }
-
- if (!m_resourceUsageOverlay)
- m_resourceUsageOverlay = std::make_unique<ResourceUsageOverlay>(*this);
-}
+Page::PageClients::PageClients()
+ : alternativeTextClient(nullptr)
+ , chromeClient(nullptr)
+#if ENABLE(CONTEXT_MENUS)
+ , contextMenuClient(nullptr)
#endif
-
-bool Page::canTabSuspend()
+ , editorClient(nullptr)
+ , dragClient(nullptr)
+ , inspectorClient(nullptr)
+ , plugInClient(nullptr)
+ , progressTrackerClient(nullptr)
+ , validationMessageClient(nullptr)
+ , loaderClientForMainFrame(nullptr)
{
- if (!s_tabSuspensionIsEnabled)
- return false;
- if (m_isPrerender)
- return false;
- if (isVisible())
- return false;
- if (m_pageThrottler.activityState() != PageActivityState::NoFlags)
- return false;
-
- for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
- if (frame->loader().state() != FrameStateComplete)
- return false;
- if (frame->loader().isLoading())
- return false;
- if (!frame->document() || !frame->document()->canSuspendActiveDOMObjectsForDocumentSuspension(nullptr))
- return false;
- }
-
- return true;
-}
-
-void Page::setIsTabSuspended(bool shouldSuspend)
-{
- if (m_isTabSuspended == shouldSuspend)
- return;
- m_isTabSuspended = shouldSuspend;
-
- for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
- if (auto* document = frame->document()) {
- if (shouldSuspend)
- document->suspend(ActiveDOMObject::PageWillBeSuspended);
- else
- document->resume(ActiveDOMObject::PageWillBeSuspended);
- }
- }
-}
-
-void Page::setTabSuspensionEnabled(bool enable)
-{
- s_tabSuspensionIsEnabled = enable;
-}
-
-void Page::updateTabSuspensionState()
-{
- if (canTabSuspend()) {
- const auto tabSuspensionDelay = std::chrono::minutes(1);
- m_tabSuspensionTimer.startOneShot(tabSuspensionDelay);
- return;
- }
- m_tabSuspensionTimer.stop();
- setIsTabSuspended(false);
}
-void Page::tabSuspensionTimerFired()
+Page::PageClients::~PageClients()
{
- setIsTabSuspended(canTabSuspend());
}
} // namespace WebCore
diff --git a/Source/WebCore/page/Page.h b/Source/WebCore/page/Page.h
index 5ed172b51..f0b331737 100644
--- a/Source/WebCore/page/Page.h
+++ b/Source/WebCore/page/Page.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006-2010, 2013, 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2013 Apple Inc. All rights reserved.
* Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
*
* This library is free software; you can redistribute it and/or
@@ -21,23 +21,17 @@
#ifndef Page_h
#define Page_h
+#include "FeatureObserver.h"
#include "FindOptions.h"
#include "FrameLoaderTypes.h"
#include "LayoutMilestones.h"
#include "LayoutRect.h"
-#include "MediaProducer.h"
-#include "PageThrottler.h"
#include "PageVisibilityState.h"
#include "Pagination.h"
#include "PlatformScreen.h"
#include "Region.h"
-#include "ScrollTypes.h"
-#include "SessionID.h"
#include "Supplementable.h"
-#include "ViewState.h"
#include "ViewportArguments.h"
-#include "WheelEventTestTrigger.h"
-#include <memory>
#include <wtf/Forward.h>
#include <wtf/HashMap.h>
#include <wtf/HashSet.h>
@@ -50,16 +44,12 @@
#include <sys/time.h> // For time_t structure.
#endif
-#if PLATFORM(COCOA)
+#if PLATFORM(MAC)
#include <wtf/SchedulePair.h>
#endif
-#if ENABLE(MEDIA_SESSION)
-#include "MediaSessionEvents.h"
-#endif
-
-#if ENABLE(WIRELESS_PLAYBACK_TARGET)
-#include "MediaPlaybackTargetContext.h"
+#if PLATFORM(IOS)
+#include "Settings.h"
#endif
namespace JSC {
@@ -68,21 +58,15 @@ class Debugger;
namespace WebCore {
-namespace IDBClient {
-class IDBConnectionToServer;
-}
-
class AlternativeTextClient;
-class ApplicationCacheStorage;
class BackForwardController;
class BackForwardClient;
class Chrome;
class ChromeClient;
class ClientRectList;
-class Color;
class ContextMenuClient;
class ContextMenuController;
-class DatabaseProvider;
+class Document;
class DragCaretController;
class DragClient;
class DragController;
@@ -90,16 +74,16 @@ class EditorClient;
class FocusController;
class Frame;
class FrameLoaderClient;
+class FrameSelection;
+class HaltablePlugin;
class HistoryItem;
-class HTMLMediaElement;
-class UserInputBridge;
class InspectorClient;
class InspectorController;
class MainFrame;
class MediaCanStartListener;
-class MediaPlaybackTarget;
-class PageConfiguration;
-class PageConsoleClient;
+class Node;
+class PageActivityAssertionToken;
+class PageConsole;
class PageDebuggable;
class PageGroup;
class PageThrottler;
@@ -112,81 +96,92 @@ class ProgressTrackerClient;
class Range;
class RenderObject;
class RenderTheme;
-class ReplayController;
-class ResourceUsageOverlay;
class VisibleSelection;
class ScrollableArea;
class ScrollingCoordinator;
class Settings;
class StorageNamespace;
-class StorageNamespaceProvider;
class UserContentController;
class ValidationMessageClient;
-class ViewStateChangeObserver;
-class VisitedLinkStore;
typedef uint64_t LinkHash;
enum FindDirection { FindDirectionForward, FindDirectionBackward };
+float deviceScaleFactor(Frame*);
+
class Page : public Supplementable<Page> {
WTF_MAKE_NONCOPYABLE(Page);
- WTF_MAKE_FAST_ALLOCATED;
friend class Settings;
friend class PageThrottler;
public:
- WEBCORE_EXPORT static void updateStyleForAllPagesAfterGlobalChangeInEnvironment();
- WEBCORE_EXPORT static void clearPreviousItemFromAllPages(HistoryItem*);
- WEBCORE_EXPORT static void setTabSuspensionEnabled(bool);
+ static void updateStyleForAllPagesAfterGlobalChangeInEnvironment();
+ static void jettisonStyleResolversInAllDocuments();
+
+ // It is up to the platform to ensure that non-null clients are provided where required.
+ struct PageClients {
+ WTF_MAKE_NONCOPYABLE(PageClients); WTF_MAKE_FAST_ALLOCATED;
+ public:
+ PageClients();
+ ~PageClients();
+
+ AlternativeTextClient* alternativeTextClient;
+ ChromeClient* chromeClient;
+#if ENABLE(CONTEXT_MENUS)
+ ContextMenuClient* contextMenuClient;
+#endif
+ EditorClient* editorClient;
+ DragClient* dragClient;
+ InspectorClient* inspectorClient;
+ PlugInClient* plugInClient;
+ ProgressTrackerClient* progressTrackerClient;
+ RefPtr<BackForwardClient> backForwardClient;
+ ValidationMessageClient* validationMessageClient;
+ FrameLoaderClient* loaderClientForMainFrame;
+ };
- WEBCORE_EXPORT explicit Page(PageConfiguration&);
- WEBCORE_EXPORT ~Page();
+ explicit Page(PageClients&);
+ ~Page();
- WEBCORE_EXPORT uint64_t renderTreeSize() const;
+ uint64_t renderTreeSize() const;
void setNeedsRecalcStyleInAllFrames();
RenderTheme& theme() const { return *m_theme; }
- WEBCORE_EXPORT ViewportArguments viewportArguments() const;
+ ViewportArguments viewportArguments() const;
static void refreshPlugins(bool reload);
- WEBCORE_EXPORT PluginData& pluginData() const;
+ PluginData& pluginData() const;
- WEBCORE_EXPORT void setCanStartMedia(bool);
+ void setCanStartMedia(bool);
bool canStartMedia() const { return m_canStartMedia; }
- EditorClient& editorClient() { return m_editorClient; }
+ EditorClient* editorClient() const { return m_editorClient; }
PlugInClient* plugInClient() const { return m_plugInClient; }
MainFrame& mainFrame() { ASSERT(m_mainFrame); return *m_mainFrame; }
const MainFrame& mainFrame() const { ASSERT(m_mainFrame); return *m_mainFrame; }
- bool inPageCache() const;
-
bool openedByDOM() const;
void setOpenedByDOM();
- WEBCORE_EXPORT void goToItem(HistoryItem&, FrameLoadType);
+ void goToItem(HistoryItem*, FrameLoadType);
- WEBCORE_EXPORT void setGroupName(const String&);
- WEBCORE_EXPORT const String& groupName() const;
+ void setGroupName(const String&);
+ const String& groupName() const;
PageGroup& group();
PageGroup* groupPtr() { return m_group; } // can return 0
- static void forEachPage(std::function<void(Page&)>);
-
void incrementSubframeCount() { ++m_subframeCount; }
void decrementSubframeCount() { ASSERT(m_subframeCount); --m_subframeCount; }
int subframeCount() const { checkSubframeCountConsistency(); return m_subframeCount; }
#if ENABLE(REMOTE_INSPECTOR)
- WEBCORE_EXPORT bool remoteInspectionAllowed() const;
- WEBCORE_EXPORT void setRemoteInspectionAllowed(bool);
- WEBCORE_EXPORT String remoteInspectionNameOverride() const;
- WEBCORE_EXPORT void setRemoteInspectionNameOverride(const String&);
+ bool remoteInspectionAllowed() const;
+ void setRemoteInspectionAllowed(bool);
void remoteInspectorInformationDidChange() const;
#endif
@@ -199,27 +194,25 @@ public:
#if ENABLE(CONTEXT_MENUS)
ContextMenuController& contextMenuController() const { return *m_contextMenuController; }
#endif
- UserInputBridge& userInputBridge() const { return *m_userInputBridge; }
-#if ENABLE(WEB_REPLAY)
- ReplayController& replayController() const { return *m_replayController; }
-#endif
+#if ENABLE(INSPECTOR)
InspectorController& inspectorController() const { return *m_inspectorController; }
+#endif
#if ENABLE(POINTER_LOCK)
- PointerLockController& pointerLockController() const { return *m_pointerLockController; }
+ PointerLockController* pointerLockController() const { return m_pointerLockController.get(); }
#endif
ValidationMessageClient* validationMessageClient() const { return m_validationMessageClient; }
- WEBCORE_EXPORT ScrollingCoordinator* scrollingCoordinator();
+ ScrollingCoordinator* scrollingCoordinator();
- WEBCORE_EXPORT String scrollingStateTreeAsText();
- WEBCORE_EXPORT String synchronousScrollingReasonsAsText();
- WEBCORE_EXPORT Ref<ClientRectList> nonFastScrollableRects();
+ String scrollingStateTreeAsText();
+ String synchronousScrollingReasonsAsText();
+ PassRefPtr<ClientRectList> nonFastScrollableRects(const Frame*);
Settings& settings() const { return *m_settings; }
ProgressTracker& progress() const { return *m_progress; }
BackForwardController& backForward() const { return *m_backForwardController; }
- double domTimerAlignmentInterval() const { return m_timerAlignmentInterval; }
+ FeatureObserver* featureObserver() { return &m_featureObserver; }
#if ENABLE(VIEW_MODE_CSS_MEDIA)
enum ViewMode {
@@ -233,20 +226,20 @@ public:
static ViewMode stringToViewMode(const String&);
ViewMode viewMode() const { return m_viewMode; }
- WEBCORE_EXPORT void setViewMode(ViewMode);
+ void setViewMode(ViewMode);
#endif // ENABLE(VIEW_MODE_CSS_MEDIA)
void setTabKeyCyclesThroughElements(bool b) { m_tabKeyCyclesThroughElements = b; }
bool tabKeyCyclesThroughElements() const { return m_tabKeyCyclesThroughElements; }
- WEBCORE_EXPORT bool findString(const String&, FindOptions);
+ bool findString(const String&, FindOptions);
- WEBCORE_EXPORT RefPtr<Range> rangeOfString(const String&, Range*, FindOptions);
+ PassRefPtr<Range> rangeOfString(const String&, Range*, FindOptions);
- WEBCORE_EXPORT unsigned countFindMatches(const String&, FindOptions, unsigned maxMatchCount);
- WEBCORE_EXPORT unsigned markAllMatchesForText(const String&, FindOptions, bool shouldHighlight, unsigned maxMatchCount);
+ unsigned countFindMatches(const String&, FindOptions, unsigned maxMatchCount);
+ unsigned markAllMatchesForText(const String&, FindOptions, bool shouldHighlight, unsigned maxMatchCount);
- WEBCORE_EXPORT void unmarkAllTextMatches();
+ void unmarkAllTextMatches();
// find all the Ranges for the matching text.
// Upon return, indexForSelection will be one of the following:
@@ -254,116 +247,95 @@ public:
// the index of the first range after the user selection
// NoMatchAfterUserSelection if there is no matching text after the user selection.
enum { NoMatchAfterUserSelection = -1 };
- WEBCORE_EXPORT void findStringMatchingRanges(const String&, FindOptions, int maxCount, Vector<RefPtr<Range>>&, int& indexForSelection);
-#if PLATFORM(COCOA)
- void platformInitialize();
- WEBCORE_EXPORT void addSchedulePair(Ref<SchedulePair>&&);
- WEBCORE_EXPORT void removeSchedulePair(Ref<SchedulePair>&&);
+ void findStringMatchingRanges(const String&, FindOptions, int maxCount, Vector<RefPtr<Range>>*, int& indexForSelection);
+#if PLATFORM(MAC)
+ void addSchedulePair(PassRefPtr<SchedulePair>);
+ void removeSchedulePair(PassRefPtr<SchedulePair>);
SchedulePairHashSet* scheduledRunLoopPairs() { return m_scheduledRunLoopPairs.get(); }
- std::unique_ptr<SchedulePairHashSet> m_scheduledRunLoopPairs;
+ OwnPtr<SchedulePairHashSet> m_scheduledRunLoopPairs;
#endif
- WEBCORE_EXPORT const VisibleSelection& selection() const;
+ const VisibleSelection& selection() const;
- WEBCORE_EXPORT void setDefersLoading(bool);
+ void setDefersLoading(bool);
bool defersLoading() const { return m_defersLoading; }
- WEBCORE_EXPORT void clearUndoRedoOperations();
+ void clearUndoRedoOperations();
- WEBCORE_EXPORT bool inLowQualityImageInterpolationMode() const;
- WEBCORE_EXPORT void setInLowQualityImageInterpolationMode(bool = true);
+ bool inLowQualityImageInterpolationMode() const;
+ void setInLowQualityImageInterpolationMode(bool = true);
float mediaVolume() const { return m_mediaVolume; }
- WEBCORE_EXPORT void setMediaVolume(float);
+ void setMediaVolume(float);
- WEBCORE_EXPORT void setPageScaleFactor(float scale, const IntPoint& origin, bool inStableState = true);
+ void setPageScaleFactor(float scale, const IntPoint& origin);
float pageScaleFactor() const { return m_pageScaleFactor; }
- // The view scale factor is multiplied into the page scale factor by all
- // callers of setPageScaleFactor.
- WEBCORE_EXPORT void setViewScaleFactor(float);
- float viewScaleFactor() const { return m_viewScaleFactor; }
-
- WEBCORE_EXPORT void setZoomedOutPageScaleFactor(float);
- float zoomedOutPageScaleFactor() const { return m_zoomedOutPageScaleFactor; }
-
float deviceScaleFactor() const { return m_deviceScaleFactor; }
- WEBCORE_EXPORT void setDeviceScaleFactor(float);
+ void setDeviceScaleFactor(float);
- float topContentInset() const { return m_topContentInset; }
- WEBCORE_EXPORT void setTopContentInset(float);
-
-#if ENABLE(IOS_TEXT_AUTOSIZING)
- float textAutosizingWidth() const { return m_textAutosizingWidth; }
- void setTextAutosizingWidth(float textAutosizingWidth) { m_textAutosizingWidth = textAutosizingWidth; }
-#endif
-
bool shouldSuppressScrollbarAnimations() const { return m_suppressScrollbarAnimations; }
- WEBCORE_EXPORT void setShouldSuppressScrollbarAnimations(bool suppressAnimations);
+ void setShouldSuppressScrollbarAnimations(bool suppressAnimations);
void lockAllOverlayScrollbarsToHidden(bool lockOverlayScrollbars);
-
- WEBCORE_EXPORT void setVerticalScrollElasticity(ScrollElasticity);
- ScrollElasticity verticalScrollElasticity() const { return static_cast<ScrollElasticity>(m_verticalScrollElasticity); }
- WEBCORE_EXPORT void setHorizontalScrollElasticity(ScrollElasticity);
- ScrollElasticity horizontalScrollElasticity() const { return static_cast<ScrollElasticity>(m_horizontalScrollElasticity); }
-
// Page and FrameView both store a Pagination value. Page::pagination() is set only by API,
// and FrameView::pagination() is set only by CSS. Page::pagination() will affect all
// FrameViews in the page cache, but FrameView::pagination() only affects the current
// FrameView.
const Pagination& pagination() const { return m_pagination; }
- WEBCORE_EXPORT void setPagination(const Pagination&);
- bool paginationLineGridEnabled() const { return m_paginationLineGridEnabled; }
- WEBCORE_EXPORT void setPaginationLineGridEnabled(bool flag);
+ void setPagination(const Pagination&);
- WEBCORE_EXPORT unsigned pageCount() const;
+ unsigned pageCount() const;
// Notifications when the Page starts and stops being presented via a native window.
- WEBCORE_EXPORT void setViewState(ViewState::Flags);
- void setPageActivityState(PageActivityState::Flags);
- WEBCORE_EXPORT void setIsVisible(bool);
- WEBCORE_EXPORT void setIsPrerender();
- bool isVisible() const { return m_viewState & ViewState::IsVisible; }
+ void setIsVisible(bool isVisible, bool isInitial);
+ void setIsPrerender();
+ bool isVisible() const { return m_isVisible; }
// Notification that this Page was moved into or out of a native window.
- WEBCORE_EXPORT void setIsInWindow(bool);
- bool isInWindow() const { return m_viewState & ViewState::IsInWindow; }
-
- void setIsClosing() { m_isClosing = true; }
- bool isClosing() const { return m_isClosing; }
-
- void addViewStateChangeObserver(ViewStateChangeObserver&);
- void removeViewStateChangeObserver(ViewStateChangeObserver&);
+ void setIsInWindow(bool);
+ bool isInWindow() const { return m_isInWindow; }
- WEBCORE_EXPORT void suspendScriptedAnimations();
- WEBCORE_EXPORT void resumeScriptedAnimations();
+ void suspendScriptedAnimations();
+ void resumeScriptedAnimations();
bool scriptedAnimationsSuspended() const { return m_scriptedAnimationsSuspended; }
+ void setIsVisuallyIdle(bool);
void userStyleSheetLocationChanged();
const String& userStyleSheet() const;
void dnsPrefetchingStateChanged();
void storageBlockingStateChanged();
-
-#if ENABLE(RESOURCE_USAGE)
- void setResourceUsageOverlayVisible(bool);
-#endif
+ void privateBrowsingStateChanged();
void setDebugger(JSC::Debugger*);
JSC::Debugger* debugger() const { return m_debugger; }
- WEBCORE_EXPORT void invalidateStylesForAllLinks();
- WEBCORE_EXPORT void invalidateStylesForLink(LinkHash);
+ static void removeAllVisitedLinks();
+
+ static void allVisitedStateChanged(PageGroup*);
+ static void visitedStateChanged(PageGroup*, LinkHash visitedHash);
StorageNamespace* sessionStorage(bool optionalCreate = true);
- void setSessionStorage(RefPtr<StorageNamespace>&&);
+ void setSessionStorage(PassRefPtr<StorageNamespace>);
+
+ // FIXME: We should make Settings::maxParseDuration() platform-independent, remove {has, set}CustomHTMLTokenizerTimeDelay()
+ // and customHTMLTokenizerTimeDelay() and modify theirs callers to update or query Settings::maxParseDuration().
+ void setCustomHTMLTokenizerTimeDelay(double);
+#if PLATFORM(IOS)
+ bool hasCustomHTMLTokenizerTimeDelay() const { return m_settings->maxParseDuration() != -1; }
+ double customHTMLTokenizerTimeDelay() const { ASSERT(m_settings->maxParseDuration() != -1); return m_settings->maxParseDuration(); }
+#else
+ bool hasCustomHTMLTokenizerTimeDelay() const { return m_customHTMLTokenizerTimeDelay != -1; }
+ double customHTMLTokenizerTimeDelay() const { ASSERT(m_customHTMLTokenizerTimeDelay != -1); return m_customHTMLTokenizerTimeDelay; }
+#endif
- bool hasCustomHTMLTokenizerTimeDelay() const;
- double customHTMLTokenizerTimeDelay() const;
+ void setCustomHTMLTokenizerChunkSize(int);
+ bool hasCustomHTMLTokenizerChunkSize() const { return m_customHTMLTokenizerChunkSize != -1; }
+ int customHTMLTokenizerChunkSize() const { ASSERT(m_customHTMLTokenizerChunkSize != -1); return m_customHTMLTokenizerChunkSize; }
- WEBCORE_EXPORT void setMemoryCacheClientCallsEnabled(bool);
+ void setMemoryCacheClientCallsEnabled(bool);
bool areMemoryCacheClientCallsEnabled() const { return m_areMemoryCacheClientCallsEnabled; }
// Don't allow more than a certain number of frames in a page.
@@ -372,40 +344,34 @@ public:
// with exponential growth in the number of frames.
static const int maxNumberOfFrames = 1000;
- static bool s_tabSuspensionIsEnabled;
-
void setEditable(bool isEditable) { m_isEditable = isEditable; }
bool isEditable() { return m_isEditable; }
- WEBCORE_EXPORT PageVisibilityState visibilityState() const;
- WEBCORE_EXPORT void resumeAnimatingImages();
+#if ENABLE(PAGE_VISIBILITY_API)
+ PageVisibilityState visibilityState() const;
+#endif
+ void resumeAnimatingImages();
- WEBCORE_EXPORT void addLayoutMilestones(LayoutMilestones);
- WEBCORE_EXPORT void removeLayoutMilestones(LayoutMilestones);
+ void addLayoutMilestones(LayoutMilestones);
+ void removeLayoutMilestones(LayoutMilestones);
LayoutMilestones requestedLayoutMilestones() const { return m_requestedLayoutMilestones; }
#if ENABLE(RUBBER_BANDING)
- WEBCORE_EXPORT void addHeaderWithHeight(int);
- WEBCORE_EXPORT void addFooterWithHeight(int);
+ void addHeaderWithHeight(int);
+ void addFooterWithHeight(int);
#endif
int headerHeight() const { return m_headerHeight; }
int footerHeight() const { return m_footerHeight; }
- WEBCORE_EXPORT Color pageExtendedBackgroundColor() const;
-
bool isCountingRelevantRepaintedObjects() const;
- void setIsCountingRelevantRepaintedObjects(bool isCounting) { m_isCountingRelevantRepaintedObjects = isCounting; }
void startCountingRelevantRepaintedObjects();
void resetRelevantPaintedObjectCounter();
void addRelevantRepaintedObject(RenderObject*, const LayoutRect& objectPaintRect);
void addRelevantUnpaintedObject(RenderObject*, const LayoutRect& objectPaintRect);
- WEBCORE_EXPORT void suspendActiveDOMObjectsAndAnimations();
- WEBCORE_EXPORT void resumeActiveDOMObjectsAndAnimations();
- void suspendDeviceMotionAndOrientationUpdates();
- void resumeDeviceMotionAndOrientationUpdates();
-
+ void suspendActiveDOMObjectsAndAnimations();
+ void resumeActiveDOMObjectsAndAnimations();
#ifndef NDEBUG
void setIsPainting(bool painting) { m_isPainting = painting; }
bool isPainting() const { return m_isPainting; }
@@ -414,7 +380,7 @@ public:
AlternativeTextClient* alternativeTextClient() const { return m_alternativeTextClient; }
bool hasSeenPlugin(const String& serviceType) const;
- WEBCORE_EXPORT bool hasSeenAnyPlugin() const;
+ bool hasSeenAnyPlugin() const;
void sawPlugin(const String& serviceType);
void resetSeenPlugins();
@@ -423,91 +389,33 @@ public:
void sawMediaEngine(const String& engineName);
void resetSeenMediaEngines();
- PageThrottler& pageThrottler() { return m_pageThrottler; }
+ PageThrottler& pageThrottler() { return *m_pageThrottler; }
+ std::unique_ptr<PageActivityAssertionToken> createActivityToken();
- PageConsoleClient& console() { return *m_consoleClient; }
+ PageConsole& console() { return *m_console; }
-#if ENABLE(REMOTE_INSPECTOR)
- PageDebuggable& inspectorDebuggable() const { return *m_inspectorDebuggable.get(); }
+#if ENABLE(HIDDEN_PAGE_DOM_TIMER_THROTTLING)
+ void hiddenPageDOMTimerThrottlingStateChanged();
#endif
-
+#if ENABLE(PAGE_VISIBILITY_API)
void hiddenPageCSSAnimationSuspensionStateChanged();
+#endif
#if ENABLE(VIDEO_TRACK)
void captionPreferencesChanged();
#endif
- void forbidPrompts();
- void allowPrompts();
- bool arePromptsAllowed();
-
+ void incrementFrameHandlingBeforeUnloadEventCount();
+ void decrementFrameHandlingBeforeUnloadEventCount();
+ bool isAnyFrameHandlingBeforeUnloadEvent();
void setLastSpatialNavigationCandidateCount(unsigned count) { m_lastSpatialNavigationCandidatesCount = count; }
unsigned lastSpatialNavigationCandidateCount() const { return m_lastSpatialNavigationCandidatesCount; }
- ApplicationCacheStorage& applicationCacheStorage() { return m_applicationCacheStorage; }
- DatabaseProvider& databaseProvider() { return m_databaseProvider; }
-
- StorageNamespaceProvider& storageNamespaceProvider() { return m_storageNamespaceProvider.get(); }
- void setStorageNamespaceProvider(Ref<StorageNamespaceProvider>&&);
-
+ void setUserContentController(UserContentController*);
UserContentController* userContentController() { return m_userContentController.get(); }
- WEBCORE_EXPORT void setUserContentController(UserContentController*);
-
- VisitedLinkStore& visitedLinkStore();
- WEBCORE_EXPORT void setVisitedLinkStore(Ref<VisitedLinkStore>&&);
-
- WEBCORE_EXPORT SessionID sessionID() const;
- WEBCORE_EXPORT void setSessionID(SessionID);
- WEBCORE_EXPORT void enableLegacyPrivateBrowsing(bool privateBrowsingEnabled);
- bool usesEphemeralSession() const { return m_sessionID.isEphemeral(); }
-
- MediaProducer::MediaStateFlags mediaState() const { return m_mediaState; }
- void updateIsPlayingMedia(uint64_t);
- bool isMuted() const { return m_muted; }
- WEBCORE_EXPORT void setMuted(bool);
-
-#if ENABLE(MEDIA_SESSION)
- WEBCORE_EXPORT void handleMediaEvent(MediaEventType);
- WEBCORE_EXPORT void setVolumeOfMediaElement(double, uint64_t);
-#endif
-
-#if ENABLE(WIRELESS_PLAYBACK_TARGET)
- void addPlaybackTargetPickerClient(uint64_t);
- void removePlaybackTargetPickerClient(uint64_t);
- void showPlaybackTargetPicker(uint64_t, const IntPoint&, bool);
- void playbackTargetPickerClientStateDidChange(uint64_t, MediaProducer::MediaStateFlags);
- WEBCORE_EXPORT void setMockMediaPlaybackTargetPickerEnabled(bool);
- WEBCORE_EXPORT void setMockMediaPlaybackTargetPickerState(const String&, MediaPlaybackTargetContext::State);
-
- WEBCORE_EXPORT void setPlaybackTarget(uint64_t, Ref<MediaPlaybackTarget>&&);
- WEBCORE_EXPORT void playbackTargetAvailabilityDidChange(uint64_t, bool);
- WEBCORE_EXPORT void setShouldPlayToPlaybackTarget(uint64_t, bool);
-#endif
-
- RefPtr<WheelEventTestTrigger> testTrigger() const { return m_testTrigger; }
- WEBCORE_EXPORT WheelEventTestTrigger& ensureTestTrigger();
- void clearTrigger() { m_testTrigger = nullptr; }
- bool expectsWheelEventTriggers() const { return !!m_testTrigger; }
-
-#if ENABLE(VIDEO)
- bool allowsMediaDocumentInlinePlayback() const { return m_allowsMediaDocumentInlinePlayback; }
- WEBCORE_EXPORT void setAllowsMediaDocumentInlinePlayback(bool);
-#endif
-
-#if ENABLE(INDEXED_DATABASE)
- IDBClient::IDBConnectionToServer& idbConnection();
-#endif
-
- void setShowAllPlugins(bool showAll) { m_showAllPlugins = showAll; }
- bool showAllPlugins() const;
- void setIsTabSuspended(bool);
private:
- WEBCORE_EXPORT void initGroup();
-
- void setIsInWindowInternal(bool);
- void setIsVisibleInternal(bool);
- void setIsVisuallyIdleInternal(bool);
+ void initGroup();
#if ASSERT_DISABLED
void checkSubframeCountConsistency() const { }
@@ -522,15 +430,16 @@ private:
MediaCanStartListener* takeAnyMediaCanStartListener();
+ void setMinimumTimerInterval(double);
+ double minimumTimerInterval() const;
+
+ void setTimerAlignmentInterval(double);
+ double timerAlignmentInterval() const;
+
Vector<Ref<PluginViewBase>> pluginViews();
- void hiddenPageDOMTimerThrottlingStateChanged();
- void setTimerThrottlingEnabled(bool);
- void setDOMTimerAlignmentInterval(double);
- void timerAlignmentIntervalTimerFired();
- bool canTabSuspend();
- void updateTabSuspensionState();
- void tabSuspensionTimerFired();
+ void throttleTimers();
+ void unthrottleTimers();
const std::unique_ptr<Chrome> m_chrome;
const std::unique_ptr<DragCaretController> m_dragCaretController;
@@ -542,13 +451,11 @@ private:
#if ENABLE(CONTEXT_MENUS)
const std::unique_ptr<ContextMenuController> m_contextMenuController;
#endif
- const std::unique_ptr<UserInputBridge> m_userInputBridge;
-#if ENABLE(WEB_REPLAY)
- const std::unique_ptr<ReplayController> m_replayController;
-#endif
+#if ENABLE(INSPECTOR)
const std::unique_ptr<InspectorController> m_inspectorController;
+#endif
#if ENABLE(POINTER_LOCK)
- const std::unique_ptr<PointerLockController> m_pointerLockController;
+ OwnPtr<PointerLockController> m_pointerLockController;
#endif
RefPtr<ScrollingCoordinator> m_scrollingCoordinator;
@@ -562,10 +469,12 @@ private:
RefPtr<RenderTheme> m_theme;
- EditorClient& m_editorClient;
+ EditorClient* m_editorClient;
PlugInClient* m_plugInClient;
ValidationMessageClient* m_validationMessageClient;
+ FeatureObserver m_featureObserver;
+
int m_subframeCount;
String m_groupName;
bool m_openedByDOM;
@@ -577,26 +486,13 @@ private:
bool m_inLowQualityInterpolationMode;
bool m_areMemoryCacheClientCallsEnabled;
float m_mediaVolume;
- bool m_muted;
float m_pageScaleFactor;
- float m_zoomedOutPageScaleFactor;
- float m_deviceScaleFactor { 1 };
- float m_viewScaleFactor { 1 };
+ float m_deviceScaleFactor;
- float m_topContentInset;
-
-#if ENABLE(IOS_TEXT_AUTOSIZING)
- float m_textAutosizingWidth;
-#endif
-
bool m_suppressScrollbarAnimations;
-
- unsigned m_verticalScrollElasticity : 2; // ScrollElasticity
- unsigned m_horizontalScrollElasticity : 2; // ScrollElasticity
Pagination m_pagination;
- bool m_paginationLineGridEnabled { false };
String m_userStyleSheetPath;
mutable String m_userStyleSheet;
@@ -608,6 +504,9 @@ private:
JSC::Debugger* m_debugger;
+ double m_customHTMLTokenizerTimeDelay;
+ int m_customHTMLTokenizerChunkSize;
+
bool m_canStartMedia;
RefPtr<StorageNamespace> m_sessionStorage;
@@ -616,13 +515,14 @@ private:
ViewMode m_viewMode;
#endif // ENABLE(VIEW_MODE_CSS_MEDIA)
- bool m_timerThrottlingEnabled;
+ double m_minimumTimerInterval;
+
double m_timerAlignmentInterval;
bool m_isEditable;
+ bool m_isInWindow;
+ bool m_isVisible;
bool m_isPrerender;
- ViewState::Flags m_viewState;
- PageActivityState::Flags m_pageActivityState;
LayoutMilestones m_requestedLayoutMilestones;
@@ -640,46 +540,20 @@ private:
AlternativeTextClient* m_alternativeTextClient;
bool m_scriptedAnimationsSuspended;
- PageThrottler m_pageThrottler;
- const std::unique_ptr<PageConsoleClient> m_consoleClient;
+ const std::unique_ptr<PageThrottler> m_pageThrottler;
+ const std::unique_ptr<PageConsole> m_console;
#if ENABLE(REMOTE_INSPECTOR)
const std::unique_ptr<PageDebuggable> m_inspectorDebuggable;
#endif
-#if ENABLE(INDEXED_DATABASE)
- RefPtr<IDBClient::IDBConnectionToServer> m_idbIDBConnectionToServer;
-#endif
-
HashSet<String> m_seenPlugins;
HashSet<String> m_seenMediaEngines;
unsigned m_lastSpatialNavigationCandidatesCount;
- unsigned m_forbidPromptsDepth;
+ unsigned m_framesHandlingBeforeUnloadEvent;
- Ref<ApplicationCacheStorage> m_applicationCacheStorage;
- Ref<DatabaseProvider> m_databaseProvider;
- Ref<StorageNamespaceProvider> m_storageNamespaceProvider;
RefPtr<UserContentController> m_userContentController;
- Ref<VisitedLinkStore> m_visitedLinkStore;
- RefPtr<WheelEventTestTrigger> m_testTrigger;
-
- HashSet<ViewStateChangeObserver*> m_viewStateChangeObservers;
-
-#if ENABLE(RESOURCE_USAGE)
- std::unique_ptr<ResourceUsageOverlay> m_resourceUsageOverlay;
-#endif
-
- SessionID m_sessionID;
-
- bool m_isClosing;
- bool m_isTabSuspended { false };
- Timer m_tabSuspensionTimer;
-
- MediaProducer::MediaStateFlags m_mediaState { MediaProducer::IsNotPlaying };
-
- bool m_allowsMediaDocumentInlinePlayback { false };
- bool m_showAllPlugins { false };
};
inline PageGroup& Page::group()
diff --git a/Source/WebCore/page/scrolling/coordinatedgraphics/ScrollingStateNodeCoordinatedGraphics.cpp b/Source/WebCore/page/PageActivityAssertionToken.cpp
index aeb6223c1..01e874bae 100644
--- a/Source/WebCore/page/scrolling/coordinatedgraphics/ScrollingStateNodeCoordinatedGraphics.cpp
+++ b/Source/WebCore/page/PageActivityAssertionToken.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 Intel Corporation. All rights reserved.
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -24,26 +24,29 @@
*/
#include "config.h"
-#include "ScrollingStateNode.h"
+#include "PageActivityAssertionToken.h"
-#include "GraphicsLayer.h"
-#include "NotImplemented.h"
-#include "ScrollingStateTree.h"
-
-#if USE(COORDINATED_GRAPHICS)
+#include "PageThrottler.h"
namespace WebCore {
-void LayerRepresentation::retainPlatformLayer(PlatformLayer*)
+PageActivityAssertionToken::PageActivityAssertionToken(PageThrottler& throttler)
+ : m_throttler(&throttler)
{
- notImplemented();
+ m_throttler->addActivityToken(*this);
}
-void LayerRepresentation::releasePlatformLayer(PlatformLayer*)
+PageActivityAssertionToken::~PageActivityAssertionToken()
{
- notImplemented();
+ if (m_throttler)
+ m_throttler->removeActivityToken(*this);
+}
+
+void PageActivityAssertionToken::invalidate()
+{
+ m_throttler = 0;
}
} // namespace WebCore
-#endif // USE(COORDINATED_GRAPHICS)
+
diff --git a/Source/WebCore/page/DiagnosticLoggingResultType.h b/Source/WebCore/page/PageActivityAssertionToken.h
index 3cb2d63cb..0f3584b27 100644
--- a/Source/WebCore/page/DiagnosticLoggingResultType.h
+++ b/Source/WebCore/page/PageActivityAssertionToken.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -23,18 +23,27 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef DiagnosticLoggingResultType_h
-#define DiagnosticLoggingResultType_h
+#ifndef PageActivityAssertionToken_h
+#define PageActivityAssertionToken_h
+
+#include <wtf/Noncopyable.h>
namespace WebCore {
-enum DiagnosticLoggingResultType {
- DiagnosticLoggingResultPass,
- DiagnosticLoggingResultFail,
- DiagnosticLoggingResultNoop,
+class PageThrottler;
+
+class PageActivityAssertionToken {
+ WTF_MAKE_NONCOPYABLE(PageActivityAssertionToken);
+public:
+ PageActivityAssertionToken(PageThrottler&);
+ ~PageActivityAssertionToken();
+
+ void invalidate();
+
+private:
+ PageThrottler* m_throttler;
};
} // namespace WebCore
-#endif // DiagnosticLoggingResultType_h
-
+#endif // PageActivityAssertionToken_h
diff --git a/Source/WebCore/page/PageConfiguration.h b/Source/WebCore/page/PageConfiguration.h
deleted file mode 100644
index 5b971c15b..000000000
--- a/Source/WebCore/page/PageConfiguration.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef PageConfiguration_h
-#define PageConfiguration_h
-
-#include <wtf/Noncopyable.h>
-#include <wtf/RefPtr.h>
-
-#if USE(APPLE_INTERNAL_SDK)
-#include <WebKitAdditions/PageConfigurationIncludes.h>
-#endif
-
-namespace WebCore {
-
-class AlternativeTextClient;
-class ApplicationCacheStorage;
-class BackForwardClient;
-class ChromeClient;
-class DatabaseProvider;
-class DiagnosticLoggingClient;
-class DragClient;
-class EditorClient;
-class FrameLoaderClient;
-class InspectorClient;
-class PlugInClient;
-class ProgressTrackerClient;
-class StorageNamespaceProvider;
-class UserContentController;
-class ValidationMessageClient;
-class VisitedLinkStore;
-
-#if ENABLE(CONTEXT_MENUS)
-class ContextMenuClient;
-#endif
-
-class PageConfiguration {
- WTF_MAKE_NONCOPYABLE(PageConfiguration); WTF_MAKE_FAST_ALLOCATED;
-public:
- WEBCORE_EXPORT PageConfiguration();
- WEBCORE_EXPORT ~PageConfiguration();
-
- AlternativeTextClient* alternativeTextClient { nullptr };
- ChromeClient* chromeClient { nullptr };
-#if ENABLE(CONTEXT_MENUS)
- ContextMenuClient* contextMenuClient { nullptr };
-#endif
- EditorClient* editorClient { nullptr };
- DragClient* dragClient { nullptr };
- InspectorClient* inspectorClient { nullptr };
- PlugInClient* plugInClient { nullptr };
- ProgressTrackerClient* progressTrackerClient { nullptr };
- RefPtr<BackForwardClient> backForwardClient;
- ValidationMessageClient* validationMessageClient { nullptr };
- FrameLoaderClient* loaderClientForMainFrame { nullptr };
- DiagnosticLoggingClient* diagnosticLoggingClient { nullptr };
-
-#if USE(APPLE_INTERNAL_SDK)
-#include <WebKitAdditions/PageConfigurationMembers.h>
-#endif
-
- RefPtr<ApplicationCacheStorage> applicationCacheStorage;
- RefPtr<DatabaseProvider> databaseProvider;
- RefPtr<StorageNamespaceProvider> storageNamespaceProvider;
- RefPtr<UserContentController> userContentController;
- RefPtr<VisitedLinkStore> visitedLinkStore;
-};
-
-}
-
-#endif
diff --git a/Source/WebCore/page/PageConsole.cpp b/Source/WebCore/page/PageConsole.cpp
new file mode 100644
index 000000000..2914cbb06
--- /dev/null
+++ b/Source/WebCore/page/PageConsole.cpp
@@ -0,0 +1,225 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "PageConsole.h"
+
+#include "Chrome.h"
+#include "ChromeClient.h"
+#include "ConsoleAPITypes.h"
+#include "ConsoleTypes.h"
+#include "Document.h"
+#include "Frame.h"
+#include "InspectorConsoleInstrumentation.h"
+#include "InspectorController.h"
+#include "JSMainThreadExecState.h"
+#include "Page.h"
+#include "ScriptArguments.h"
+#include "ScriptCallStack.h"
+#include "ScriptCallStackFactory.h"
+#include "ScriptableDocumentParser.h"
+#include "Settings.h"
+#include <bindings/ScriptValue.h>
+#include <stdio.h>
+#include <wtf/text/CString.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+namespace {
+ int muteCount = 0;
+}
+
+PageConsole::PageConsole(Page& page)
+ : m_page(page)
+{
+}
+
+PageConsole::~PageConsole()
+{
+}
+
+void PageConsole::printSourceURLAndPosition(const String& sourceURL, unsigned lineNumber, unsigned columnNumber)
+{
+ if (!sourceURL.isEmpty()) {
+ if (lineNumber > 0 && columnNumber > 0)
+ printf("%s:%u:%u", sourceURL.utf8().data(), lineNumber, columnNumber);
+ else if (lineNumber > 0)
+ printf("%s:%u", sourceURL.utf8().data(), lineNumber);
+ else
+ printf("%s", sourceURL.utf8().data());
+ }
+}
+
+void PageConsole::printMessageSourceAndLevelPrefix(MessageSource source, MessageLevel level, bool showAsTrace)
+{
+ const char* sourceString;
+ switch (source) {
+ case XMLMessageSource:
+ sourceString = "XML";
+ break;
+ case JSMessageSource:
+ sourceString = "JS";
+ break;
+ case NetworkMessageSource:
+ sourceString = "NETWORK";
+ break;
+ case ConsoleAPIMessageSource:
+ sourceString = "CONSOLE";
+ break;
+ case StorageMessageSource:
+ sourceString = "STORAGE";
+ break;
+ case AppCacheMessageSource:
+ sourceString = "APPCACHE";
+ break;
+ case RenderingMessageSource:
+ sourceString = "RENDERING";
+ break;
+ case CSSMessageSource:
+ sourceString = "CSS";
+ break;
+ case SecurityMessageSource:
+ sourceString = "SECURITY";
+ break;
+ case OtherMessageSource:
+ sourceString = "OTHER";
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ sourceString = "UNKNOWN";
+ break;
+ }
+
+ const char* levelString;
+ switch (level) {
+ case DebugMessageLevel:
+ levelString = "DEBUG";
+ break;
+ case LogMessageLevel:
+ levelString = "LOG";
+ break;
+ case WarningMessageLevel:
+ levelString = "WARN";
+ break;
+ case ErrorMessageLevel:
+ levelString = "ERROR";
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ levelString = "UNKNOWN";
+ break;
+ }
+
+ if (showAsTrace)
+ levelString = "TRACE";
+
+ printf("%s %s:", sourceString, levelString);
+}
+
+void PageConsole::addMessage(MessageSource source, MessageLevel level, const String& message, unsigned long requestIdentifier, Document* document)
+{
+ String url;
+ if (document)
+ url = document->url().string();
+ // FIXME: The below code attempts to determine line numbers for parser generated errors, but this is not the only reason why we can get here.
+ // For example, if we are still parsing and get a WebSocket network error, it will be erroneously attributed to a line where parsing was paused.
+ // Also, we should determine line numbers for script generated messages (e.g. calling getImageData on a canvas).
+ // We probably need to split this function into multiple ones, as appropriate for different call sites. Or maybe decide based on MessageSource.
+ // https://bugs.webkit.org/show_bug.cgi?id=125340
+ unsigned line = 0;
+ unsigned column = 0;
+ if (document && document->parsing() && !document->isInDocumentWrite() && document->scriptableDocumentParser()) {
+ ScriptableDocumentParser* parser = document->scriptableDocumentParser();
+ if (!parser->isWaitingForScripts() && !JSMainThreadExecState::currentState()) {
+ TextPosition position = parser->textPosition();
+ line = position.m_line.oneBasedInt();
+ column = position.m_column.oneBasedInt();
+ }
+ }
+ addMessage(source, level, message, url, line, column, 0, 0, requestIdentifier);
+}
+
+void PageConsole::addMessage(MessageSource source, MessageLevel level, const String& message, PassRefPtr<ScriptCallStack> callStack)
+{
+ addMessage(source, level, message, String(), 0, 0, callStack, 0);
+}
+
+void PageConsole::addMessage(MessageSource source, MessageLevel level, const String& message, const String& url, unsigned lineNumber, unsigned columnNumber, PassRefPtr<ScriptCallStack> callStack, JSC::ExecState* state, unsigned long requestIdentifier)
+{
+ if (muteCount && source != ConsoleAPIMessageSource)
+ return;
+
+ if (callStack)
+ InspectorInstrumentation::addMessageToConsole(&m_page, source, LogMessageType, level, message, callStack, requestIdentifier);
+ else
+ InspectorInstrumentation::addMessageToConsole(&m_page, source, LogMessageType, level, message, url, lineNumber, columnNumber, state, requestIdentifier);
+
+ if (source == CSSMessageSource)
+ return;
+
+ if (m_page.settings().privateBrowsingEnabled())
+ return;
+
+ m_page.chrome().client().addMessageToConsole(source, level, message, lineNumber, columnNumber, url);
+
+ if (!m_page.settings().logsPageMessagesToSystemConsoleEnabled() && !shouldPrintExceptions())
+ return;
+
+ printSourceURLAndPosition(url, lineNumber, columnNumber);
+ printMessageSourceAndLevelPrefix(source, level);
+
+ printf(" %s\n", message.utf8().data());
+}
+
+// static
+void PageConsole::mute()
+{
+ muteCount++;
+}
+
+// static
+void PageConsole::unmute()
+{
+ ASSERT(muteCount > 0);
+ muteCount--;
+}
+
+static bool printExceptions = false;
+
+bool PageConsole::shouldPrintExceptions()
+{
+ return printExceptions;
+}
+
+void PageConsole::setShouldPrintExceptions(bool print)
+{
+ printExceptions = print;
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/page/PageConsoleClient.h b/Source/WebCore/page/PageConsole.h
index 14b65a7ef..9a70e54d9 100644
--- a/Source/WebCore/page/PageConsoleClient.h
+++ b/Source/WebCore/page/PageConsole.h
@@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Inc. ("Apple") nor the names of
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
@@ -26,13 +26,13 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef PageConsoleClient_h
-#define PageConsoleClient_h
+#ifndef PageConsole_h
+#define PageConsole_h
-#include <inspector/ScriptCallStack.h>
-#include <profiler/Profile.h>
-#include <runtime/ConsoleClient.h>
+#include "ConsoleTypes.h"
+#include "ScriptCallStack.h"
#include <wtf/Forward.h>
+#include <wtf/PassOwnPtr.h>
namespace JSC {
class ExecState;
@@ -43,41 +43,28 @@ namespace WebCore {
class Document;
class Page;
-typedef Vector<RefPtr<JSC::Profile>> ProfilesArray;
-
-class WEBCORE_EXPORT PageConsoleClient final : public JSC::ConsoleClient {
- WTF_MAKE_FAST_ALLOCATED;
+class PageConsole {
public:
- explicit PageConsoleClient(Page&);
- virtual ~PageConsoleClient();
+ PageConsole(Page&);
+ ~PageConsole();
- static bool shouldPrintExceptions();
- static void setShouldPrintExceptions(bool);
+ static void printSourceURLAndPosition(const String& sourceURL, unsigned lineNumber, unsigned columnNumber = 0);
+ static void printMessageSourceAndLevelPrefix(MessageSource, MessageLevel, bool showAsTrace = false);
+
+ void addMessage(MessageSource, MessageLevel, const String& message, const String& sourceURL, unsigned lineNumber, unsigned columnNumber, PassRefPtr<ScriptCallStack> = 0, JSC::ExecState* = 0, unsigned long requestIdentifier = 0);
+ void addMessage(MessageSource, MessageLevel, const String& message, PassRefPtr<ScriptCallStack>);
+ void addMessage(MessageSource, MessageLevel, const String& message, unsigned long requestIdentifier = 0, Document* = 0);
static void mute();
static void unmute();
- void addMessage(MessageSource, MessageLevel, const String& message, const String& sourceURL, unsigned lineNumber, unsigned columnNumber, RefPtr<Inspector::ScriptCallStack>&& = nullptr, JSC::ExecState* = nullptr, unsigned long requestIdentifier = 0);
- void addMessage(MessageSource, MessageLevel, const String& message, RefPtr<Inspector::ScriptCallStack>&&);
- void addMessage(MessageSource, MessageLevel, const String& message, unsigned long requestIdentifier = 0, Document* = nullptr);
-
- const ProfilesArray& profiles() const { return m_profiles; }
- void clearProfiles();
-
-protected:
- virtual void messageWithTypeAndLevel(MessageType, MessageLevel, JSC::ExecState*, RefPtr<Inspector::ScriptArguments>&&) override;
- virtual void count(JSC::ExecState*, RefPtr<Inspector::ScriptArguments>&&) override;
- virtual void profile(JSC::ExecState*, const String& title) override;
- virtual void profileEnd(JSC::ExecState*, const String& title) override;
- virtual void time(JSC::ExecState*, const String& title) override;
- virtual void timeEnd(JSC::ExecState*, const String& title) override;
- virtual void timeStamp(JSC::ExecState*, RefPtr<Inspector::ScriptArguments>&&) override;
+ static bool shouldPrintExceptions();
+ static void setShouldPrintExceptions(bool);
private:
Page& m_page;
- ProfilesArray m_profiles;
};
} // namespace WebCore
-#endif // PageConsoleClient_h
+#endif // PageConsole_h
diff --git a/Source/WebCore/page/PageConsoleClient.cpp b/Source/WebCore/page/PageConsoleClient.cpp
deleted file mode 100644
index 1164e003b..000000000
--- a/Source/WebCore/page/PageConsoleClient.cpp
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "PageConsoleClient.h"
-
-#include "Chrome.h"
-#include "ChromeClient.h"
-#include "Document.h"
-#include "Frame.h"
-#include "InspectorConsoleInstrumentation.h"
-#include "InspectorController.h"
-#include "JSMainThreadExecState.h"
-#include "MainFrame.h"
-#include "Page.h"
-#include "ScriptableDocumentParser.h"
-#include "Settings.h"
-#include <bindings/ScriptValue.h>
-#include <inspector/ConsoleMessage.h>
-#include <inspector/ScriptArguments.h>
-#include <inspector/ScriptCallStack.h>
-#include <inspector/ScriptCallStackFactory.h>
-
-using namespace Inspector;
-
-namespace WebCore {
-
-PageConsoleClient::PageConsoleClient(Page& page)
- : m_page(page)
-{
-}
-
-PageConsoleClient::~PageConsoleClient()
-{
-}
-
-static int muteCount = 0;
-static bool printExceptions = false;
-
-bool PageConsoleClient::shouldPrintExceptions()
-{
- return printExceptions;
-}
-
-void PageConsoleClient::setShouldPrintExceptions(bool print)
-{
- printExceptions = print;
-}
-
-void PageConsoleClient::mute()
-{
- muteCount++;
-}
-
-void PageConsoleClient::unmute()
-{
- ASSERT(muteCount > 0);
- muteCount--;
-}
-
-static void getParserLocationForConsoleMessage(Document* document, String& url, unsigned& line, unsigned& column)
-{
- if (!document)
- return;
-
- // We definitely cannot associate the message with a location being parsed if we are not even parsing.
- if (!document->parsing())
- return;
-
- ScriptableDocumentParser* parser = document->scriptableDocumentParser();
- if (!parser)
- return;
-
- // When the parser waits for scripts, any messages must be coming from some other source, and are not related to the location of the script element that made the parser wait.
- if (!parser->shouldAssociateConsoleMessagesWithTextPosition())
- return;
-
- url = document->url().string();
- TextPosition position = parser->textPosition();
- line = position.m_line.oneBasedInt();
- column = position.m_column.oneBasedInt();
-}
-
-void PageConsoleClient::addMessage(MessageSource source, MessageLevel level, const String& message, unsigned long requestIdentifier, Document* document)
-{
- String url;
- unsigned line = 0;
- unsigned column = 0;
- getParserLocationForConsoleMessage(document, url, line, column);
-
- addMessage(source, level, message, url, line, column, 0, JSMainThreadExecState::currentState(), requestIdentifier);
-}
-
-void PageConsoleClient::addMessage(MessageSource source, MessageLevel level, const String& message, RefPtr<ScriptCallStack>&& callStack)
-{
- addMessage(source, level, message, String(), 0, 0, WTFMove(callStack), 0);
-}
-
-void PageConsoleClient::addMessage(MessageSource source, MessageLevel level, const String& messageText, const String& suggestedURL, unsigned suggestedLineNumber, unsigned suggestedColumnNumber, RefPtr<ScriptCallStack>&& callStack, JSC::ExecState* state, unsigned long requestIdentifier)
-{
- if (muteCount && source != MessageSource::ConsoleAPI)
- return;
-
- std::unique_ptr<Inspector::ConsoleMessage> message;
-
- if (callStack)
- message = std::make_unique<Inspector::ConsoleMessage>(source, MessageType::Log, level, messageText, WTFMove(callStack), requestIdentifier);
- else
- message = std::make_unique<Inspector::ConsoleMessage>(source, MessageType::Log, level, messageText, suggestedURL, suggestedLineNumber, suggestedColumnNumber, state, requestIdentifier);
-
- String url = message->url();
- unsigned lineNumber = message->line();
- unsigned columnNumber = message->column();
-
- InspectorInstrumentation::addMessageToConsole(m_page, WTFMove(message));
-
- if (source == MessageSource::CSS)
- return;
-
- if (m_page.usesEphemeralSession())
- return;
-
- m_page.chrome().client().addMessageToConsole(source, level, messageText, lineNumber, columnNumber, url);
-
- if (!m_page.settings().logsPageMessagesToSystemConsoleEnabled() && !shouldPrintExceptions())
- return;
-
- ConsoleClient::printConsoleMessage(MessageSource::ConsoleAPI, MessageType::Log, level, messageText, url, lineNumber, columnNumber);
-}
-
-
-void PageConsoleClient::messageWithTypeAndLevel(MessageType type, MessageLevel level, JSC::ExecState* exec, RefPtr<Inspector::ScriptArguments>&& arguments)
-{
- String messageText;
- bool gotMessage = arguments->getFirstArgumentAsString(messageText);
-
- auto message = std::make_unique<Inspector::ConsoleMessage>(MessageSource::ConsoleAPI, type, level, messageText, arguments.copyRef(), exec);
-
- String url = message->url();
- unsigned lineNumber = message->line();
- unsigned columnNumber = message->column();
-
- InspectorInstrumentation::addMessageToConsole(m_page, WTFMove(message));
-
- if (m_page.usesEphemeralSession())
- return;
-
- if (gotMessage)
- m_page.chrome().client().addMessageToConsole(MessageSource::ConsoleAPI, level, messageText, lineNumber, columnNumber, url);
-
- if (m_page.settings().logsPageMessagesToSystemConsoleEnabled() || PageConsoleClient::shouldPrintExceptions())
- ConsoleClient::printConsoleMessageWithArguments(MessageSource::ConsoleAPI, type, level, exec, WTFMove(arguments));
-}
-
-void PageConsoleClient::count(JSC::ExecState* exec, RefPtr<ScriptArguments>&& arguments)
-{
- InspectorInstrumentation::consoleCount(m_page, exec, WTFMove(arguments));
-}
-
-void PageConsoleClient::profile(JSC::ExecState* exec, const String& title)
-{
- // FIXME: <https://webkit.org/b/153499> Web Inspector: console.profile should use the new Sampling Profiler
- InspectorInstrumentation::startProfiling(m_page, exec, title);
-}
-
-void PageConsoleClient::profileEnd(JSC::ExecState* exec, const String& title)
-{
- // FIXME: <https://webkit.org/b/153499> Web Inspector: console.profile should use the new Sampling Profiler
- if (RefPtr<JSC::Profile> profile = InspectorInstrumentation::stopProfiling(m_page, exec, title))
- m_profiles.append(WTFMove(profile));
-}
-
-void PageConsoleClient::time(JSC::ExecState*, const String& title)
-{
- InspectorInstrumentation::startConsoleTiming(m_page.mainFrame(), title);
-}
-
-void PageConsoleClient::timeEnd(JSC::ExecState* exec, const String& title)
-{
- RefPtr<ScriptCallStack> callStack(createScriptCallStackForConsole(exec, 1));
- InspectorInstrumentation::stopConsoleTiming(m_page.mainFrame(), title, WTFMove(callStack));
-}
-
-void PageConsoleClient::timeStamp(JSC::ExecState*, RefPtr<ScriptArguments>&& arguments)
-{
- InspectorInstrumentation::consoleTimeStamp(m_page.mainFrame(), WTFMove(arguments));
-}
-
-void PageConsoleClient::clearProfiles()
-{
- m_profiles.clear();
-}
-
-} // namespace WebCore
diff --git a/Source/WebCore/page/PageDebuggable.cpp b/Source/WebCore/page/PageDebuggable.cpp
index 9c99f2279..067df5a1c 100644
--- a/Source/WebCore/page/PageDebuggable.cpp
+++ b/Source/WebCore/page/PageDebuggable.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -29,10 +29,11 @@
#if ENABLE(REMOTE_INSPECTOR)
#include "Document.h"
+#include "InspectorClient.h"
#include "InspectorController.h"
+#include "InspectorForwarding.h"
#include "MainFrame.h"
#include "Page.h"
-#include "Settings.h"
#include <inspector/InspectorAgentBase.h>
using namespace Inspector;
@@ -41,15 +42,11 @@ namespace WebCore {
PageDebuggable::PageDebuggable(Page& page)
: m_page(page)
- , m_forcedDeveloperExtrasEnabled(false)
{
}
String PageDebuggable::name() const
{
- if (!m_nameOverride.isNull())
- return m_nameOverride;
-
if (!m_page.mainFrame().document())
return String();
@@ -70,30 +67,29 @@ bool PageDebuggable::hasLocalDebugger() const
return m_page.inspectorController().hasLocalFrontend();
}
-void PageDebuggable::connect(Inspector::FrontendChannel* channel, bool isAutomaticConnection)
+pid_t PageDebuggable::parentProcessIdentifier() const
{
- if (!m_page.settings().developerExtrasEnabled()) {
- m_forcedDeveloperExtrasEnabled = true;
- m_page.settings().setDeveloperExtrasEnabled(true);
- } else
- m_forcedDeveloperExtrasEnabled = false;
+ if (InspectorClient* inspectorClient = m_page.inspectorController().inspectorClient())
+ return inspectorClient->parentProcessIdentifier();
- InspectorController& inspectorController = m_page.inspectorController();
- inspectorController.connectFrontend(channel, isAutomaticConnection);
+ return 0;
}
-void PageDebuggable::disconnect(Inspector::FrontendChannel* channel)
+void PageDebuggable::connect(Inspector::InspectorFrontendChannel* channel)
{
InspectorController& inspectorController = m_page.inspectorController();
- inspectorController.disconnectFrontend(channel);
+ inspectorController.setHasRemoteFrontend(true);
+ inspectorController.connectFrontend(reinterpret_cast<WebCore::InspectorFrontendChannel*>(channel));
+}
- if (m_forcedDeveloperExtrasEnabled) {
- m_forcedDeveloperExtrasEnabled = false;
- m_page.settings().setDeveloperExtrasEnabled(false);
- }
+void PageDebuggable::disconnect()
+{
+ InspectorController& inspectorController = m_page.inspectorController();
+ inspectorController.disconnectFrontend(InspectorDisconnectReason::InspectorDestroyed);
+ inspectorController.setHasRemoteFrontend(false);
}
-void PageDebuggable::dispatchMessageFromRemote(const String& message)
+void PageDebuggable::dispatchMessageFromRemoteFrontend(const String& message)
{
m_page.inspectorController().dispatchMessageFromFrontend(message);
}
@@ -103,12 +99,6 @@ void PageDebuggable::setIndicating(bool indicating)
m_page.inspectorController().setIndicating(indicating);
}
-void PageDebuggable::setNameOverride(const String& name)
-{
- m_nameOverride = name;
- update();
-}
-
} // namespace WebCore
#endif // ENABLE(REMOTE_INSPECTOR)
diff --git a/Source/WebCore/page/PageDebuggable.h b/Source/WebCore/page/PageDebuggable.h
index bef85bc80..bc1ff6458 100644
--- a/Source/WebCore/page/PageDebuggable.h
+++ b/Source/WebCore/page/PageDebuggable.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -28,44 +28,37 @@
#if ENABLE(REMOTE_INSPECTOR)
-#include <JavaScriptCore/RemoteInspectionTarget.h>
+#include <JavaScriptCore/RemoteInspectorDebuggable.h>
#include <wtf/Noncopyable.h>
namespace WebCore {
class Page;
-class PageDebuggable final : public Inspector::RemoteInspectionTarget {
- WTF_MAKE_FAST_ALLOCATED;
+class PageDebuggable final : public Inspector::RemoteInspectorDebuggable {
WTF_MAKE_NONCOPYABLE(PageDebuggable);
public:
PageDebuggable(Page&);
~PageDebuggable() { }
- virtual Inspector::RemoteControllableTarget::Type type() const override { return Inspector::RemoteControllableTarget::Type::Web; }
+ virtual Inspector::RemoteInspectorDebuggable::DebuggableType type() const override { return Inspector::RemoteInspectorDebuggable::Web; }
virtual String name() const override;
virtual String url() const override;
virtual bool hasLocalDebugger() const override;
+ virtual pid_t parentProcessIdentifier() const override;
- virtual void connect(Inspector::FrontendChannel*, bool isAutomaticConnection = false) override;
- virtual void disconnect(Inspector::FrontendChannel*) override;
- virtual void dispatchMessageFromRemote(const String& message) override;
+ virtual void connect(Inspector::InspectorFrontendChannel*) override;
+ virtual void disconnect() override;
+ virtual void dispatchMessageFromRemoteFrontend(const String& message) override;
virtual void setIndicating(bool) override;
- String nameOverride() const { return m_nameOverride; }
- void setNameOverride(const String&);
-
private:
Page& m_page;
- String m_nameOverride;
- bool m_forcedDeveloperExtrasEnabled;
};
} // namespace WebCore
-SPECIALIZE_TYPE_TRAITS_CONTROLLABLE_TARGET(WebCore::PageDebuggable, Web);
-
#endif // ENABLE(REMOTE_INSPECTOR)
#endif // !defined(PageDebuggable_h)
diff --git a/Source/WebCore/page/PageGroup.cpp b/Source/WebCore/page/PageGroup.cpp
index a2e7c33a9..8a1cd2081 100644
--- a/Source/WebCore/page/PageGroup.cpp
+++ b/Source/WebCore/page/PageGroup.cpp
@@ -30,17 +30,20 @@
#include "ChromeClient.h"
#include "DOMWrapperWorld.h"
#include "Document.h"
+#include "DocumentStyleSheetCollection.h"
+#include "GroupSettings.h"
#include "MainFrame.h"
#include "Page.h"
#include "PageCache.h"
#include "SecurityOrigin.h"
#include "Settings.h"
#include "StorageNamespace.h"
-#include <runtime/StructureInlines.h>
+#include "UserContentController.h"
+#include "VisitedLinkProvider.h"
#include <wtf/StdLibExtras.h>
#if ENABLE(VIDEO_TRACK)
-#if PLATFORM(MAC) || HAVE(MEDIA_ACCESSIBILITY_FRAMEWORK)
+#if (PLATFORM(MAC) && !PLATFORM(IOS)) || HAVE(MEDIA_ACCESSIBILITY_FRAMEWORK)
#include "CaptionUserPreferencesMediaAF.h"
#else
#include "CaptionUserPreferences.h"
@@ -57,24 +60,35 @@ static unsigned getUniqueIdentifier()
// --------
+static bool shouldTrackVisitedLinks = false;
+
PageGroup::PageGroup(const String& name)
: m_name(name)
+ , m_visitedLinkProvider(VisitedLinkProvider::create())
+ , m_visitedLinksPopulated(false)
, m_identifier(getUniqueIdentifier())
+ , m_userContentController(UserContentController::create())
+ , m_groupSettings(std::make_unique<GroupSettings>())
{
}
PageGroup::PageGroup(Page& page)
- : m_identifier(getUniqueIdentifier())
+ : m_visitedLinkProvider(VisitedLinkProvider::create())
+ , m_visitedLinksPopulated(false)
+ , m_identifier(getUniqueIdentifier())
+ , m_userContentController(UserContentController::create())
+ , m_groupSettings(std::make_unique<GroupSettings>())
{
addPage(page);
}
PageGroup::~PageGroup()
{
+ removeAllUserContent();
}
typedef HashMap<String, PageGroup*> PageGroupMap;
-static PageGroupMap* pageGroups = nullptr;
+static PageGroupMap* pageGroups = 0;
PageGroup* PageGroup::pageGroup(const String& groupName)
{
@@ -94,37 +108,227 @@ PageGroup* PageGroup::pageGroup(const String& groupName)
return result.iterator->value;
}
+void PageGroup::closeLocalStorage()
+{
+ if (!pageGroups)
+ return;
+
+ for (auto it = pageGroups->begin(), end = pageGroups->end(); it != end; ++it) {
+ if (it->value->hasLocalStorage())
+ it->value->localStorage()->close();
+ }
+}
+
+void PageGroup::clearLocalStorageForAllOrigins()
+{
+ if (!pageGroups)
+ return;
+
+ for (auto it = pageGroups->begin(), end = pageGroups->end(); it != end; ++it) {
+ if (it->value->hasLocalStorage())
+ it->value->localStorage()->clearAllOriginsForDeletion();
+ }
+}
+
+void PageGroup::clearLocalStorageForOrigin(SecurityOrigin* origin)
+{
+ if (!pageGroups)
+ return;
+
+ for (auto it = pageGroups->begin(), end = pageGroups->end(); it != end; ++it) {
+ if (it->value->hasLocalStorage())
+ it->value->localStorage()->clearOriginForDeletion(origin);
+ }
+}
+
+void PageGroup::closeIdleLocalStorageDatabases()
+{
+ if (!pageGroups)
+ return;
+
+ for (auto it = pageGroups->begin(), end = pageGroups->end(); it != end; ++it) {
+ if (it->value->hasLocalStorage())
+ it->value->localStorage()->closeIdleLocalStorageDatabases();
+ }
+}
+
+void PageGroup::syncLocalStorage()
+{
+ if (!pageGroups)
+ return;
+
+ for (auto it = pageGroups->begin(), end = pageGroups->end(); it != end; ++it) {
+ if (it->value->hasLocalStorage())
+ it->value->localStorage()->sync();
+ }
+}
+
void PageGroup::addPage(Page& page)
{
ASSERT(!m_pages.contains(&page));
m_pages.add(&page);
+
+ page.setUserContentController(m_userContentController.get());
}
void PageGroup::removePage(Page& page)
{
ASSERT(m_pages.contains(&page));
m_pages.remove(&page);
+
+ page.setUserContentController(nullptr);
+}
+
+bool PageGroup::isLinkVisited(LinkHash visitedLinkHash)
+{
+ if (!m_visitedLinksPopulated) {
+ m_visitedLinksPopulated = true;
+ ASSERT(!m_pages.isEmpty());
+ (*m_pages.begin())->chrome().client().populateVisitedLinks();
+ }
+ return m_visitedLinkHashes.contains(visitedLinkHash);
+}
+
+void PageGroup::addVisitedLinkHash(LinkHash hash)
+{
+ if (shouldTrackVisitedLinks)
+ addVisitedLink(hash);
+}
+
+inline void PageGroup::addVisitedLink(LinkHash hash)
+{
+ ASSERT(shouldTrackVisitedLinks);
+ if (!m_visitedLinkHashes.add(hash).isNewEntry)
+ return;
+ Page::visitedStateChanged(this, hash);
+ pageCache()->markPagesForVistedLinkStyleRecalc();
+}
+
+void PageGroup::addVisitedLink(const URL& url)
+{
+ if (!shouldTrackVisitedLinks)
+ return;
+ ASSERT(!url.isEmpty());
+ addVisitedLink(visitedLinkHash(url.string()));
+}
+
+void PageGroup::addVisitedLink(const UChar* characters, size_t length)
+{
+ if (!shouldTrackVisitedLinks)
+ return;
+ addVisitedLink(visitedLinkHash(characters, length));
+}
+
+void PageGroup::removeVisitedLink(const URL& url)
+{
+ LinkHash hash = visitedLinkHash(url.string());
+ ASSERT(m_visitedLinkHashes.contains(hash));
+ m_visitedLinkHashes.remove(hash);
+
+ Page::allVisitedStateChanged(this);
+ pageCache()->markPagesForVistedLinkStyleRecalc();
+}
+
+void PageGroup::removeVisitedLinks()
+{
+ m_visitedLinksPopulated = false;
+ if (m_visitedLinkHashes.isEmpty())
+ return;
+ m_visitedLinkHashes.clear();
+ Page::allVisitedStateChanged(this);
+ pageCache()->markPagesForVistedLinkStyleRecalc();
+}
+
+void PageGroup::removeAllVisitedLinks()
+{
+ Page::removeAllVisitedLinks();
+ pageCache()->markPagesForVistedLinkStyleRecalc();
+}
+
+void PageGroup::setShouldTrackVisitedLinks(bool shouldTrack)
+{
+ if (shouldTrackVisitedLinks == shouldTrack)
+ return;
+ shouldTrackVisitedLinks = shouldTrack;
+ if (!shouldTrackVisitedLinks)
+ removeAllVisitedLinks();
+}
+
+StorageNamespace* PageGroup::localStorage()
+{
+ if (!m_localStorage)
+ m_localStorage = StorageNamespace::localStorageNamespace(this);
+
+ return m_localStorage.get();
+}
+
+StorageNamespace* PageGroup::transientLocalStorage(SecurityOrigin* topOrigin)
+{
+ auto result = m_transientLocalStorageMap.add(topOrigin, nullptr);
+
+ if (result.isNewEntry)
+ result.iterator->value = StorageNamespace::transientLocalStorageNamespace(this, topOrigin);
+
+ return result.iterator->value.get();
+}
+
+void PageGroup::addUserScriptToWorld(DOMWrapperWorld& world, const String& source, const URL& url, const Vector<String>& whitelist, const Vector<String>& blacklist, UserScriptInjectionTime injectionTime, UserContentInjectedFrames injectedFrames)
+{
+ auto userScript = std::make_unique<UserScript>(source, url, whitelist, blacklist, injectionTime, injectedFrames);
+ m_userContentController->addUserScript(world, std::move(userScript));
+}
+
+void PageGroup::addUserStyleSheetToWorld(DOMWrapperWorld& world, const String& source, const URL& url, const Vector<String>& whitelist, const Vector<String>& blacklist, UserContentInjectedFrames injectedFrames, UserStyleLevel level, UserStyleInjectionTime injectionTime)
+{
+ auto userStyleSheet = std::make_unique<UserStyleSheet>(source, url, whitelist, blacklist, injectedFrames, level);
+ m_userContentController->addUserStyleSheet(world, std::move(userStyleSheet), injectionTime);
+
+}
+
+void PageGroup::removeUserScriptFromWorld(DOMWrapperWorld& world, const URL& url)
+{
+ m_userContentController->removeUserScript(world, url);
+}
+
+void PageGroup::removeUserStyleSheetFromWorld(DOMWrapperWorld& world, const URL& url)
+{
+ m_userContentController->removeUserStyleSheet(world, url);
+}
+
+void PageGroup::removeUserScriptsFromWorld(DOMWrapperWorld& world)
+{
+ m_userContentController->removeUserScripts(world);
+}
+
+void PageGroup::removeUserStyleSheetsFromWorld(DOMWrapperWorld& world)
+{
+ m_userContentController->removeUserStyleSheets(world);
+}
+
+void PageGroup::removeAllUserContent()
+{
+ m_userContentController->removeAllUserContent();
}
#if ENABLE(VIDEO_TRACK)
void PageGroup::captionPreferencesChanged()
{
- for (auto& page : m_pages)
- page->captionPreferencesChanged();
- PageCache::singleton().markPagesForCaptionPreferencesChanged();
+ for (auto it = m_pages.begin(), end = m_pages.end(); it != end; ++it)
+ (*it)->captionPreferencesChanged();
+ pageCache()->markPagesForCaptionPreferencesChanged();
}
-CaptionUserPreferences& PageGroup::captionPreferences()
+CaptionUserPreferences* PageGroup::captionPreferences()
{
if (!m_captionPreferences) {
-#if PLATFORM(MAC) || HAVE(MEDIA_ACCESSIBILITY_FRAMEWORK)
+#if (PLATFORM(MAC) && !PLATFORM(IOS)) || HAVE(MEDIA_ACCESSIBILITY_FRAMEWORK)
m_captionPreferences = std::make_unique<CaptionUserPreferencesMediaAF>(*this);
#else
m_captionPreferences = std::make_unique<CaptionUserPreferences>(*this);
#endif
}
- return *m_captionPreferences.get();
+ return m_captionPreferences.get();
}
#endif
diff --git a/Source/WebCore/page/PageGroup.h b/Source/WebCore/page/PageGroup.h
index dc1197df0..01f2e33e8 100644
--- a/Source/WebCore/page/PageGroup.h
+++ b/Source/WebCore/page/PageGroup.h
@@ -26,45 +26,106 @@
#ifndef PageGroup_h
#define PageGroup_h
+#include "LinkHash.h"
+#include "SecurityOriginHash.h"
#include "Supplementable.h"
+#include "UserScript.h"
+#include "UserStyleSheet.h"
#include <wtf/HashSet.h>
#include <wtf/Noncopyable.h>
-#include <wtf/text/WTFString.h>
namespace WebCore {
+ class URL;
+ class GroupSettings;
+ class IDBFactoryBackendInterface;
class Page;
+ class SecurityOrigin;
+ class StorageNamespace;
+ class VisitedLinkProvider;
+ class UserContentController;
+
#if ENABLE(VIDEO_TRACK)
+ class CaptionPreferencesChangedListener;
class CaptionUserPreferences;
#endif
- class PageGroup {
+ class PageGroup : public Supplementable<PageGroup> {
WTF_MAKE_NONCOPYABLE(PageGroup); WTF_MAKE_FAST_ALLOCATED;
public:
- WEBCORE_EXPORT explicit PageGroup(const String& name);
+ explicit PageGroup(const String& name);
explicit PageGroup(Page&);
~PageGroup();
- WEBCORE_EXPORT static PageGroup* pageGroup(const String& groupName);
+ static PageGroup* pageGroup(const String& groupName);
+
+ static void closeLocalStorage();
+
+ static void clearLocalStorageForAllOrigins();
+ static void clearLocalStorageForOrigin(SecurityOrigin*);
+ static void closeIdleLocalStorageDatabases();
+ // DumpRenderTree helper that triggers a StorageArea sync.
+ static void syncLocalStorage();
const HashSet<Page*>& pages() const { return m_pages; }
void addPage(Page&);
void removePage(Page&);
+ VisitedLinkProvider& visitedLinkProvider() { return *m_visitedLinkProvider; }
+
+ bool isLinkVisited(LinkHash);
+
+ void addVisitedLink(const URL&);
+ void addVisitedLink(const UChar*, size_t);
+ void addVisitedLinkHash(LinkHash);
+ void removeVisitedLink(const URL&);
+ void removeVisitedLinks();
+
+ static void setShouldTrackVisitedLinks(bool);
+ static void removeAllVisitedLinks();
+
const String& name() { return m_name; }
unsigned identifier() { return m_identifier; }
+ StorageNamespace* localStorage();
+ bool hasLocalStorage() { return m_localStorage; }
+
+ StorageNamespace* transientLocalStorage(SecurityOrigin* topOrigin);
+
+ void addUserScriptToWorld(DOMWrapperWorld&, const String& source, const URL&, const Vector<String>& whitelist, const Vector<String>& blacklist, UserScriptInjectionTime, UserContentInjectedFrames);
+ void addUserStyleSheetToWorld(DOMWrapperWorld&, const String& source, const URL&, const Vector<String>& whitelist, const Vector<String>& blacklist, UserContentInjectedFrames, UserStyleLevel = UserStyleUserLevel, UserStyleInjectionTime = InjectInExistingDocuments);
+ void removeUserStyleSheetFromWorld(DOMWrapperWorld&, const URL&);
+ void removeUserScriptFromWorld(DOMWrapperWorld&, const URL&);
+ void removeUserScriptsFromWorld(DOMWrapperWorld&);
+ void removeUserStyleSheetsFromWorld(DOMWrapperWorld&);
+ void removeAllUserContent();
+
+ GroupSettings& groupSettings() const { return *m_groupSettings; }
+
#if ENABLE(VIDEO_TRACK)
- WEBCORE_EXPORT void captionPreferencesChanged();
- WEBCORE_EXPORT CaptionUserPreferences& captionPreferences();
+ void captionPreferencesChanged();
+ CaptionUserPreferences* captionPreferences();
#endif
private:
+ void addVisitedLink(LinkHash);
+
String m_name;
HashSet<Page*> m_pages;
+ RefPtr<VisitedLinkProvider> m_visitedLinkProvider;
+
+ HashSet<LinkHash, LinkHashHash> m_visitedLinkHashes;
+ bool m_visitedLinksPopulated;
+
unsigned m_identifier;
+ RefPtr<StorageNamespace> m_localStorage;
+ HashMap<RefPtr<SecurityOrigin>, RefPtr<StorageNamespace>> m_transientLocalStorageMap;
+
+ RefPtr<UserContentController> m_userContentController;
+
+ const std::unique_ptr<GroupSettings> m_groupSettings;
#if ENABLE(VIDEO_TRACK)
std::unique_ptr<CaptionUserPreferences> m_captionPreferences;
diff --git a/Source/WebCore/page/PageGroupLoadDeferrer.cpp b/Source/WebCore/page/PageGroupLoadDeferrer.cpp
index 3523eda46..b5f1ca341 100644
--- a/Source/WebCore/page/PageGroupLoadDeferrer.cpp
+++ b/Source/WebCore/page/PageGroupLoadDeferrer.cpp
@@ -33,7 +33,11 @@ namespace WebCore {
PageGroupLoadDeferrer::PageGroupLoadDeferrer(Page& page, bool deferSelf)
{
- for (auto& otherPage : page.group().pages()) {
+ const HashSet<Page*>& pages = page.group().pages();
+
+ HashSet<Page*>::const_iterator end = pages.end();
+ for (HashSet<Page*>::const_iterator it = pages.begin(); it != end; ++it) {
+ Page* otherPage = *it;
if ((deferSelf || otherPage != &page)) {
if (!otherPage->defersLoading()) {
m_deferredFrames.append(&otherPage->mainFrame());
@@ -46,16 +50,16 @@ PageGroupLoadDeferrer::PageGroupLoadDeferrer(Page& page, bool deferSelf)
}
}
- for (auto& deferredFrame : m_deferredFrames) {
- if (Page* page = deferredFrame->page())
+ size_t count = m_deferredFrames.size();
+ for (size_t i = 0; i < count; ++i)
+ if (Page* page = m_deferredFrames[i]->page())
page->setDefersLoading(true);
- }
}
PageGroupLoadDeferrer::~PageGroupLoadDeferrer()
{
- for (auto& deferredFrame : m_deferredFrames) {
- if (Page* page = deferredFrame->page()) {
+ for (size_t i = 0; i < m_deferredFrames.size(); ++i) {
+ if (Page* page = m_deferredFrames[i]->page()) {
page->setDefersLoading(false);
for (Frame* frame = &page->mainFrame(); frame; frame = frame->tree().traverseNext())
diff --git a/Source/WebCore/page/PageOverlay.cpp b/Source/WebCore/page/PageOverlay.cpp
deleted file mode 100644
index 64d07e48b..000000000
--- a/Source/WebCore/page/PageOverlay.cpp
+++ /dev/null
@@ -1,292 +0,0 @@
-/*
- * Copyright (C) 2010 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "PageOverlay.h"
-
-#include "FrameView.h"
-#include "GraphicsContext.h"
-#include "MainFrame.h"
-#include "Page.h"
-#include "PageOverlayController.h"
-#include "PlatformMouseEvent.h"
-#include "ScrollbarTheme.h"
-#include <wtf/CurrentTime.h>
-
-namespace WebCore {
-
-static const double fadeAnimationDuration = 0.2;
-static const double fadeAnimationFrameRate = 30;
-
-static PageOverlay::PageOverlayID generatePageOverlayID()
-{
- static PageOverlay::PageOverlayID pageOverlayID;
- return ++pageOverlayID;
-}
-
-Ref<PageOverlay> PageOverlay::create(Client& client, OverlayType overlayType)
-{
- return adoptRef(*new PageOverlay(client, overlayType));
-}
-
-PageOverlay::PageOverlay(Client& client, OverlayType overlayType)
- : m_client(client)
- , m_fadeAnimationTimer(*this, &PageOverlay::fadeAnimationTimerFired)
- , m_fadeAnimationDuration(fadeAnimationDuration)
- , m_needsSynchronousScrolling(overlayType == OverlayType::View)
- , m_overlayType(overlayType)
- , m_pageOverlayID(generatePageOverlayID())
-{
-}
-
-PageOverlay::~PageOverlay()
-{
-}
-
-PageOverlayController* PageOverlay::controller() const
-{
- if (!m_page)
- return nullptr;
- return &m_page->mainFrame().pageOverlayController();
-}
-
-IntRect PageOverlay::bounds() const
-{
- if (!m_overrideFrame.isEmpty())
- return { { }, m_overrideFrame.size() };
-
- FrameView* frameView = m_page->mainFrame().view();
-
- if (!frameView)
- return IntRect();
-
- switch (m_overlayType) {
- case OverlayType::View: {
- int width = frameView->width();
- int height = frameView->height();
-
- if (!ScrollbarTheme::theme().usesOverlayScrollbars()) {
- if (frameView->verticalScrollbar())
- width -= frameView->verticalScrollbar()->width();
- if (frameView->horizontalScrollbar())
- height -= frameView->horizontalScrollbar()->height();
- }
- return IntRect(0, 0, width, height);
- }
- case OverlayType::Document:
- return IntRect(IntPoint(), frameView->contentsSize());
- }
-
- ASSERT_NOT_REACHED();
- return IntRect(IntPoint(), frameView->contentsSize());
-}
-
-IntRect PageOverlay::frame() const
-{
- if (!m_overrideFrame.isEmpty())
- return m_overrideFrame;
-
- return bounds();
-}
-
-void PageOverlay::setFrame(IntRect frame)
-{
- if (m_overrideFrame == frame)
- return;
-
- m_overrideFrame = frame;
-
- if (auto pageOverlayController = controller())
- pageOverlayController->didChangeOverlayFrame(*this);
-}
-
-IntSize PageOverlay::viewToOverlayOffset() const
-{
- switch (m_overlayType) {
- case OverlayType::View:
- return IntSize();
-
- case OverlayType::Document: {
- FrameView* frameView = m_page->mainFrame().view();
- return frameView ? toIntSize(frameView->viewToContents(IntPoint())) : IntSize();
- }
- }
- return IntSize();
-}
-
-void PageOverlay::setBackgroundColor(RGBA32 backgroundColor)
-{
- if (m_backgroundColor == backgroundColor)
- return;
-
- m_backgroundColor = backgroundColor;
-
- if (auto pageOverlayController = controller())
- pageOverlayController->didChangeOverlayBackgroundColor(*this);
-}
-
-void PageOverlay::setPage(Page* page)
-{
- m_client.willMoveToPage(*this, page);
- m_page = page;
- m_client.didMoveToPage(*this, page);
-
- m_fadeAnimationTimer.stop();
-}
-
-void PageOverlay::setNeedsDisplay(const IntRect& dirtyRect)
-{
- if (auto pageOverlayController = controller()) {
- if (m_fadeAnimationType != FadeAnimationType::NoAnimation)
- pageOverlayController->setPageOverlayOpacity(*this, m_fractionFadedIn);
- pageOverlayController->setPageOverlayNeedsDisplay(*this, dirtyRect);
- }
-}
-
-void PageOverlay::setNeedsDisplay()
-{
- setNeedsDisplay(bounds());
-}
-
-void PageOverlay::drawRect(GraphicsContext& graphicsContext, const IntRect& dirtyRect)
-{
- // If the dirty rect is outside the bounds, ignore it.
- IntRect paintRect = intersection(dirtyRect, bounds());
- if (paintRect.isEmpty())
- return;
-
- GraphicsContextStateSaver stateSaver(graphicsContext);
-
- if (m_overlayType == PageOverlay::OverlayType::Document) {
- if (FrameView* frameView = m_page->mainFrame().view()) {
- auto offset = frameView->scrollOrigin();
- graphicsContext.translate(toFloatSize(offset));
- paintRect.moveBy(-offset);
- }
- }
-
- m_client.drawRect(*this, graphicsContext, paintRect);
-}
-
-bool PageOverlay::mouseEvent(const PlatformMouseEvent& mouseEvent)
-{
- IntPoint mousePositionInOverlayCoordinates(mouseEvent.position());
-
- if (m_overlayType == PageOverlay::OverlayType::Document)
- mousePositionInOverlayCoordinates = m_page->mainFrame().view()->windowToContents(mousePositionInOverlayCoordinates);
- mousePositionInOverlayCoordinates.moveBy(-frame().location());
-
- // Ignore events outside the bounds.
- if (m_shouldIgnoreMouseEventsOutsideBounds && !bounds().contains(mousePositionInOverlayCoordinates))
- return false;
-
- return m_client.mouseEvent(*this, mouseEvent);
-}
-
-void PageOverlay::didScrollFrame(Frame& frame)
-{
- m_client.didScrollFrame(*this, frame);
-}
-
-bool PageOverlay::copyAccessibilityAttributeStringValueForPoint(String attribute, FloatPoint parameter, String& value)
-{
- return m_client.copyAccessibilityAttributeStringValueForPoint(*this, attribute, parameter, value);
-}
-
-bool PageOverlay::copyAccessibilityAttributeBoolValueForPoint(String attribute, FloatPoint parameter, bool& value)
-{
- return m_client.copyAccessibilityAttributeBoolValueForPoint(*this, attribute, parameter, value);
-}
-
-Vector<String> PageOverlay::copyAccessibilityAttributeNames(bool parameterizedNames)
-{
- return m_client.copyAccessibilityAttributeNames(*this, parameterizedNames);
-}
-
-void PageOverlay::startFadeInAnimation()
-{
- m_fractionFadedIn = 0;
- m_fadeAnimationType = FadeInAnimation;
-
- startFadeAnimation();
-}
-
-void PageOverlay::startFadeOutAnimation()
-{
- m_fractionFadedIn = 1;
- m_fadeAnimationType = FadeOutAnimation;
-
- startFadeAnimation();
-}
-
-void PageOverlay::stopFadeOutAnimation()
-{
- m_fractionFadedIn = 1.0;
- m_fadeAnimationTimer.stop();
-}
-
-void PageOverlay::startFadeAnimation()
-{
- m_fadeAnimationStartTime = currentTime();
- m_fadeAnimationTimer.startRepeating(1 / fadeAnimationFrameRate);
-}
-
-void PageOverlay::fadeAnimationTimerFired()
-{
- float animationProgress = (currentTime() - m_fadeAnimationStartTime) / m_fadeAnimationDuration;
-
- if (animationProgress >= 1.0)
- animationProgress = 1.0;
-
- double sine = sin(piOverTwoFloat * animationProgress);
- float fadeAnimationValue = sine * sine;
-
- m_fractionFadedIn = (m_fadeAnimationType == FadeInAnimation) ? fadeAnimationValue : 1 - fadeAnimationValue;
- controller()->setPageOverlayOpacity(*this, m_fractionFadedIn);
-
- if (animationProgress == 1.0) {
- m_fadeAnimationTimer.stop();
-
- bool wasFadingOut = m_fadeAnimationType == FadeOutAnimation;
- m_fadeAnimationType = NoAnimation;
-
- // If this was a fade out, uninstall the page overlay.
- if (wasFadingOut)
- controller()->uninstallPageOverlay(this, PageOverlay::FadeMode::DoNotFade);
- }
-}
-
-void PageOverlay::clear()
-{
- if (auto pageOverlayController = controller())
- pageOverlayController->clearPageOverlay(*this);
-}
-
-GraphicsLayer& PageOverlay::layer()
-{
- return controller()->layerForOverlay(*this);
-}
-
-} // namespace WebKit
diff --git a/Source/WebCore/page/PageOverlay.h b/Source/WebCore/page/PageOverlay.h
deleted file mode 100644
index 3ce0e4695..000000000
--- a/Source/WebCore/page/PageOverlay.h
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * Copyright (C) 2010 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef PageOverlay_h
-#define PageOverlay_h
-
-#include "Color.h"
-#include "FloatPoint.h"
-#include "IntRect.h"
-#include "Timer.h"
-#include <wtf/PassRefPtr.h>
-#include <wtf/RefCounted.h>
-#include <wtf/text/WTFString.h>
-
-namespace WebCore {
-
-class Frame;
-class GraphicsContext;
-class GraphicsLayer;
-class Page;
-class PageOverlayController;
-class PlatformMouseEvent;
-
-class PageOverlay final : public RefCounted<PageOverlay> {
- WTF_MAKE_NONCOPYABLE(PageOverlay);
- WTF_MAKE_FAST_ALLOCATED;
-public:
- class Client {
- protected:
- virtual ~Client() { }
-
- public:
- virtual void pageOverlayDestroyed(PageOverlay&) = 0;
- virtual void willMoveToPage(PageOverlay&, Page*) = 0;
- virtual void didMoveToPage(PageOverlay&, Page*) = 0;
- virtual void drawRect(PageOverlay&, GraphicsContext&, const IntRect& dirtyRect) = 0;
- virtual bool mouseEvent(PageOverlay&, const PlatformMouseEvent&) = 0;
- virtual void didScrollFrame(PageOverlay&, Frame&) { }
-
- virtual bool copyAccessibilityAttributeStringValueForPoint(PageOverlay&, String /* attribute */, FloatPoint, String&) { return false; }
- virtual bool copyAccessibilityAttributeBoolValueForPoint(PageOverlay&, String /* attribute */, FloatPoint, bool&) { return false; }
- virtual Vector<String> copyAccessibilityAttributeNames(PageOverlay&, bool /* parameterizedNames */) { return { }; }
- };
-
- enum class OverlayType {
- View, // Fixed to the view size; does not scale or scroll with the document, repaints on scroll.
- Document, // Scales and scrolls with the document.
- };
-
- WEBCORE_EXPORT static Ref<PageOverlay> create(Client&, OverlayType = OverlayType::View);
- WEBCORE_EXPORT virtual ~PageOverlay();
-
- WEBCORE_EXPORT PageOverlayController* controller() const;
-
- typedef uint64_t PageOverlayID;
- virtual PageOverlayID pageOverlayID() const { return m_pageOverlayID; }
-
- void setPage(Page*);
- Page* page() const { return m_page; }
- WEBCORE_EXPORT void setNeedsDisplay(const IntRect& dirtyRect);
- WEBCORE_EXPORT void setNeedsDisplay();
-
- void drawRect(GraphicsContext&, const IntRect& dirtyRect);
- bool mouseEvent(const PlatformMouseEvent&);
- void didScrollFrame(Frame&);
-
- bool copyAccessibilityAttributeStringValueForPoint(String attribute, FloatPoint parameter, String& value);
- bool copyAccessibilityAttributeBoolValueForPoint(String attribute, FloatPoint parameter, bool& value);
- Vector<String> copyAccessibilityAttributeNames(bool parameterizedNames);
-
- void startFadeInAnimation();
- void startFadeOutAnimation();
- WEBCORE_EXPORT void stopFadeOutAnimation();
-
- WEBCORE_EXPORT void clear();
-
- Client& client() const { return m_client; }
-
- enum class FadeMode { DoNotFade, Fade };
-
- OverlayType overlayType() { return m_overlayType; }
-
- WEBCORE_EXPORT IntRect bounds() const;
- WEBCORE_EXPORT IntRect frame() const;
- WEBCORE_EXPORT void setFrame(IntRect);
-
- WEBCORE_EXPORT IntSize viewToOverlayOffset() const;
-
- RGBA32 backgroundColor() const { return m_backgroundColor; }
- void setBackgroundColor(RGBA32);
-
- void setShouldIgnoreMouseEventsOutsideBounds(bool flag) { m_shouldIgnoreMouseEventsOutsideBounds = flag; }
-
- // FIXME: PageOverlay should own its layer, instead of PageOverlayController.
- WEBCORE_EXPORT GraphicsLayer& layer();
-
- bool needsSynchronousScrolling() const { return m_needsSynchronousScrolling; }
- void setNeedsSynchronousScrolling(bool needsSynchronousScrolling) { m_needsSynchronousScrolling = needsSynchronousScrolling; }
-
-private:
- explicit PageOverlay(Client&, OverlayType);
-
- void startFadeAnimation();
- void fadeAnimationTimerFired();
-
- Client& m_client;
- Page* m_page { nullptr };
-
- Timer m_fadeAnimationTimer;
- double m_fadeAnimationStartTime { 0 };
- double m_fadeAnimationDuration;
-
- enum FadeAnimationType {
- NoAnimation,
- FadeInAnimation,
- FadeOutAnimation,
- };
-
- FadeAnimationType m_fadeAnimationType { NoAnimation };
- float m_fractionFadedIn { 1 };
-
- bool m_needsSynchronousScrolling;
-
- OverlayType m_overlayType;
- IntRect m_overrideFrame;
-
- RGBA32 m_backgroundColor { Color::transparent };
- PageOverlayID m_pageOverlayID;
-
- bool m_shouldIgnoreMouseEventsOutsideBounds { true };
-};
-
-} // namespace WebKit
-
-#endif // PageOverlay_h
diff --git a/Source/WebCore/page/PageOverlayController.cpp b/Source/WebCore/page/PageOverlayController.cpp
deleted file mode 100644
index 82ba3f6a7..000000000
--- a/Source/WebCore/page/PageOverlayController.cpp
+++ /dev/null
@@ -1,365 +0,0 @@
-/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "PageOverlayController.h"
-
-#include "Chrome.h"
-#include "ChromeClient.h"
-#include "Frame.h"
-#include "FrameView.h"
-#include "GraphicsContext.h"
-#include "GraphicsLayer.h"
-#include "MainFrame.h"
-#include "Page.h"
-#include "PageOverlay.h"
-#include "ScrollingCoordinator.h"
-#include "Settings.h"
-#include "TiledBacking.h"
-
-// FIXME: Someone needs to call didChangeSettings() if we want dynamic updates of layer border/repaint counter settings.
-
-namespace WebCore {
-
-PageOverlayController::PageOverlayController(MainFrame& mainFrame)
- : m_initialized(false)
- , m_mainFrame(mainFrame)
-{
-}
-
-PageOverlayController::~PageOverlayController()
-{
-
-}
-
-void PageOverlayController::createRootLayersIfNeeded()
-{
- if (m_initialized)
- return;
-
- m_initialized = true;
-
- ASSERT(!m_documentOverlayRootLayer);
- ASSERT(!m_viewOverlayRootLayer);
-
- m_documentOverlayRootLayer = GraphicsLayer::create(m_mainFrame.page()->chrome().client().graphicsLayerFactory(), *this);
- m_viewOverlayRootLayer = GraphicsLayer::create(m_mainFrame.page()->chrome().client().graphicsLayerFactory(), *this);
-#ifndef NDEBUG
- m_documentOverlayRootLayer->setName("Page Overlay container (document-relative)");
- m_viewOverlayRootLayer->setName("Page Overlay container (view-relative)");
-#endif
-}
-
-GraphicsLayer& PageOverlayController::documentOverlayRootLayer()
-{
- createRootLayersIfNeeded();
- return *m_documentOverlayRootLayer;
-}
-
-GraphicsLayer& PageOverlayController::viewOverlayRootLayer()
-{
- createRootLayersIfNeeded();
- return *m_viewOverlayRootLayer;
-}
-
-static void updateOverlayGeometry(PageOverlay& overlay, GraphicsLayer& graphicsLayer)
-{
- IntRect overlayFrame = overlay.frame();
-
- if (overlayFrame.location() == graphicsLayer.position() && overlayFrame.size() == graphicsLayer.size())
- return;
-
- graphicsLayer.setPosition(overlayFrame.location());
- graphicsLayer.setSize(overlayFrame.size());
-}
-
-void PageOverlayController::installPageOverlay(PassRefPtr<PageOverlay> pageOverlay, PageOverlay::FadeMode fadeMode)
-{
- createRootLayersIfNeeded();
-
- RefPtr<PageOverlay> overlay = pageOverlay;
-
- if (m_pageOverlays.contains(overlay))
- return;
-
- m_pageOverlays.append(overlay);
-
- std::unique_ptr<GraphicsLayer> layer = GraphicsLayer::create(m_mainFrame.page()->chrome().client().graphicsLayerFactory(), *this);
- layer->setAnchorPoint(FloatPoint3D());
- layer->setBackgroundColor(overlay->backgroundColor());
-#ifndef NDEBUG
- layer->setName("Page Overlay content");
-#endif
-
- updateSettingsForLayer(*layer);
-
- switch (overlay->overlayType()) {
- case PageOverlay::OverlayType::View:
- m_viewOverlayRootLayer->addChild(layer.get());
- break;
- case PageOverlay::OverlayType::Document:
- m_documentOverlayRootLayer->addChild(layer.get());
- break;
- }
-
- GraphicsLayer& rawLayer = *layer;
- m_overlayGraphicsLayers.set(overlay.get(), WTFMove(layer));
-
- updateForceSynchronousScrollLayerPositionUpdates();
-
- overlay->setPage(m_mainFrame.page());
-
- if (FrameView* frameView = m_mainFrame.view())
- frameView->enterCompositingMode();
-
- updateOverlayGeometry(*overlay, rawLayer);
-
- if (fadeMode == PageOverlay::FadeMode::Fade)
- overlay->startFadeInAnimation();
-}
-
-void PageOverlayController::uninstallPageOverlay(PageOverlay* overlay, PageOverlay::FadeMode fadeMode)
-{
- if (fadeMode == PageOverlay::FadeMode::Fade) {
- overlay->startFadeOutAnimation();
- return;
- }
-
- overlay->setPage(nullptr);
-
- m_overlayGraphicsLayers.take(overlay)->removeFromParent();
-
- bool removed = m_pageOverlays.removeFirst(overlay);
- ASSERT_UNUSED(removed, removed);
-
- updateForceSynchronousScrollLayerPositionUpdates();
-}
-
-void PageOverlayController::updateForceSynchronousScrollLayerPositionUpdates()
-{
-#if ENABLE(ASYNC_SCROLLING)
- bool forceSynchronousScrollLayerPositionUpdates = false;
-
- for (auto& overlay : m_pageOverlays) {
- if (overlay->needsSynchronousScrolling())
- forceSynchronousScrollLayerPositionUpdates = true;
- }
-
- if (ScrollingCoordinator* scrollingCoordinator = m_mainFrame.page()->scrollingCoordinator())
- scrollingCoordinator->setForceSynchronousScrollLayerPositionUpdates(forceSynchronousScrollLayerPositionUpdates);
-#endif
-}
-
-void PageOverlayController::setPageOverlayNeedsDisplay(PageOverlay& overlay, const WebCore::IntRect& dirtyRect)
-{
- ASSERT(m_pageOverlays.contains(&overlay));
- GraphicsLayer& graphicsLayer = *m_overlayGraphicsLayers.get(&overlay);
-
- if (!graphicsLayer.drawsContent()) {
- graphicsLayer.setDrawsContent(true);
- updateOverlayGeometry(overlay, graphicsLayer);
- }
-
- graphicsLayer.setNeedsDisplayInRect(dirtyRect);
-}
-
-void PageOverlayController::setPageOverlayOpacity(PageOverlay& overlay, float opacity)
-{
- ASSERT(m_pageOverlays.contains(&overlay));
- m_overlayGraphicsLayers.get(&overlay)->setOpacity(opacity);
-}
-
-void PageOverlayController::clearPageOverlay(PageOverlay& overlay)
-{
- ASSERT(m_pageOverlays.contains(&overlay));
- m_overlayGraphicsLayers.get(&overlay)->setDrawsContent(false);
-}
-
-GraphicsLayer& PageOverlayController::layerForOverlay(PageOverlay& overlay) const
-{
- ASSERT(m_pageOverlays.contains(&overlay));
- return *m_overlayGraphicsLayers.get(&overlay);
-}
-
-void PageOverlayController::willAttachRootLayer()
-{
- for (auto& overlayAndLayer : m_overlayGraphicsLayers)
- updateOverlayGeometry(*overlayAndLayer.key, *overlayAndLayer.value);
-}
-
-void PageOverlayController::didChangeViewSize()
-{
- for (auto& overlayAndLayer : m_overlayGraphicsLayers) {
- if (overlayAndLayer.key->overlayType() == PageOverlay::OverlayType::View)
- updateOverlayGeometry(*overlayAndLayer.key, *overlayAndLayer.value);
- }
-}
-
-void PageOverlayController::didChangeDocumentSize()
-{
- for (auto& overlayAndLayer : m_overlayGraphicsLayers) {
- if (overlayAndLayer.key->overlayType() == PageOverlay::OverlayType::Document)
- updateOverlayGeometry(*overlayAndLayer.key, *overlayAndLayer.value);
- }
-}
-
-void PageOverlayController::didChangeSettings()
-{
- // FIXME: We should apply these settings to all overlay sublayers recursively.
- for (auto& graphicsLayer : m_overlayGraphicsLayers.values())
- updateSettingsForLayer(*graphicsLayer);
-}
-
-void PageOverlayController::didChangeDeviceScaleFactor()
-{
- createRootLayersIfNeeded();
-
- m_documentOverlayRootLayer->noteDeviceOrPageScaleFactorChangedIncludingDescendants();
- m_viewOverlayRootLayer->noteDeviceOrPageScaleFactorChangedIncludingDescendants();
-
- for (auto& graphicsLayer : m_overlayGraphicsLayers.values())
- graphicsLayer->setNeedsDisplay();
-}
-
-void PageOverlayController::didChangeExposedRect()
-{
- m_mainFrame.page()->chrome().client().scheduleCompositingLayerFlush();
-}
-
-void PageOverlayController::didScrollFrame(Frame& frame)
-{
- for (auto& overlayAndLayer : m_overlayGraphicsLayers) {
- if (overlayAndLayer.key->overlayType() == PageOverlay::OverlayType::View || !frame.isMainFrame())
- overlayAndLayer.value->setNeedsDisplay();
- overlayAndLayer.key->didScrollFrame(frame);
- }
-}
-
-void PageOverlayController::updateSettingsForLayer(GraphicsLayer& layer)
-{
- Settings& settings = m_mainFrame.settings();
- layer.setAcceleratesDrawing(settings.acceleratedDrawingEnabled());
- layer.setShowDebugBorder(settings.showDebugBorders());
- layer.setShowRepaintCounter(settings.showRepaintCounter());
-}
-
-bool PageOverlayController::handleMouseEvent(const PlatformMouseEvent& mouseEvent)
-{
- if (m_pageOverlays.isEmpty())
- return false;
-
- for (auto it = m_pageOverlays.rbegin(), end = m_pageOverlays.rend(); it != end; ++it) {
- if ((*it)->mouseEvent(mouseEvent))
- return true;
- }
-
- return false;
-}
-
-bool PageOverlayController::copyAccessibilityAttributeStringValueForPoint(String attribute, FloatPoint parameter, String& value)
-{
- if (m_pageOverlays.isEmpty())
- return false;
-
- for (auto it = m_pageOverlays.rbegin(), end = m_pageOverlays.rend(); it != end; ++it) {
- if ((*it)->copyAccessibilityAttributeStringValueForPoint(attribute, parameter, value))
- return true;
- }
-
- return false;
-}
-
-bool PageOverlayController::copyAccessibilityAttributeBoolValueForPoint(String attribute, FloatPoint parameter, bool& value)
-{
- if (m_pageOverlays.isEmpty())
- return false;
-
- for (auto it = m_pageOverlays.rbegin(), end = m_pageOverlays.rend(); it != end; ++it) {
- if ((*it)->copyAccessibilityAttributeBoolValueForPoint(attribute, parameter, value))
- return true;
- }
-
- return false;
-}
-
-Vector<String> PageOverlayController::copyAccessibilityAttributesNames(bool parameterizedNames)
-{
- if (m_pageOverlays.isEmpty())
- return { };
-
- for (auto it = m_pageOverlays.rbegin(), end = m_pageOverlays.rend(); it != end; ++it) {
- Vector<String> names = (*it)->copyAccessibilityAttributeNames(parameterizedNames);
- if (!names.isEmpty())
- return names;
- }
-
- return { };
-}
-
-void PageOverlayController::paintContents(const WebCore::GraphicsLayer* graphicsLayer, WebCore::GraphicsContext& graphicsContext, WebCore::GraphicsLayerPaintingPhase, const WebCore::FloatRect& clipRect)
-{
- for (auto& overlayAndGraphicsLayer : m_overlayGraphicsLayers) {
- if (overlayAndGraphicsLayer.value.get() != graphicsLayer)
- continue;
-
- GraphicsContextStateSaver stateSaver(graphicsContext);
- graphicsContext.clip(clipRect);
- overlayAndGraphicsLayer.key->drawRect(graphicsContext, enclosingIntRect(clipRect));
-
- return;
- }
-}
-
-float PageOverlayController::deviceScaleFactor() const
-{
- if (Page* page = m_mainFrame.page())
- return page->deviceScaleFactor();
- return 1;
-}
-
-void PageOverlayController::notifyFlushRequired(const WebCore::GraphicsLayer*)
-{
- if (Page* page = m_mainFrame.page())
- page->chrome().client().scheduleCompositingLayerFlush();
-}
-
-void PageOverlayController::didChangeOverlayFrame(PageOverlay& overlay)
-{
- ASSERT(m_pageOverlays.contains(&overlay));
- updateOverlayGeometry(overlay, *m_overlayGraphicsLayers.get(&overlay));
-}
-
-void PageOverlayController::didChangeOverlayBackgroundColor(PageOverlay& overlay)
-{
- ASSERT(m_pageOverlays.contains(&overlay));
- m_overlayGraphicsLayers.get(&overlay)->setBackgroundColor(overlay.backgroundColor());
-}
-
-bool PageOverlayController::shouldSkipLayerInDump(const GraphicsLayer*, LayerTreeAsTextBehavior behavior) const
-{
- return !(behavior & LayerTreeAsTextIncludePageOverlayLayers);
-}
-
-} // namespace WebKit
diff --git a/Source/WebCore/page/PageOverlayController.h b/Source/WebCore/page/PageOverlayController.h
deleted file mode 100644
index 18ddcfc0b..000000000
--- a/Source/WebCore/page/PageOverlayController.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef PageOverlayController_h
-#define PageOverlayController_h
-
-#include "GraphicsLayerClient.h"
-#include "PageOverlay.h"
-#include <wtf/HashMap.h>
-#include <wtf/RefPtr.h>
-#include <wtf/Vector.h>
-
-namespace WebCore {
-
-class Frame;
-class MainFrame;
-class Page;
-class PlatformMouseEvent;
-
-class PageOverlayController final : public GraphicsLayerClient {
- WTF_MAKE_NONCOPYABLE(PageOverlayController);
- WTF_MAKE_FAST_ALLOCATED;
-public:
- PageOverlayController(MainFrame&);
- virtual ~PageOverlayController();
-
- WEBCORE_EXPORT GraphicsLayer& documentOverlayRootLayer();
- WEBCORE_EXPORT GraphicsLayer& viewOverlayRootLayer();
-
- const Vector<RefPtr<PageOverlay>>& pageOverlays() const { return m_pageOverlays; }
-
- WEBCORE_EXPORT void installPageOverlay(PassRefPtr<PageOverlay>, PageOverlay::FadeMode);
- WEBCORE_EXPORT void uninstallPageOverlay(PageOverlay*, PageOverlay::FadeMode);
-
- void setPageOverlayNeedsDisplay(PageOverlay&, const IntRect&);
- void setPageOverlayOpacity(PageOverlay&, float);
- void clearPageOverlay(PageOverlay&);
- GraphicsLayer& layerForOverlay(PageOverlay&) const;
-
- void willAttachRootLayer();
-
- void didChangeViewSize();
- void didChangeDocumentSize();
- void didChangeSettings();
- void didChangeDeviceScaleFactor();
- void didChangeExposedRect();
- void didScrollFrame(Frame&);
-
- void didChangeOverlayFrame(PageOverlay&);
- void didChangeOverlayBackgroundColor(PageOverlay&);
-
- int overlayCount() const { return m_overlayGraphicsLayers.size(); }
-
- bool handleMouseEvent(const PlatformMouseEvent&);
-
- WEBCORE_EXPORT bool copyAccessibilityAttributeStringValueForPoint(String attribute, FloatPoint, String& value);
- WEBCORE_EXPORT bool copyAccessibilityAttributeBoolValueForPoint(String attribute, FloatPoint, bool& value);
- WEBCORE_EXPORT Vector<String> copyAccessibilityAttributesNames(bool parameterizedNames);
-
-private:
- void createRootLayersIfNeeded();
-
- void updateSettingsForLayer(GraphicsLayer&);
- void updateForceSynchronousScrollLayerPositionUpdates();
-
- // GraphicsLayerClient
- virtual void notifyFlushRequired(const GraphicsLayer*) override;
- virtual void paintContents(const GraphicsLayer*, GraphicsContext&, GraphicsLayerPaintingPhase, const FloatRect& clipRect) override;
- virtual float deviceScaleFactor() const override;
- virtual bool shouldSkipLayerInDump(const GraphicsLayer*, LayerTreeAsTextBehavior) const override;
-
- std::unique_ptr<GraphicsLayer> m_documentOverlayRootLayer;
- std::unique_ptr<GraphicsLayer> m_viewOverlayRootLayer;
- bool m_initialized;
-
- HashMap<PageOverlay*, std::unique_ptr<GraphicsLayer>> m_overlayGraphicsLayers;
- Vector<RefPtr<PageOverlay>> m_pageOverlays;
- MainFrame& m_mainFrame;
-};
-
-} // namespace WebKit
-
-#endif // PageOverlayController_h
diff --git a/Source/WebCore/page/PageSerializer.cpp b/Source/WebCore/page/PageSerializer.cpp
index 9766b2655..55eeaa942 100644
--- a/Source/WebCore/page/PageSerializer.cpp
+++ b/Source/WebCore/page/PageSerializer.cpp
@@ -31,7 +31,6 @@
#include "config.h"
#include "PageSerializer.h"
-#include "CSSFontFaceRule.h"
#include "CSSImageValue.h"
#include "CSSImportRule.h"
#include "CSSStyleRule.h"
@@ -67,10 +66,10 @@ namespace WebCore {
static bool isCharsetSpecifyingNode(const Node& node)
{
- if (!is<HTMLElement>(node))
+ if (!node.isHTMLElement())
return false;
- const HTMLElement& element = downcast<HTMLElement>(node);
+ const HTMLElement& element = toHTMLElement(node);
if (!element.hasTagName(HTMLNames::metaTag))
return false;
HTMLMetaCharsetParser::AttributeList attributes;
@@ -92,7 +91,7 @@ static bool shouldIgnoreElement(const Element& element)
static const QualifiedName& frameOwnerURLAttributeName(const HTMLFrameOwnerElement& frameOwner)
{
// FIXME: We should support all frame owners including applets.
- return is<HTMLObjectElement>(frameOwner) ? HTMLNames::dataAttr : HTMLNames::srcAttr;
+ return isHTMLObjectElement(frameOwner) ? HTMLNames::dataAttr : HTMLNames::srcAttr;
}
class SerializerMarkupAccumulator final : public WebCore::MarkupAccumulator {
@@ -107,7 +106,7 @@ private:
virtual void appendText(StringBuilder&, const Text&) override;
virtual void appendElement(StringBuilder&, const Element&, Namespaces*) override;
virtual void appendCustomAttributes(StringBuilder&, const Element&, Namespaces*) override;
- virtual void appendEndTag(const Element&) override;
+ virtual void appendEndTag(const Node&) override;
};
SerializerMarkupAccumulator::SerializerMarkupAccumulator(PageSerializer& serializer, Document& document, Vector<Node*>* nodes)
@@ -116,7 +115,7 @@ SerializerMarkupAccumulator::SerializerMarkupAccumulator(PageSerializer& seriali
, m_document(document)
{
// MarkupAccumulator does not serialize the <?xml ... line, so we add it explicitely to ensure the right encoding is specified.
- if (m_document.isXMLDocument() || m_document.xmlStandalone())
+ if (m_document.isXHTMLDocument() || m_document.xmlStandalone() || m_document.isSVGDocument())
appendString("<?xml version=\"" + m_document.xmlVersion() + "\" encoding=\"" + m_document.charset() + "\"?>");
}
@@ -137,9 +136,9 @@ void SerializerMarkupAccumulator::appendElement(StringBuilder& out, const Elemen
MarkupAccumulator::appendElement(out, element, namespaces);
if (element.hasTagName(HTMLNames::headTag)) {
- out.appendLiteral("<meta charset=\"");
+ out.append("<meta charset=\"");
out.append(m_document.charset());
- out.appendLiteral("\">");
+ out.append("\">");
}
// FIXME: For object (plugins) tags and video tag we could replace them by an image of their current contents.
@@ -147,10 +146,10 @@ void SerializerMarkupAccumulator::appendElement(StringBuilder& out, const Elemen
void SerializerMarkupAccumulator::appendCustomAttributes(StringBuilder& out, const Element& element, Namespaces* namespaces)
{
- if (!is<HTMLFrameOwnerElement>(element))
+ if (!element.isFrameOwnerElement())
return;
- const HTMLFrameOwnerElement& frameOwner = downcast<HTMLFrameOwnerElement>(element);
+ const HTMLFrameOwnerElement& frameOwner = toHTMLFrameOwnerElement(element);
Frame* frame = frameOwner.contentFrame();
if (!frame)
return;
@@ -164,10 +163,10 @@ void SerializerMarkupAccumulator::appendCustomAttributes(StringBuilder& out, con
appendAttribute(out, element, Attribute(frameOwnerURLAttributeName(frameOwner), url.string()), namespaces);
}
-void SerializerMarkupAccumulator::appendEndTag(const Element& element)
+void SerializerMarkupAccumulator::appendEndTag(const Node& node)
{
- if (!shouldIgnoreElement(element))
- MarkupAccumulator::appendEndTag(element);
+ if (node.isElementNode() && !shouldIgnoreElement(toElement(node)))
+ MarkupAccumulator::appendEndTag(node);
}
PageSerializer::Resource::Resource()
@@ -216,34 +215,35 @@ void PageSerializer::serializeFrame(Frame* frame)
// FIXME: iframes used as images trigger this. We should deal with them correctly.
return;
}
- String text = accumulator.serializeNodes(*document->documentElement(), IncludeNode);
- CString frameHTML = textEncoding.encode(text, EntitiesForUnencodables);
+ String text = accumulator.serializeNodes(*document->documentElement(), 0, IncludeNode);
+ CString frameHTML = textEncoding.encode(text.deprecatedCharacters(), text.length(), EntitiesForUnencodables);
m_resources->append(Resource(url, document->suggestedMIMEType(), SharedBuffer::create(frameHTML.data(), frameHTML.length())));
m_resourceURLs.add(url);
- for (auto& node : nodes) {
- if (!is<Element>(*node))
+ for (Vector<Node*>::iterator iter = nodes.begin(); iter != nodes.end(); ++iter) {
+ Node* node = *iter;
+ if (!node->isElementNode())
continue;
- Element& element = downcast<Element>(*node);
+ Element* element = toElement(node);
// We have to process in-line style as it might contain some resources (typically background images).
- if (is<StyledElement>(element))
- retrieveResourcesForProperties(downcast<StyledElement>(element).inlineStyle(), document);
-
- if (is<HTMLImageElement>(element)) {
- HTMLImageElement& imageElement = downcast<HTMLImageElement>(element);
- URL url = document->completeURL(imageElement.fastGetAttribute(HTMLNames::srcAttr));
- CachedImage* cachedImage = imageElement.cachedImage();
- addImageToResources(cachedImage, imageElement.renderer(), url);
- } else if (is<HTMLLinkElement>(element)) {
- HTMLLinkElement& linkElement = downcast<HTMLLinkElement>(element);
- if (CSSStyleSheet* sheet = linkElement.sheet()) {
- URL url = document->completeURL(linkElement.getAttribute(HTMLNames::hrefAttr));
+ if (element->isStyledElement())
+ retrieveResourcesForProperties(toStyledElement(element)->inlineStyle(), document);
+
+ if (isHTMLImageElement(element)) {
+ HTMLImageElement* imageElement = toHTMLImageElement(element);
+ URL url = document->completeURL(imageElement->getAttribute(HTMLNames::srcAttr));
+ CachedImage* cachedImage = imageElement->cachedImage();
+ addImageToResources(cachedImage, imageElement->renderer(), url);
+ } else if (element->hasTagName(HTMLNames::linkTag)) {
+ HTMLLinkElement* linkElement = toHTMLLinkElement(element);
+ if (CSSStyleSheet* sheet = linkElement->sheet()) {
+ URL url = document->completeURL(linkElement->getAttribute(HTMLNames::hrefAttr));
serializeCSSStyleSheet(sheet, url);
ASSERT(m_resourceURLs.contains(url));
}
- } else if (is<HTMLStyleElement>(element)) {
- if (CSSStyleSheet* sheet = downcast<HTMLStyleElement>(element).sheet())
+ } else if (isHTMLStyleElement(element)) {
+ if (CSSStyleSheet* sheet = toHTMLStyleElement(element)->sheet())
serializeCSSStyleSheet(sheet, URL());
}
}
@@ -261,21 +261,21 @@ void PageSerializer::serializeCSSStyleSheet(CSSStyleSheet* styleSheet, const URL
if (!itemText.isEmpty()) {
cssText.append(itemText);
if (i < styleSheet->length() - 1)
- cssText.appendLiteral("\n\n");
+ cssText.append("\n\n");
}
Document* document = styleSheet->ownerDocument();
// Some rules have resources associated with them that we need to retrieve.
- if (is<CSSImportRule>(*rule)) {
- CSSImportRule& importRule = downcast<CSSImportRule>(*rule);
- URL importURL = document->completeURL(importRule.href());
+ if (rule->type() == CSSRule::IMPORT_RULE) {
+ CSSImportRule* importRule = static_cast<CSSImportRule*>(rule);
+ URL importURL = document->completeURL(importRule->href());
if (m_resourceURLs.contains(importURL))
continue;
- serializeCSSStyleSheet(importRule.styleSheet(), importURL);
- } else if (is<CSSFontFaceRule>(*rule)) {
+ serializeCSSStyleSheet(importRule->styleSheet(), importURL);
+ } else if (rule->type() == CSSRule::FONT_FACE_RULE) {
// FIXME: Add support for font face rule. It is not clear to me at this point if the actual otf/eot file can
// be retrieved from the CSSFontFaceRule object.
- } else if (is<CSSStyleRule>(*rule))
- retrieveResourcesForRule(downcast<CSSStyleRule>(*rule).styleRule(), document);
+ } else if (rule->type() == CSSRule::STYLE_RULE)
+ retrieveResourcesForRule(static_cast<CSSStyleRule*>(rule)->styleRule(), document);
}
if (url.isValid() && !m_resourceURLs.contains(url)) {
@@ -283,7 +283,7 @@ void PageSerializer::serializeCSSStyleSheet(CSSStyleSheet* styleSheet, const URL
TextEncoding textEncoding(styleSheet->contents().charset());
ASSERT(textEncoding.isValid());
String textString = cssText.toString();
- CString text = textEncoding.encode(textString, EntitiesForUnencodables);
+ CString text = textEncoding.encode(textString.deprecatedCharacters(), textString.length(), EntitiesForUnencodables);
m_resources->append(Resource(url, String("text/css"), SharedBuffer::create(text.data(), text.length())));
m_resourceURLs.add(url);
}
@@ -311,9 +311,9 @@ void PageSerializer::addImageToResources(CachedImage* image, RenderElement* imag
m_resourceURLs.add(url);
}
-void PageSerializer::retrieveResourcesForRule(StyleRule& rule, Document* document)
+void PageSerializer::retrieveResourcesForRule(StyleRule* rule, Document* document)
{
- retrieveResourcesForProperties(&rule.properties(), document);
+ retrieveResourcesForProperties(&rule->properties(), document);
}
void PageSerializer::retrieveResourcesForProperties(const StyleProperties* styleDeclaration, Document* document)
@@ -327,18 +327,18 @@ void PageSerializer::retrieveResourcesForProperties(const StyleProperties* style
unsigned propertyCount = styleDeclaration->propertyCount();
for (unsigned i = 0; i < propertyCount; ++i) {
RefPtr<CSSValue> cssValue = styleDeclaration->propertyAt(i).value();
- if (!is<CSSImageValue>(*cssValue))
+ if (!cssValue->isImageValue())
continue;
- StyleImage* styleImage = downcast<CSSImageValue>(*cssValue).cachedOrPendingImage();
+ StyleImage* styleImage = toCSSImageValue(cssValue.get())->cachedOrPendingImage();
// Non cached-images are just place-holders and do not contain data.
- if (!is<StyleCachedImage>(styleImage))
+ if (!styleImage || !styleImage->isCachedImage())
continue;
- CachedImage* image = downcast<StyleCachedImage>(*styleImage).cachedImage();
+ CachedImage* image = static_cast<StyleCachedImage*>(styleImage)->cachedImage();
URL url = document->completeURL(image->url());
- addImageToResources(image, nullptr, url);
+ addImageToResources(image, 0, url);
}
}
diff --git a/Source/WebCore/page/PageSerializer.h b/Source/WebCore/page/PageSerializer.h
index a5944472c..f25488f7f 100644
--- a/Source/WebCore/page/PageSerializer.h
+++ b/Source/WebCore/page/PageSerializer.h
@@ -79,7 +79,7 @@ private:
void addImageToResources(CachedImage*, RenderElement*, const URL&);
void retrieveResourcesForProperties(const StyleProperties*, Document*);
- void retrieveResourcesForRule(StyleRule&, Document*);
+ void retrieveResourcesForRule(StyleRule*, Document*);
Vector<Resource>* m_resources;
ListHashSet<URL> m_resourceURLs;
diff --git a/Source/WebCore/page/PageThrottler.cpp b/Source/WebCore/page/PageThrottler.cpp
index 824cfd129..28c63f1e1 100644
--- a/Source/WebCore/page/PageThrottler.cpp
+++ b/Source/WebCore/page/PageThrottler.cpp
@@ -26,42 +26,153 @@
#include "config.h"
#include "PageThrottler.h"
+#include "Chrome.h"
+#include "ChromeClient.h"
+#include "MainFrame.h"
#include "Page.h"
+#include "PageActivityAssertionToken.h"
+#include <wtf/StdLibExtras.h>
namespace WebCore {
+static const double kThrottleHysteresisSeconds = 2.0;
+
PageThrottler::PageThrottler(Page& page)
: m_page(page)
- , m_userInputHysteresis([this](HysteresisState state) { setActivityFlag(PageActivityState::UserInputActivity, state == HysteresisState::Started); })
- , m_audiblePluginHysteresis([this](HysteresisState state) { setActivityFlag(PageActivityState::AudiblePlugin, state == HysteresisState::Started); })
- , m_mediaActivityCounter([this](bool value) { setActivityFlag(PageActivityState::MediaActivity, value); })
- , m_pageLoadActivityCounter([this](bool value) { setActivityFlag(PageActivityState::PageLoadActivity, value); })
+ , m_throttleState(PageNotThrottledState)
+ , m_throttleHysteresisTimer(this, &PageThrottler::throttleHysteresisTimerFired)
+ , m_visuallyNonIdle("Page is not visually idle.")
+{
+ m_page.chrome().client().incrementActivePageCount();
+}
+
+PageThrottler::~PageThrottler()
{
+ setIsVisuallyIdle(false);
+
+ for (auto it = m_activityTokens.begin(), end = m_activityTokens.end(); it != end; ++it)
+ (*it)->invalidate();
+
+ if (m_throttleState != PageThrottledState)
+ m_page.chrome().client().decrementActivePageCount();
}
-PageActivityAssertionToken PageThrottler::mediaActivityToken()
+std::unique_ptr<PageActivityAssertionToken> PageThrottler::createActivityToken()
{
- return m_mediaActivityCounter.token<PageActivityAssertionTokenType>();
+ return std::make_unique<PageActivityAssertionToken>(*this);
}
-PageActivityAssertionToken PageThrottler::pageLoadActivityToken()
+void PageThrottler::throttlePage()
{
- return m_pageLoadActivityCounter.token<PageActivityAssertionTokenType>();
+ m_throttleState = PageThrottledState;
+
+ m_page.chrome().client().decrementActivePageCount();
+
+ for (Frame* frame = &m_page.mainFrame(); frame; frame = frame->tree().traverseNext()) {
+ if (frame->document())
+ frame->document()->scriptedAnimationControllerSetThrottled(true);
+ }
+
+ m_page.throttleTimers();
}
-void PageThrottler::setActivityFlag(PageActivityState::Flags flag, bool value)
+void PageThrottler::unthrottlePage()
{
- PageActivityState::Flags activityState = m_activityState;
- if (value)
- activityState |= flag;
- else
- activityState &= ~flag;
+ PageThrottleState oldState = m_throttleState;
+ m_throttleState = PageNotThrottledState;
+
+ if (oldState == PageNotThrottledState)
+ return;
+
+ if (oldState == PageThrottledState)
+ m_page.chrome().client().incrementActivePageCount();
+
+ for (Frame* frame = &m_page.mainFrame(); frame; frame = frame->tree().traverseNext()) {
+ if (frame->document())
+ frame->document()->scriptedAnimationControllerSetThrottled(false);
+ }
+
+ m_page.unthrottleTimers();
+}
+
+void PageThrottler::setIsVisuallyIdle(bool isVisuallyIdle)
+{
+ if (isVisuallyIdle) {
+ m_throttleState = PageWaitingToThrottleState;
+ startThrottleHysteresisTimer();
+ if (m_visuallyNonIdle.isActive())
+ m_visuallyNonIdle.endActivity();
+ } else {
+ unthrottlePage();
+ stopThrottleHysteresisTimer();
+ if (!m_visuallyNonIdle.isActive())
+ m_visuallyNonIdle.beginActivity();
+ }
+}
+
+void PageThrottler::stopThrottleHysteresisTimer()
+{
+ m_throttleHysteresisTimer.stop();
+}
+
+void PageThrottler::reportInterestingEvent()
+{
+ if (m_throttleState == PageNotThrottledState)
+ return;
+ if (m_throttleState == PageThrottledState)
+ unthrottlePage();
+ m_throttleState = PageWaitingToThrottleState;
+ startThrottleHysteresisTimer();
+}
+
+void PageThrottler::startThrottleHysteresisTimer()
+{
+ if (m_throttleHysteresisTimer.isActive())
+ m_throttleHysteresisTimer.stop();
+ if (!m_activityTokens.size())
+ m_throttleHysteresisTimer.startOneShot(kThrottleHysteresisSeconds);
+}
+
+void PageThrottler::throttleHysteresisTimerFired(Timer<PageThrottler>&)
+{
+ ASSERT(!m_activityTokens.size());
+ throttlePage();
+}
+
+void PageThrottler::addActivityToken(PageActivityAssertionToken& token)
+{
+ ASSERT(!m_activityTokens.contains(&token));
+
+ m_activityTokens.add(&token);
+
+ // If we've already got events that block throttling we can return early
+ if (m_activityTokens.size() > 1)
+ return;
+
+ if (m_throttleState == PageNotThrottledState)
+ return;
+
+ if (m_throttleState == PageThrottledState)
+ unthrottlePage();
+
+ m_throttleState = PageWaitingToThrottleState;
+ stopThrottleHysteresisTimer();
+}
+
+void PageThrottler::removeActivityToken(PageActivityAssertionToken& token)
+{
+ ASSERT(m_activityTokens.contains(&token));
+
+ m_activityTokens.remove(&token);
+
+ if (m_activityTokens.size())
+ return;
- if (m_activityState == activityState)
+ if (m_throttleState == PageNotThrottledState)
return;
- m_activityState = activityState;
- m_page.setPageActivityState(m_activityState);
+ ASSERT(m_throttleState == PageWaitingToThrottleState);
+ startThrottleHysteresisTimer();
}
}
diff --git a/Source/WebCore/page/PageThrottler.h b/Source/WebCore/page/PageThrottler.h
index ffecbf0ac..dc57f1212 100644
--- a/Source/WebCore/page/PageThrottler.h
+++ b/Source/WebCore/page/PageThrottler.h
@@ -29,50 +29,52 @@
#include "Timer.h"
#include "UserActivity.h"
-#include "ViewState.h"
-#include <wtf/RefCounter.h>
+#include <wtf/HashSet.h>
+#include <wtf/OwnPtr.h>
+#include <wtf/PassOwnPtr.h>
namespace WebCore {
class Page;
-
-enum PageActivityAssertionTokenType { };
-typedef RefCounter::Token<PageActivityAssertionTokenType> PageActivityAssertionToken;
-
-struct PageActivityState {
- enum {
- UserInputActivity = 1 << 0,
- AudiblePlugin = 1 << 1,
- MediaActivity = 1 << 2,
- PageLoadActivity = 1 << 3,
- };
-
- typedef unsigned Flags;
-
- static const Flags NoFlags = 0;
- static const Flags AllFlags = UserInputActivity | AudiblePlugin | MediaActivity | PageLoadActivity;
-};
+class PageActivityAssertionToken;
class PageThrottler {
- WTF_MAKE_FAST_ALLOCATED;
public:
PageThrottler(Page&);
+ ~PageThrottler();
+
+ std::unique_ptr<PageActivityAssertionToken> createActivityToken();
- void didReceiveUserInput() { m_userInputHysteresis.impulse(); }
- PageActivityState::Flags activityState() { return m_activityState; }
- void pluginDidEvaluateWhileAudioIsPlaying() { m_audiblePluginHysteresis.impulse(); }
- PageActivityAssertionToken mediaActivityToken();
- PageActivityAssertionToken pageLoadActivityToken();
+ bool shouldThrottleAnimations() const { return m_throttleState != PageNotThrottledState; }
+ bool shouldThrottleTimers() const { return m_throttleState != PageNotThrottledState; }
+
+ void setIsVisuallyIdle(bool);
+
+ void reportInterestingEvent();
private:
- void setActivityFlag(PageActivityState::Flags, bool);
+ enum PageThrottleState {
+ PageNotThrottledState,
+ PageWaitingToThrottleState,
+ PageThrottledState
+ };
+
+ friend class PageActivityAssertionToken;
+ void addActivityToken(PageActivityAssertionToken&);
+ void removeActivityToken(PageActivityAssertionToken&);
+
+ void startThrottleHysteresisTimer();
+ void stopThrottleHysteresisTimer();
+ void throttleHysteresisTimerFired(Timer<PageThrottler>&);
+
+ void throttlePage();
+ void unthrottlePage();
Page& m_page;
- PageActivityState::Flags m_activityState { PageActivityState::NoFlags };
- HysteresisActivity m_userInputHysteresis;
- HysteresisActivity m_audiblePluginHysteresis;
- RefCounter m_mediaActivityCounter;
- RefCounter m_pageLoadActivityCounter;
+ PageThrottleState m_throttleState;
+ Timer<PageThrottler> m_throttleHysteresisTimer;
+ HashSet<PageActivityAssertionToken*> m_activityTokens;
+ UserActivity m_visuallyNonIdle;
};
}
diff --git a/Source/WebCore/page/PageVisibilityState.cpp b/Source/WebCore/page/PageVisibilityState.cpp
index 7450c068c..b06b0b85f 100644
--- a/Source/WebCore/page/PageVisibilityState.cpp
+++ b/Source/WebCore/page/PageVisibilityState.cpp
@@ -31,15 +31,15 @@
#include "config.h"
#include "PageVisibilityState.h"
-#include <wtf/NeverDestroyed.h>
+#if ENABLE(PAGE_VISIBILITY_API)
namespace WebCore {
String pageVisibilityStateString(PageVisibilityState state)
{
- static NeverDestroyed<const String> visible(ASCIILiteral("visible"));
- static NeverDestroyed<const String> hidden(ASCIILiteral("hidden"));
- static NeverDestroyed<const String> prerender(ASCIILiteral("prerender"));
+ DEFINE_STATIC_LOCAL(const String, visible, (ASCIILiteral("visible")));
+ DEFINE_STATIC_LOCAL(const String, hidden, (ASCIILiteral("hidden")));
+ DEFINE_STATIC_LOCAL(const String, prerender, (ASCIILiteral("prerender")));
switch (state) {
case PageVisibilityStateVisible:
@@ -55,3 +55,5 @@ String pageVisibilityStateString(PageVisibilityState state)
}
} // namespace WebCore
+
+#endif // if ENABLE(PAGE_VISIBILITY_API)
diff --git a/Source/WebCore/page/PageVisibilityState.h b/Source/WebCore/page/PageVisibilityState.h
index 3ff309eca..3fab2e42a 100644
--- a/Source/WebCore/page/PageVisibilityState.h
+++ b/Source/WebCore/page/PageVisibilityState.h
@@ -43,7 +43,9 @@ enum PageVisibilityState {
PageVisibilityStatePrerender
};
+#if ENABLE(PAGE_VISIBILITY_API)
String pageVisibilityStateString(PageVisibilityState);
+#endif
} // namespace WebCore
diff --git a/Source/WebCore/page/Performance.cpp b/Source/WebCore/page/Performance.cpp
index ed39a1d15..b4372f618 100644
--- a/Source/WebCore/page/Performance.cpp
+++ b/Source/WebCore/page/Performance.cpp
@@ -30,13 +30,10 @@
*/
#include "config.h"
-
-#if ENABLE(WEB_TIMING)
#include "Performance.h"
#include "Document.h"
#include "DocumentLoader.h"
-#include "Frame.h"
#include "PerformanceEntry.h"
#include "PerformanceNavigation.h"
#include "PerformanceResourceTiming.h"
@@ -45,23 +42,25 @@
#include "ResourceResponse.h"
#include <wtf/CurrentTime.h>
+#if ENABLE(WEB_TIMING)
+
+#include "Frame.h"
+
namespace WebCore {
#if ENABLE(RESOURCE_TIMING)
static const size_t defaultResourceTimingBufferSize = 150;
#endif
-Performance::Performance(Frame& frame)
- : DOMWindowProperty(&frame)
+Performance::Performance(Frame* frame)
+ : DOMWindowProperty(frame)
#if ENABLE(RESOURCE_TIMING)
, m_resourceTimingBufferSize(defaultResourceTimingBufferSize)
#endif // ENABLE(RESOURCE_TIMING)
- , m_referenceTime(frame.document()->loader() ? frame.document()->loader()->timing().referenceMonotonicTime() : monotonicallyIncreasingTime())
#if ENABLE(USER_TIMING)
- , m_userTiming(nullptr)
+ , m_userTiming(0)
#endif // ENABLE(USER_TIMING)
{
- ASSERT(m_referenceTime);
}
Performance::~Performance()
@@ -71,7 +70,7 @@ Performance::~Performance()
ScriptExecutionContext* Performance::scriptExecutionContext() const
{
if (!frame())
- return nullptr;
+ return 0;
return frame()->document();
}
@@ -116,20 +115,19 @@ PassRefPtr<PerformanceEntryList> Performance::webkitGetEntriesByType(const Strin
RefPtr<PerformanceEntryList> entries = PerformanceEntryList::create();
#if ENABLE(RESOURCE_TIMING)
- if (equalLettersIgnoringASCIICase(entryType, "resource")) {
- for (auto& resource : m_resourceTimingBuffer)
- entries->append(resource);
- }
-#endif
+ if (equalIgnoringCase(entryType, "resource"))
+ for (Vector<RefPtr<PerformanceEntry>>::const_iterator resource = m_resourceTimingBuffer.begin(); resource != m_resourceTimingBuffer.end(); ++resource)
+ entries->append(*resource);
+#endif // ENABLE(RESOURCE_TIMING)
#if ENABLE(USER_TIMING)
if (m_userTiming) {
- if (equalLettersIgnoringASCIICase(entryType, "mark"))
+ if (equalIgnoringCase(entryType, "mark"))
entries->appendAll(m_userTiming->getMarks());
- else if (equalLettersIgnoringASCIICase(entryType, "measure"))
+ else if (equalIgnoringCase(entryType, "measure"))
entries->appendAll(m_userTiming->getMeasures());
}
-#endif
+#endif // ENABLE(USER_TIMING)
entries->sort();
return entries;
@@ -140,22 +138,20 @@ PassRefPtr<PerformanceEntryList> Performance::webkitGetEntriesByName(const Strin
RefPtr<PerformanceEntryList> entries = PerformanceEntryList::create();
#if ENABLE(RESOURCE_TIMING)
- if (entryType.isNull() || equalLettersIgnoringASCIICase(entryType, "resource")) {
- for (auto& resource : m_resourceTimingBuffer) {
- if (resource->name() == name)
- entries->append(resource);
- }
- }
-#endif
+ if (entryType.isNull() || equalIgnoringCase(entryType, "resource"))
+ for (Vector<RefPtr<PerformanceEntry>>::const_iterator resource = m_resourceTimingBuffer.begin(); resource != m_resourceTimingBuffer.end(); ++resource)
+ if ((*resource)->name() == name)
+ entries->append(*resource);
+#endif // ENABLE(RESOURCE_TIMING)
#if ENABLE(USER_TIMING)
if (m_userTiming) {
- if (entryType.isNull() || equalLettersIgnoringASCIICase(entryType, "mark"))
+ if (entryType.isNull() || equalIgnoringCase(entryType, "mark"))
entries->appendAll(m_userTiming->getMarks(name));
- if (entryType.isNull() || equalLettersIgnoringASCIICase(entryType, "measure"))
+ if (entryType.isNull() || equalIgnoringCase(entryType, "measure"))
entries->appendAll(m_userTiming->getMeasures(name));
}
-#endif
+#endif // ENABLE(USER_TIMING)
entries->sort();
return entries;
@@ -232,9 +228,7 @@ void Performance::webkitClearMeasures(const String& measureName)
double Performance::now() const
{
- double nowSeconds = monotonicallyIncreasingTime() - m_referenceTime;
- const double resolutionSeconds = 0.000005;
- return 1000.0 * floor(nowSeconds / resolutionSeconds) * resolutionSeconds;
+ return 1000.0 * m_frame->document()->loader()->timing()->monotonicTimeToZeroBasedDocumentTime(monotonicallyIncreasingTime());
}
} // namespace WebCore
diff --git a/Source/WebCore/page/Performance.h b/Source/WebCore/page/Performance.h
index 5bf23f1c3..19c995bae 100644
--- a/Source/WebCore/page/Performance.h
+++ b/Source/WebCore/page/Performance.h
@@ -52,9 +52,9 @@ class ResourceRequest;
class ResourceResponse;
class UserTiming;
-class Performance final : public RefCounted<Performance>, public DOMWindowProperty, public EventTargetWithInlineData {
+class Performance final : public ScriptWrappable, public RefCounted<Performance>, public DOMWindowProperty, public EventTargetWithInlineData {
public:
- static Ref<Performance> create(Frame& frame) { return adoptRef(*new Performance(frame)); }
+ static PassRefPtr<Performance> create(Frame* frame) { return adoptRef(new Performance(frame)); }
~Performance();
virtual EventTargetInterface eventTargetInterface() const override { return PerformanceEventTargetInterfaceType; }
@@ -74,6 +74,8 @@ public:
void webkitClearResourceTimings();
void webkitSetResourceTimingBufferSize(unsigned int);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitresourcetimingbufferfull);
+
void addResourceTiming(const String& initiatorName, Document*, const ResourceRequest&, const ResourceResponse&, double initiationTime, double finishTime);
#endif
@@ -89,7 +91,7 @@ public:
#endif // ENABLE(USER_TIMING)
private:
- explicit Performance(Frame&);
+ explicit Performance(Frame*);
virtual void refEventTarget() override { ref(); }
virtual void derefEventTarget() override { deref(); }
@@ -103,8 +105,6 @@ private:
unsigned m_resourceTimingBufferSize;
#endif
- double m_referenceTime;
-
#if ENABLE(USER_TIMING)
RefPtr<UserTiming> m_userTiming;
#endif // ENABLE(USER_TIMING)
diff --git a/Source/WebCore/page/Performance.idl b/Source/WebCore/page/Performance.idl
index 471fb50fd..53e8390db 100644
--- a/Source/WebCore/page/Performance.idl
+++ b/Source/WebCore/page/Performance.idl
@@ -29,10 +29,11 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-// See: https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/NavigationTiming/Overview.html
+// See: http://dev.w3.org/2006/webapi/WebTiming/
[
Conditional=WEB_TIMING,
-] interface Performance : EventTarget {
+ EventTarget,
+] interface Performance {
readonly attribute PerformanceNavigation navigation;
readonly attribute PerformanceTiming timing;
@@ -46,7 +47,7 @@
void webkitClearResourceTimings();
void webkitSetResourceTimingBufferSize(unsigned long maxSize);
- attribute EventHandler onwebkitresourcetimingbufferfull;
+ attribute EventListener onwebkitresourcetimingbufferfull;
#endif
// See http://www.w3.org/TR/2012/CR-user-timing-20120726/
@@ -59,6 +60,6 @@
#endif
// See http://www.w3.org/TR/hr-time/ for details.
- unrestricted double now();
+ double now();
};
diff --git a/Source/WebCore/page/PerformanceEntry.idl b/Source/WebCore/page/PerformanceEntry.idl
index 9bcaf4c34..23f79479b 100644
--- a/Source/WebCore/page/PerformanceEntry.idl
+++ b/Source/WebCore/page/PerformanceEntry.idl
@@ -36,6 +36,6 @@
] interface PerformanceEntry {
readonly attribute DOMString name;
readonly attribute DOMString entryType;
- readonly attribute unrestricted double startTime;
- readonly attribute unrestricted double duration;
+ readonly attribute double startTime;
+ readonly attribute double duration;
};
diff --git a/Source/WebCore/page/PerformanceEntryList.h b/Source/WebCore/page/PerformanceEntryList.h
index 97a212dd6..d900287ad 100644
--- a/Source/WebCore/page/PerformanceEntryList.h
+++ b/Source/WebCore/page/PerformanceEntryList.h
@@ -45,7 +45,7 @@ class PerformanceEntry;
class PerformanceEntryList : public RefCounted<PerformanceEntryList> {
public:
- static Ref<PerformanceEntryList> create() { return adoptRef(*new PerformanceEntryList); }
+ static PassRefPtr<PerformanceEntryList> create() { return adoptRef(new PerformanceEntryList); }
~PerformanceEntryList();
unsigned length() const;
diff --git a/Source/WebCore/page/PerformanceMark.h b/Source/WebCore/page/PerformanceMark.h
index cd71a026f..64b39abfd 100644
--- a/Source/WebCore/page/PerformanceMark.h
+++ b/Source/WebCore/page/PerformanceMark.h
@@ -36,7 +36,7 @@ namespace WebCore {
class PerformanceMark : public PerformanceEntry {
public:
- static Ref<PerformanceMark> create(const String& name, double startTime) { return adoptRef(*new PerformanceMark(name, startTime)); }
+ static PassRefPtr<PerformanceMark> create(const String& name, double startTime) { return adoptRef(new PerformanceMark(name, startTime)); }
virtual bool isMark() { return true; }
diff --git a/Source/WebCore/page/PerformanceMeasure.h b/Source/WebCore/page/PerformanceMeasure.h
index af3e36e50..65564959b 100644
--- a/Source/WebCore/page/PerformanceMeasure.h
+++ b/Source/WebCore/page/PerformanceMeasure.h
@@ -36,7 +36,7 @@ namespace WebCore {
class PerformanceMeasure : public PerformanceEntry {
public:
- static Ref<PerformanceMeasure> create(const String& name, double startTime, double duration) { return adoptRef(*new PerformanceMeasure(name, startTime, duration)); }
+ static PassRefPtr<PerformanceMeasure> create(const String& name, double startTime, double duration) { return adoptRef(new PerformanceMeasure(name, startTime, duration)); }
virtual bool isMeasure() { return true; }
diff --git a/Source/WebCore/page/PerformanceNavigation.cpp b/Source/WebCore/page/PerformanceNavigation.cpp
index be472a05c..2cb3aefed 100644
--- a/Source/WebCore/page/PerformanceNavigation.cpp
+++ b/Source/WebCore/page/PerformanceNavigation.cpp
@@ -55,9 +55,9 @@ unsigned short PerformanceNavigation::type() const
WebCore::NavigationType navigationType = documentLoader->triggeringAction().type();
switch (navigationType) {
- case NavigationType::Reload:
+ case NavigationTypeReload:
return TYPE_RELOAD;
- case NavigationType::BackForward:
+ case NavigationTypeBackForward:
return TYPE_BACK_FORWARD;
default:
return TYPE_NAVIGATE;
@@ -73,11 +73,11 @@ unsigned short PerformanceNavigation::redirectCount() const
if (!loader)
return 0;
- DocumentLoadTiming& timing = loader->timing();
- if (timing.hasCrossOriginRedirect())
+ DocumentLoadTiming* timing = loader->timing();
+ if (timing->hasCrossOriginRedirect())
return 0;
- return timing.redirectCount();
+ return timing->redirectCount();
}
} // namespace WebCore
diff --git a/Source/WebCore/page/PerformanceNavigation.h b/Source/WebCore/page/PerformanceNavigation.h
index 2acc60b02..f397923e6 100644
--- a/Source/WebCore/page/PerformanceNavigation.h
+++ b/Source/WebCore/page/PerformanceNavigation.h
@@ -43,7 +43,7 @@ class Frame;
class PerformanceNavigation : public RefCounted<PerformanceNavigation>, public DOMWindowProperty {
public:
- static Ref<PerformanceNavigation> create(Frame* frame) { return adoptRef(*new PerformanceNavigation(frame)); }
+ static PassRefPtr<PerformanceNavigation> create(Frame* frame) { return adoptRef(new PerformanceNavigation(frame)); }
enum PerformanceNavigationType {
TYPE_NAVIGATE,
diff --git a/Source/WebCore/page/PerformanceResourceTiming.cpp b/Source/WebCore/page/PerformanceResourceTiming.cpp
index 31b897137..bb6bc6ad9 100644
--- a/Source/WebCore/page/PerformanceResourceTiming.cpp
+++ b/Source/WebCore/page/PerformanceResourceTiming.cpp
@@ -37,7 +37,6 @@
#include "Document.h"
#include "DocumentLoadTiming.h"
#include "DocumentLoader.h"
-#include "HTTPHeaderNames.h"
#include "URL.h"
#include "ResourceRequest.h"
#include "ResourceResponse.h"
@@ -49,7 +48,7 @@ namespace WebCore {
static double monotonicTimeToDocumentMilliseconds(Document* document, double seconds)
{
ASSERT(seconds >= 0.0);
- return document->loader()->timing().monotonicTimeToZeroBasedDocumentTime(seconds) * 1000.0;
+ return document->loader()->timing()->monotonicTimeToZeroBasedDocumentTime(seconds) * 1000.0;
}
static bool passesTimingAllowCheck(const ResourceResponse& response, Document* requestingDocument)
@@ -58,8 +57,8 @@ static bool passesTimingAllowCheck(const ResourceResponse& response, Document* r
if (resourceOrigin->isSameSchemeHostPort(requestingDocument->securityOrigin()))
return true;
- const String& timingAllowOriginString = response.httpHeaderField(HTTPHeaderName::TimingAllowOrigin);
- if (timingAllowOriginString.isEmpty() || equalLettersIgnoringASCIICase(timingAllowOriginString, "null"))
+ const String& timingAllowOriginString = response.httpHeaderField("timing-allow-origin");
+ if (timingAllowOriginString.isEmpty() || equalIgnoringCase(timingAllowOriginString, "null"))
return false;
if (timingAllowOriginString == "*")
@@ -67,11 +66,10 @@ static bool passesTimingAllowCheck(const ResourceResponse& response, Document* r
const String& securityOrigin = requestingDocument->securityOrigin()->toString();
Vector<String> timingAllowOrigins;
- timingAllowOriginString.split(' ', timingAllowOrigins);
- for (auto& origin : timingAllowOrigins) {
- if (origin == securityOrigin)
+ timingAllowOriginString.split(" ", timingAllowOrigins);
+ for (size_t i = 0; i < timingAllowOrigins.size(); ++i)
+ if (timingAllowOrigins[i] == securityOrigin)
return true;
- }
return false;
}
@@ -81,6 +79,7 @@ PerformanceResourceTiming::PerformanceResourceTiming(const AtomicString& initiat
, m_initiatorType(initiatorType)
, m_timing(response.resourceLoadTiming())
, m_finishTime(finishTime)
+ , m_didReuseConnection(response.connectionReused())
, m_shouldReportDetails(passesTimingAllowCheck(response, requestingDocument))
, m_requestingDocument(requestingDocument)
{
@@ -121,10 +120,10 @@ double PerformanceResourceTiming::domainLookupStart() const
if (!m_shouldReportDetails)
return 0.0;
- if (m_timing.domainLookupStart < 0)
+ if (!m_timing || m_timing->dnsStart < 0)
return fetchStart();
- return resourceTimeToDocumentMilliseconds(m_timing.domainLookupStart);
+ return resourceTimeToDocumentMilliseconds(m_timing->dnsStart);
}
double PerformanceResourceTiming::domainLookupEnd() const
@@ -132,10 +131,10 @@ double PerformanceResourceTiming::domainLookupEnd() const
if (!m_shouldReportDetails)
return 0.0;
- if (m_timing.domainLookupEnd < 0)
+ if (!m_timing || m_timing->dnsEnd < 0)
return domainLookupStart();
- return resourceTimeToDocumentMilliseconds(m_timing.domainLookupEnd);
+ return resourceTimeToDocumentMilliseconds(m_timing->dnsEnd);
}
double PerformanceResourceTiming::connectStart() const
@@ -144,13 +143,13 @@ double PerformanceResourceTiming::connectStart() const
return 0.0;
// connectStart will be -1 when a network request is not made.
- if (m_timing.connectStart < 0)
+ if (!m_timing || m_timing->connectStart < 0 || m_didReuseConnection)
return domainLookupEnd();
// connectStart includes any DNS time, so we may need to trim that off.
- int connectStart = m_timing.connectStart;
- if (m_timing.domainLookupEnd >= 0)
- connectStart = m_timing.domainLookupEnd;
+ int connectStart = m_timing->connectStart;
+ if (m_timing->dnsEnd >= 0)
+ connectStart = m_timing->dnsEnd;
return resourceTimeToDocumentMilliseconds(connectStart);
}
@@ -161,10 +160,10 @@ double PerformanceResourceTiming::connectEnd() const
return 0.0;
// connectStart will be -1 when a network request is not made.
- if (m_timing.connectEnd < 0)
+ if (!m_timing || m_timing->connectEnd < 0 || m_didReuseConnection)
return connectStart();
- return resourceTimeToDocumentMilliseconds(m_timing.connectEnd);
+ return resourceTimeToDocumentMilliseconds(m_timing->connectEnd);
}
double PerformanceResourceTiming::secureConnectionStart() const
@@ -172,10 +171,10 @@ double PerformanceResourceTiming::secureConnectionStart() const
if (!m_shouldReportDetails)
return 0.0;
- if (m_timing.secureConnectionStart < 0) // Secure connection not negotiated.
+ if (!m_timing || m_timing->sslStart < 0) // Secure connection not negotiated.
return 0.0;
- return resourceTimeToDocumentMilliseconds(m_timing.secureConnectionStart);
+ return resourceTimeToDocumentMilliseconds(m_timing->sslStart);
}
double PerformanceResourceTiming::requestStart() const
@@ -183,11 +182,28 @@ double PerformanceResourceTiming::requestStart() const
if (!m_shouldReportDetails)
return 0.0;
- return resourceTimeToDocumentMilliseconds(m_timing.requestStart);
+ if (!m_timing)
+ return connectEnd();
+
+ return resourceTimeToDocumentMilliseconds(m_timing->sendStart);
+}
+
+double PerformanceResourceTiming::responseStart() const
+{
+ if (!m_shouldReportDetails)
+ return 0.0;
+
+ if (!m_timing)
+ return requestStart();
+ // FIXME: This number isn't exactly correct. See the notes in PerformanceTiming::responseStart().
+ return resourceTimeToDocumentMilliseconds(m_timing->receiveHeadersEnd);
}
double PerformanceResourceTiming::responseEnd() const
{
+ if (!m_finishTime)
+ return responseStart();
+
return monotonicTimeToDocumentMilliseconds(m_requestingDocument.get(), m_finishTime);
}
@@ -195,7 +211,7 @@ double PerformanceResourceTiming::resourceTimeToDocumentMilliseconds(int deltaMi
{
if (!deltaMilliseconds)
return 0.0;
- return monotonicTimeToDocumentMilliseconds(m_requestingDocument.get(), m_requestingDocument->loader()->timing().navigationStart()) + deltaMilliseconds;
+ return monotonicTimeToDocumentMilliseconds(m_requestingDocument.get(), m_timing->requestTime) + deltaMilliseconds;
}
} // namespace WebCore
diff --git a/Source/WebCore/page/PerformanceResourceTiming.h b/Source/WebCore/page/PerformanceResourceTiming.h
index 99dfc5bcd..6276944ca 100644
--- a/Source/WebCore/page/PerformanceResourceTiming.h
+++ b/Source/WebCore/page/PerformanceResourceTiming.h
@@ -35,7 +35,6 @@
#if ENABLE(RESOURCE_TIMING)
#include "PerformanceEntry.h"
-#include "ResourceLoadTiming.h"
#include <wtf/PassRefPtr.h>
#include <wtf/RefPtr.h>
#include <wtf/text/WTFString.h>
@@ -50,9 +49,9 @@ class ResourceResponse;
class PerformanceResourceTiming : public PerformanceEntry {
public:
- static Ref<PerformanceResourceTiming> create(const AtomicString& initiatorType, const ResourceRequest& request, const ResourceResponse& response, double initiationTime, double finishTime, Document* requestingDocument)
+ static PassRefPtr<PerformanceResourceTiming> create(const AtomicString& initiatorType, const ResourceRequest& request, const ResourceResponse& response, double initiationTime, double finishTime, Document* requestingDocument)
{
- return adoptRef(*new PerformanceResourceTiming(initiatorType, request, response, initiationTime, finishTime, requestingDocument));
+ return adoptRef(new PerformanceResourceTiming(initiatorType, request, response, initiationTime, finishTime, requestingDocument));
}
AtomicString initiatorType() const;
@@ -66,6 +65,7 @@ public:
double connectEnd() const;
double secureConnectionStart() const;
double requestStart() const;
+ double responseStart() const;
double responseEnd() const;
virtual bool isResource() { return true; }
@@ -77,8 +77,9 @@ private:
double resourceTimeToDocumentMilliseconds(int deltaMilliseconds) const;
AtomicString m_initiatorType;
- ResourceLoadTiming m_timing;
+ RefPtr<ResourceLoadTiming> m_timing;
double m_finishTime;
+ bool m_didReuseConnection;
bool m_shouldReportDetails;
RefPtr<Document> m_requestingDocument;
};
diff --git a/Source/WebCore/page/PerformanceResourceTiming.idl b/Source/WebCore/page/PerformanceResourceTiming.idl
index 3f011b23b..a0e48633b 100644
--- a/Source/WebCore/page/PerformanceResourceTiming.idl
+++ b/Source/WebCore/page/PerformanceResourceTiming.idl
@@ -34,14 +34,15 @@
] interface PerformanceResourceTiming : PerformanceEntry {
readonly attribute DOMString initiatorType;
- readonly attribute unrestricted double redirectStart;
- readonly attribute unrestricted double redirectEnd;
- readonly attribute unrestricted double fetchStart;
- readonly attribute unrestricted double domainLookupStart;
- readonly attribute unrestricted double domainLookupEnd;
- readonly attribute unrestricted double connectStart;
- readonly attribute unrestricted double connectEnd;
- readonly attribute unrestricted double secureConnectionStart;
- readonly attribute unrestricted double requestStart;
- readonly attribute unrestricted double responseEnd;
+ readonly attribute double redirectStart;
+ readonly attribute double redirectEnd;
+ readonly attribute double fetchStart;
+ readonly attribute double domainLookupStart;
+ readonly attribute double domainLookupEnd;
+ readonly attribute double connectStart;
+ readonly attribute double connectEnd;
+ readonly attribute double secureConnectionStart;
+ readonly attribute double requestStart;
+ readonly attribute double responseStart;
+ readonly attribute double responseEnd;
};
diff --git a/Source/WebCore/page/PerformanceTiming.cpp b/Source/WebCore/page/PerformanceTiming.cpp
index 7d571b5f3..c14080ffb 100644
--- a/Source/WebCore/page/PerformanceTiming.cpp
+++ b/Source/WebCore/page/PerformanceTiming.cpp
@@ -124,34 +124,32 @@ unsigned long long PerformanceTiming::fetchStart() const
unsigned long long PerformanceTiming::domainLookupStart() const
{
- DocumentLoader* loader = documentLoader();
- if (!loader)
+ ResourceLoadTiming* timing = resourceLoadTiming();
+ if (!timing)
return fetchStart();
-
- const ResourceLoadTiming& timing = loader->response().resourceLoadTiming();
-
+
// This will be -1 when a DNS request is not performed.
// Rather than exposing a special value that indicates no DNS, we "backfill" with fetchStart.
- if (timing.domainLookupStart < 0)
+ int dnsStart = timing->dnsStart;
+ if (dnsStart < 0)
return fetchStart();
- return resourceLoadTimeRelativeToFetchStart(timing.domainLookupStart);
+ return resourceLoadTimeRelativeToAbsolute(dnsStart);
}
unsigned long long PerformanceTiming::domainLookupEnd() const
{
- DocumentLoader* loader = documentLoader();
- if (!loader)
+ ResourceLoadTiming* timing = resourceLoadTiming();
+ if (!timing)
return domainLookupStart();
-
- const ResourceLoadTiming& timing = loader->response().resourceLoadTiming();
-
+
// This will be -1 when a DNS request is not performed.
// Rather than exposing a special value that indicates no DNS, we "backfill" with domainLookupStart.
- if (timing.domainLookupEnd < 0)
+ int dnsEnd = timing->dnsEnd;
+ if (dnsEnd < 0)
return domainLookupStart();
- return resourceLoadTimeRelativeToFetchStart(timing.domainLookupEnd);
+ return resourceLoadTimeRelativeToAbsolute(dnsEnd);
}
unsigned long long PerformanceTiming::connectStart() const
@@ -160,20 +158,22 @@ unsigned long long PerformanceTiming::connectStart() const
if (!loader)
return domainLookupEnd();
- const ResourceLoadTiming& timing = loader->response().resourceLoadTiming();
-
+ ResourceLoadTiming* timing = loader->response().resourceLoadTiming();
+ if (!timing)
+ return domainLookupEnd();
+
// connectStart will be -1 when a network request is not made.
// Rather than exposing a special value that indicates no new connection, we "backfill" with domainLookupEnd.
- int connectStart = timing.connectStart;
- if (connectStart < 0)
+ int connectStart = timing->connectStart;
+ if (connectStart < 0 || loader->response().connectionReused())
return domainLookupEnd();
// ResourceLoadTiming's connect phase includes DNS, however Navigation Timing's
// connect phase should not. So if there is DNS time, trim it from the start.
- if (timing.domainLookupEnd >= 0 && timing.domainLookupEnd > connectStart)
- connectStart = timing.domainLookupEnd;
+ if (timing->dnsEnd >= 0 && timing->dnsEnd > connectStart)
+ connectStart = timing->dnsEnd;
- return resourceLoadTimeRelativeToFetchStart(connectStart);
+ return resourceLoadTimeRelativeToAbsolute(connectStart);
}
unsigned long long PerformanceTiming::connectEnd() const
@@ -182,14 +182,17 @@ unsigned long long PerformanceTiming::connectEnd() const
if (!loader)
return connectStart();
- const ResourceLoadTiming& timing = loader->response().resourceLoadTiming();
-
+ ResourceLoadTiming* timing = loader->response().resourceLoadTiming();
+ if (!timing)
+ return connectStart();
+
// connectEnd will be -1 when a network request is not made.
// Rather than exposing a special value that indicates no new connection, we "backfill" with connectStart.
- if (timing.connectEnd < 0)
+ int connectEnd = timing->connectEnd;
+ if (connectEnd < 0 || loader->response().connectionReused())
return connectStart();
- return resourceLoadTimeRelativeToFetchStart(timing.connectEnd);
+ return resourceLoadTimeRelativeToAbsolute(connectEnd);
}
unsigned long long PerformanceTiming::secureConnectionStart() const
@@ -198,36 +201,41 @@ unsigned long long PerformanceTiming::secureConnectionStart() const
if (!loader)
return 0;
- const ResourceLoadTiming& timing = loader->response().resourceLoadTiming();
-
- if (timing.secureConnectionStart < 0)
+ ResourceLoadTiming* timing = loader->response().resourceLoadTiming();
+ if (!timing)
return 0;
- return resourceLoadTimeRelativeToFetchStart(timing.secureConnectionStart);
+ int sslStart = timing->sslStart;
+ if (sslStart < 0)
+ return 0;
+
+ return resourceLoadTimeRelativeToAbsolute(sslStart);
}
unsigned long long PerformanceTiming::requestStart() const
{
- DocumentLoader* loader = documentLoader();
- if (!loader)
+ ResourceLoadTiming* timing = resourceLoadTiming();
+ if (!timing)
return connectEnd();
-
- const ResourceLoadTiming& timing = loader->response().resourceLoadTiming();
-
- ASSERT(timing.requestStart >= 0);
- return resourceLoadTimeRelativeToFetchStart(timing.requestStart);
+
+ ASSERT(timing->sendStart >= 0);
+ return resourceLoadTimeRelativeToAbsolute(timing->sendStart);
}
unsigned long long PerformanceTiming::responseStart() const
{
- DocumentLoader* loader = documentLoader();
- if (!loader)
+ ResourceLoadTiming* timing = resourceLoadTiming();
+ if (!timing)
return requestStart();
- const ResourceLoadTiming& timing = loader->response().resourceLoadTiming();
-
- ASSERT(timing.responseStart >= 0);
- return resourceLoadTimeRelativeToFetchStart(timing.responseStart);
+ // FIXME: Response start needs to be the time of the first received byte.
+ // However, the ResourceLoadTiming API currently only supports the time
+ // the last header byte was received. For many responses with reasonable
+ // sized cookies, the HTTP headers fit into a single packet so this time
+ // is basically equivalent. But for some responses, particularly those with
+ // headers larger than a single packet, this time will be too late.
+ ASSERT(timing->receiveHeadersEnd >= 0);
+ return resourceLoadTimeRelativeToAbsolute(timing->receiveHeadersEnd);
}
unsigned long long PerformanceTiming::responseEnd() const
@@ -319,7 +327,7 @@ const DocumentTiming* PerformanceTiming::documentTiming() const
if (!document)
return 0;
- return &document->timing();
+ return document->timing();
}
DocumentLoadTiming* PerformanceTiming::documentLoadTiming() const
@@ -328,21 +336,32 @@ DocumentLoadTiming* PerformanceTiming::documentLoadTiming() const
if (!loader)
return 0;
- return &loader->timing();
+ return loader->timing();
+}
+
+ResourceLoadTiming* PerformanceTiming::resourceLoadTiming() const
+{
+ DocumentLoader* loader = documentLoader();
+ if (!loader)
+ return 0;
+
+ return loader->response().resourceLoadTiming();
}
-unsigned long long PerformanceTiming::resourceLoadTimeRelativeToFetchStart(int relativeMilliseconds) const
+unsigned long long PerformanceTiming::resourceLoadTimeRelativeToAbsolute(int relativeMilliseconds) const
{
ASSERT(relativeMilliseconds >= 0);
- return fetchStart() + relativeMilliseconds;
+ ResourceLoadTiming* resourceTiming = resourceLoadTiming();
+ ASSERT(resourceTiming);
+ return monotonicTimeToIntegerMilliseconds(resourceTiming->convertResourceLoadTimeToMonotonicTime(relativeMilliseconds));
}
unsigned long long PerformanceTiming::monotonicTimeToIntegerMilliseconds(double monotonicSeconds) const
{
ASSERT(monotonicSeconds >= 0);
- if (const DocumentLoadTiming* timing = documentLoadTiming())
- return toIntegerMilliseconds(timing->monotonicTimeToPseudoWallTime(monotonicSeconds));
- return 0;
+ const DocumentLoadTiming* timing = documentLoadTiming();
+ ASSERT(timing);
+ return toIntegerMilliseconds(timing->monotonicTimeToPseudoWallTime(monotonicSeconds));
}
} // namespace WebCore
diff --git a/Source/WebCore/page/PerformanceTiming.h b/Source/WebCore/page/PerformanceTiming.h
index 99092fef4..30b80b967 100644
--- a/Source/WebCore/page/PerformanceTiming.h
+++ b/Source/WebCore/page/PerformanceTiming.h
@@ -47,7 +47,7 @@ class ResourceLoadTiming;
class PerformanceTiming : public RefCounted<PerformanceTiming>, public DOMWindowProperty {
public:
- static Ref<PerformanceTiming> create(Frame* frame) { return adoptRef(*new PerformanceTiming(frame)); }
+ static PassRefPtr<PerformanceTiming> create(Frame* frame) { return adoptRef(new PerformanceTiming(frame)); }
unsigned long long navigationStart() const;
unsigned long long unloadEventStart() const;
@@ -77,7 +77,8 @@ private:
const DocumentTiming* documentTiming() const;
DocumentLoader* documentLoader() const;
DocumentLoadTiming* documentLoadTiming() const;
- unsigned long long resourceLoadTimeRelativeToFetchStart(int) const;
+ ResourceLoadTiming* resourceLoadTiming() const;
+ unsigned long long resourceLoadTimeRelativeToAbsolute(int) const;
unsigned long long monotonicTimeToIntegerMilliseconds(double) const;
};
diff --git a/Source/WebCore/page/PerformanceTiming.idl b/Source/WebCore/page/PerformanceTiming.idl
index 9fdbb01c7..9f4f60c40 100644
--- a/Source/WebCore/page/PerformanceTiming.idl
+++ b/Source/WebCore/page/PerformanceTiming.idl
@@ -28,7 +28,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-// See: https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/NavigationTiming/Overview.html
+// See: http://dev.w3.org/2006/webapi/WebTiming/
[
Conditional=WEB_TIMING,
] interface PerformanceTiming {
diff --git a/Source/WebCore/page/PerformanceUserTiming.cpp b/Source/WebCore/page/PerformanceUserTiming.cpp
index 5c85fd13e..e2af43ed8 100644
--- a/Source/WebCore/page/PerformanceUserTiming.cpp
+++ b/Source/WebCore/page/PerformanceUserTiming.cpp
@@ -31,7 +31,6 @@
#include "Performance.h"
#include "PerformanceMark.h"
#include "PerformanceMeasure.h"
-#include <wtf/NeverDestroyed.h>
#include <wtf/dtoa/utils.h>
#include <wtf/text/WTFString.h>
@@ -39,40 +38,34 @@ namespace WebCore {
namespace {
-static NavigationTimingFunction restrictedMarkFunction(const String& markName)
+typedef HashMap<String, NavigationTimingFunction> RestrictedKeyMap;
+static RestrictedKeyMap restrictedKeyMap()
{
- using MapPair = std::pair<ASCIILiteral, NavigationTimingFunction>;
- static const std::array<MapPair, 21> pairs = { {
- MapPair{ ASCIILiteral("navigationStart"), &PerformanceTiming::navigationStart },
- MapPair{ ASCIILiteral("unloadEventStart"), &PerformanceTiming::unloadEventStart },
- MapPair{ ASCIILiteral("unloadEventEnd"), &PerformanceTiming::unloadEventEnd },
- MapPair{ ASCIILiteral("redirectStart"), &PerformanceTiming::redirectStart },
- MapPair{ ASCIILiteral("redirectEnd"), &PerformanceTiming::redirectEnd },
- MapPair{ ASCIILiteral("fetchStart"), &PerformanceTiming::fetchStart },
- MapPair{ ASCIILiteral("domainLookupStart"), &PerformanceTiming::domainLookupStart },
- MapPair{ ASCIILiteral("domainLookupEnd"), &PerformanceTiming::domainLookupEnd },
- MapPair{ ASCIILiteral("connectStart"), &PerformanceTiming::connectStart },
- MapPair{ ASCIILiteral("connectEnd"), &PerformanceTiming::connectEnd },
- MapPair{ ASCIILiteral("secureConnectionStart"), &PerformanceTiming::secureConnectionStart },
- MapPair{ ASCIILiteral("requestStart"), &PerformanceTiming::requestStart },
- MapPair{ ASCIILiteral("responseStart"), &PerformanceTiming::responseStart },
- MapPair{ ASCIILiteral("responseEnd"), &PerformanceTiming::responseEnd },
- MapPair{ ASCIILiteral("domLoading"), &PerformanceTiming::domLoading },
- MapPair{ ASCIILiteral("domInteractive"), &PerformanceTiming::domInteractive },
- MapPair{ ASCIILiteral("domContentLoadedEventStart"), &PerformanceTiming::domContentLoadedEventStart },
- MapPair{ ASCIILiteral("domContentLoadedEventEnd"), &PerformanceTiming::domContentLoadedEventEnd },
- MapPair{ ASCIILiteral("domComplete"), &PerformanceTiming::domComplete },
- MapPair{ ASCIILiteral("loadEventStart"), &PerformanceTiming::loadEventStart },
- MapPair{ ASCIILiteral("loadEventEnd"), &PerformanceTiming::loadEventEnd },
- } };
-
- static NeverDestroyed<HashMap<String, NavigationTimingFunction>> map;
- if (map.get().isEmpty()) {
- for (auto& pair : pairs)
- map.get().add(pair.first, pair.second);
+ DEFINE_STATIC_LOCAL(RestrictedKeyMap, map, ());
+ if (map.isEmpty()) {
+ map.add("navigationStart", &PerformanceTiming::navigationStart);
+ map.add("unloadEventStart", &PerformanceTiming::unloadEventStart);
+ map.add("unloadEventEnd", &PerformanceTiming::unloadEventEnd);
+ map.add("redirectStart", &PerformanceTiming::redirectStart);
+ map.add("redirectEnd", &PerformanceTiming::redirectEnd);
+ map.add("fetchStart", &PerformanceTiming::fetchStart);
+ map.add("domainLookupStart", &PerformanceTiming::domainLookupStart);
+ map.add("domainLookupEnd", &PerformanceTiming::domainLookupEnd);
+ map.add("connectStart", &PerformanceTiming::connectStart);
+ map.add("connectEnd", &PerformanceTiming::connectEnd);
+ map.add("secureConnectionStart", &PerformanceTiming::secureConnectionStart);
+ map.add("requestStart", &PerformanceTiming::requestStart);
+ map.add("responseStart", &PerformanceTiming::responseStart);
+ map.add("responseEnd", &PerformanceTiming::responseEnd);
+ map.add("domLoading", &PerformanceTiming::domLoading);
+ map.add("domInteractive", &PerformanceTiming::domInteractive);
+ map.add("domContentLoadedEventStart", &PerformanceTiming::domContentLoadedEventStart);
+ map.add("domContentLoadedEventEnd", &PerformanceTiming::domContentLoadedEventEnd);
+ map.add("domComplete", &PerformanceTiming::domComplete);
+ map.add("loadEventStart", &PerformanceTiming::loadEventStart);
+ map.add("loadEventEnd", &PerformanceTiming::loadEventEnd);
}
-
- return map.get().get(markName);
+ return map;
}
} // namespace anonymous
@@ -88,8 +81,11 @@ static void insertPerformanceEntry(PerformanceEntryMap& performanceEntryMap, Pas
PerformanceEntryMap::iterator it = performanceEntryMap.find(entry->name());
if (it != performanceEntryMap.end())
it->value.append(entry);
- else
- performanceEntryMap.set(entry->name(), Vector<RefPtr<PerformanceEntry>>{ entry });
+ else {
+ Vector<RefPtr<PerformanceEntry> > v(1);
+ v[0] = entry;
+ performanceEntryMap.set(entry->name(), v);
+ }
}
static void clearPeformanceEntries(PerformanceEntryMap& performanceEntryMap, const String& name)
@@ -105,7 +101,7 @@ static void clearPeformanceEntries(PerformanceEntryMap& performanceEntryMap, con
void UserTiming::mark(const String& markName, ExceptionCode& ec)
{
ec = 0;
- if (restrictedMarkFunction(markName)) {
+ if (restrictedKeyMap().contains(markName)) {
ec = SYNTAX_ERR;
return;
}
@@ -126,8 +122,8 @@ double UserTiming::findExistingMarkStartTime(const String& markName, ExceptionCo
if (m_marksMap.contains(markName))
return m_marksMap.get(markName).last()->startTime();
- if (auto function = restrictedMarkFunction(markName)) {
- double value = static_cast<double>((m_performance->timing()->*(function))());
+ if (restrictedKeyMap().contains(markName)) {
+ double value = static_cast<double>((m_performance->timing()->*(restrictedKeyMap().get(markName)))());
if (!value) {
ec = INVALID_ACCESS_ERR;
return 0.0;
@@ -172,8 +168,8 @@ static Vector<RefPtr<PerformanceEntry> > convertToEntrySequence(const Performanc
{
Vector<RefPtr<PerformanceEntry> > entries;
- for (auto& entry : performanceEntryMap.values())
- entries.appendVector(entry);
+ for (PerformanceEntryMap::const_iterator it = performanceEntryMap.begin(); it != performanceEntryMap.end(); ++it)
+ entries.appendVector(it->value);
return entries;
}
diff --git a/Source/WebCore/page/PerformanceUserTiming.h b/Source/WebCore/page/PerformanceUserTiming.h
index 0a48b3fcc..14c8c3f9b 100644
--- a/Source/WebCore/page/PerformanceUserTiming.h
+++ b/Source/WebCore/page/PerformanceUserTiming.h
@@ -28,6 +28,7 @@
#if ENABLE(USER_TIMING)
+#include "EventException.h"
#include "ExceptionCode.h"
#include "Performance.h"
#include "PerformanceTiming.h"
@@ -47,7 +48,7 @@ typedef HashMap<String, Vector<RefPtr<PerformanceEntry> > > PerformanceEntryMap;
class UserTiming : public RefCounted<UserTiming> {
public:
- static Ref<UserTiming> create(Performance* performance) { return adoptRef(*new UserTiming(performance)); }
+ static PassRefPtr<UserTiming> create(Performance* performance) { return adoptRef(new UserTiming(performance)); }
void mark(const String& markName, ExceptionCode&);
void clearMarks(const String& markName);
diff --git a/Source/WebCore/page/PlugInClient.h b/Source/WebCore/page/PlugInClient.h
index 928b95caa..6582c4efe 100644
--- a/Source/WebCore/page/PlugInClient.h
+++ b/Source/WebCore/page/PlugInClient.h
@@ -26,7 +26,6 @@
#ifndef PlugInClient_h
#define PlugInClient_h
-#include "SessionID.h"
#include <wtf/Forward.h>
namespace WebCore {
@@ -35,7 +34,7 @@ class PlugInClient {
public:
virtual void pageDestroyed() = 0;
virtual bool shouldAutoStartFromOrigin(const String& pageOrigin, const String& pluginOrigin, const String& mimeType) = 0;
- virtual void didStartFromOrigin(const String& pageOrigin, const String& pluginOrigin, const String& mimeType, SessionID) = 0;
+ virtual void didStartFromOrigin(const String& pageOrigin, const String& pluginOrigin, const String& mimeType) = 0;
protected:
virtual ~PlugInClient() { }
diff --git a/Source/WebCore/page/PointerLockController.cpp b/Source/WebCore/page/PointerLockController.cpp
index 897a415d9..5d6f5a5ea 100644
--- a/Source/WebCore/page/PointerLockController.cpp
+++ b/Source/WebCore/page/PointerLockController.cpp
@@ -25,8 +25,6 @@
#include "config.h"
#include "PointerLockController.h"
-#if ENABLE(POINTER_LOCK)
-
#include "Chrome.h"
#include "ChromeClient.h"
#include "Element.h"
@@ -35,46 +33,52 @@
#include "PlatformMouseEvent.h"
#include "VoidCallback.h"
+#if ENABLE(POINTER_LOCK)
namespace WebCore {
-PointerLockController::PointerLockController(Page& page)
+PointerLockController::PointerLockController(Page* page)
: m_page(page)
- , m_lockPending(false)
{
}
+PassOwnPtr<PointerLockController> PointerLockController::create(Page* page)
+{
+ return adoptPtr(new PointerLockController(page));
+}
+
void PointerLockController::requestPointerLock(Element* target)
{
if (!target || !target->inDocument() || m_documentOfRemovedElementWhileWaitingForUnlock) {
- enqueueEvent(eventNames().pointerlockerrorEvent, target);
+ enqueueEvent(eventNames().webkitpointerlockerrorEvent, target);
return;
}
if (target->document().isSandboxed(SandboxPointerLock)) {
// FIXME: This message should be moved off the console once a solution to https://bugs.webkit.org/show_bug.cgi?id=103274 exists.
- target->document().addConsoleMessage(MessageSource::Security, MessageLevel::Error, ASCIILiteral("Blocked pointer lock on an element because the element's frame is sandboxed and the 'allow-pointer-lock' permission is not set."));
- enqueueEvent(eventNames().pointerlockerrorEvent, target);
+ target->document().addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, "Blocked pointer lock on an element because the element's frame is sandboxed and the 'allow-pointer-lock' permission is not set.");
+ enqueueEvent(eventNames().webkitpointerlockerrorEvent, target);
return;
}
if (m_element) {
if (&m_element->document() != &target->document()) {
- enqueueEvent(eventNames().pointerlockerrorEvent, target);
+ enqueueEvent(eventNames().webkitpointerlockerrorEvent, target);
return;
}
- enqueueEvent(eventNames().pointerlockchangeEvent, target);
+ enqueueEvent(eventNames().webkitpointerlockchangeEvent, target);
m_element = target;
- } else if (m_page.chrome().client().requestPointerLock()) {
+ } else if (m_page->chrome().client().requestPointerLock()) {
m_lockPending = true;
m_element = target;
- } else
- enqueueEvent(eventNames().pointerlockerrorEvent, target);
+ } else {
+ enqueueEvent(eventNames().webkitpointerlockerrorEvent, target);
+ }
}
void PointerLockController::requestPointerUnlock()
{
- return m_page.chrome().client().requestPointerUnlock();
+ return m_page->chrome().client().requestPointerUnlock();
}
void PointerLockController::elementRemoved(Element* element)
@@ -108,21 +112,21 @@ Element* PointerLockController::element() const
void PointerLockController::didAcquirePointerLock()
{
- enqueueEvent(eventNames().pointerlockchangeEvent, m_element.get());
+ enqueueEvent(eventNames().webkitpointerlockchangeEvent, m_element.get());
m_lockPending = false;
}
void PointerLockController::didNotAcquirePointerLock()
{
- enqueueEvent(eventNames().pointerlockerrorEvent, m_element.get());
+ enqueueEvent(eventNames().webkitpointerlockerrorEvent, m_element.get());
clearElement();
}
void PointerLockController::didLosePointerLock()
{
- enqueueEvent(eventNames().pointerlockchangeEvent, m_element ? &m_element->document() : m_documentOfRemovedElementWhileWaitingForUnlock.get());
+ enqueueEvent(eventNames().webkitpointerlockchangeEvent, m_element ? &m_element->document() : m_documentOfRemovedElementWhileWaitingForUnlock.get());
clearElement();
- m_documentOfRemovedElementWhileWaitingForUnlock = nullptr;
+ m_documentOfRemovedElementWhileWaitingForUnlock = 0;
}
void PointerLockController::dispatchLockedMouseEvent(const PlatformMouseEvent& event, const AtomicString& eventType)
@@ -140,7 +144,7 @@ void PointerLockController::dispatchLockedMouseEvent(const PlatformMouseEvent& e
void PointerLockController::clearElement()
{
m_lockPending = false;
- m_element = nullptr;
+ m_element = 0;
}
void PointerLockController::enqueueEvent(const AtomicString& type, Element* element)
diff --git a/Source/WebCore/page/PointerLockController.h b/Source/WebCore/page/PointerLockController.h
index 762851b0f..c820754ae 100644
--- a/Source/WebCore/page/PointerLockController.h
+++ b/Source/WebCore/page/PointerLockController.h
@@ -42,7 +42,8 @@ class PointerLockController {
WTF_MAKE_NONCOPYABLE(PointerLockController);
WTF_MAKE_FAST_ALLOCATED;
public:
- explicit PointerLockController(Page&);
+ static PassOwnPtr<PointerLockController> create(Page*);
+
void requestPointerLock(Element* target);
void requestPointerUnlock();
void elementRemoved(Element*);
@@ -56,10 +57,11 @@ public:
void dispatchLockedMouseEvent(const PlatformMouseEvent&, const AtomicString& eventType);
private:
+ explicit PointerLockController(Page*);
void clearElement();
void enqueueEvent(const AtomicString& type, Element*);
void enqueueEvent(const AtomicString& type, Document*);
- Page& m_page;
+ Page* m_page;
bool m_lockPending;
RefPtr<Element> m_element;
RefPtr<Document> m_documentOfRemovedElementWhileWaitingForUnlock;
diff --git a/Source/WebCore/page/PrintContext.cpp b/Source/WebCore/page/PrintContext.cpp
index 034689acb..e3fddb0e3 100644
--- a/Source/WebCore/page/PrintContext.cpp
+++ b/Source/WebCore/page/PrintContext.cpp
@@ -201,7 +201,7 @@ void PrintContext::spoolPage(GraphicsContext& ctx, int pageNumber, float width)
ctx.scale(FloatSize(scale, scale));
ctx.translate(-pageRect.x(), -pageRect.y());
ctx.clip(pageRect);
- m_frame->view()->paintContents(ctx, pageRect);
+ m_frame->view()->paintContents(&ctx, pageRect);
ctx.restore();
}
@@ -211,7 +211,7 @@ void PrintContext::spoolRect(GraphicsContext& ctx, const IntRect& rect)
ctx.save();
ctx.translate(-rect.x(), -rect.y());
ctx.clip(rect);
- m_frame->view()->paintContents(ctx, rect);
+ m_frame->view()->paintContents(&ctx, rect);
ctx.restore();
}
@@ -225,11 +225,11 @@ void PrintContext::end()
static RenderBoxModelObject* enclosingBoxModelObject(RenderObject* object)
{
- while (object && !is<RenderBoxModelObject>(*object))
+ while (object && !object->isBoxModelObject())
object = object->parent();
if (!object)
- return nullptr;
- return downcast<RenderBoxModelObject>(object);
+ return 0;
+ return toRenderBoxModelObject(object);
}
int PrintContext::pageNumberForElement(Element* element, const FloatSize& pageSizeInPixels)
@@ -250,8 +250,8 @@ int PrintContext::pageNumberForElement(Element* element, const FloatSize& pageSi
scaledPageSize.scale(frame->view()->contentsSize().width() / pageRect.width());
printContext.computePageRectsWithPageSize(scaledPageSize, false);
- int top = roundToInt(box->offsetTop());
- int left = roundToInt(box->offsetLeft());
+ int top = box->pixelSnappedOffsetTop();
+ int left = box->pixelSnappedOffsetLeft();
size_t pageNumber = 0;
for (; pageNumber < printContext.pageCount(); pageNumber++) {
const IntRect& page = printContext.pageRect(pageNumber);
@@ -301,64 +301,54 @@ String PrintContext::pageSizeAndMarginsInPixels(Frame* frame, int pageNumber, in
String::number(marginTop) + ' ' + String::number(marginRight) + ' ' + String::number(marginBottom) + ' ' + String::number(marginLeft);
}
-bool PrintContext::beginAndComputePageRectsWithPageSize(Frame& frame, const FloatSize& pageSizeInPixels)
+int PrintContext::numberOfPages(Frame* frame, const FloatSize& pageSizeInPixels)
{
- if (!frame.document() || !frame.view() || !frame.document()->renderView())
- return false;
+ frame->document()->updateLayout();
- frame.document()->updateLayout();
-
- begin(pageSizeInPixels.width(), pageSizeInPixels.height());
+ FloatRect pageRect(FloatPoint(0, 0), pageSizeInPixels);
+ PrintContext printContext(frame);
+ printContext.begin(pageRect.width(), pageRect.height());
// Account for shrink-to-fit.
FloatSize scaledPageSize = pageSizeInPixels;
- scaledPageSize.scale(frame.view()->contentsSize().width() / pageSizeInPixels.width());
- computePageRectsWithPageSize(scaledPageSize, false);
-
- return true;
-}
-
-int PrintContext::numberOfPages(Frame& frame, const FloatSize& pageSizeInPixels)
-{
- PrintContext printContext(&frame);
- if (!printContext.beginAndComputePageRectsWithPageSize(frame, pageSizeInPixels))
- return -1;
-
+ scaledPageSize.scale(frame->view()->contentsSize().width() / pageRect.width());
+ printContext.computePageRectsWithPageSize(scaledPageSize, false);
return printContext.pageCount();
}
-void PrintContext::spoolAllPagesWithBoundaries(Frame& frame, GraphicsContext& graphicsContext, const FloatSize& pageSizeInPixels)
+void PrintContext::spoolAllPagesWithBoundaries(Frame* frame, GraphicsContext& graphicsContext, const FloatSize& pageSizeInPixels)
{
- PrintContext printContext(&frame);
- if (!printContext.beginAndComputePageRectsWithPageSize(frame, pageSizeInPixels))
+ if (!frame->document() || !frame->view() || !frame->document()->renderView())
return;
+ frame->document()->updateLayout();
+
+ PrintContext printContext(frame);
+ printContext.begin(pageSizeInPixels.width(), pageSizeInPixels.height());
+
+ float pageHeight;
+ printContext.computePageRects(FloatRect(FloatPoint(0, 0), pageSizeInPixels), 0, 0, 1, pageHeight);
+
const float pageWidth = pageSizeInPixels.width();
const Vector<IntRect>& pageRects = printContext.pageRects();
int totalHeight = pageRects.size() * (pageSizeInPixels.height() + 1) - 1;
// Fill the whole background by white.
- graphicsContext.setFillColor(Color(255, 255, 255));
+ graphicsContext.setFillColor(Color(255, 255, 255), ColorSpaceDeviceRGB);
graphicsContext.fillRect(FloatRect(0, 0, pageWidth, totalHeight));
graphicsContext.save();
-#if PLATFORM(COCOA)
graphicsContext.translate(0, totalHeight);
graphicsContext.scale(FloatSize(1, -1));
-#endif
int currentHeight = 0;
for (size_t pageIndex = 0; pageIndex < pageRects.size(); pageIndex++) {
// Draw a line for a page boundary if this isn't the first page.
if (pageIndex > 0) {
-#if PLATFORM(COCOA)
- int boundaryLineY = currentHeight;
-#else
- int boundaryLineY = currentHeight - 1;
-#endif
graphicsContext.save();
- graphicsContext.setStrokeColor(Color(0, 0, 255));
- graphicsContext.setFillColor(Color(0, 0, 255));
- graphicsContext.drawLine(IntPoint(0, boundaryLineY), IntPoint(pageWidth, boundaryLineY));
+ graphicsContext.setStrokeColor(Color(0, 0, 255), ColorSpaceDeviceRGB);
+ graphicsContext.setFillColor(Color(0, 0, 255), ColorSpaceDeviceRGB);
+ graphicsContext.drawLine(IntPoint(0, currentHeight),
+ IntPoint(pageWidth, currentHeight));
graphicsContext.restore();
}
diff --git a/Source/WebCore/page/PrintContext.h b/Source/WebCore/page/PrintContext.h
index d3d3eae2b..2efd05d3f 100644
--- a/Source/WebCore/page/PrintContext.h
+++ b/Source/WebCore/page/PrintContext.h
@@ -35,8 +35,8 @@ class IntRect;
class PrintContext {
public:
- WEBCORE_EXPORT explicit PrintContext(Frame*);
- WEBCORE_EXPORT ~PrintContext();
+ explicit PrintContext(Frame*);
+ ~PrintContext();
Frame* frame() const { return m_frame; }
@@ -44,40 +44,40 @@ public:
// FIXME: This means that CSS page breaks won't be on page boundary if the size is different than what was passed to begin(). That's probably not always desirable.
// FIXME: Header and footer height should be applied before layout, not after.
// FIXME: The printRect argument is only used to determine page aspect ratio, it would be better to pass a FloatSize with page dimensions instead.
- WEBCORE_EXPORT void computePageRects(const FloatRect& printRect, float headerHeight, float footerHeight, float userScaleFactor, float& outPageHeight, bool allowHorizontalTiling = false);
+ void computePageRects(const FloatRect& printRect, float headerHeight, float footerHeight, float userScaleFactor, float& outPageHeight, bool allowHorizontalTiling = false);
// Deprecated. Page size computation is already in this class, clients shouldn't be copying it.
- WEBCORE_EXPORT void computePageRectsWithPageSize(const FloatSize& pageSizeInPixels, bool allowHorizontalTiling);
+ void computePageRectsWithPageSize(const FloatSize& pageSizeInPixels, bool allowHorizontalTiling);
// These are only valid after page rects are computed.
size_t pageCount() const { return m_pageRects.size(); }
const IntRect& pageRect(size_t pageNumber) const { return m_pageRects[pageNumber]; }
const Vector<IntRect>& pageRects() const { return m_pageRects; }
- WEBCORE_EXPORT float computeAutomaticScaleFactor(const FloatSize& availablePaperSize);
+ float computeAutomaticScaleFactor(const FloatSize& availablePaperSize);
// Enter print mode, updating layout for new page size.
// This function can be called multiple times to apply new print options without going back to screen mode.
- WEBCORE_EXPORT void begin(float width, float height = 0);
+ void begin(float width, float height = 0);
// FIXME: eliminate width argument.
- WEBCORE_EXPORT void spoolPage(GraphicsContext& ctx, int pageNumber, float width);
+ void spoolPage(GraphicsContext& ctx, int pageNumber, float width);
- WEBCORE_EXPORT void spoolRect(GraphicsContext& ctx, const IntRect&);
+ void spoolRect(GraphicsContext& ctx, const IntRect&);
// Return to screen mode.
- WEBCORE_EXPORT void end();
+ void end();
// Used by layout tests.
- WEBCORE_EXPORT static int pageNumberForElement(Element*, const FloatSize& pageSizeInPixels); // Returns -1 if page isn't found.
- WEBCORE_EXPORT static String pageProperty(Frame*, const char* propertyName, int pageNumber);
- WEBCORE_EXPORT static bool isPageBoxVisible(Frame*, int pageNumber);
- WEBCORE_EXPORT static String pageSizeAndMarginsInPixels(Frame*, int pageNumber, int width, int height, int marginTop, int marginRight, int marginBottom, int marginLeft);
- WEBCORE_EXPORT static int numberOfPages(Frame&, const FloatSize& pageSizeInPixels);
+ static int pageNumberForElement(Element*, const FloatSize& pageSizeInPixels); // Returns -1 if page isn't found.
+ static String pageProperty(Frame* frame, const char* propertyName, int pageNumber);
+ static bool isPageBoxVisible(Frame* frame, int pageNumber);
+ static String pageSizeAndMarginsInPixels(Frame* frame, int pageNumber, int width, int height, int marginTop, int marginRight, int marginBottom, int marginLeft);
+ static int numberOfPages(Frame*, const FloatSize& pageSizeInPixels);
// Draw all pages into a graphics context with lines which mean page boundaries.
// The height of the graphics context should be
// (pageSizeInPixels.height() + 1) * number-of-pages - 1
- WEBCORE_EXPORT static void spoolAllPagesWithBoundaries(Frame&, GraphicsContext&, const FloatSize& pageSizeInPixels);
+ static void spoolAllPagesWithBoundaries(Frame*, GraphicsContext&, const FloatSize& pageSizeInPixels);
protected:
Frame* m_frame;
@@ -85,7 +85,6 @@ protected:
private:
void computePageRectsWithPageSizeInternal(const FloatSize& pageSizeInPixels, bool allowHorizontalTiling);
- bool beginAndComputePageRectsWithPageSize(Frame&, const FloatSize& pageSizeInPixels);
// Used to prevent misuses of begin() and end() (e.g., call end without begin).
bool m_isPrinting;
diff --git a/Source/WebCore/page/ResourceUsageData.cpp b/Source/WebCore/page/ResourceUsageData.cpp
deleted file mode 100644
index c9759ccb9..000000000
--- a/Source/WebCore/page/ResourceUsageData.cpp
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2016 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "ResourceUsageData.h"
-
-#if ENABLE(RESOURCE_USAGE)
-
-namespace WebCore {
-
-ResourceUsageData::ResourceUsageData()
-{
- // VM tag categories.
- categories[MemoryCategory::JSJIT] = MemoryCategoryInfo(MemoryCategory::JSJIT);
- categories[MemoryCategory::Images] = MemoryCategoryInfo(MemoryCategory::Images);
- categories[MemoryCategory::Layers] = MemoryCategoryInfo(MemoryCategory::Layers);
- categories[MemoryCategory::LibcMalloc] = MemoryCategoryInfo(MemoryCategory::LibcMalloc);
- categories[MemoryCategory::bmalloc] = MemoryCategoryInfo(MemoryCategory::bmalloc);
- categories[MemoryCategory::Other] = MemoryCategoryInfo(MemoryCategory::Other);
-
- // Sub categories (e.g breakdown of bmalloc tag.)
- categories[MemoryCategory::GCHeap] = MemoryCategoryInfo(MemoryCategory::GCHeap, true);
- categories[MemoryCategory::GCOwned] = MemoryCategoryInfo(MemoryCategory::GCOwned, true);
-}
-
-ResourceUsageData::ResourceUsageData(const ResourceUsageData& other)
- : cpu(other.cpu)
- , totalDirtySize(other.totalDirtySize)
- , timeOfNextEdenCollection(other.timeOfNextEdenCollection)
- , timeOfNextFullCollection(other.timeOfNextFullCollection)
-{
- std::copy(other.categories.begin(), other.categories.end(), categories.begin());
-}
-
-}
-
-#endif // ENABLE(RESOURCE_USAGE)
diff --git a/Source/WebCore/page/ResourceUsageData.h b/Source/WebCore/page/ResourceUsageData.h
deleted file mode 100644
index 1c809443f..000000000
--- a/Source/WebCore/page/ResourceUsageData.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2016 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef ResourceUsageData_h
-#define ResourceUsageData_h
-
-#if ENABLE(RESOURCE_USAGE)
-
-#include <array>
-
-namespace WebCore {
-
-namespace MemoryCategory {
-static const unsigned bmalloc = 0;
-static const unsigned LibcMalloc = 1;
-static const unsigned JSJIT = 2;
-static const unsigned Images = 3;
-static const unsigned GCHeap = 4;
-static const unsigned GCOwned = 5;
-static const unsigned Other = 6;
-static const unsigned Layers = 7;
-static const unsigned NumberOfCategories = 8;
-}
-
-struct MemoryCategoryInfo {
- MemoryCategoryInfo() { } // Needed for std::array.
- MemoryCategoryInfo(unsigned category, bool subcategory = false)
- : isSubcategory(subcategory)
- , type(category)
- {
- }
-
- size_t dirtySize { 0 };
- size_t reclaimableSize { 0 };
- bool isSubcategory { false };
- unsigned type { MemoryCategory::NumberOfCategories };
-};
-
-struct ResourceUsageData {
- ResourceUsageData();
- ResourceUsageData(const ResourceUsageData& data);
-
- float cpu { 0 };
- size_t totalDirtySize { 0 };
- std::array<MemoryCategoryInfo, MemoryCategory::NumberOfCategories> categories;
- double timeOfNextEdenCollection { 0 };
- double timeOfNextFullCollection { 0 };
-};
-
-} // namespace WebCore
-
-#endif // ResourceUsageData_h
-
-#endif // ENABLE(RESOURCE_USAGE)
diff --git a/Source/WebCore/page/ResourceUsageOverlay.cpp b/Source/WebCore/page/ResourceUsageOverlay.cpp
deleted file mode 100644
index 79da01fb0..000000000
--- a/Source/WebCore/page/ResourceUsageOverlay.cpp
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#if ENABLE(RESOURCE_USAGE)
-
-#include "ResourceUsageOverlay.h"
-
-#include "FrameView.h"
-#include "PageOverlayController.h"
-#include "PlatformMouseEvent.h"
-
-namespace WebCore {
-
-ResourceUsageOverlay::ResourceUsageOverlay(Page& page)
- : m_page(page)
- , m_overlay(PageOverlay::create(*this, PageOverlay::OverlayType::View))
-{
- // Let the event loop cycle before continuing with initialization.
- // This way we'll have access to the FrameView's dimensions.
- callOnMainThread([this] {
- initialize();
- });
-}
-
-ResourceUsageOverlay::~ResourceUsageOverlay()
-{
- platformDestroy();
-
- // FIXME: This is a hack so we don't try to uninstall the PageOverlay during Page destruction.
- if (m_page.mainFrame().page())
- m_page.mainFrame().pageOverlayController().uninstallPageOverlay(m_overlay.get(), PageOverlay::FadeMode::DoNotFade);
-}
-
-void ResourceUsageOverlay::initialize()
-{
- if (!m_page.mainFrame().view())
- return;
-
- FrameView& frameView = *m_page.mainFrame().view();
-
- IntRect initialRect(frameView.width() / 2 - normalWidth / 2, frameView.height() - normalHeight - 20, normalWidth, normalHeight);
-
-#if PLATFORM(IOS)
- // FIXME: The overlay should be stuck to the viewport instead of moving along with the page.
- initialRect.setY(20);
-#endif
-
- m_overlay->setFrame(initialRect);
- m_overlay->setShouldIgnoreMouseEventsOutsideBounds(false);
- m_page.mainFrame().pageOverlayController().installPageOverlay(m_overlay.get(), PageOverlay::FadeMode::DoNotFade);
- platformInitialize();
-}
-
-bool ResourceUsageOverlay::mouseEvent(PageOverlay&, const PlatformMouseEvent& event)
-{
- if (event.button() != LeftButton)
- return false;
-
- switch (event.type()) {
- case PlatformEvent::MousePressed: {
- m_overlay->setShouldIgnoreMouseEventsOutsideBounds(false);
- m_dragging = true;
- IntPoint location = m_overlay->frame().location();
- m_dragPoint = event.position() + IntPoint(-location.x(), -location.y());
- return true;
- }
- case PlatformEvent::MouseReleased:
- if (m_dragging) {
- m_overlay->setShouldIgnoreMouseEventsOutsideBounds(true);
- m_dragging = false;
- return true;
- }
- break;
- case PlatformEvent::MouseMoved:
- if (m_dragging) {
- IntRect newFrame = m_overlay->frame();
-
- // Move the new frame relative to the point where the drag was initiated.
- newFrame.setLocation(event.position());
- newFrame.moveBy(IntPoint(-m_dragPoint.x(), -m_dragPoint.y()));
-
- // Force the frame to stay inside the viewport entirely.
- if (newFrame.x() < 0)
- newFrame.setX(0);
- if (newFrame.y() < m_page.topContentInset())
- newFrame.setY(m_page.topContentInset());
- FrameView& frameView = *m_page.mainFrame().view();
- if (newFrame.maxX() > frameView.width())
- newFrame.setX(frameView.width() - newFrame.width());
- if (newFrame.maxY() > frameView.height())
- newFrame.setY(frameView.height() - newFrame.height());
-
- m_overlay->setFrame(newFrame);
- m_overlay->setNeedsDisplay();
- return true;
- }
- break;
- default:
- break;
- }
- return false;
-}
-
-}
-
-#endif
diff --git a/Source/WebCore/page/ResourceUsageOverlay.h b/Source/WebCore/page/ResourceUsageOverlay.h
deleted file mode 100644
index e039dee8e..000000000
--- a/Source/WebCore/page/ResourceUsageOverlay.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef ResourceUsageOverlay_h
-#define ResourceUsageOverlay_h
-
-#if ENABLE(RESOURCE_USAGE)
-
-#include "FloatRect.h"
-#include "IntRect.h"
-#include "MainFrame.h"
-#include "PageOverlay.h"
-#include <wtf/Noncopyable.h>
-#include <wtf/RetainPtr.h>
-
-#if PLATFORM(COCOA)
-#include "PlatformCALayer.h"
-#endif
-
-namespace WebCore {
-
-class FloatRect;
-class IntPoint;
-class IntRect;
-
-class ResourceUsageOverlay final : public PageOverlay::Client {
- WTF_MAKE_FAST_ALLOCATED;
- WTF_MAKE_NONCOPYABLE(ResourceUsageOverlay);
-public:
- explicit ResourceUsageOverlay(Page&);
- ~ResourceUsageOverlay();
-
- PageOverlay& overlay() { return *m_overlay; }
-
-#if PLATFORM(COCOA)
- void platformDraw(CGContextRef);
-#endif
-
- static const int normalWidth = 570;
- static const int normalHeight = 160;
-
-private:
- void pageOverlayDestroyed(PageOverlay&) override { }
- void willMoveToPage(PageOverlay&, Page*) override { }
- void didMoveToPage(PageOverlay&, Page*) override { }
- void drawRect(PageOverlay&, GraphicsContext&, const IntRect&) override { }
- bool mouseEvent(PageOverlay&, const PlatformMouseEvent&) override;
- void didScrollFrame(PageOverlay&, Frame&) override { }
-
- void initialize();
-
- void platformInitialize();
- void platformDestroy();
-
- Page& m_page;
- RefPtr<PageOverlay> m_overlay;
- bool m_dragging { false };
- IntPoint m_dragPoint;
-
-#if PLATFORM(COCOA)
- ThreadIdentifier m_threadID { 0 };
- RetainPtr<CALayer> m_layer;
- RetainPtr<CALayer> m_containerLayer;
-#endif
-};
-
-}
-
-#endif
-
-#endif
diff --git a/Source/WebCore/page/ResourceUsageThread.cpp b/Source/WebCore/page/ResourceUsageThread.cpp
deleted file mode 100644
index 23500be2a..000000000
--- a/Source/WebCore/page/ResourceUsageThread.cpp
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright (C) 2016 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "ResourceUsageThread.h"
-
-#if ENABLE(RESOURCE_USAGE)
-
-#include "JSDOMWindow.h"
-#include <thread>
-#include <wtf/MainThread.h>
-#include <wtf/Vector.h>
-
-namespace WebCore {
-
-ResourceUsageThread::ResourceUsageThread()
-{
-}
-
-ResourceUsageThread& ResourceUsageThread::singleton()
-{
- static NeverDestroyed<ResourceUsageThread> resourceUsageThread;
- return resourceUsageThread;
-}
-
-void ResourceUsageThread::addObserver(void* key, std::function<void (const ResourceUsageData&)> function)
-{
- auto& resourceUsageThread = ResourceUsageThread::singleton();
- resourceUsageThread.createThreadIfNeeded();
-
- {
- LockHolder locker(resourceUsageThread.m_lock);
- bool wasEmpty = resourceUsageThread.m_observers.isEmpty();
- resourceUsageThread.m_observers.set(key, function);
-
- if (wasEmpty)
- resourceUsageThread.m_condition.notifyAll();
- }
-}
-
-void ResourceUsageThread::removeObserver(void* key)
-{
- auto& resourceUsageThread = ResourceUsageThread::singleton();
-
- {
- LockHolder locker(resourceUsageThread.m_lock);
- resourceUsageThread.m_observers.remove(key);
- }
-}
-
-void ResourceUsageThread::waitUntilObservers()
-{
- LockHolder locker(m_lock);
- while (m_observers.isEmpty())
- m_condition.wait(m_lock);
-}
-
-void ResourceUsageThread::notifyObservers(ResourceUsageData& data)
-{
- callOnMainThread([data]() mutable {
- Vector<std::function<void (const ResourceUsageData&)>> functions;
-
- {
- auto& resourceUsageThread = ResourceUsageThread::singleton();
- LockHolder locker(resourceUsageThread.m_lock);
- copyValuesToVector(resourceUsageThread.m_observers, functions);
- }
-
- for (auto& function : functions)
- function(data);
- });
-}
-
-void ResourceUsageThread::createThreadIfNeeded()
-{
- if (m_threadIdentifier)
- return;
-
- m_vm = &JSDOMWindow::commonVM();
- m_threadIdentifier = createThread(threadCallback, this, "WebCore: ResourceUsage");
-}
-
-void ResourceUsageThread::threadCallback(void* resourceUsageThread)
-{
- static_cast<ResourceUsageThread*>(resourceUsageThread)->threadBody();
-}
-
-NO_RETURN void ResourceUsageThread::threadBody()
-{
- while (true) {
- // Only do work if we have observers.
- waitUntilObservers();
-
- auto start = std::chrono::system_clock::now();
-
- ResourceUsageData data;
- platformThreadBody(m_vm, data);
- notifyObservers(data);
-
- auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - start);
- auto difference = std::chrono::milliseconds(500) - duration;
- std::this_thread::sleep_for(difference);
- }
-}
-
-} // namespace WebCore
-
-#endif // ENABLE(RESOURCE_USAGE)
diff --git a/Source/WebCore/page/ResourceUsageThread.h b/Source/WebCore/page/ResourceUsageThread.h
deleted file mode 100644
index fd2581afc..000000000
--- a/Source/WebCore/page/ResourceUsageThread.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2016 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef ResourceUsageThread_h
-#define ResourceUsageThread_h
-
-#if ENABLE(RESOURCE_USAGE)
-
-#include "ResourceUsageData.h"
-#include <array>
-#include <functional>
-#include <wtf/Condition.h>
-#include <wtf/HashMap.h>
-#include <wtf/Lock.h>
-#include <wtf/NeverDestroyed.h>
-#include <wtf/Noncopyable.h>
-
-namespace JSC {
-class VM;
-}
-
-namespace WebCore {
-
-class ResourceUsageThread {
- WTF_MAKE_NONCOPYABLE(ResourceUsageThread);
-
-public:
- static void addObserver(void* key, std::function<void (const ResourceUsageData&)>);
- static void removeObserver(void* key);
-
-private:
- friend NeverDestroyed<ResourceUsageThread>;
- ResourceUsageThread();
- static ResourceUsageThread& singleton();
-
- void waitUntilObservers();
- void notifyObservers(ResourceUsageData&);
-
- void createThreadIfNeeded();
- static void threadCallback(void* scrollingThread);
- void threadBody();
- void platformThreadBody(JSC::VM*, ResourceUsageData&);
-
- ThreadIdentifier m_threadIdentifier { 0 };
- Lock m_lock;
- Condition m_condition;
- HashMap<void*, std::function<void (const ResourceUsageData&)>> m_observers;
-
- // Platforms may need to access some data from the common VM.
- // They should ensure their use of the VM is thread safe.
- JSC::VM* m_vm { nullptr };
-};
-
-#if PLATFORM(COCOA)
-struct TagInfo {
- TagInfo() { }
- size_t dirty { 0 };
- size_t reclaimable { 0 };
-};
-
-const char* displayNameForVMTag(unsigned);
-std::array<TagInfo, 256> pagesPerVMTag();
-void logFootprintComparison(const std::array<TagInfo, 256>&, const std::array<TagInfo, 256>&);
-#endif
-
-} // namespace WebCore
-
-#endif // ENABLE(RESOURCE_USAGE)
-
-#endif // ResourceUsageThread_h
diff --git a/Source/WebCore/page/Screen.cpp b/Source/WebCore/page/Screen.cpp
index ff487d7ca..824a20032 100644
--- a/Source/WebCore/page/Screen.cpp
+++ b/Source/WebCore/page/Screen.cpp
@@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Inc. ("Apple") nor the names of
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
@@ -26,13 +26,17 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+
#include "config.h"
#include "Screen.h"
#include "FloatRect.h"
#include "Frame.h"
#include "FrameView.h"
+#include "InspectorInstrumentation.h"
#include "PlatformScreen.h"
+#include "Settings.h"
+#include "Widget.h"
namespace WebCore {
diff --git a/Source/WebCore/page/Screen.h b/Source/WebCore/page/Screen.h
index 0edcd1acd..c78850c1e 100644
--- a/Source/WebCore/page/Screen.h
+++ b/Source/WebCore/page/Screen.h
@@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Inc. ("Apple") nor the names of
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
@@ -37,24 +37,24 @@
namespace WebCore {
-class Frame;
+ class Frame;
-class Screen final : public ScriptWrappable, public RefCounted<Screen>, public DOMWindowProperty {
-public:
- static Ref<Screen> create(Frame* frame) { return adoptRef(*new Screen(frame)); }
+ class Screen : public ScriptWrappable, public RefCounted<Screen>, public DOMWindowProperty {
+ public:
+ static PassRefPtr<Screen> create(Frame *frame) { return adoptRef(new Screen(frame)); }
- unsigned height() const;
- unsigned width() const;
- unsigned colorDepth() const;
- unsigned pixelDepth() const;
- int availLeft() const;
- int availTop() const;
- unsigned availHeight() const;
- unsigned availWidth() const;
+ unsigned height() const;
+ unsigned width() const;
+ unsigned colorDepth() const;
+ unsigned pixelDepth() const;
+ int availLeft() const;
+ int availTop() const;
+ unsigned availHeight() const;
+ unsigned availWidth() const;
-private:
- explicit Screen(Frame*);
-};
+ private:
+ explicit Screen(Frame*);
+ };
} // namespace WebCore
diff --git a/Source/WebCore/page/Screen.idl b/Source/WebCore/page/Screen.idl
index 844850478..8ff1748b8 100644
--- a/Source/WebCore/page/Screen.idl
+++ b/Source/WebCore/page/Screen.idl
@@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Inc. ("Apple") nor the names of
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
@@ -30,13 +30,13 @@
[
GenerateIsReachable=ImplFrame,
] interface Screen {
- [Nondeterministic] readonly attribute unsigned long height;
- [Nondeterministic] readonly attribute unsigned long width;
- [Nondeterministic] readonly attribute unsigned long colorDepth;
- [Nondeterministic] readonly attribute unsigned long pixelDepth;
- [Nondeterministic] readonly attribute long availLeft;
- [Nondeterministic] readonly attribute long availTop;
- [Nondeterministic] readonly attribute unsigned long availHeight;
- [Nondeterministic] readonly attribute unsigned long availWidth;
+ readonly attribute unsigned long height;
+ readonly attribute unsigned long width;
+ readonly attribute unsigned long colorDepth;
+ readonly attribute unsigned long pixelDepth;
+ readonly attribute long availLeft;
+ readonly attribute long availTop;
+ readonly attribute unsigned long availHeight;
+ readonly attribute unsigned long availWidth;
};
diff --git a/Source/WebCore/page/SecurityOrigin.cpp b/Source/WebCore/page/SecurityOrigin.cpp
index 976c33f3f..2be30d44f 100644
--- a/Source/WebCore/page/SecurityOrigin.cpp
+++ b/Source/WebCore/page/SecurityOrigin.cpp
@@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Inc. ("Apple") nor the names of
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
@@ -36,7 +36,6 @@
#include "SecurityPolicy.h"
#include "ThreadableBlobRegistry.h"
#include <wtf/MainThread.h>
-#include <wtf/NeverDestroyed.h>
#include <wtf/StdLibExtras.h>
#include <wtf/text/StringBuilder.h>
@@ -55,9 +54,11 @@ static bool schemeRequiresHost(const URL& url)
bool SecurityOrigin::shouldUseInnerURL(const URL& url)
{
+#if ENABLE(BLOB)
// FIXME: Blob URLs don't have inner URLs. Their form is "blob:<inner-origin>/<UUID>", so treating the part after "blob:" as a URL is incorrect.
- if (url.protocolIsBlob())
+ if (url.protocolIs("blob"))
return true;
+#endif
UNUSED_PARAM(url);
return false;
}
@@ -74,11 +75,15 @@ URL SecurityOrigin::extractInnerURL(const URL& url)
return URL(ParsedURLString, decodeURLEscapeSequences(url.path()));
}
-static RefPtr<SecurityOrigin> getCachedOrigin(const URL& url)
+static PassRefPtr<SecurityOrigin> getCachedOrigin(const URL& url)
{
- if (url.protocolIsBlob())
+#if ENABLE(BLOB)
+ if (url.protocolIs("blob"))
return ThreadableBlobRegistry::getCachedOrigin(url);
- return nullptr;
+#else
+ UNUSED_PARAM(url);
+#endif
+ return 0;
}
static bool shouldTreatAsUniqueOrigin(const URL& url)
@@ -97,7 +102,11 @@ static bool shouldTreatAsUniqueOrigin(const URL& url)
if (schemeRequiresHost(innerURL) && innerURL.host().isEmpty())
return true;
- if (SchemeRegistry::shouldTreatURLSchemeAsNoAccess(innerURL.protocol()))
+ // SchemeRegistry needs a lower case protocol because it uses HashMaps
+ // that assume the scheme has already been canonicalized.
+ String protocol = innerURL.protocol().lower();
+
+ if (SchemeRegistry::shouldTreatURLSchemeAsNoAccess(protocol))
return true;
// This is the common case.
@@ -105,8 +114,8 @@ static bool shouldTreatAsUniqueOrigin(const URL& url)
}
SecurityOrigin::SecurityOrigin(const URL& url)
- : m_protocol(url.protocol().isNull() ? emptyString() : url.protocol().convertToASCIILowercase())
- , m_host(url.host().isNull() ? emptyString() : url.host().convertToASCIILowercase())
+ : m_protocol(url.protocol().isNull() ? "" : url.protocol().lower())
+ , m_host(url.host().isNull() ? "" : url.host().lower())
, m_port(url.port())
, m_isUnique(false)
, m_universalAccess(false)
@@ -129,9 +138,9 @@ SecurityOrigin::SecurityOrigin(const URL& url)
}
SecurityOrigin::SecurityOrigin()
- : m_protocol(emptyString())
- , m_host(emptyString())
- , m_domain(emptyString())
+ : m_protocol("")
+ , m_host("")
+ , m_domain("")
, m_port(InvalidPort)
, m_isUnique(true)
, m_universalAccess(false)
@@ -159,13 +168,14 @@ SecurityOrigin::SecurityOrigin(const SecurityOrigin* other)
{
}
-Ref<SecurityOrigin> SecurityOrigin::create(const URL& url)
+PassRefPtr<SecurityOrigin> SecurityOrigin::create(const URL& url)
{
- if (RefPtr<SecurityOrigin> cachedOrigin = getCachedOrigin(url))
- return cachedOrigin.releaseNonNull();
+ RefPtr<SecurityOrigin> cachedOrigin = getCachedOrigin(url);
+ if (cachedOrigin.get())
+ return cachedOrigin;
if (shouldTreatAsUniqueOrigin(url)) {
- Ref<SecurityOrigin> origin(adoptRef(*new SecurityOrigin));
+ RefPtr<SecurityOrigin> origin = adoptRef(new SecurityOrigin());
if (url.protocolIs("file")) {
// Unfortunately, we can't represent all unique origins exactly
@@ -175,31 +185,31 @@ Ref<SecurityOrigin> SecurityOrigin::create(const URL& url)
origin->m_needsDatabaseIdentifierQuirkForFiles = true;
}
- return origin;
+ return origin.release();
}
if (shouldUseInnerURL(url))
- return adoptRef(*new SecurityOrigin(extractInnerURL(url)));
+ return adoptRef(new SecurityOrigin(extractInnerURL(url)));
- return adoptRef(*new SecurityOrigin(url));
+ return adoptRef(new SecurityOrigin(url));
}
-Ref<SecurityOrigin> SecurityOrigin::createUnique()
+PassRefPtr<SecurityOrigin> SecurityOrigin::createUnique()
{
- Ref<SecurityOrigin> origin(adoptRef(*new SecurityOrigin));
- ASSERT(origin.get().isUnique());
- return origin;
+ RefPtr<SecurityOrigin> origin = adoptRef(new SecurityOrigin());
+ ASSERT(origin->isUnique());
+ return origin.release();
}
-Ref<SecurityOrigin> SecurityOrigin::isolatedCopy() const
+PassRefPtr<SecurityOrigin> SecurityOrigin::isolatedCopy() const
{
- return adoptRef(*new SecurityOrigin(this));
+ return adoptRef(new SecurityOrigin(this));
}
void SecurityOrigin::setDomainFromDOM(const String& newDomain)
{
m_domainWasSetInDOM = true;
- m_domain = newDomain.convertToASCIILowercase();
+ m_domain = newDomain.lower();
}
bool SecurityOrigin::isSecure(const URL& url)
@@ -284,17 +294,17 @@ bool SecurityOrigin::canRequest(const URL& url) const
if (isUnique())
return false;
- Ref<SecurityOrigin> targetOrigin(SecurityOrigin::create(url));
+ RefPtr<SecurityOrigin> targetOrigin = SecurityOrigin::create(url);
if (targetOrigin->isUnique())
return false;
// We call isSameSchemeHostPort here instead of canAccess because we want
// to ignore document.domain effects.
- if (isSameSchemeHostPort(&targetOrigin.get()))
+ if (isSameSchemeHostPort(targetOrigin.get()))
return true;
- if (SecurityPolicy::isAccessWhiteListed(this, &targetOrigin.get()))
+ if (SecurityPolicy::isAccessWhiteListed(this, targetOrigin.get()))
return true;
return false;
@@ -350,16 +360,16 @@ bool SecurityOrigin::canDisplay(const URL& url) const
if (m_universalAccess)
return true;
+ String protocol = url.protocol().lower();
+
if (isFeedWithNestedProtocolInHTTPFamily(url))
return true;
- String protocol = url.protocol();
-
if (SchemeRegistry::canDisplayOnlyIfCanRequest(protocol))
return canRequest(url);
if (SchemeRegistry::shouldTreatURLSchemeAsDisplayIsolated(protocol))
- return equalIgnoringASCIICase(m_protocol, protocol) || SecurityPolicy::isAccessToURLWhiteListed(this, url);
+ return m_protocol == protocol || SecurityPolicy::isAccessToURLWhiteListed(this, url);
if (SecurityPolicy::restrictAccessToLocal() && SchemeRegistry::shouldTreatURLSchemeAsLocal(protocol))
return canLoadLocalResources() || SecurityPolicy::isAccessToURLWhiteListed(this, url);
@@ -375,11 +385,6 @@ bool SecurityOrigin::canAccessStorage(const SecurityOrigin* topOrigin, ShouldAll
if (m_storageBlockingPolicy == BlockAllStorage)
return false;
- // We allow access to local storage from file URLs also when allowFileAccessFromFileURLs setting is enabled,
- // for backwards compatibility only in WebKitGTK+ 2.12 branch, this should not be backported to any other branch, nor trunk.
- if (isLocal() && !m_universalAccess && m_enforceFilePathSeparation && shouldAllowFromThirdParty != AlwaysAllowFromThirdParty)
- return false;
-
// FIXME: This check should be replaced with an ASSERT once we can guarantee that topOrigin is not null.
if (!topOrigin)
return true;
@@ -434,18 +439,15 @@ void SecurityOrigin::grantUniversalAccess()
}
#if ENABLE(CACHE_PARTITIONING)
-String SecurityOrigin::domainForCachePartition() const
+String SecurityOrigin::cachePartition() const
{
if (m_storageBlockingPolicy != BlockThirdPartyStorage)
return String();
- if (isHTTPFamily())
- return host();
-
- if (SchemeRegistry::shouldPartitionCacheForURLScheme(m_protocol))
- return host();
+ if (m_protocol != "http" && m_protocol != "https")
+ return String();
- return String();
+ return host();
}
#endif
@@ -463,9 +465,9 @@ bool SecurityOrigin::isLocal() const
String SecurityOrigin::toString() const
{
if (isUnique())
- return ASCIILiteral("null");
+ return "null";
if (m_protocol == "file" && m_enforceFilePathSeparation)
- return ASCIILiteral("null");
+ return "null";
return toRawString();
}
@@ -477,7 +479,7 @@ String SecurityOrigin::toRawString() const
StringBuilder result;
result.reserveCapacity(m_protocol.length() + m_host.length() + 10);
result.append(m_protocol);
- result.appendLiteral("://");
+ result.append("://");
result.append(m_host);
if (m_port) {
@@ -488,40 +490,40 @@ String SecurityOrigin::toRawString() const
return result.toString();
}
-Ref<SecurityOrigin> SecurityOrigin::createFromString(const String& originString)
+PassRefPtr<SecurityOrigin> SecurityOrigin::createFromString(const String& originString)
{
return SecurityOrigin::create(URL(URL(), originString));
}
static const char separatorCharacter = '_';
-RefPtr<SecurityOrigin> SecurityOrigin::maybeCreateFromDatabaseIdentifier(const String& databaseIdentifier)
+PassRefPtr<SecurityOrigin> SecurityOrigin::createFromDatabaseIdentifier(const String& databaseIdentifier)
{
// Make sure there's a first separator
size_t separator1 = databaseIdentifier.find(separatorCharacter);
if (separator1 == notFound)
- return nullptr;
+ return create(URL());
// Make sure there's a second separator
size_t separator2 = databaseIdentifier.reverseFind(separatorCharacter);
if (separator2 == notFound)
- return nullptr;
-
+ return create(URL());
+
// Ensure there were at least 2 separator characters. Some hostnames on intranets have
// underscores in them, so we'll assume that any additional underscores are part of the host.
if (separator1 == separator2)
- return nullptr;
-
+ return create(URL());
+
// Make sure the port section is a valid port number or doesn't exist
bool portOkay;
int port = databaseIdentifier.right(databaseIdentifier.length() - separator2 - 1).toInt(&portOkay);
bool portAbsent = (separator2 == databaseIdentifier.length() - 1);
if (!(portOkay || portAbsent))
- return nullptr;
-
+ return create(URL());
+
if (port < 0 || port > MaxAllowedPort)
- return nullptr;
-
+ return create(URL());
+
// Split out the 3 sections of data
String protocol = databaseIdentifier.substring(0, separator1);
String host = databaseIdentifier.substring(separator1 + 1, separator2 - separator1 - 1);
@@ -530,14 +532,7 @@ RefPtr<SecurityOrigin> SecurityOrigin::maybeCreateFromDatabaseIdentifier(const S
return create(URL(URL(), protocol + "://" + host + ":" + String::number(port) + "/"));
}
-Ref<SecurityOrigin> SecurityOrigin::createFromDatabaseIdentifier(const String& databaseIdentifier)
-{
- if (RefPtr<SecurityOrigin> origin = maybeCreateFromDatabaseIdentifier(databaseIdentifier))
- return origin.releaseNonNull();
- return create(URL());
-}
-
-Ref<SecurityOrigin> SecurityOrigin::create(const String& protocol, const String& host, int port)
+PassRefPtr<SecurityOrigin> SecurityOrigin::create(const String& protocol, const String& host, int port)
{
if (port < 0 || port > MaxAllowedPort)
return createUnique();
@@ -553,7 +548,7 @@ String SecurityOrigin::databaseIdentifier() const
// Now that we've fixed that bug, we still need to produce this string
// to avoid breaking existing persistent state.
if (m_needsDatabaseIdentifierQuirkForFiles)
- return ASCIILiteral("file__0");
+ return "file__0";
StringBuilder stringBuilder;
stringBuilder.append(m_protocol);
@@ -599,10 +594,10 @@ bool SecurityOrigin::isSameSchemeHostPort(const SecurityOrigin* other) const
return true;
}
-URL SecurityOrigin::urlWithUniqueSecurityOrigin()
+String SecurityOrigin::urlWithUniqueSecurityOrigin()
{
ASSERT(isMainThread());
- static NeverDestroyed<URL> uniqueSecurityOriginURL(ParsedURLString, ASCIILiteral("data:,"));
+ DEFINE_STATIC_LOCAL(const String, uniqueSecurityOriginURL, (ASCIILiteral("data:,")));
return uniqueSecurityOriginURL;
}
diff --git a/Source/WebCore/page/SecurityOrigin.h b/Source/WebCore/page/SecurityOrigin.h
index f1108d512..d11866de0 100644
--- a/Source/WebCore/page/SecurityOrigin.h
+++ b/Source/WebCore/page/SecurityOrigin.h
@@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Inc. ("Apple") nor the names of
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
@@ -50,17 +50,12 @@ public:
BlockAllStorage
};
- WEBCORE_EXPORT static Ref<SecurityOrigin> create(const URL&);
- static Ref<SecurityOrigin> createUnique();
+ static PassRefPtr<SecurityOrigin> create(const URL&);
+ static PassRefPtr<SecurityOrigin> createUnique();
- WEBCORE_EXPORT static Ref<SecurityOrigin> createFromDatabaseIdentifier(const String&);
- // Alternate form of createFromDatabaseIdentifier that returns a nullptr on failure, instead of an empty origin.
- // FIXME: Many users of createFromDatabaseIdentifier seem to expect maybeCreateFromDatabaseIdentifier behavior,
- // but they aren't getting it so they might be buggy.
- WEBCORE_EXPORT static RefPtr<SecurityOrigin> maybeCreateFromDatabaseIdentifier(const String&);
-
- WEBCORE_EXPORT static Ref<SecurityOrigin> createFromString(const String&);
- WEBCORE_EXPORT static Ref<SecurityOrigin> create(const String& protocol, const String& host, int port);
+ static PassRefPtr<SecurityOrigin> createFromDatabaseIdentifier(const String&);
+ static PassRefPtr<SecurityOrigin> createFromString(const String&);
+ static PassRefPtr<SecurityOrigin> create(const String& protocol, const String& host, int port);
// Some URL schemes use nested URLs for their security context. For example,
// filesystem URLs look like the following:
@@ -77,7 +72,7 @@ public:
// Create a deep copy of this SecurityOrigin. This method is useful
// when marshalling a SecurityOrigin to another thread.
- WEBCORE_EXPORT Ref<SecurityOrigin> isolatedCopy() const;
+ PassRefPtr<SecurityOrigin> isolatedCopy() const;
// Set the domain property of this security origin to newDomain. This
// function does not check whether newDomain is a suffix of the current
@@ -99,7 +94,7 @@ public:
// SecurityOrigin. For example, call this function before allowing
// script from one security origin to read or write objects from
// another SecurityOrigin.
- WEBCORE_EXPORT bool canAccess(const SecurityOrigin*) const;
+ bool canAccess(const SecurityOrigin*) const;
// Returns true if this SecurityOrigin can read content retrieved from
// the given URL. For example, call this function before issuing
@@ -119,7 +114,7 @@ public:
// Returns true if |document| can display content from the given URL (e.g.,
// in an iframe or as an image). For example, web sites generally cannot
// display content from the user's files system.
- WEBCORE_EXPORT bool canDisplay(const URL&) const;
+ bool canDisplay(const URL&) const;
// Returns true if this SecurityOrigin can load local resources, such
// as images, iframes, and style sheets, and can link to local URLs.
@@ -147,22 +142,24 @@ public:
void setStorageBlockingPolicy(StorageBlockingPolicy policy) { m_storageBlockingPolicy = policy; }
#if ENABLE(CACHE_PARTITIONING)
- WEBCORE_EXPORT String domainForCachePartition() const;
+ String cachePartition() const;
#endif
- bool canAccessDatabase(const SecurityOrigin* topOrigin = nullptr) const { return canAccessStorage(topOrigin); };
+ bool canAccessDatabase(const SecurityOrigin* topOrigin = 0) const { return canAccessStorage(topOrigin); };
bool canAccessSessionStorage(const SecurityOrigin* topOrigin) const { return canAccessStorage(topOrigin, AlwaysAllowFromThirdParty); }
bool canAccessLocalStorage(const SecurityOrigin* topOrigin) const { return canAccessStorage(topOrigin); };
+ bool canAccessSharedWorkers(const SecurityOrigin* topOrigin) const { return canAccessStorage(topOrigin); }
bool canAccessPluginStorage(const SecurityOrigin* topOrigin) const { return canAccessStorage(topOrigin); }
bool canAccessApplicationCache(const SecurityOrigin* topOrigin) const { return canAccessStorage(topOrigin); }
bool canAccessCookies() const { return !isUnique(); }
- bool canRequestGeolocation() const { return !isUnique(); }
+ bool canAccessPasswordManager() const { return !isUnique(); }
+ bool canAccessFileSystem() const { return !isUnique(); }
Policy canShowNotifications() const;
// The local SecurityOrigin is the most privileged SecurityOrigin.
// The local SecurityOrigin can script any document, navigate to local
// resources, and can set arbitrary headers on XMLHttpRequests.
- WEBCORE_EXPORT bool isLocal() const;
+ bool isLocal() const;
// The origin is a globally unique identifier assigned when the Document is
// created. http://www.whatwg.org/specs/web-apps/current-work/#sandboxOrigin
@@ -187,28 +184,28 @@ public:
// this SecurityOrigin might have come from a sandboxed iframe, the
// SecurityOrigin might be empty, or we might have explicitly decided that
// we shouldTreatURLSchemeAsNoAccess.
- WEBCORE_EXPORT String toString() const;
+ String toString() const;
// Similar to toString(), but does not take into account any factors that
// could make the string return "null".
- WEBCORE_EXPORT String toRawString() const;
+ String toRawString() const;
// Serialize the security origin to a string that could be used as part of
// file names. This format should be used in storage APIs only.
- WEBCORE_EXPORT String databaseIdentifier() const;
+ String databaseIdentifier() const;
// This method checks for equality between SecurityOrigins, not whether
// one origin can access another. It is used for hash table keys.
// For access checks, use canAccess().
// FIXME: If this method is really only useful for hash table keys, it
// should be refactored into SecurityOriginHash.
- WEBCORE_EXPORT bool equal(const SecurityOrigin*) const;
+ bool equal(const SecurityOrigin*) const;
// This method checks for equality, ignoring the value of document.domain
// (and whether it was set) but considering the host. It is used for postMessage.
- WEBCORE_EXPORT bool isSameSchemeHostPort(const SecurityOrigin*) const;
+ bool isSameSchemeHostPort(const SecurityOrigin*) const;
- static URL urlWithUniqueSecurityOrigin();
+ static String urlWithUniqueSecurityOrigin();
private:
SecurityOrigin();
@@ -218,13 +215,9 @@ private:
// FIXME: Rename this function to something more semantic.
bool passesFileCheck(const SecurityOrigin*) const;
bool isThirdParty(const SecurityOrigin*) const;
-
- // This method checks that the scheme for this origin is an HTTP-family
- // scheme, e.g. HTTP and HTTPS.
- bool isHTTPFamily() const { return m_protocol == "http" || m_protocol == "https"; }
enum ShouldAllowFromThirdParty { AlwaysAllowFromThirdParty, MaybeAllowFromThirdParty };
- WEBCORE_EXPORT bool canAccessStorage(const SecurityOrigin*, ShouldAllowFromThirdParty = MaybeAllowFromThirdParty) const;
+ bool canAccessStorage(const SecurityOrigin*, ShouldAllowFromThirdParty = MaybeAllowFromThirdParty) const;
String m_protocol;
String m_host;
diff --git a/Source/WebCore/page/SecurityOriginData.cpp b/Source/WebCore/page/SecurityOriginData.cpp
deleted file mode 100644
index 839647f87..000000000
--- a/Source/WebCore/page/SecurityOriginData.cpp
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (C) 2011, 2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "SecurityOriginData.h"
-
-#include "Document.h"
-#include "Frame.h"
-#include "SecurityOrigin.h"
-#include <wtf/text/CString.h>
-
-using namespace WebCore;
-
-namespace WebCore {
-
-SecurityOriginData SecurityOriginData::fromSecurityOrigin(const SecurityOrigin& securityOrigin)
-{
- SecurityOriginData securityOriginData;
-
- securityOriginData.protocol = securityOrigin.protocol();
- securityOriginData.host = securityOrigin.host();
- securityOriginData.port = securityOrigin.port();
-
- return securityOriginData;
-}
-
-#ifndef NDEBUG
-String SecurityOriginData::debugString() const
-{
- return makeString(protocol, "://", host, ":", String::number(port));
-}
-#endif
-
-SecurityOriginData SecurityOriginData::fromFrame(Frame* frame)
-{
- if (!frame)
- return SecurityOriginData();
-
- Document* document = frame->document();
- if (!document)
- return SecurityOriginData();
-
- SecurityOrigin* origin = document->securityOrigin();
- if (!origin)
- return SecurityOriginData();
-
- return SecurityOriginData::fromSecurityOrigin(*origin);
-}
-
-Ref<SecurityOrigin> SecurityOriginData::securityOrigin() const
-{
- return SecurityOrigin::create(protocol.isolatedCopy(), host.isolatedCopy(), port);
-}
-
-SecurityOriginData SecurityOriginData::isolatedCopy() const
-{
- SecurityOriginData result;
-
- result.protocol = protocol.isolatedCopy();
- result.host = host.isolatedCopy();
- result.port = port;
-
- return result;
-}
-
-bool operator==(const SecurityOriginData& a, const SecurityOriginData& b)
-{
- if (&a == &b)
- return true;
-
- return a.protocol == b.protocol
- && a.host == b.host
- && a.port == b.port;
-}
-
-} // namespace WebCore
diff --git a/Source/WebCore/page/SecurityOriginData.h b/Source/WebCore/page/SecurityOriginData.h
deleted file mode 100644
index b6eb16593..000000000
--- a/Source/WebCore/page/SecurityOriginData.h
+++ /dev/null
@@ -1,83 +0,0 @@
- /*
- * Copyright (C) 2011, 2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef SecurityOriginData_h
-#define SecurityOriginData_h
-
-#include <wtf/text/WTFString.h>
-
-namespace WebCore {
-class Frame;
-class SecurityOrigin;
-
-struct SecurityOriginData {
- WEBCORE_EXPORT static SecurityOriginData fromSecurityOrigin(const SecurityOrigin&);
- WEBCORE_EXPORT static SecurityOriginData fromFrame(Frame*);
-
- WEBCORE_EXPORT Ref<SecurityOrigin> securityOrigin() const;
-
- // FIXME <rdar://9018386>: We should be sending more state across the wire than just the protocol,
- // host, and port.
-
- String protocol;
- String host;
- int port { 0 };
-
- WEBCORE_EXPORT SecurityOriginData isolatedCopy() const;
-
- template<class Encoder> void encode(Encoder&) const;
- template<class Decoder> static bool decode(Decoder&, SecurityOriginData&);
-
-#ifndef NDEBUG
- String debugString() const;
-#endif
-};
-
-WEBCORE_EXPORT bool operator==(const SecurityOriginData&, const SecurityOriginData&);
-
-template<class Encoder>
-void SecurityOriginData::encode(Encoder& encoder) const
-{
- encoder << protocol;
- encoder << host;
- encoder << port;
-}
-
-template<class Decoder>
-bool SecurityOriginData::decode(Decoder& decoder, SecurityOriginData& securityOriginData)
-{
- if (!decoder.decode(securityOriginData.protocol))
- return false;
- if (!decoder.decode(securityOriginData.host))
- return false;
- if (!decoder.decode(securityOriginData.port))
- return false;
-
- return true;
-}
-
-} // namespace WebCore
-
-#endif // SecurityOriginData_h
diff --git a/Source/WebCore/page/SecurityOriginHash.h b/Source/WebCore/page/SecurityOriginHash.h
index 05efef7bd..9886c7d04 100644
--- a/Source/WebCore/page/SecurityOriginHash.h
+++ b/Source/WebCore/page/SecurityOriginHash.h
@@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Inc. ("Apple") nor the names of
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
diff --git a/Source/WebCore/page/SecurityPolicy.cpp b/Source/WebCore/page/SecurityPolicy.cpp
index 3bd320056..9d18879f6 100644
--- a/Source/WebCore/page/SecurityPolicy.cpp
+++ b/Source/WebCore/page/SecurityPolicy.cpp
@@ -33,8 +33,8 @@
#include <wtf/MainThread.h>
#include "OriginAccessEntry.h"
#include "SecurityOrigin.h"
-#include <memory>
-#include <wtf/NeverDestroyed.h>
+#include <wtf/OwnPtr.h>
+#include <wtf/PassOwnPtr.h>
#include <wtf/text/StringHash.h>
namespace WebCore {
@@ -42,11 +42,11 @@ namespace WebCore {
static SecurityPolicy::LocalLoadPolicy localLoadPolicy = SecurityPolicy::AllowLocalLoadsForLocalOnly;
typedef Vector<OriginAccessEntry> OriginAccessWhiteList;
-typedef HashMap<String, std::unique_ptr<OriginAccessWhiteList>> OriginAccessMap;
+typedef HashMap<String, OwnPtr<OriginAccessWhiteList>> OriginAccessMap;
static OriginAccessMap& originAccessMap()
{
- static NeverDestroyed<OriginAccessMap> originAccessMap;
+ DEFINE_STATIC_LOCAL(OriginAccessMap, originAccessMap, ());
return originAccessMap;
}
@@ -112,18 +112,18 @@ bool SecurityPolicy::allowSubstituteDataAccessToLocal()
bool SecurityPolicy::isAccessWhiteListed(const SecurityOrigin* activeOrigin, const SecurityOrigin* targetOrigin)
{
if (OriginAccessWhiteList* list = originAccessMap().get(activeOrigin->toString())) {
- for (auto& entry : *list) {
- if (entry.matchesOrigin(*targetOrigin))
- return true;
- }
+ for (size_t i = 0; i < list->size(); ++i) {
+ if (list->at(i).matchesOrigin(*targetOrigin))
+ return true;
+ }
}
return false;
}
bool SecurityPolicy::isAccessToURLWhiteListed(const SecurityOrigin* activeOrigin, const URL& url)
{
- Ref<SecurityOrigin> targetOrigin(SecurityOrigin::create(url));
- return isAccessWhiteListed(activeOrigin, &targetOrigin.get());
+ RefPtr<SecurityOrigin> targetOrigin = SecurityOrigin::create(url);
+ return isAccessWhiteListed(activeOrigin, targetOrigin.get());
}
void SecurityPolicy::addOriginAccessWhitelistEntry(const SecurityOrigin& sourceOrigin, const String& destinationProtocol, const String& destinationDomain, bool allowDestinationSubdomains)
@@ -136,7 +136,7 @@ void SecurityPolicy::addOriginAccessWhitelistEntry(const SecurityOrigin& sourceO
String sourceString = sourceOrigin.toString();
OriginAccessMap::AddResult result = originAccessMap().add(sourceString, nullptr);
if (result.isNewEntry)
- result.iterator->value = std::make_unique<OriginAccessWhiteList>();
+ result.iterator->value = adoptPtr(new OriginAccessWhiteList);
OriginAccessWhiteList* list = result.iterator->value.get();
list->append(OriginAccessEntry(destinationProtocol, destinationDomain, allowDestinationSubdomains ? OriginAccessEntry::AllowSubdomains : OriginAccessEntry::DisallowSubdomains));
@@ -155,12 +155,14 @@ void SecurityPolicy::removeOriginAccessWhitelistEntry(const SecurityOrigin& sour
if (it == map.end())
return;
- OriginAccessWhiteList& list = *it->value;
- OriginAccessEntry originAccessEntry(destinationProtocol, destinationDomain, allowDestinationSubdomains ? OriginAccessEntry::AllowSubdomains : OriginAccessEntry::DisallowSubdomains);
- if (!list.removeFirst(originAccessEntry))
+ OriginAccessWhiteList* list = it->value.get();
+ size_t index = list->find(OriginAccessEntry(destinationProtocol, destinationDomain, allowDestinationSubdomains ? OriginAccessEntry::AllowSubdomains : OriginAccessEntry::DisallowSubdomains));
+ if (index == notFound)
return;
- if (list.isEmpty())
+ list->remove(index);
+
+ if (list->isEmpty())
map.remove(it);
}
diff --git a/Source/WebCore/page/SecurityPolicy.h b/Source/WebCore/page/SecurityPolicy.h
index 7679c9fbb..b269c1af5 100644
--- a/Source/WebCore/page/SecurityPolicy.h
+++ b/Source/WebCore/page/SecurityPolicy.h
@@ -42,12 +42,12 @@ public:
// True if the referrer should be omitted according to the
// ReferrerPolicyDefault. If you intend to send a referrer header, you
// should use generateReferrerHeader instead.
- WEBCORE_EXPORT static bool shouldHideReferrer(const URL&, const String& referrer);
+ static bool shouldHideReferrer(const URL&, const String& referrer);
// Returns the referrer modified according to the referrer policy for a
// navigation to a given URL. If the referrer returned is empty, the
// referrer header should be omitted.
- WEBCORE_EXPORT static String generateReferrerHeader(ReferrerPolicy, const URL&, const String& referrer);
+ static String generateReferrerHeader(ReferrerPolicy, const URL&, const String& referrer);
enum LocalLoadPolicy {
AllowLocalLoadsForAll, // No restriction on local loads.
@@ -55,13 +55,13 @@ public:
AllowLocalLoadsForLocalOnly,
};
- WEBCORE_EXPORT static void setLocalLoadPolicy(LocalLoadPolicy);
+ static void setLocalLoadPolicy(LocalLoadPolicy);
static bool restrictAccessToLocal();
static bool allowSubstituteDataAccessToLocal();
- WEBCORE_EXPORT static void addOriginAccessWhitelistEntry(const SecurityOrigin& sourceOrigin, const String& destinationProtocol, const String& destinationDomain, bool allowDestinationSubdomains);
- WEBCORE_EXPORT static void removeOriginAccessWhitelistEntry(const SecurityOrigin& sourceOrigin, const String& destinationProtocol, const String& destinationDomain, bool allowDestinationSubdomains);
- WEBCORE_EXPORT static void resetOriginAccessWhitelists();
+ static void addOriginAccessWhitelistEntry(const SecurityOrigin& sourceOrigin, const String& destinationProtocol, const String& destinationDomain, bool allowDestinationSubdomains);
+ static void removeOriginAccessWhitelistEntry(const SecurityOrigin& sourceOrigin, const String& destinationProtocol, const String& destinationDomain, bool allowDestinationSubdomains);
+ static void resetOriginAccessWhitelists();
static bool isAccessWhiteListed(const SecurityOrigin* activeOrigin, const SecurityOrigin* targetOrigin);
static bool isAccessToURLWhiteListed(const SecurityOrigin* activeOrigin, const URL&);
diff --git a/Source/WebCore/page/SessionID.h b/Source/WebCore/page/SessionID.h
deleted file mode 100644
index 0dbaa1b47..000000000
--- a/Source/WebCore/page/SessionID.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef SessionID_h
-#define SessionID_h
-
-#include <wtf/HashFunctions.h>
-#include <wtf/HashTraits.h>
-
-namespace WebCore {
-
-class SessionID {
-public:
- SessionID()
- : SessionID(emptySessionID()) { }
- explicit SessionID(uint64_t sessionID)
- : m_sessionID(sessionID) { }
- bool isValid() const { return *this != emptySessionID(); }
- bool isEphemeral() const { return *this != defaultSessionID(); }
- uint64_t sessionID() const { return m_sessionID; }
- bool operator==(SessionID sessionID) const { return m_sessionID == sessionID.m_sessionID; }
- bool operator!=(SessionID sessionID) const { return m_sessionID != sessionID.m_sessionID; }
-
- static SessionID emptySessionID() { return SessionID(0); }
- static SessionID defaultSessionID() { return SessionID(1); }
- static SessionID legacyPrivateSessionID() { return SessionID(2); }
-private:
- uint64_t m_sessionID;
-};
-
-}
-
-namespace WTF {
-
-// The empty value is emptySessionID(), the deleted value is (-1)
-struct SessionIDHash {
- static unsigned hash(const WebCore::SessionID& p) { return intHash(p.sessionID()); }
- static bool equal(const WebCore::SessionID& a, const WebCore::SessionID& b) { return a == b; }
- static const bool safeToCompareToEmptyOrDeleted = true;
-};
-template<> struct HashTraits<WebCore::SessionID> : GenericHashTraits<WebCore::SessionID> {
- static const uint64_t deletedValueIdentifier = std::numeric_limits<uint64_t>::max();
- static WebCore::SessionID emptyValue() { return WebCore::SessionID::emptySessionID(); }
-
- static void constructDeletedValue(WebCore::SessionID& slot) { slot = WebCore::SessionID(deletedValueIdentifier); }
- static bool isDeletedValue(const WebCore::SessionID& slot) { return slot == WebCore::SessionID(deletedValueIdentifier); }
-};
-template<> struct DefaultHash<WebCore::SessionID> {
- typedef SessionIDHash Hash;
-};
-
-}
-
-#endif // SessionID_h
diff --git a/Source/WebCore/page/Settings.cpp b/Source/WebCore/page/Settings.cpp
index edec940c0..681c3a69d 100644
--- a/Source/WebCore/page/Settings.cpp
+++ b/Source/WebCore/page/Settings.cpp
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -33,7 +33,7 @@
#include "DOMTimer.h"
#include "Database.h"
#include "Document.h"
-#include "FontCascade.h"
+#include "Font.h"
#include "FontGenericFamilies.h"
#include "FrameTree.h"
#include "FrameView.h"
@@ -49,10 +49,6 @@
#include <wtf/NeverDestroyed.h>
#include <wtf/StdLibExtras.h>
-#if ENABLE(MEDIA_STREAM)
-#include "MockRealtimeMediaSourceCenter.h"
-#endif
-
namespace WebCore {
static void setImageLoadingSettings(Page* page)
@@ -61,64 +57,62 @@ static void setImageLoadingSettings(Page* page)
return;
for (Frame* frame = &page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
- if (!frame->document())
- continue;
- frame->document()->cachedResourceLoader().setImagesEnabled(page->settings().areImagesEnabled());
- frame->document()->cachedResourceLoader().setAutoLoadImages(page->settings().loadsImagesAutomatically());
+ frame->document()->cachedResourceLoader()->setImagesEnabled(page->settings().areImagesEnabled());
+ frame->document()->cachedResourceLoader()->setAutoLoadImages(page->settings().loadsImagesAutomatically());
}
}
static void invalidateAfterGenericFamilyChange(Page* page)
{
- invalidateFontCascadeCache();
+ invalidateFontGlyphsCache();
if (page)
page->setNeedsRecalcStyleInAllFrames();
}
+double Settings::gDefaultMinDOMTimerInterval = 0.010; // 10 milliseconds
+double Settings::gDefaultDOMTimerAlignmentInterval = 0;
+double Settings::gHiddenPageDOMTimerAlignmentInterval = 1.0;
+
+#if USE(SAFARI_THEME)
+bool Settings::gShouldPaintNativeControls = true;
+#endif
+
#if USE(AVFOUNDATION)
-bool Settings::gAVFoundationEnabled = true;
-bool Settings::gAVFoundationNSURLSessionEnabled = false;
+bool Settings::gAVFoundationEnabled = false;
+#endif
+
+#if PLATFORM(MAC)
+bool Settings::gQTKitEnabled = true;
#endif
-#if PLATFORM(COCOA)
-bool Settings::gQTKitEnabled = false;
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+bool Settings::gVideoPluginProxyEnabled = true;
#endif
bool Settings::gMockScrollbarsEnabled = false;
bool Settings::gUsesOverlayScrollbars = false;
-bool Settings::gMockScrollAnimatorEnabled = false;
-
-#if ENABLE(MEDIA_STREAM)
-bool Settings::gMockCaptureDevicesEnabled = false;
-#endif
#if PLATFORM(WIN)
bool Settings::gShouldUseHighResolutionTimers = true;
#endif
-bool Settings::gShouldRewriteConstAsVar = false;
bool Settings::gShouldRespectPriorityInCSSAttributeSetters = false;
bool Settings::gLowPowerVideoAudioBufferSizeEnabled = false;
-bool Settings::gResourceLoadStatisticsEnabledEnabled = false;
#if PLATFORM(IOS)
bool Settings::gNetworkDataUsageTrackingEnabled = false;
bool Settings::gAVKitEnabled = false;
-bool Settings::gShouldOptOutOfNetworkStateObservation = false;
-bool Settings::gManageAudioSession = false;
#endif
// NOTEs
// 1) EditingMacBehavior comprises Tiger, Leopard, SnowLeopard and iOS builds, as well as QtWebKit when built on Mac;
-// 2) EditingWindowsBehavior comprises Win32 build;
+// 2) EditingWindowsBehavior comprises Win32 and WinCE builds, as well as QtWebKit and Chromium when built on Windows;
// 3) EditingUnixBehavior comprises all unix-based systems, but Darwin/MacOS (and then abusing the terminology);
// 99) MacEditingBehavior is used as a fallback.
static EditingBehaviorType editingBehaviorTypeForPlatform()
{
return
-#if PLATFORM(IOS)
- EditingIOSBehavior
-#elif OS(DARWIN)
+#if OS(DARWIN)
EditingMacBehavior
#elif OS(WINDOWS)
EditingWindowsBehavior
@@ -133,34 +127,16 @@ static EditingBehaviorType editingBehaviorTypeForPlatform()
#if PLATFORM(IOS)
static const bool defaultFixedPositionCreatesStackingContext = true;
-static const bool defaultFixedBackgroundsPaintRelativeToDocument = true;
-static const bool defaultAcceleratedCompositingForFixedPositionEnabled = true;
-static const bool defaultAllowsInlineMediaPlayback = false;
-static const bool defaultInlineMediaPlaybackRequiresPlaysInlineAttribute = true;
-static const bool defaultRequiresUserGestureForMediaPlayback = true;
-static const bool defaultAudioPlaybackRequiresUserGesture = true;
-static const bool defaultMediaDataLoadsAutomatically = false;
+static const bool defaultMediaPlaybackAllowsInline = false;
+static const bool defaultMediaPlaybackRequiresUserGesture = true;
static const bool defaultShouldRespectImageOrientation = true;
-static const bool defaultImageSubsamplingEnabled = true;
-static const bool defaultScrollingTreeIncludesFrames = true;
-static const bool defaultMediaControlsScaleWithPageZoom = true;
#else
static const bool defaultFixedPositionCreatesStackingContext = false;
-static const bool defaultFixedBackgroundsPaintRelativeToDocument = false;
-static const bool defaultAcceleratedCompositingForFixedPositionEnabled = false;
-static const bool defaultAllowsInlineMediaPlayback = true;
-static const bool defaultInlineMediaPlaybackRequiresPlaysInlineAttribute = false;
-static const bool defaultRequiresUserGestureForMediaPlayback = false;
-static const bool defaultAudioPlaybackRequiresUserGesture = false;
-static const bool defaultMediaDataLoadsAutomatically = true;
+static const bool defaultMediaPlaybackAllowsInline = true;
+static const bool defaultMediaPlaybackRequiresUserGesture = false;
static const bool defaultShouldRespectImageOrientation = false;
-static const bool defaultImageSubsamplingEnabled = false;
-static const bool defaultScrollingTreeIncludesFrames = false;
-static const bool defaultMediaControlsScaleWithPageZoom = true;
#endif
-static const bool defaultAllowsPictureInPictureMediaPlayback = true;
-
static const double defaultIncrementalRenderingSuppressionTimeoutInSeconds = 5;
#if USE(UNIFIED_TEXT_CHECKING)
static const bool defaultUnifiedTextCheckerEnabled = true;
@@ -176,12 +152,14 @@ static const bool defaultSelectTrailingWhitespaceEnabled = false;
static const auto layoutScheduleThreshold = std::chrono::milliseconds(250);
Settings::Settings(Page* page)
- : m_page(nullptr)
+ : m_page(0)
, m_mediaTypeOverride("screen")
, m_fontGenericFamilies(std::make_unique<FontGenericFamilies>())
, m_storageBlockingPolicy(SecurityOrigin::AllowAllStorage)
, m_layoutInterval(layoutScheduleThreshold)
- , m_minimumDOMTimerInterval(DOMTimer::defaultMinimumInterval())
+#if PLATFORM(IOS)
+ , m_maxParseDuration(-1)
+#endif
#if ENABLE(TEXT_AUTOSIZING)
, m_textAutosizingFontScaleFactor(1)
#if HACK_FORCE_TEXT_AUTOSIZING_ON_DESKTOP
@@ -192,31 +170,47 @@ Settings::Settings(Page* page)
#endif
#endif
SETTINGS_INITIALIZER_LIST
+ , m_screenFontSubstitutionEnabled(shouldEnableScreenFontSubstitutionByDefault())
, m_isJavaEnabled(false)
, m_isJavaEnabledForLocalFiles(true)
, m_loadsImagesAutomatically(false)
+ , m_privateBrowsingEnabled(false)
, m_areImagesEnabled(true)
, m_arePluginsEnabled(false)
, m_isScriptEnabled(false)
, m_needsAdobeFrameReloadingQuirk(false)
, m_usesPageCache(false)
, m_fontRenderingMode(0)
- , m_antialiasedFontDilationEnabled(false)
+#if PLATFORM(IOS)
+ , m_standalone(false)
+ , m_telephoneNumberParsingEnabled(false)
+ , m_mediaDataLoadsAutomatically(false)
+ , m_shouldTransformsAffectOverflow(true)
+ , m_shouldDispatchJavaScriptWindowOnErrorEvents(false)
+ , m_alwaysUseBaselineOfPrimaryFont(false)
+ , m_alwaysUseAcceleratedOverflowScroll(false)
+#endif
+#if ENABLE(CSS_STICKY_POSITION)
+ , m_cssStickyPositionEnabled(true)
+#endif
, m_showTiledScrollingIndicator(false)
+ , m_tiledBackingStoreEnabled(false)
, m_backgroundShouldExtendBeyondPage(false)
, m_dnsPrefetchingEnabled(false)
#if ENABLE(TOUCH_EVENTS)
, m_touchEventEmulationEnabled(false)
#endif
, m_scrollingPerformanceLoggingEnabled(false)
+ , m_aggressiveTileRetentionEnabled(false)
, m_timeWithoutMouseMovementBeforeHidingControls(3)
- , m_setImageLoadingSettingsTimer(*this, &Settings::imageLoadingSettingsTimerFired)
+ , m_setImageLoadingSettingsTimer(this, &Settings::imageLoadingSettingsTimerFired)
#if ENABLE(HIDDEN_PAGE_DOM_TIMER_THROTTLING)
, m_hiddenPageDOMTimerThrottlingEnabled(false)
#endif
+#if ENABLE(PAGE_VISIBILITY_API)
, m_hiddenPageCSSAnimationSuspensionEnabled(false)
+#endif
, m_fontFallbackPrefersPictographs(false)
- , m_forcePendingWebGLPolicy(false)
{
// A Frame may not have been created yet, so we initialize the AtomicString
// hash before trying to use it.
@@ -229,14 +223,31 @@ Settings::~Settings()
{
}
-Ref<Settings> Settings::create(Page* page)
+PassRefPtr<Settings> Settings::create(Page* page)
{
- return adoptRef(*new Settings(page));
+ return adoptRef(new Settings(page));
}
SETTINGS_SETTER_BODIES
-#if !PLATFORM(COCOA)
+void Settings::setHiddenPageDOMTimerAlignmentInterval(double hiddenPageDOMTimerAlignmentinterval)
+{
+ gHiddenPageDOMTimerAlignmentInterval = hiddenPageDOMTimerAlignmentinterval;
+}
+
+double Settings::hiddenPageDOMTimerAlignmentInterval()
+{
+ return gHiddenPageDOMTimerAlignmentInterval;
+}
+
+#if !PLATFORM(MAC)
+bool Settings::shouldEnableScreenFontSubstitutionByDefault()
+{
+ return true;
+}
+#endif
+
+#if !PLATFORM(MAC)
void Settings::initializeDefaultFontFamilies()
{
// Other platforms can set up fonts from a client, but on Mac, we want it in WebCore to share code between WebKit1 and WebKit2.
@@ -364,12 +375,6 @@ void Settings::setTextAutosizingFontScaleFactor(float fontScaleFactor)
#endif
-void Settings::setAntialiasedFontDilationEnabled(bool enabled)
-{
- // FIXME: It's wrong for a setting to toggle a global, but this code is temporary.
- FontCascade::setAntialiasedFontDilationEnabled(enabled);
-}
-
void Settings::setMediaTypeOverride(const String& mediaTypeOverride)
{
if (m_mediaTypeOverride == mediaTypeOverride)
@@ -401,15 +406,17 @@ void Settings::setLoadsImagesAutomatically(bool loadsImagesAutomatically)
m_setImageLoadingSettingsTimer.startOneShot(0);
}
-void Settings::imageLoadingSettingsTimerFired()
+void Settings::imageLoadingSettingsTimerFired(Timer<Settings>*)
{
setImageLoadingSettings(m_page);
}
void Settings::setScriptEnabled(bool isScriptEnabled)
{
+#if PLATFORM(IOS)
if (m_isScriptEnabled == isScriptEnabled)
return;
+#endif
m_isScriptEnabled = isScriptEnabled;
@@ -419,7 +426,7 @@ void Settings::setScriptEnabled(bool isScriptEnabled)
#if PLATFORM(IOS)
m_page->setNeedsRecalcStyleInAllFrames();
#endif
- InspectorInstrumentation::scriptsEnabled(*m_page, m_isScriptEnabled);
+ InspectorInstrumentation::scriptsEnabled(m_page, m_isScriptEnabled);
}
void Settings::setJavaEnabled(bool isJavaEnabled)
@@ -440,11 +447,6 @@ void Settings::setImagesEnabled(bool areImagesEnabled)
m_setImageLoadingSettingsTimer.startOneShot(0);
}
-void Settings::setForcePendingWebGLPolicy(bool forced)
-{
- m_forcePendingWebGLPolicy = forced;
-}
-
void Settings::setPluginsEnabled(bool arePluginsEnabled)
{
if (m_arePluginsEnabled == arePluginsEnabled)
@@ -454,6 +456,16 @@ void Settings::setPluginsEnabled(bool arePluginsEnabled)
Page::refreshPlugins(false);
}
+void Settings::setPrivateBrowsingEnabled(bool privateBrowsingEnabled)
+{
+ if (m_privateBrowsingEnabled == privateBrowsingEnabled)
+ return;
+
+ m_privateBrowsingEnabled = privateBrowsingEnabled;
+ if (m_page)
+ m_page->privateBrowsingStateChanged();
+}
+
void Settings::setUserStyleSheetLocation(const URL& userStyleSheetLocation)
{
if (m_userStyleSheetLocation == userStyleSheetLocation)
@@ -472,18 +484,50 @@ void Settings::setNeedsAdobeFrameReloadingQuirk(bool shouldNotReloadIFramesForUn
m_needsAdobeFrameReloadingQuirk = shouldNotReloadIFramesForUnchangedSRC;
}
-void Settings::setMinimumDOMTimerInterval(double interval)
+void Settings::setDefaultMinDOMTimerInterval(double interval)
+{
+ gDefaultMinDOMTimerInterval = interval;
+}
+
+double Settings::defaultMinDOMTimerInterval()
{
- double oldTimerInterval = m_minimumDOMTimerInterval;
- m_minimumDOMTimerInterval = interval;
+ return gDefaultMinDOMTimerInterval;
+}
+
+void Settings::setMinDOMTimerInterval(double interval)
+{
+ if (m_page)
+ m_page->setMinimumTimerInterval(interval);
+}
+double Settings::minDOMTimerInterval()
+{
if (!m_page)
- return;
+ return 0;
+ return m_page->minimumTimerInterval();
+}
- for (Frame* frame = &m_page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
- if (frame->document())
- frame->document()->adjustMinimumTimerInterval(oldTimerInterval);
- }
+void Settings::setDefaultDOMTimerAlignmentInterval(double interval)
+{
+ gDefaultDOMTimerAlignmentInterval = interval;
+}
+
+double Settings::defaultDOMTimerAlignmentInterval()
+{
+ return gDefaultDOMTimerAlignmentInterval;
+}
+
+void Settings::setDOMTimerAlignmentInterval(double interval)
+{
+ if (m_page)
+ m_page->setTimerAlignmentInterval(interval);
+}
+
+double Settings::domTimerAlignmentInterval() const
+{
+ if (!m_page)
+ return 0;
+ return m_page->timerAlignmentInterval();
}
void Settings::setLayoutInterval(std::chrono::milliseconds layoutInterval)
@@ -503,15 +547,29 @@ void Settings::setUsesPageCache(bool usesPageCache)
if (!m_page)
return;
- if (!m_usesPageCache)
- PageCache::singleton().pruneToSizeNow(0, PruningReason::None);
+ if (!m_usesPageCache) {
+ int first = -m_page->backForward().backCount();
+ int last = m_page->backForward().forwardCount();
+ for (int i = first; i <= last; i++)
+ pageCache()->remove(m_page->backForward().itemAtIndex(i));
+ }
+}
+
+void Settings::setScreenFontSubstitutionEnabled(bool enabled)
+{
+ if (m_screenFontSubstitutionEnabled == enabled)
+ return;
+ m_screenFontSubstitutionEnabled = enabled;
+
+ if (m_page)
+ m_page->setNeedsRecalcStyleInAllFrames();
}
void Settings::setFontRenderingMode(FontRenderingMode mode)
{
if (fontRenderingMode() == mode)
return;
- m_fontRenderingMode = static_cast<int>(mode);
+ m_fontRenderingMode = mode;
if (m_page)
m_page->setNeedsRecalcStyleInAllFrames();
}
@@ -521,6 +579,13 @@ FontRenderingMode Settings::fontRenderingMode() const
return static_cast<FontRenderingMode>(m_fontRenderingMode);
}
+#if USE(SAFARI_THEME)
+void Settings::setShouldPaintNativeControls(bool shouldPaintNativeControls)
+{
+ gShouldPaintNativeControls = shouldPaintNativeControls;
+}
+#endif
+
void Settings::setDNSPrefetchingEnabled(bool dnsPrefetchingEnabled)
{
if (m_dnsPrefetchingEnabled == dnsPrefetchingEnabled)
@@ -539,18 +604,6 @@ void Settings::setShowTiledScrollingIndicator(bool enabled)
m_showTiledScrollingIndicator = enabled;
}
-#if ENABLE(RESOURCE_USAGE)
-void Settings::setResourceUsageOverlayVisible(bool visible)
-{
- if (m_resourceUsageOverlayVisible == visible)
- return;
-
- m_resourceUsageOverlayVisible = visible;
- if (m_page)
- m_page->setResourceUsageOverlayVisible(visible);
-}
-#endif
-
#if PLATFORM(WIN)
void Settings::setShouldUseHighResolutionTimers(bool shouldUseHighResolutionTimers)
{
@@ -568,6 +621,15 @@ void Settings::setStorageBlockingPolicy(SecurityOrigin::StorageBlockingPolicy en
m_page->storageBlockingStateChanged();
}
+void Settings::setTiledBackingStoreEnabled(bool enabled)
+{
+ m_tiledBackingStoreEnabled = enabled;
+#if USE(TILED_BACKING_STORE)
+ if (m_page)
+ m_page->mainFrame().setTiledBackingStoreEnabled(enabled);
+#endif
+}
+
void Settings::setBackgroundShouldExtendBeyondPage(bool shouldExtend)
{
if (m_backgroundShouldExtendBeyondPage == shouldExtend)
@@ -575,8 +637,10 @@ void Settings::setBackgroundShouldExtendBeyondPage(bool shouldExtend)
m_backgroundShouldExtendBeyondPage = shouldExtend;
+#if USE(ACCELERATED_COMPOSITING)
if (m_page)
- m_page->mainFrame().view()->updateExtendBackgroundIfNecessary();
+ m_page->mainFrame().view()->setBackgroundExtendsBeyondPage(shouldExtend);
+#endif
}
#if USE(AVFOUNDATION)
@@ -588,17 +652,9 @@ void Settings::setAVFoundationEnabled(bool enabled)
gAVFoundationEnabled = enabled;
HTMLMediaElement::resetMediaEngines();
}
-
-void Settings::setAVFoundationNSURLSessionEnabled(bool enabled)
-{
- if (gAVFoundationNSURLSessionEnabled == enabled)
- return;
-
- gAVFoundationNSURLSessionEnabled = enabled;
-}
#endif
-#if PLATFORM(COCOA)
+#if PLATFORM(MAC)
void Settings::setQTKitEnabled(bool enabled)
{
if (gQTKitEnabled == enabled)
@@ -609,16 +665,14 @@ void Settings::setQTKitEnabled(bool enabled)
}
#endif
-#if ENABLE(MEDIA_STREAM)
-bool Settings::mockCaptureDevicesEnabled()
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+void Settings::setVideoPluginProxyEnabled(bool enabled)
{
- return gMockCaptureDevicesEnabled;
-}
+ if (gVideoPluginProxyEnabled == enabled)
+ return;
-void Settings::setMockCaptureDevicesEnabled(bool enabled)
-{
- gMockCaptureDevicesEnabled = enabled;
- MockRealtimeMediaSourceCenter::setMockRealtimeMediaSourceCenterEnabled(enabled);
+ gVideoPluginProxyEnabled = enabled;
+ HTMLMediaElement::resetMediaEngines();
}
#endif
@@ -629,6 +683,11 @@ void Settings::setScrollingPerformanceLoggingEnabled(bool enabled)
if (m_page && m_page->mainFrame().view())
m_page->mainFrame().view()->setScrollingPerformanceLoggingEnabled(enabled);
}
+
+void Settings::setAggressiveTileRetentionEnabled(bool enabled)
+{
+ m_aggressiveTileRetentionEnabled = enabled;
+}
void Settings::setMockScrollbarsEnabled(bool flag)
{
@@ -652,16 +711,6 @@ bool Settings::usesOverlayScrollbars()
return gUsesOverlayScrollbars;
}
-void Settings::setUsesMockScrollAnimator(bool flag)
-{
- gMockScrollAnimatorEnabled = flag;
-}
-
-bool Settings::usesMockScrollAnimator()
-{
- return gMockScrollAnimatorEnabled;
-}
-
void Settings::setShouldRespectPriorityInCSSAttributeSetters(bool flag)
{
gShouldRespectPriorityInCSSAttributeSetters = flag;
@@ -683,6 +732,7 @@ void Settings::setHiddenPageDOMTimerThrottlingEnabled(bool flag)
}
#endif
+#if ENABLE(PAGE_VISIBILITY_API)
void Settings::setHiddenPageCSSAnimationSuspensionEnabled(bool flag)
{
if (m_hiddenPageCSSAnimationSuspensionEnabled == flag)
@@ -691,6 +741,7 @@ void Settings::setHiddenPageCSSAnimationSuspensionEnabled(bool flag)
if (m_page)
m_page->hiddenPageCSSAnimationSuspensionStateChanged();
}
+#endif
void Settings::setFontFallbackPrefersPictographs(bool preferPictographs)
{
@@ -707,12 +758,12 @@ void Settings::setLowPowerVideoAudioBufferSizeEnabled(bool flag)
gLowPowerVideoAudioBufferSizeEnabled = flag;
}
-void Settings::setResourceLoadStatisticsEnabled(bool flag)
+#if PLATFORM(IOS)
+void Settings::setStandalone(bool standalone)
{
- gResourceLoadStatisticsEnabledEnabled = flag;
+ m_standalone = standalone;
}
-#if PLATFORM(IOS)
void Settings::setAudioSessionCategoryOverride(unsigned sessionCategory)
{
AudioSession::sharedSession().setCategoryOverride(static_cast<AudioSession::CategoryType>(sessionCategory));
diff --git a/Source/WebCore/page/Settings.h b/Source/WebCore/page/Settings.h
index 147062c16..a3e527d52 100644
--- a/Source/WebCore/page/Settings.h
+++ b/Source/WebCore/page/Settings.h
@@ -11,10 +11,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -28,23 +28,18 @@
#define Settings_h
#include "EditingBehaviorTypes.h"
+#include "FontRenderingMode.h"
#include "IntSize.h"
#include "URL.h"
#include "SecurityOrigin.h"
#include "SettingsMacros.h"
-#include "TextFlags.h"
#include "Timer.h"
#include <chrono>
-#include <runtime/RuntimeFlags.h>
-#include <unicode/uscript.h>
#include <wtf/HashMap.h>
#include <wtf/RefCounted.h>
#include <wtf/text/AtomicString.h>
#include <wtf/text/AtomicStringHash.h>
-
-#if ENABLE(DATA_DETECTION)
-#include "DataDetection.h"
-#endif
+#include <wtf/unicode/Unicode.h>
namespace WebCore {
@@ -65,41 +60,34 @@ enum TextDirectionSubmenuInclusionBehavior {
TextDirectionSubmenuAlwaysIncluded
};
-enum DebugOverlayRegionFlags {
- NonFastScrollableRegion = 1 << 0,
- WheelEventHandlerRegion = 1 << 1,
-};
-
-typedef unsigned DebugOverlayRegions;
-
class Settings : public RefCounted<Settings> {
WTF_MAKE_NONCOPYABLE(Settings); WTF_MAKE_FAST_ALLOCATED;
public:
- static Ref<Settings> create(Page*);
+ static PassRefPtr<Settings> create(Page*);
~Settings();
void pageDestroyed() { m_page = nullptr; }
- WEBCORE_EXPORT void setStandardFontFamily(const AtomicString&, UScriptCode = USCRIPT_COMMON);
- WEBCORE_EXPORT const AtomicString& standardFontFamily(UScriptCode = USCRIPT_COMMON) const;
+ void setStandardFontFamily(const AtomicString&, UScriptCode = USCRIPT_COMMON);
+ const AtomicString& standardFontFamily(UScriptCode = USCRIPT_COMMON) const;
- WEBCORE_EXPORT void setFixedFontFamily(const AtomicString&, UScriptCode = USCRIPT_COMMON);
- WEBCORE_EXPORT const AtomicString& fixedFontFamily(UScriptCode = USCRIPT_COMMON) const;
+ void setFixedFontFamily(const AtomicString&, UScriptCode = USCRIPT_COMMON);
+ const AtomicString& fixedFontFamily(UScriptCode = USCRIPT_COMMON) const;
- WEBCORE_EXPORT void setSerifFontFamily(const AtomicString&, UScriptCode = USCRIPT_COMMON);
- WEBCORE_EXPORT const AtomicString& serifFontFamily(UScriptCode = USCRIPT_COMMON) const;
+ void setSerifFontFamily(const AtomicString&, UScriptCode = USCRIPT_COMMON);
+ const AtomicString& serifFontFamily(UScriptCode = USCRIPT_COMMON) const;
- WEBCORE_EXPORT void setSansSerifFontFamily(const AtomicString&, UScriptCode = USCRIPT_COMMON);
- WEBCORE_EXPORT const AtomicString& sansSerifFontFamily(UScriptCode = USCRIPT_COMMON) const;
+ void setSansSerifFontFamily(const AtomicString&, UScriptCode = USCRIPT_COMMON);
+ const AtomicString& sansSerifFontFamily(UScriptCode = USCRIPT_COMMON) const;
- WEBCORE_EXPORT void setCursiveFontFamily(const AtomicString&, UScriptCode = USCRIPT_COMMON);
- WEBCORE_EXPORT const AtomicString& cursiveFontFamily(UScriptCode = USCRIPT_COMMON) const;
+ void setCursiveFontFamily(const AtomicString&, UScriptCode = USCRIPT_COMMON);
+ const AtomicString& cursiveFontFamily(UScriptCode = USCRIPT_COMMON) const;
- WEBCORE_EXPORT void setFantasyFontFamily(const AtomicString&, UScriptCode = USCRIPT_COMMON);
- WEBCORE_EXPORT const AtomicString& fantasyFontFamily(UScriptCode = USCRIPT_COMMON) const;
+ void setFantasyFontFamily(const AtomicString&, UScriptCode = USCRIPT_COMMON);
+ const AtomicString& fantasyFontFamily(UScriptCode = USCRIPT_COMMON) const;
- WEBCORE_EXPORT void setPictographFontFamily(const AtomicString&, UScriptCode = USCRIPT_COMMON);
- WEBCORE_EXPORT const AtomicString& pictographFontFamily(UScriptCode = USCRIPT_COMMON) const;
+ void setPictographFontFamily(const AtomicString&, UScriptCode = USCRIPT_COMMON);
+ const AtomicString& pictographFontFamily(UScriptCode = USCRIPT_COMMON) const;
#if ENABLE(TEXT_AUTOSIZING)
void setTextAutosizingEnabled(bool);
@@ -113,185 +101,221 @@ public:
const IntSize& textAutosizingWindowSizeOverride() const { return m_textAutosizingWindowSizeOverride; }
#endif
- WEBCORE_EXPORT void setAntialiasedFontDilationEnabled(bool);
- bool antialiasedFontDilationEnabled() const { return m_antialiasedFontDilationEnabled; }
-
// Only set by Layout Tests.
- WEBCORE_EXPORT void setMediaTypeOverride(const String&);
+ void setMediaTypeOverride(const String&);
const String& mediaTypeOverride() const { return m_mediaTypeOverride; }
// Unlike areImagesEnabled, this only suppresses the network load of
// the image URL. A cached image will still be rendered if requested.
- WEBCORE_EXPORT void setLoadsImagesAutomatically(bool);
+ void setLoadsImagesAutomatically(bool);
bool loadsImagesAutomatically() const { return m_loadsImagesAutomatically; }
// Clients that execute script should call ScriptController::canExecuteScripts()
// instead of this function. ScriptController::canExecuteScripts() checks the
// HTML sandbox, plug-in sandboxing, and other important details.
bool isScriptEnabled() const { return m_isScriptEnabled; }
- WEBCORE_EXPORT void setScriptEnabled(bool);
+ void setScriptEnabled(bool);
SETTINGS_GETTERS_AND_SETTERS
- WEBCORE_EXPORT void setJavaEnabled(bool);
+ void setScreenFontSubstitutionEnabled(bool);
+ bool screenFontSubstitutionEnabled() const { return m_screenFontSubstitutionEnabled; }
+
+ void setJavaEnabled(bool);
bool isJavaEnabled() const { return m_isJavaEnabled; }
// This settings is only consulted if isJavaEnabled() returns true;
- WEBCORE_EXPORT void setJavaEnabledForLocalFiles(bool);
+ void setJavaEnabledForLocalFiles(bool);
bool isJavaEnabledForLocalFiles() const { return m_isJavaEnabledForLocalFiles; }
- WEBCORE_EXPORT void setImagesEnabled(bool);
+ void setImagesEnabled(bool);
bool areImagesEnabled() const { return m_areImagesEnabled; }
- WEBCORE_EXPORT void setPluginsEnabled(bool);
+ void setPluginsEnabled(bool);
bool arePluginsEnabled() const { return m_arePluginsEnabled; }
- WEBCORE_EXPORT void setDNSPrefetchingEnabled(bool);
+ // When this option is set, WebCore will avoid storing any record of browsing activity
+ // that may persist on disk or remain displayed when the option is reset.
+ // This option does not affect the storage of such information in RAM.
+ // The following functions respect this setting:
+ // - HTML5/DOM Storage
+ // - Icon Database
+ // - Console Messages
+ // - MemoryCache
+ // - Application Cache
+ // - Back/Forward Page History
+ // - Page Search Results
+ // - HTTP Cookies
+ // - Plug-ins (that support NPNVprivateModeBool)
+ void setPrivateBrowsingEnabled(bool);
+ bool privateBrowsingEnabled() const { return m_privateBrowsingEnabled; }
+
+ void setDNSPrefetchingEnabled(bool);
bool dnsPrefetchingEnabled() const { return m_dnsPrefetchingEnabled; }
- WEBCORE_EXPORT void setUserStyleSheetLocation(const URL&);
+ void setUserStyleSheetLocation(const URL&);
const URL& userStyleSheetLocation() const { return m_userStyleSheetLocation; }
- WEBCORE_EXPORT void setNeedsAdobeFrameReloadingQuirk(bool);
+ void setNeedsAdobeFrameReloadingQuirk(bool);
bool needsAcrobatFrameReloadingQuirk() const { return m_needsAdobeFrameReloadingQuirk; }
- WEBCORE_EXPORT void setMinimumDOMTimerInterval(double); // Initialized to DOMTimer::defaultMinimumInterval().
- double minimumDOMTimerInterval() const { return m_minimumDOMTimerInterval; }
+ static void setDefaultMinDOMTimerInterval(double); // Interval specified in seconds.
+ static double defaultMinDOMTimerInterval();
+
+ static void setHiddenPageDOMTimerAlignmentInterval(double); // Interval specified in seconds.
+ static double hiddenPageDOMTimerAlignmentInterval();
- WEBCORE_EXPORT void setLayoutInterval(std::chrono::milliseconds);
+ void setMinDOMTimerInterval(double); // Per-page; initialized to default value.
+ double minDOMTimerInterval();
+
+ static void setDefaultDOMTimerAlignmentInterval(double);
+ static double defaultDOMTimerAlignmentInterval();
+
+ void setDOMTimerAlignmentInterval(double);
+ double domTimerAlignmentInterval() const;
+
+ void setLayoutInterval(std::chrono::milliseconds);
std::chrono::milliseconds layoutInterval() const { return m_layoutInterval; }
#if ENABLE(HIDDEN_PAGE_DOM_TIMER_THROTTLING)
bool hiddenPageDOMTimerThrottlingEnabled() const { return m_hiddenPageDOMTimerThrottlingEnabled; }
- WEBCORE_EXPORT void setHiddenPageDOMTimerThrottlingEnabled(bool);
+ void setHiddenPageDOMTimerThrottlingEnabled(bool);
+#endif
+
+#if PLATFORM(IOS)
+ // FIXME: This setting isn't specific to iOS.
+ void setMaxParseDuration(double maxParseDuration) { m_maxParseDuration = maxParseDuration; }
+ double maxParseDuration() const { return m_maxParseDuration; }
+
+ void setStandalone(bool);
+ bool standalone() const { return m_standalone; }
+
+ void setTelephoneNumberParsingEnabled(bool flag) { m_telephoneNumberParsingEnabled = flag; }
+ bool telephoneNumberParsingEnabled() const { return m_telephoneNumberParsingEnabled; }
+
+ void setMediaDataLoadsAutomatically(bool flag) { m_mediaDataLoadsAutomatically = flag; }
+ bool mediaDataLoadsAutomatically() const { return m_mediaDataLoadsAutomatically; }
+
+ void setShouldTransformsAffectOverflow(bool flag) { m_shouldTransformsAffectOverflow = flag; }
+ bool shouldTransformsAffectOverflow() const { return m_shouldTransformsAffectOverflow; }
+
+ void setShouldDispatchJavaScriptWindowOnErrorEvents(bool flag) { m_shouldDispatchJavaScriptWindowOnErrorEvents = flag; }
+ bool shouldDispatchJavaScriptWindowOnErrorEvents() const { return m_shouldDispatchJavaScriptWindowOnErrorEvents; }
+
+ void setAlwaysUseBaselineOfPrimaryFont(bool flag) { m_alwaysUseBaselineOfPrimaryFont = flag; }
+ bool alwaysUseBaselineOfPrimaryFont() const { return m_alwaysUseBaselineOfPrimaryFont; }
+
+ void setAlwaysUseAcceleratedOverflowScroll(bool flag) { m_alwaysUseAcceleratedOverflowScroll = flag; }
+ bool alwaysUseAcceleratedOverflowScroll() const { return m_alwaysUseAcceleratedOverflowScroll; }
#endif
- WEBCORE_EXPORT void setUsesPageCache(bool);
+ void setUsesPageCache(bool);
bool usesPageCache() const { return m_usesPageCache; }
void setFontRenderingMode(FontRenderingMode mode);
FontRenderingMode fontRenderingMode() const;
- WEBCORE_EXPORT void setShowTiledScrollingIndicator(bool);
- bool showTiledScrollingIndicator() const { return m_showTiledScrollingIndicator; }
-
-#if ENABLE(RESOURCE_USAGE)
- bool resourceUsageOverlayVisible() const { return m_resourceUsageOverlayVisible; }
- WEBCORE_EXPORT void setResourceUsageOverlayVisible(bool);
+#if ENABLE(CSS_STICKY_POSITION)
+ void setCSSStickyPositionEnabled(bool enabled) { m_cssStickyPositionEnabled = enabled; }
+ bool cssStickyPositionEnabled() const { return m_cssStickyPositionEnabled; }
+#else
+ void setCSSStickyPositionEnabled(bool) { }
+ bool cssStickyPositionEnabled() const { return false; }
#endif
+ void setShowTiledScrollingIndicator(bool);
+ bool showTiledScrollingIndicator() const { return m_showTiledScrollingIndicator; }
+
#if PLATFORM(WIN)
static void setShouldUseHighResolutionTimers(bool);
static bool shouldUseHighResolutionTimers() { return gShouldUseHighResolutionTimers; }
#endif
- static bool shouldRewriteConstAsVar() { return gShouldRewriteConstAsVar; }
- static void setShouldRewriteConstAsVar(bool shouldRewriteConstAsVar) { gShouldRewriteConstAsVar = shouldRewriteConstAsVar; }
+ void setTiledBackingStoreEnabled(bool);
+ bool tiledBackingStoreEnabled() const { return m_tiledBackingStoreEnabled; }
- WEBCORE_EXPORT void setBackgroundShouldExtendBeyondPage(bool);
+ void setBackgroundShouldExtendBeyondPage(bool);
bool backgroundShouldExtendBeyondPage() const { return m_backgroundShouldExtendBeyondPage; }
#if USE(AVFOUNDATION)
- WEBCORE_EXPORT static void setAVFoundationEnabled(bool flag);
+ static void setAVFoundationEnabled(bool flag);
static bool isAVFoundationEnabled() { return gAVFoundationEnabled; }
- WEBCORE_EXPORT static void setAVFoundationNSURLSessionEnabled(bool flag);
- static bool isAVFoundationNSURLSessionEnabled() { return gAVFoundationNSURLSessionEnabled; }
#endif
-#if PLATFORM(COCOA)
- WEBCORE_EXPORT static void setQTKitEnabled(bool flag);
+#if PLATFORM(MAC)
+ static void setQTKitEnabled(bool flag);
static bool isQTKitEnabled() { return gQTKitEnabled; }
-#else
- static bool isQTKitEnabled() { return false; }
#endif
static const unsigned defaultMaximumHTMLParserDOMTreeDepth = 512;
- static const unsigned defaultMaximumRenderTreeDepth = 512;
- WEBCORE_EXPORT static void setMockScrollbarsEnabled(bool flag);
- WEBCORE_EXPORT static bool mockScrollbarsEnabled();
+#if USE(SAFARI_THEME)
+ // Windows debugging pref (global) for switching between the Aqua look and a native windows look.
+ static void setShouldPaintNativeControls(bool);
+ static bool shouldPaintNativeControls() { return gShouldPaintNativeControls; }
+#endif
- WEBCORE_EXPORT static void setUsesOverlayScrollbars(bool flag);
- static bool usesOverlayScrollbars();
+ static void setMockScrollbarsEnabled(bool flag);
+ static bool mockScrollbarsEnabled();
- WEBCORE_EXPORT static void setUsesMockScrollAnimator(bool);
- static bool usesMockScrollAnimator();
+ static void setUsesOverlayScrollbars(bool flag);
+ static bool usesOverlayScrollbars();
#if ENABLE(TOUCH_EVENTS)
void setTouchEventEmulationEnabled(bool enabled) { m_touchEventEmulationEnabled = enabled; }
bool isTouchEventEmulationEnabled() const { return m_touchEventEmulationEnabled; }
#endif
- WEBCORE_EXPORT void setStorageBlockingPolicy(SecurityOrigin::StorageBlockingPolicy);
+ void setStorageBlockingPolicy(SecurityOrigin::StorageBlockingPolicy);
SecurityOrigin::StorageBlockingPolicy storageBlockingPolicy() const { return m_storageBlockingPolicy; }
- WEBCORE_EXPORT void setScrollingPerformanceLoggingEnabled(bool);
+ void setScrollingPerformanceLoggingEnabled(bool);
bool scrollingPerformanceLoggingEnabled() { return m_scrollingPerformanceLoggingEnabled; }
+
+ void setAggressiveTileRetentionEnabled(bool);
+ bool aggressiveTileRetentionEnabled() { return m_aggressiveTileRetentionEnabled; }
- WEBCORE_EXPORT static void setShouldRespectPriorityInCSSAttributeSetters(bool);
+ static void setShouldRespectPriorityInCSSAttributeSetters(bool);
static bool shouldRespectPriorityInCSSAttributeSetters();
void setTimeWithoutMouseMovementBeforeHidingControls(double time) { m_timeWithoutMouseMovementBeforeHidingControls = time; }
double timeWithoutMouseMovementBeforeHidingControls() const { return m_timeWithoutMouseMovementBeforeHidingControls; }
+#if ENABLE(PAGE_VISIBILITY_API)
bool hiddenPageCSSAnimationSuspensionEnabled() const { return m_hiddenPageCSSAnimationSuspensionEnabled; }
- WEBCORE_EXPORT void setHiddenPageCSSAnimationSuspensionEnabled(bool);
+ void setHiddenPageCSSAnimationSuspensionEnabled(bool);
+#endif
- WEBCORE_EXPORT void setFontFallbackPrefersPictographs(bool);
+ void setFontFallbackPrefersPictographs(bool);
bool fontFallbackPrefersPictographs() const { return m_fontFallbackPrefersPictographs; }
static bool lowPowerVideoAudioBufferSizeEnabled() { return gLowPowerVideoAudioBufferSizeEnabled; }
- WEBCORE_EXPORT static void setLowPowerVideoAudioBufferSizeEnabled(bool);
+ static void setLowPowerVideoAudioBufferSizeEnabled(bool);
- static bool resourceLoadStatisticsEnabled() { return gResourceLoadStatisticsEnabledEnabled; }
- WEBCORE_EXPORT static void setResourceLoadStatisticsEnabled(bool);
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+ static void setVideoPluginProxyEnabled(bool flag);
+ static bool isVideoPluginProxyEnabled() { return gVideoPluginProxyEnabled; }
+#endif
#if PLATFORM(IOS)
- WEBCORE_EXPORT static void setAudioSessionCategoryOverride(unsigned);
+ static void setAudioSessionCategoryOverride(unsigned);
static unsigned audioSessionCategoryOverride();
- WEBCORE_EXPORT static void setNetworkDataUsageTrackingEnabled(bool);
+ static void setNetworkDataUsageTrackingEnabled(bool);
static bool networkDataUsageTrackingEnabled();
- WEBCORE_EXPORT static void setNetworkInterfaceName(const String&);
+ static void setNetworkInterfaceName(const String&);
static const String& networkInterfaceName();
-#if HAVE(AVKIT)
static void setAVKitEnabled(bool flag) { gAVKitEnabled = flag; }
-#endif
static bool avKitEnabled() { return gAVKitEnabled; }
-
- static void setShouldOptOutOfNetworkStateObservation(bool flag) { gShouldOptOutOfNetworkStateObservation = flag; }
- static bool shouldOptOutOfNetworkStateObservation() { return gShouldOptOutOfNetworkStateObservation; }
-
- static void setShouldManageAudioSessionCategory(bool flag) { gManageAudioSession = flag; }
- static bool shouldManageAudioSessionCategory() { return gManageAudioSession; }
-#endif
-
-#if ENABLE(ENCRYPTED_MEDIA_V2)
- void setMediaKeysStorageDirectory(const String& directory) { m_mediaKeysStorageDirectory = directory; }
- const String& mediaKeysStorageDirectory() const { return m_mediaKeysStorageDirectory; }
-#endif
-
-#if ENABLE(MEDIA_STREAM)
- void setMediaDeviceIdentifierStorageDirectory(const String& directory) { m_mediaDeviceIdentifierStorageDirectory = directory; }
- const String& mediaDeviceIdentifierStorageDirectory() const { return m_mediaDeviceIdentifierStorageDirectory; }
-
- static bool mockCaptureDevicesEnabled();
- WEBCORE_EXPORT static void setMockCaptureDevicesEnabled(bool);
-#endif
-
- WEBCORE_EXPORT void setForcePendingWebGLPolicy(bool);
- bool isForcePendingWebGLPolicy() const { return m_forcePendingWebGLPolicy; }
-
-#if PLATFORM(IOS)
- WEBCORE_EXPORT static float defaultMinimumZoomFontSize();
#endif
private:
explicit Settings(Page*);
void initializeDefaultFontFamilies();
+ static bool shouldEnableScreenFontSubstitutionByDefault();
Page* m_page;
@@ -300,8 +324,9 @@ private:
const std::unique_ptr<FontGenericFamilies> m_fontGenericFamilies;
SecurityOrigin::StorageBlockingPolicy m_storageBlockingPolicy;
std::chrono::milliseconds m_layoutInterval;
- double m_minimumDOMTimerInterval;
-
+#if PLATFORM(IOS)
+ double m_maxParseDuration;
+#endif
#if ENABLE(TEXT_AUTOSIZING)
float m_textAutosizingFontScaleFactor;
IntSize m_textAutosizingWindowSizeOverride;
@@ -310,17 +335,32 @@ private:
SETTINGS_MEMBER_VARIABLES
+ bool m_screenFontSubstitutionEnabled : 1;
bool m_isJavaEnabled : 1;
bool m_isJavaEnabledForLocalFiles : 1;
bool m_loadsImagesAutomatically : 1;
+ bool m_privateBrowsingEnabled : 1;
bool m_areImagesEnabled : 1;
bool m_arePluginsEnabled : 1;
bool m_isScriptEnabled : 1;
bool m_needsAdobeFrameReloadingQuirk : 1;
bool m_usesPageCache : 1;
unsigned m_fontRenderingMode : 1;
- bool m_antialiasedFontDilationEnabled : 1;
+#if PLATFORM(IOS)
+ bool m_standalone : 1;
+ bool m_telephoneNumberParsingEnabled : 1;
+ bool m_mediaDataLoadsAutomatically : 1;
+ bool m_shouldTransformsAffectOverflow : 1;
+ bool m_shouldDispatchJavaScriptWindowOnErrorEvents : 1;
+ bool m_alwaysUseBaselineOfPrimaryFont : 1;
+ bool m_allowMultiElementImplicitFormSubmission : 1;
+ bool m_alwaysUseAcceleratedOverflowScroll : 1;
+#endif
+#if ENABLE(CSS_STICKY_POSITION)
+ bool m_cssStickyPositionEnabled : 1;
+#endif
bool m_showTiledScrollingIndicator : 1;
+ bool m_tiledBackingStoreEnabled : 1;
bool m_backgroundShouldExtendBeyondPage : 1;
bool m_dnsPrefetchingEnabled : 1;
@@ -328,60 +368,54 @@ private:
bool m_touchEventEmulationEnabled : 1;
#endif
bool m_scrollingPerformanceLoggingEnabled : 1;
+ bool m_aggressiveTileRetentionEnabled : 1;
double m_timeWithoutMouseMovementBeforeHidingControls;
- Timer m_setImageLoadingSettingsTimer;
- void imageLoadingSettingsTimerFired();
+ Timer<Settings> m_setImageLoadingSettingsTimer;
+ void imageLoadingSettingsTimerFired(Timer<Settings>*);
#if ENABLE(HIDDEN_PAGE_DOM_TIMER_THROTTLING)
bool m_hiddenPageDOMTimerThrottlingEnabled : 1;
#endif
+#if ENABLE(PAGE_VISIBILITY_API)
bool m_hiddenPageCSSAnimationSuspensionEnabled : 1;
+#endif
bool m_fontFallbackPrefersPictographs : 1;
- bool m_forcePendingWebGLPolicy : 1;
-
-#if ENABLE(RESOURCE_USAGE)
- bool m_resourceUsageOverlayVisible { false };
-#endif
+ static double gDefaultMinDOMTimerInterval;
+ static double gDefaultDOMTimerAlignmentInterval;
#if USE(AVFOUNDATION)
- WEBCORE_EXPORT static bool gAVFoundationEnabled;
- WEBCORE_EXPORT static bool gAVFoundationNSURLSessionEnabled;
+ static bool gAVFoundationEnabled;
#endif
-#if PLATFORM(COCOA)
- WEBCORE_EXPORT static bool gQTKitEnabled;
+#if PLATFORM(MAC)
+ static bool gQTKitEnabled;
#endif
-
+
static bool gMockScrollbarsEnabled;
static bool gUsesOverlayScrollbars;
- static bool gMockScrollAnimatorEnabled;
+#if USE(SAFARI_THEME)
+ static bool gShouldPaintNativeControls;
+#endif
#if PLATFORM(WIN)
static bool gShouldUseHighResolutionTimers;
#endif
- WEBCORE_EXPORT static bool gShouldRewriteConstAsVar;
static bool gShouldRespectPriorityInCSSAttributeSetters;
#if PLATFORM(IOS)
static bool gNetworkDataUsageTrackingEnabled;
- WEBCORE_EXPORT static bool gAVKitEnabled;
- WEBCORE_EXPORT static bool gShouldOptOutOfNetworkStateObservation;
- WEBCORE_EXPORT static bool gManageAudioSession;
+ static bool gAVKitEnabled;
#endif
-#if ENABLE(ENCRYPTED_MEDIA_V2)
- String m_mediaKeysStorageDirectory;
-#endif
-
-#if ENABLE(MEDIA_STREAM)
- String m_mediaDeviceIdentifierStorageDirectory;
- static bool gMockCaptureDevicesEnabled;
-#endif
+ static double gHiddenPageDOMTimerAlignmentInterval;
static bool gLowPowerVideoAudioBufferSizeEnabled;
- static bool gResourceLoadStatisticsEnabledEnabled;
+
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+ static bool gVideoPluginProxyEnabled;
+#endif
};
} // namespace WebCore
diff --git a/Source/WebCore/page/Settings.in b/Source/WebCore/page/Settings.in
index b54f8d31d..ed48be472 100644
--- a/Source/WebCore/page/Settings.in
+++ b/Source/WebCore/page/Settings.in
@@ -25,6 +25,7 @@ validationMessageTimerMagnification type=int, initial=50
minimumAccelerated2dCanvasSize type=int, initial=257*256
layoutFallbackWidth type=int, initial=980
+maximumDecodedImageSize type=size_t, initial=std::numeric_limits<size_t>::max()
deviceWidth type=int, initial=0
deviceHeight type=int, initial=0
@@ -34,7 +35,7 @@ sessionStorageQuota type=unsigned, initial=StorageMap::noQuota
minimumFontSize type=int, initial=0, setNeedsStyleRecalcInAllFrames=1
minimumLogicalFontSize type=int, initial=0, setNeedsStyleRecalcInAllFrames=1
-defaultFontSize type=int, initial=16, setNeedsStyleRecalcInAllFrames=1
+defaultFontSize type=int, initial=0, setNeedsStyleRecalcInAllFrames=1
defaultFixedFontSize type=int, initial=0, setNeedsStyleRecalcInAllFrames=1
editingBehaviorType type=EditingBehaviorType, initial=editingBehaviorTypeForPlatform()
@@ -45,7 +46,6 @@ maximumHTMLParserDOMTreeDepth type=unsigned, initial=defaultMaximumHTMLParserDOM
loadsSiteIconsIgnoringImageLoadingSetting initial=false
caretBrowsingEnabled initial=false
-preventKeyboardDOMEventDispatch initial=false
localStorageEnabled initial=false
allowUniversalAccessFromFileURLs initial=true
allowFileAccessFromFileURLs initial=true
@@ -60,7 +60,6 @@ acceleratedCompositingEnabled initial=true, setNeedsStyleRecalcInAllFrames=1
acceleratedCompositedAnimationsEnabled initial=true, setNeedsStyleRecalcInAllFrames=1
showDebugBorders initial=false, setNeedsStyleRecalcInAllFrames=1
showRepaintCounter initial=false, setNeedsStyleRecalcInAllFrames=1
-visibleDebugOverlayRegions type=DebugOverlayRegions, initial=0
# This is a quirk we are pro-actively applying to old applications. It changes keyboard event dispatching,
# making keyIdentifier available on keypress events, making charCode available on keydown/keyup events,
@@ -74,9 +73,9 @@ showsURLsInToolTips initial=false
showsToolTipOverTruncatedText initial=false
forceFTPDirectoryListings initial=false
developerExtrasEnabled initial=false
+javaScriptExperimentsEnabled initial=false
scriptMarkupEnabled initial=true
needsSiteSpecificQuirks initial=false
-domTimersThrottlingEnabled initial=true
webArchiveDebugModeEnabled initial=false, conditional=WEB_ARCHIVE
localFileContentSniffingEnabled initial=false
offlineWebApplicationCacheEnabled initial=false
@@ -85,10 +84,10 @@ usesEncodingDetector initial=false
allowScriptsToCloseWindows initial=false
canvasUsesAcceleratedDrawing initial=false
acceleratedDrawingEnabled initial=false
-displayListDrawingEnabled initial=false
acceleratedFiltersEnabled initial=false
+regionBasedColumnsEnabled initial=false
+cssGridLayoutEnabled initial=false
useLegacyTextAlignPositionedElementBehavior initial=false
-javaScriptRuntimeFlags type=JSC::RuntimeFlags
# FIXME: This should really be disabled by default as it makes platforms that don't support the feature download files
# they can't use by. Leaving enabled for now to not change existing behavior.
@@ -96,14 +95,18 @@ downloadableBinaryFontsEnabled initial=true
xssAuditorEnabled initial=false
unsafePluginPastingEnabled initial=true
-acceleratedCompositingForFixedPositionEnabled initial=defaultAcceleratedCompositingForFixedPositionEnabled
+acceleratedCompositingForFixedPositionEnabled initial=false
acceleratedCompositingForOverflowScrollEnabled initial=false
-rubberBandingForSubScrollableRegionsEnabled initial=true, conditional=RUBBER_BANDING
+
+# Works only in conjunction with forceCompositingMode.
+compositedScrollingForFramesEnabled initial=false
experimentalNotificationsEnabled initial=false
webGLEnabled initial=false
webGLErrorsToConsoleEnabled initial=true
openGLMultisamplingEnabled initial=true
+multithreadedWebGLEnabled initial=false
+privilegedWebGLExtensionsEnabled initial=false
forceSoftwareWebGLRendering initial=false
accelerated2dCanvasEnabled initial=false
antialiased2dCanvasEnabled initial=true
@@ -123,15 +126,10 @@ crossOriginCheckInGetMatchedCSSRulesDisabled initial=false
forceCompositingMode initial=false
shouldInjectUserScriptsInInitialEmptyDocument initial=false
fixedElementsLayoutRelativeToFrame initial=false
-allowDisplayOfInsecureContent initial=false
-allowRunningOfInsecureContent initial=false
-requiresUserGestureForMediaPlayback initial=defaultRequiresUserGestureForMediaPlayback
-audioPlaybackRequiresUserGesture initial=defaultAudioPlaybackRequiresUserGesture
-allowsInlineMediaPlayback initial=defaultAllowsInlineMediaPlayback
-inlineMediaPlaybackRequiresPlaysInlineAttribute initial=defaultInlineMediaPlaybackRequiresPlaysInlineAttribute
-allowsPictureInPictureMediaPlayback initial=defaultAllowsPictureInPictureMediaPlayback
-mediaControlsScaleWithPageZoom initial=defaultMediaControlsScaleWithPageZoom
-invisibleAutoplayNotPermitted initial=false
+allowDisplayOfInsecureContent initial=true
+allowRunningOfInsecureContent initial=true
+mediaPlaybackRequiresUserGesture initial=defaultMediaPlaybackRequiresUserGesture
+mediaPlaybackAllowsInline initial=defaultMediaPlaybackAllowsInline
passwordEchoEnabled initial=false
suppressesIncrementalRendering initial=false
incrementalRenderingSuppressionTimeoutInSeconds type=double, initial=defaultIncrementalRenderingSuppressionTimeoutInSeconds
@@ -140,23 +138,23 @@ shouldDisplaySubtitles initial=false, conditional=VIDEO_TRACK
shouldDisplayCaptions initial=false, conditional=VIDEO_TRACK
shouldDisplayTextDescriptions initial=false, conditional=VIDEO_TRACK
scrollingCoordinatorEnabled initial=false
-scrollingTreeIncludesFrames initial=defaultScrollingTreeIncludesFrames
scrollAnimatorEnabled initial=true, conditional=SMOOTH_SCROLLING
-forceUpdateScrollbarsOnMainThreadForPerformanceTesting initial=false
notificationsEnabled initial=true
# Some apps needs isLoadingInAPISense to account for active subresource loaders.
needsIsLoadingInAPISenseQuirk initial=false
shouldRespectImageOrientation initial=defaultShouldRespectImageOrientation
-imageSubsamplingEnabled initial=defaultImageSubsamplingEnabled
wantsBalancedSetDefersLoadingBehavior initial=false
requestAnimationFrameEnabled initial=true
+deviceSupportsTouch initial=false
+deviceSupportsMouse initial=true
fixedPositionCreatesStackingContext initial=defaultFixedPositionCreatesStackingContext
syncXHRInDocumentsEnabled initial=true
cookieEnabled initial=true
mediaEnabled initial=true
+applicationChromeMode initial=false
DOMPasteAllowed initial=false
# When enabled, window.blur() does not change focus, and
@@ -165,6 +163,7 @@ DOMPasteAllowed initial=false
windowFocusRestricted initial=true
diagnosticLoggingEnabled initial=false
+applyDeviceScaleFactorInCompositor initial=true
delegatesPageScaling initial=false
plugInSnapshottingEnabled initial=false
snapshotAllPlugIns initial=false
@@ -193,59 +192,15 @@ selectTrailingWhitespaceEnabled initial=defaultSelectTrailingWhitespaceEnabled
selectionIncludesAltImageText initial=true
useLegacyBackgroundSizeShorthandBehavior initial=false
-fixedBackgroundsPaintRelativeToDocument initial=defaultFixedBackgroundsPaintRelativeToDocument
minimumZoomFontSize type=float, initial=15, conditional=IOS_TEXT_AUTOSIZING
simpleLineLayoutEnabled initial=true, setNeedsStyleRecalcInAllFrames=1
simpleLineLayoutDebugBordersEnabled initial=false, setNeedsStyleRecalcInAllFrames=1
-subpixelCSSOMElementMetricsEnabled initial=false
-
-useGiantTiles initial=false
-
-mediaSourceEnabled initial=true, conditional=MEDIA_SOURCE
+mediaSourceEnabled initial=false
# FIXME: Rename to allowMultiElementImplicitFormSubmission once we upstream the iOS changes to WebView.mm.
allowMultiElementImplicitSubmission initial=false
-allowsAirPlayForMediaPlayback initial=true, conditional=WIRELESS_PLAYBACK_TARGET
-
-shouldConvertPositionStyleOnCopy initial=false
-
-maxParseDuration type=double, initial=-1
-standalone initial=false
-telephoneNumberParsingEnabled initial=false
-mediaDataLoadsAutomatically initial=defaultMediaDataLoadsAutomatically
-shouldTransformsAffectOverflow initial=true
-shouldDispatchJavaScriptWindowOnErrorEvents initial=false
-alwaysUseAcceleratedOverflowScroll initial=false
-imageControlsEnabled initial=false, conditional=SERVICE_CONTROLS
-
-enableInheritURIQueryComponent initial=false
-
-aggressiveTileRetentionEnabled initial=false
-temporaryTileCohortRetentionEnabled initial=true
-
-useImageDocumentForSubframePDF initial=false
-dataDetectorTypes type=DataDetectorTypes, initial=DataDetectorTypeNone, conditional=DATA_DETECTION
-
-# Allow SourceBuffers to store up to 304MB each, enough for approximately five minutes
-# of 1080p video and stereo audio.
-maximumSourceBufferSize type=int, initial=318767104, conditional=MEDIA_SOURCE
-
-serviceControlsEnabled initial=false, conditional=SERVICE_CONTROLS
-
-appleMailPaginationQuirkEnabled initial=false
-
-attachmentElementEnabled initial=true, conditional=ATTACHMENT_ELEMENT
-
-newBlockInsideInlineModelEnabled initial=false, setNeedsStyleRecalcInAllFrames=1
-
-httpEquivEnabled initial=true
-
-# Some ports (e.g. iOS) might choose to display attachments inline, regardless of whether the response includes the
-# HTTP header "Content-Disposition: attachment". This setting enables a sandbox around these attachments. The sandbox
-# enforces all frame sandbox flags (see enum SandboxFlag in SecurityContext.h), and also disables <meta http-equiv>
-# processing and subframe loading.
-contentDispositionAttachmentSandboxEnabled initial=false
+mediaPlaybackAllowsAirPlay initial=true, conditional=IOS_AIRPLAY
diff --git a/Source/WebCore/page/SpatialNavigation.cpp b/Source/WebCore/page/SpatialNavigation.cpp
index 1e5754f57..50cb3f367 100644
--- a/Source/WebCore/page/SpatialNavigation.cpp
+++ b/Source/WebCore/page/SpatialNavigation.cpp
@@ -13,10 +13,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -55,24 +55,25 @@ static void entryAndExitPointsForDirection(FocusDirection, const LayoutRect& sta
static bool isScrollableNode(const Node*);
FocusCandidate::FocusCandidate(Node* node, FocusDirection direction)
- : visibleNode(nullptr)
- , focusableNode(nullptr)
- , enclosingScrollableBox(nullptr)
+ : visibleNode(0)
+ , focusableNode(0)
+ , enclosingScrollableBox(0)
, distance(maxDistance())
, alignment(None)
, isOffscreen(true)
, isOffscreenAfterScrolling(true)
{
- ASSERT(is<Element>(node));
+ ASSERT(node);
+ ASSERT(node->isElementNode());
- if (is<HTMLAreaElement>(*node)) {
- HTMLAreaElement& area = downcast<HTMLAreaElement>(*node);
- HTMLImageElement* image = area.imageElement();
+ if (isHTMLAreaElement(node)) {
+ HTMLAreaElement* area = toHTMLAreaElement(node);
+ HTMLImageElement* image = area->imageElement();
if (!image || !image->renderer())
return;
visibleNode = image;
- rect = virtualRectForAreaElementAndDirection(&area, direction);
+ rect = virtualRectForAreaElementAndDirection(area, direction);
} else {
if (!node->renderer())
return;
@@ -365,8 +366,8 @@ bool scrollInDirection(Frame* frame, FocusDirection direction)
bool scrollInDirection(Node* container, FocusDirection direction)
{
ASSERT(container);
- if (is<Document>(*container))
- return scrollInDirection(downcast<Document>(*container).frame(), direction);
+ if (container->isDocumentNode())
+ return scrollInDirection(toDocument(container)->frame(), direction);
if (!container->renderBox())
return false;
@@ -424,7 +425,7 @@ bool isScrollableNode(const Node* node)
return false;
if (RenderObject* renderer = node->renderer())
- return is<RenderBox>(*renderer) && downcast<RenderBox>(*renderer).canBeScrolledAndHasScrollableArea() && node->hasChildNodes();
+ return renderer->isBox() && toRenderBox(renderer)->canBeScrolledAndHasScrollableArea() && node->hasChildNodes();
return false;
}
@@ -434,11 +435,11 @@ Node* scrollableEnclosingBoxOrParentFrameForNodeInDirection(FocusDirection direc
ASSERT(node);
Node* parent = node;
do {
- if (is<Document>(*parent))
- parent = downcast<Document>(*parent).document().frame()->ownerElement();
+ if (parent->isDocumentNode())
+ parent = toDocument(parent)->document().frame()->ownerElement();
else
parent = parent->parentNode();
- } while (parent && !canScrollInDirection(parent, direction) && !is<Document>(*parent));
+ } while (parent && !canScrollInDirection(parent, direction) && !parent->isDocumentNode());
return parent;
}
@@ -447,11 +448,11 @@ bool canScrollInDirection(const Node* container, FocusDirection direction)
{
ASSERT(container);
- if (is<HTMLSelectElement>(*container))
+ if (isHTMLSelectElement(container))
return false;
- if (is<Document>(*container))
- return canScrollInDirection(downcast<Document>(*container).frame(), direction);
+ if (container->isDocumentNode())
+ return canScrollInDirection(toDocument(container)->frame(), direction);
if (!isScrollableNode(container))
return false;
@@ -483,26 +484,24 @@ bool canScrollInDirection(const Frame* frame, FocusDirection direction)
if ((direction == FocusDirectionUp || direction == FocusDirectionDown) && ScrollbarAlwaysOff == verticalMode)
return false;
LayoutSize size = frame->view()->totalContentsSize();
- LayoutPoint scrollPosition = frame->view()->scrollPosition();
- LayoutRect rect = frame->view()->unobscuredContentRectIncludingScrollbars();
+ LayoutSize offset = frame->view()->scrollOffset();
+ LayoutRect rect = frame->view()->visibleContentRectIncludingScrollbars();
- // FIXME: wrong in RTL documents.
switch (direction) {
case FocusDirectionLeft:
- return scrollPosition.x() > 0;
+ return offset.width() > 0;
case FocusDirectionUp:
- return scrollPosition.y() > 0;
+ return offset.height() > 0;
case FocusDirectionRight:
- return rect.width() + scrollPosition.x() < size.width();
+ return rect.width() + offset.width() < size.width();
case FocusDirectionDown:
- return rect.height() + scrollPosition.y() < size.height();
+ return rect.height() + offset.height() < size.height();
default:
ASSERT_NOT_REACHED();
return false;
}
}
-// FIXME: This is completely broken. This should be deleted and callers should be calling ScrollView::contentsToWindow() instead.
static LayoutRect rectToAbsoluteCoordinates(Frame* initialFrame, const LayoutRect& initialRect)
{
LayoutRect rect = initialRect;
@@ -511,7 +510,7 @@ static LayoutRect rectToAbsoluteCoordinates(Frame* initialFrame, const LayoutRec
do {
rect.move(element->offsetLeft(), element->offsetTop());
} while ((element = element->offsetParent()));
- rect.moveBy((-frame->view()->scrollPosition()));
+ rect.move((-frame->view()->scrollOffset()));
}
}
return rect;
@@ -521,12 +520,9 @@ LayoutRect nodeRectInAbsoluteCoordinates(Node* node, bool ignoreBorder)
{
ASSERT(node && node->renderer() && !node->document().view()->needsLayout());
- if (is<Document>(*node))
- return frameRectInAbsoluteCoordinates(downcast<Document>(*node).frame());
-
- LayoutRect rect;
- if (RenderObject* renderer = node->renderer())
- rect = rectToAbsoluteCoordinates(node->document().frame(), renderer->absoluteBoundingBoxRect());
+ if (node->isDocumentNode())
+ return frameRectInAbsoluteCoordinates(toDocument(node)->frame());
+ LayoutRect rect = rectToAbsoluteCoordinates(node->document().frame(), node->boundingBox());
// For authors that use border instead of outline in their CSS, we compensate by ignoring the border when calculating
// the rect of the focused element.
@@ -611,7 +607,7 @@ bool areElementsOnSameLine(const FocusCandidate& firstCandidate, const FocusCand
if (!firstCandidate.rect.intersects(secondCandidate.rect))
return false;
- if (is<HTMLAreaElement>(*firstCandidate.focusableNode) || is<HTMLAreaElement>(*secondCandidate.focusableNode))
+ if (isHTMLAreaElement(firstCandidate.focusableNode) || isHTMLAreaElement(secondCandidate.focusableNode))
return false;
if (!firstCandidate.visibleNode->renderer()->isRenderInline() || !secondCandidate.visibleNode->renderer()->isRenderInline())
@@ -762,7 +758,7 @@ LayoutRect virtualRectForAreaElementAndDirection(HTMLAreaElement* area, FocusDir
HTMLFrameOwnerElement* frameOwnerElement(FocusCandidate& candidate)
{
- return candidate.isFrameOwnerElement() ? downcast<HTMLFrameOwnerElement>(candidate.visibleNode) : nullptr;
-}
+ return candidate.isFrameOwnerElement() ? toHTMLFrameOwnerElement(candidate.visibleNode) : nullptr;
+};
} // namespace WebCore
diff --git a/Source/WebCore/page/SpatialNavigation.h b/Source/WebCore/page/SpatialNavigation.h
index 21fe51229..fd6f48f52 100644
--- a/Source/WebCore/page/SpatialNavigation.h
+++ b/Source/WebCore/page/SpatialNavigation.h
@@ -99,9 +99,9 @@ enum RectsAlignment {
struct FocusCandidate {
FocusCandidate()
- : visibleNode(nullptr)
- , focusableNode(nullptr)
- , enclosingScrollableBox(nullptr)
+ : visibleNode(0)
+ , focusableNode(0)
+ , enclosingScrollableBox(0)
, distance(maxDistance())
, alignment(None)
, isOffscreen(true)
diff --git a/Source/WebCore/page/SpeechInput.cpp b/Source/WebCore/page/SpeechInput.cpp
new file mode 100644
index 000000000..228d3fcd8
--- /dev/null
+++ b/Source/WebCore/page/SpeechInput.cpp
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "SpeechInput.h"
+
+#if ENABLE(INPUT_SPEECH)
+
+#include "SecurityOrigin.h"
+#include "SpeechInputClient.h"
+#include "SpeechInputListener.h"
+#include <wtf/PassOwnPtr.h>
+
+namespace WebCore {
+
+SpeechInput::SpeechInput(SpeechInputClient* client)
+ : m_client(client)
+ , m_nextListenerId(1)
+{
+ m_client->setListener(this);
+}
+
+SpeechInput::~SpeechInput()
+{
+ m_client->setListener(0);
+}
+
+PassOwnPtr<SpeechInput> SpeechInput::create(SpeechInputClient* client)
+{
+ return adoptPtr(new SpeechInput(client));
+}
+
+int SpeechInput::registerListener(SpeechInputListener* listener)
+{
+#if defined(DEBUG)
+ // Check if already present.
+ for (HashMap<int, SpeechInputListener*>::iterator it = m_listeners.begin(); it != m_listeners.end(); ++it)
+ ASSERT(it->value != listener);
+#endif
+
+ m_listeners.add(m_nextListenerId, listener);
+ return m_nextListenerId++;
+}
+
+void SpeechInput::unregisterListener(int listenerId)
+{
+ if (m_listeners.contains(listenerId))
+ m_listeners.remove(listenerId);
+}
+
+void SpeechInput::didCompleteRecording(int listenerId)
+{
+ // Don't assert if not present as the element might have been removed by the page while
+ // this event was on the way.
+ if (m_listeners.contains(listenerId))
+ m_listeners.get(listenerId)->didCompleteRecording(listenerId);
+}
+
+void SpeechInput::didCompleteRecognition(int listenerId)
+{
+ // Don't assert if not present as the element might have been removed by the page while
+ // this event was on the way.
+ if (m_listeners.contains(listenerId))
+ m_listeners.get(listenerId)->didCompleteRecognition(listenerId);
+}
+
+void SpeechInput::setRecognitionResult(int listenerId, const SpeechInputResultArray& result)
+{
+ // Don't assert if not present as the element might have been removed by the page while
+ // this event was on the way.
+ if (m_listeners.contains(listenerId))
+ m_listeners.get(listenerId)->setRecognitionResult(listenerId, result);
+}
+
+bool SpeechInput::startRecognition(int listenerId, const IntRect& elementRect, const AtomicString& language, const String& grammar, SecurityOrigin* origin)
+{
+ ASSERT(m_listeners.contains(listenerId));
+ return m_client->startRecognition(listenerId, elementRect, language, grammar, origin);
+}
+
+void SpeechInput::stopRecording(int listenerId)
+{
+ ASSERT(m_listeners.contains(listenerId));
+ m_client->stopRecording(listenerId);
+}
+
+void SpeechInput::cancelRecognition(int listenerId)
+{
+ ASSERT(m_listeners.contains(listenerId));
+ m_client->cancelRecognition(listenerId);
+}
+
+const char* SpeechInput::supplementName()
+{
+ return "SpeechInput";
+}
+
+void provideSpeechInputTo(Page* page, SpeechInputClient* client)
+{
+ SpeechInput::provideTo(page, SpeechInput::supplementName(), SpeechInput::create(client));
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(INPUT_SPEECH)
diff --git a/Source/WebCore/page/SpeechInput.h b/Source/WebCore/page/SpeechInput.h
new file mode 100644
index 000000000..447f632e6
--- /dev/null
+++ b/Source/WebCore/page/SpeechInput.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SpeechInput_h
+#define SpeechInput_h
+
+#if ENABLE(INPUT_SPEECH)
+
+#include "Page.h"
+#include "SpeechInputListener.h"
+#include <wtf/Forward.h>
+#include <wtf/HashMap.h>
+
+namespace WebCore {
+
+class IntRect;
+class SecurityOrigin;
+class SpeechInputClient;
+class SpeechInputListener;
+
+// This class connects the input elements requiring speech input with the platform specific
+// speech recognition engine. It provides methods for the input elements to activate speech
+// recognition and methods for the speech recognition engine to return back the results.
+class SpeechInput : public SpeechInputListener,
+ public Supplement<Page> {
+ WTF_MAKE_NONCOPYABLE(SpeechInput);
+public:
+ virtual ~SpeechInput();
+
+ static PassOwnPtr<SpeechInput> create(SpeechInputClient*);
+ static const char* supplementName();
+ static SpeechInput* from(Page* page) { return static_cast<SpeechInput*>(Supplement<Page>::from(page, supplementName())); }
+
+ // Generates a unique ID for the given listener to be used for speech requests.
+ // This should be the first call made by listeners before anything else.
+ int registerListener(SpeechInputListener*);
+
+ // Invoked when the listener is done with recording or getting destroyed.
+ // Failure to unregister may result in crashes if there were any pending speech events.
+ void unregisterListener(int);
+
+ // Methods invoked by the input elements.
+ bool startRecognition(int listenerId, const IntRect& elementRect, const AtomicString& language, const String& grammar, SecurityOrigin*);
+ void stopRecording(int);
+ void cancelRecognition(int);
+
+ // SpeechInputListener methods.
+ virtual void didCompleteRecording(int);
+ virtual void didCompleteRecognition(int);
+ virtual void setRecognitionResult(int, const SpeechInputResultArray&);
+
+private:
+ explicit SpeechInput(SpeechInputClient*);
+
+ SpeechInputClient* m_client;
+ HashMap<int, SpeechInputListener*> m_listeners;
+ int m_nextListenerId;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(INPUT_SPEECH)
+
+#endif // SpeechInput_h
diff --git a/Source/WebCore/page/SpeechInputClient.h b/Source/WebCore/page/SpeechInputClient.h
new file mode 100644
index 000000000..6992fba43
--- /dev/null
+++ b/Source/WebCore/page/SpeechInputClient.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SpeechInputClient_h
+#define SpeechInputClient_h
+
+#include <wtf/Forward.h>
+
+#if ENABLE(INPUT_SPEECH)
+
+namespace WebCore {
+
+class IntRect;
+class SecurityOrigin;
+class SpeechInputListener;
+class Page;
+
+// Provides an interface for SpeechInput to call into the embedder.
+class SpeechInputClient {
+public:
+ // This is the first call made by a listener, registering itself for future callbacks.
+ // When the listener no longer needs speech input (for e.g. when it gets destroyed),
+ // it should set a null listener to stop receiving callbacks.
+ // The client does not take ownership of the pointer.
+ virtual void setListener(SpeechInputListener*) = 0;
+
+ // Starts speech recognition and audio recording. elementRect is the position
+ // of the element where the user clicked in the RootView coordinate system.
+ virtual bool startRecognition(int requestId, const IntRect& elementRect, const AtomicString& language, const String& grammar, SecurityOrigin*) = 0;
+
+ // Stops audio recording and performs recognition with the audio recorded until now
+ // (does not discard audio).
+ virtual void stopRecording(int requestId) = 0;
+
+ // Cancels an ongoing recognition and discards any audio recorded so far. No partial
+ // recognition results are returned to the listener.
+ virtual void cancelRecognition(int requestId) = 0;
+
+protected:
+ virtual ~SpeechInputClient() { }
+};
+
+void provideSpeechInputTo(Page*, SpeechInputClient*);
+
+} // namespace WebCore
+
+#endif // ENABLE(INPUT_SPEECH)
+
+#endif // SpeechInputClient_h
diff --git a/Source/WebCore/page/SpeechInputEvent.cpp b/Source/WebCore/page/SpeechInputEvent.cpp
new file mode 100644
index 000000000..9afb7710e
--- /dev/null
+++ b/Source/WebCore/page/SpeechInputEvent.cpp
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(INPUT_SPEECH)
+
+#include "SpeechInputEvent.h"
+
+#include "EventNames.h"
+
+namespace WebCore {
+
+PassRefPtr<SpeechInputEvent> SpeechInputEvent::create()
+{
+ return adoptRef(new SpeechInputEvent);
+}
+
+PassRefPtr<SpeechInputEvent> SpeechInputEvent::create(const AtomicString& eventType, const SpeechInputResultArray& results)
+{
+ return adoptRef(new SpeechInputEvent(eventType, results));
+}
+
+SpeechInputEvent::SpeechInputEvent()
+{
+}
+
+SpeechInputEvent::SpeechInputEvent(const AtomicString& eventType, const SpeechInputResultArray& results)
+ : Event(eventType, true, false) // Can bubble, not cancelable
+ , m_results(SpeechInputResultList::create(results))
+{
+}
+
+SpeechInputEvent::~SpeechInputEvent()
+{
+}
+
+EventInterface SpeechInputEvent::eventInterface() const
+{
+ return SpeechInputEventInterfaceType;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(INPUT_SPEECH)
diff --git a/Source/WebCore/page/SpeechInputEvent.h b/Source/WebCore/page/SpeechInputEvent.h
new file mode 100644
index 000000000..bb33cebdb
--- /dev/null
+++ b/Source/WebCore/page/SpeechInputEvent.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SpeechInputEvent_h
+#define SpeechInputEvent_h
+
+#if ENABLE(INPUT_SPEECH)
+
+#include "Event.h"
+#include "SpeechInputResultList.h"
+
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+class SpeechInputEvent : public Event {
+public:
+ static PassRefPtr<SpeechInputEvent> create();
+ static PassRefPtr<SpeechInputEvent> create(const AtomicString& eventType, const SpeechInputResultArray& results);
+ ~SpeechInputEvent();
+
+ SpeechInputResultList* results() const { return m_results.get(); }
+
+ virtual EventInterface eventInterface() const;
+
+private:
+ SpeechInputEvent();
+ SpeechInputEvent(const AtomicString& eventType, const SpeechInputResultArray& results);
+
+ RefPtr<SpeechInputResultList> m_results;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(INPUT_SPEECH)
+
+#endif // SpeechInputEvent_h
diff --git a/Source/WebCore/page/ContextMenuContext.cpp b/Source/WebCore/page/SpeechInputEvent.idl
index bc81dc0fb..be82107d1 100644
--- a/Source/WebCore/page/ContextMenuContext.cpp
+++ b/Source/WebCore/page/SpeechInputEvent.idl
@@ -1,19 +1,19 @@
/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2010 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
- * 1. Redistributions of source code must retain the above copyright
+ * * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
+ * * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE, INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -21,28 +21,11 @@
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
*/
-#include "config.h"
-#include "ContextMenuContext.h"
-
-#if ENABLE(CONTEXT_MENUS)
-
-namespace WebCore {
-
-ContextMenuContext::ContextMenuContext()
-{
-}
-
-ContextMenuContext::ContextMenuContext(const HitTestResult& hitTestResult)
- : m_hitTestResult(hitTestResult)
-#if ENABLE(SERVICE_CONTROLS)
- , m_controlledImage(nullptr)
-#endif
-{
-}
-
-} // namespace WebCore
+[
+ Conditional=INPUT_SPEECH,
+] interface SpeechInputEvent : Event {
+ readonly attribute SpeechInputResultList results;
+};
-#endif // ENABLE(CONTEXT_MENUS)
diff --git a/Source/WebCore/page/SpeechInputListener.h b/Source/WebCore/page/SpeechInputListener.h
new file mode 100644
index 000000000..741530127
--- /dev/null
+++ b/Source/WebCore/page/SpeechInputListener.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SpeechInputListener_h
+#define SpeechInputListener_h
+
+#if ENABLE(INPUT_SPEECH)
+
+#include "SpeechInputResult.h"
+#include <wtf/Forward.h>
+
+namespace WebCore {
+
+// Interface to be implemented by the element which invokes SpeechInput.
+class SpeechInputListener {
+public:
+ // Informs that audio recording has completed and recognition is underway.
+ virtual void didCompleteRecording(int requestId) = 0;
+
+ // Informs that speech recognition has completed. This gets invoked irrespective of whether
+ // recognition was succesful or not, whether setRecognitionResult() was invoked or not. The
+ // handler typically frees up any temporary resources allocated and waits for the next speech
+ // recognition request.
+ virtual void didCompleteRecognition(int requestId) = 0;
+
+ // Gives results from speech recognition, either partial or the final results.
+ // This method can potentially get called multiple times if there are partial results
+ // available as the user keeps speaking. If the speech could not be recognized properly
+ // or if there was any other errors in the process, this method may never be called.
+ virtual void setRecognitionResult(int requestId, const SpeechInputResultArray&) = 0;
+
+protected:
+ virtual ~SpeechInputListener() { }
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(INPUT_SPEECH)
+
+#endif // SpeechInputListener_h
diff --git a/Source/WebCore/page/SpeechInputResult.cpp b/Source/WebCore/page/SpeechInputResult.cpp
new file mode 100644
index 000000000..1c042a056
--- /dev/null
+++ b/Source/WebCore/page/SpeechInputResult.cpp
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "SpeechInputResult.h"
+
+#if ENABLE(INPUT_SPEECH)
+
+namespace WebCore {
+
+PassRefPtr<SpeechInputResult> SpeechInputResult::create(const String& utterance, double confidence)
+{
+ return adoptRef(new SpeechInputResult(utterance, confidence));
+}
+
+PassRefPtr<SpeechInputResult> SpeechInputResult::create(const SpeechInputResult& source)
+{
+ return adoptRef(new SpeechInputResult(source.m_utterance, source.m_confidence));
+}
+
+SpeechInputResult::SpeechInputResult(const String& utterance, double confidence)
+ : m_utterance(utterance)
+ , m_confidence(confidence)
+{
+}
+
+double SpeechInputResult::confidence() const
+{
+ return m_confidence;
+}
+
+const String& SpeechInputResult::utterance() const
+{
+ return m_utterance;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(INPUT_SPEECH)
diff --git a/Source/WebCore/page/SpeechInputResult.h b/Source/WebCore/page/SpeechInputResult.h
new file mode 100644
index 000000000..1070e1257
--- /dev/null
+++ b/Source/WebCore/page/SpeechInputResult.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SpeechInputResult_h
+#define SpeechInputResult_h
+
+#if ENABLE(INPUT_SPEECH)
+
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+// This class holds one speech recognition result including the text and other related
+// fields, as received from the embedder.
+class SpeechInputResult : public RefCounted<SpeechInputResult> {
+public:
+ static PassRefPtr<SpeechInputResult> create(const SpeechInputResult& source);
+ static PassRefPtr<SpeechInputResult> create(const String& utterance, double confidence);
+
+ double confidence() const;
+ const String& utterance() const;
+
+private:
+ SpeechInputResult(const String& utterance, double confidence);
+
+ String m_utterance;
+ double m_confidence;
+};
+
+typedef Vector<RefPtr<SpeechInputResult>> SpeechInputResultArray;
+
+} // namespace WebCore
+
+#endif // ENABLE(INPUT_SPEECH)
+
+#endif // SpeechInputResult_h
diff --git a/Source/WebCore/page/SpeechInputResult.idl b/Source/WebCore/page/SpeechInputResult.idl
new file mode 100644
index 000000000..41a530ad3
--- /dev/null
+++ b/Source/WebCore/page/SpeechInputResult.idl
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+[
+ NoInterfaceObject,
+ Conditional=INPUT_SPEECH,
+ ImplementationLacksVTable
+] interface SpeechInputResult {
+ readonly attribute DOMString utterance;
+ readonly attribute float confidence;
+};
+
diff --git a/Source/WebCore/page/SpeechInputResultList.cpp b/Source/WebCore/page/SpeechInputResultList.cpp
new file mode 100644
index 000000000..41fd108f5
--- /dev/null
+++ b/Source/WebCore/page/SpeechInputResultList.cpp
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "SpeechInputResultList.h"
+
+#if ENABLE(INPUT_SPEECH)
+
+namespace WebCore {
+
+PassRefPtr<SpeechInputResultList> SpeechInputResultList::create(const SpeechInputResultArray& results)
+{
+ return adoptRef(new SpeechInputResultList(results));
+}
+
+SpeechInputResult* SpeechInputResultList::item(unsigned index)
+{
+ return index >= m_results.size() ? 0 : m_results[index].get();
+}
+
+SpeechInputResultList::SpeechInputResultList(const SpeechInputResultArray& results)
+ : m_results(results) // Takes a copy of the array of RefPtrs.
+{
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(INPUT_SPEECH)
diff --git a/Source/WebCore/page/csp/ContentSecurityPolicyMediaListDirective.h b/Source/WebCore/page/SpeechInputResultList.h
index f1a057e77..8556aecf0 100644
--- a/Source/WebCore/page/csp/ContentSecurityPolicyMediaListDirective.h
+++ b/Source/WebCore/page/SpeechInputResultList.h
@@ -1,20 +1,19 @@
/*
- * Copyright (C) 2011 Google, Inc. All rights reserved.
- * Copyright (C) 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2010 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
- * 1. Redistributions of source code must retain the above copyright
+ * * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
+ * * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -24,29 +23,35 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef ContentSecurityPolicyMediaListDirective_h
-#define ContentSecurityPolicyMediaListDirective_h
+#ifndef SpeechInputResultList_h
+#define SpeechInputResultList_h
-#include "ContentSecurityPolicyDirective.h"
-#include <wtf/HashSet.h>
-#include <wtf/text/WTFString.h>
+#if ENABLE(INPUT_SPEECH)
-namespace WebCore {
+#include "SpeechInputResult.h"
+
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/Vector.h>
-class ContentSecurityPolicy;
+namespace WebCore {
-class ContentSecurityPolicyMediaListDirective : public ContentSecurityPolicyDirective {
+class SpeechInputResultList : public RefCounted<SpeechInputResultList> {
public:
- ContentSecurityPolicyMediaListDirective(const String& name, const String& value, const ContentSecurityPolicy&);
+ static PassRefPtr<SpeechInputResultList> create(const SpeechInputResultArray& results);
- bool allows(const String& type) const;
+ // Methods from the IDL.
+ size_t length() { return m_results.size(); }
+ SpeechInputResult* item(unsigned index);
private:
- void parse(const String&);
+ explicit SpeechInputResultList(const SpeechInputResultArray& results);
- HashSet<String> m_pluginTypes;
+ SpeechInputResultArray m_results;
};
} // namespace WebCore
-#endif /* ContentSecurityPolicyMediaListDirective_h */
+#endif // ENABLE(INPUT_SPEECH)
+
+#endif // SpeechInputResultList_h
diff --git a/Source/WebCore/page/SpeechInputResultList.idl b/Source/WebCore/page/SpeechInputResultList.idl
new file mode 100644
index 000000000..7a21c136f
--- /dev/null
+++ b/Source/WebCore/page/SpeechInputResultList.idl
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+[
+ NoInterfaceObject,
+ Conditional=INPUT_SPEECH,
+ ImplementationLacksVTable,
+] interface SpeechInputResultList {
+ readonly attribute unsigned long length;
+ getter SpeechInputResult item([IsIndex] unsigned long index);
+};
+
diff --git a/Source/WebCore/page/SuspendableTimer.cpp b/Source/WebCore/page/SuspendableTimer.cpp
index 76583c12b..00df344f5 100644
--- a/Source/WebCore/page/SuspendableTimer.cpp
+++ b/Source/WebCore/page/SuspendableTimer.cpp
@@ -13,7 +13,7 @@
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -31,8 +31,8 @@
namespace WebCore {
-SuspendableTimer::SuspendableTimer(ScriptExecutionContext& context)
- : ActiveDOMObject(&context)
+SuspendableTimer::SuspendableTimer(ScriptExecutionContext* context)
+ : ActiveDOMObject(context)
, m_suspended(false)
, m_savedNextFireInterval(0)
, m_savedRepeatInterval(0)
@@ -84,7 +84,7 @@ void SuspendableTimer::resume()
start(m_savedNextFireInterval, m_savedRepeatInterval);
}
-bool SuspendableTimer::canSuspendForDocumentSuspension() const
+bool SuspendableTimer::canSuspend() const
{
return true;
}
diff --git a/Source/WebCore/page/SuspendableTimer.h b/Source/WebCore/page/SuspendableTimer.h
index a01dd5e29..44cb13856 100644
--- a/Source/WebCore/page/SuspendableTimer.h
+++ b/Source/WebCore/page/SuspendableTimer.h
@@ -13,7 +13,7 @@
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -34,7 +34,7 @@ namespace WebCore {
class SuspendableTimer : private TimerBase, public ActiveDOMObject {
public:
- explicit SuspendableTimer(ScriptExecutionContext&);
+ explicit SuspendableTimer(ScriptExecutionContext*);
virtual ~SuspendableTimer();
// A hook for derived classes to perform cleanup.
@@ -55,14 +55,14 @@ public:
void cancel(); // Equivalent to TimerBase::stop(), whose name conflicts with ActiveDOMObject::stop().
private:
- virtual void fired() override = 0;
+ virtual void fired() = 0;
- // ActiveDOMObject API.
- bool hasPendingActivity() const override final;
- void stop() override final;
- bool canSuspendForDocumentSuspension() const override final;
- void suspend(ReasonForSuspension) override final;
- void resume() override final;
+ // ActiveDOMObject
+ virtual bool hasPendingActivity() const final override;
+ virtual void stop() final override;
+ virtual bool canSuspend() const final override;
+ virtual void suspend(ReasonForSuspension) final override;
+ virtual void resume() final override;
bool m_suspended;
diff --git a/Source/WebCore/page/TextIndicator.cpp b/Source/WebCore/page/TextIndicator.cpp
deleted file mode 100644
index fd0c0ba73..000000000
--- a/Source/WebCore/page/TextIndicator.cpp
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- * Copyright (C) 2010, 2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "TextIndicator.h"
-
-#include "Document.h"
-#include "Editor.h"
-#include "Element.h"
-#include "Frame.h"
-#include "FrameSelection.h"
-#include "FrameSnapshotting.h"
-#include "FrameView.h"
-#include "GeometryUtilities.h"
-#include "GraphicsContext.h"
-#include "ImageBuffer.h"
-#include "IntRect.h"
-#include "NodeTraversal.h"
-#include "Page.h"
-#include "Range.h"
-#include "RenderObject.h"
-
-using namespace WebCore;
-
-namespace WebCore {
-
-static bool initializeIndicator(TextIndicatorData&, Frame&, const Range&, FloatSize margin, bool indicatesCurrentSelection);
-
-TextIndicator::TextIndicator(const TextIndicatorData& data)
- : m_data(data)
-{
-}
-
-TextIndicator::~TextIndicator()
-{
-}
-
-Ref<TextIndicator> TextIndicator::create(const TextIndicatorData& data)
-{
- return adoptRef(*new TextIndicator(data));
-}
-
-RefPtr<TextIndicator> TextIndicator::createWithRange(const Range& range, TextIndicatorOptions options, TextIndicatorPresentationTransition presentationTransition, FloatSize margin)
-{
- Frame* frame = range.startContainer().document().frame();
-
- if (!frame)
- return nullptr;
-
-#if PLATFORM(IOS)
- frame->editor().setIgnoreCompositionSelectionChange(true);
- frame->selection().setUpdateAppearanceEnabled(true);
-#endif
-
- VisibleSelection oldSelection = frame->selection().selection();
- frame->selection().setSelection(range);
-
- TextIndicatorData data;
-
- data.presentationTransition = presentationTransition;
- data.options = options;
-
- bool indicatesCurrentSelection = areRangesEqual(&range, oldSelection.toNormalizedRange().get());
-
- if (!initializeIndicator(data, *frame, range, margin, indicatesCurrentSelection))
- return nullptr;
-
- RefPtr<TextIndicator> indicator = TextIndicator::create(data);
-
- frame->selection().setSelection(oldSelection);
-
-#if PLATFORM(IOS)
- frame->editor().setIgnoreCompositionSelectionChange(false, Editor::RevealSelection::No);
- frame->selection().setUpdateAppearanceEnabled(false);
-#endif
-
- return indicator;
-}
-
-RefPtr<TextIndicator> TextIndicator::createWithSelectionInFrame(Frame& frame, TextIndicatorOptions options, TextIndicatorPresentationTransition presentationTransition, FloatSize margin)
-{
- RefPtr<Range> range = frame.selection().toNormalizedRange();
- if (!range)
- return nullptr;
-
- TextIndicatorData data;
-
- data.presentationTransition = presentationTransition;
- data.options = options;
-
- if (!initializeIndicator(data, frame, *range, margin, true))
- return nullptr;
-
- return TextIndicator::create(data);
-}
-
-static bool hasNonInlineOrReplacedElements(const Range& range)
-{
- Node* stopNode = range.pastLastNode();
- for (Node* node = range.firstNode(); node != stopNode; node = NodeTraversal::next(*node)) {
- if (!node)
- continue;
- RenderObject* renderer = node->renderer();
- if (!renderer)
- continue;
- if ((!renderer->isInline() || renderer->isReplaced()) && range.intersectsNode(node, ASSERT_NO_EXCEPTION))
- return true;
- }
-
- return false;
-}
-
-static SnapshotOptions snapshotOptionsForTextIndicatorOptions(TextIndicatorOptions options)
-{
- SnapshotOptions snapshotOptions = SnapshotOptionsNone;
- if (!(options & TextIndicatorOptionRespectTextColor))
- snapshotOptions |= SnapshotOptionsForceBlackText;
-
- if (!(options & TextIndicatorOptionPaintAllContent)) {
- if (options & TextIndicatorOptionPaintBackgrounds)
- snapshotOptions |= SnapshotOptionsPaintSelectionAndBackgroundsOnly;
- else
- snapshotOptions |= SnapshotOptionsPaintSelectionOnly;
- } else
- snapshotOptions |= SnapshotOptionsExcludeSelectionHighlighting;
-
- return snapshotOptions;
-}
-
-static RefPtr<Image> takeSnapshot(Frame& frame, IntRect rect, SnapshotOptions options, float& scaleFactor)
-{
- std::unique_ptr<ImageBuffer> buffer = snapshotFrameRect(frame, rect, options);
- if (!buffer)
- return nullptr;
- scaleFactor = buffer->resolutionScale();
- return ImageBuffer::sinkIntoImage(WTFMove(buffer), Unscaled);
-}
-
-static bool takeSnapshots(TextIndicatorData& data, Frame& frame, IntRect snapshotRect)
-{
- SnapshotOptions snapshotOptions = snapshotOptionsForTextIndicatorOptions(data.options);
-
- data.contentImage = takeSnapshot(frame, snapshotRect, snapshotOptions, data.contentImageScaleFactor);
- if (!data.contentImage)
- return false;
-
- if (data.options & TextIndicatorOptionIncludeSnapshotWithSelectionHighlight) {
- float snapshotScaleFactor;
- data.contentImageWithHighlight = takeSnapshot(frame, snapshotRect, SnapshotOptionsNone, snapshotScaleFactor);
- ASSERT(!data.contentImageWithHighlight || data.contentImageScaleFactor == snapshotScaleFactor);
- }
-
- return true;
-}
-
-static bool initializeIndicator(TextIndicatorData& data, Frame& frame, const Range& range, FloatSize margin, bool indicatesCurrentSelection)
-{
- Vector<FloatRect> textRects;
-
- // FIXME (138888): Ideally we wouldn't remove the margin in this case, but we need to
- // ensure that the indicator and indicator-with-highlight overlap precisely, and
- // we can't add a margin to the indicator-with-highlight.
- if (indicatesCurrentSelection && !(data.options & TextIndicatorOptionIncludeMarginIfRangeMatchesSelection))
- margin = FloatSize();
-
- FrameSelection::TextRectangleHeight textRectHeight = (data.options & TextIndicatorOptionTightlyFitContent) ? FrameSelection::TextRectangleHeight::TextHeight : FrameSelection::TextRectangleHeight::SelectionHeight;
-
- if ((data.options & TextIndicatorOptionUseBoundingRectAndPaintAllContentForComplexRanges) && hasNonInlineOrReplacedElements(range))
- data.options |= TextIndicatorOptionPaintAllContent;
- else {
- if (data.options & TextIndicatorOptionDoNotClipToVisibleRect)
- frame.selection().getTextRectangles(textRects, textRectHeight);
- else
- frame.selection().getClippedVisibleTextRectangles(textRects, textRectHeight);
- }
-
- if (textRects.isEmpty()) {
- RenderView* renderView = frame.contentRenderer();
- if (!renderView)
- return false;
- FloatRect boundingRect = range.absoluteBoundingRect();
- if (data.options & TextIndicatorOptionDoNotClipToVisibleRect)
- textRects.append(boundingRect);
- else {
- // Clip to the visible rect, just like getClippedVisibleTextRectangles does.
- // FIXME: We really want to clip to the unobscured rect in both cases, I think.
- // (this seems to work on Mac, but maybe not iOS?)
- FloatRect visibleContentRect = frame.view()->visibleContentRect(ScrollableArea::LegacyIOSDocumentVisibleRect);
- textRects.append(intersection(visibleContentRect, boundingRect));
- }
- }
-
- FloatRect textBoundingRectInRootViewCoordinates;
- FloatRect textBoundingRectInDocumentCoordinates;
- Vector<FloatRect> textRectsInRootViewCoordinates;
- for (const FloatRect& textRect : textRects) {
- FloatRect textRectInDocumentCoordinatesIncludingMargin = textRect;
- textRectInDocumentCoordinatesIncludingMargin.inflateX(margin.width());
- textRectInDocumentCoordinatesIncludingMargin.inflateY(margin.height());
- textBoundingRectInDocumentCoordinates.unite(textRectInDocumentCoordinatesIncludingMargin);
-
- FloatRect textRectInRootViewCoordinates = frame.view()->contentsToRootView(enclosingIntRect(textRectInDocumentCoordinatesIncludingMargin));
- textRectsInRootViewCoordinates.append(textRectInRootViewCoordinates);
- textBoundingRectInRootViewCoordinates.unite(textRectInRootViewCoordinates);
- }
-
- Vector<FloatRect> textRectsInBoundingRectCoordinates;
- for (auto rect : textRectsInRootViewCoordinates) {
- rect.moveBy(-textBoundingRectInRootViewCoordinates.location());
- textRectsInBoundingRectCoordinates.append(rect);
- }
-
- // Store the selection rect in window coordinates, to be used subsequently
- // to determine if the indicator and selection still precisely overlap.
- data.selectionRectInRootViewCoordinates = frame.view()->contentsToRootView(enclosingIntRect(frame.selection().selectionBounds()));
- data.textBoundingRectInRootViewCoordinates = textBoundingRectInRootViewCoordinates;
- data.textRectsInBoundingRectCoordinates = textRectsInBoundingRectCoordinates;
-
- return takeSnapshots(data, frame, enclosingIntRect(textBoundingRectInDocumentCoordinates));
-}
-
-} // namespace WebCore
diff --git a/Source/WebCore/page/TextIndicator.h b/Source/WebCore/page/TextIndicator.h
deleted file mode 100644
index dc11e8570..000000000
--- a/Source/WebCore/page/TextIndicator.h
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright (C) 2010 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TextIndicator_h
-#define TextIndicator_h
-
-#include "FloatRect.h"
-#include "Image.h"
-#include <wtf/PassRefPtr.h>
-#include <wtf/RefCounted.h>
-#include <wtf/Vector.h>
-
-namespace WebCore {
-
-class Frame;
-class GraphicsContext;
-class Range;
-
-// FIXME: Move PresentationTransition to TextIndicatorWindow, because it's about presentation.
-enum class TextIndicatorPresentationTransition {
- None,
-
- // These animations drive themselves.
- Bounce,
- BounceAndCrossfade,
-
- // This animation needs to be driven manually via TextIndicatorWindow::setAnimationProgress.
- FadeIn,
-};
-
-// Make sure to keep these in sync with the ones in Internals.idl.
-enum TextIndicatorOption : uint8_t {
- TextIndicatorOptionDefault = 0,
-
- // Use the styled text color instead of forcing black text (the default)
- TextIndicatorOptionRespectTextColor = 1 << 0,
-
- // Paint backgrounds, even if they're not part of the Range
- TextIndicatorOptionPaintBackgrounds = 1 << 1,
-
- // Don't restrict painting to the given Range
- TextIndicatorOptionPaintAllContent = 1 << 2,
-
- // Take two snapshots:
- // - one including the selection highlight and ignoring other painting-related options
- // - one respecting the other painting-related options
- TextIndicatorOptionIncludeSnapshotWithSelectionHighlight = 1 << 3,
-
- // Tightly fit the content instead of expanding to cover the bounds of the selection highlight
- TextIndicatorOptionTightlyFitContent = 1 << 4,
-
- // If there are any non-inline or replaced elements in the Range, indicate the bounding rect
- // of the range instead of the individual subrects, and don't restrict painting to the given Range
- TextIndicatorOptionUseBoundingRectAndPaintAllContentForComplexRanges = 1 << 5,
-
- // By default, TextIndicator removes any margin if the given Range matches the
- // selection Range. If this option is set, maintain the margin in any case.
- TextIndicatorOptionIncludeMarginIfRangeMatchesSelection = 1 << 6,
-
- // By default, TextIndicator clips the indicated rects to the visible content rect.
- // If this option is set, do not clip the indicated rects.
- TextIndicatorOptionDoNotClipToVisibleRect = 1 << 7,
-};
-typedef uint8_t TextIndicatorOptions;
-
-struct TextIndicatorData {
- FloatRect selectionRectInRootViewCoordinates;
- FloatRect textBoundingRectInRootViewCoordinates;
- Vector<FloatRect> textRectsInBoundingRectCoordinates;
- float contentImageScaleFactor;
- RefPtr<Image> contentImageWithHighlight;
- RefPtr<Image> contentImage;
- TextIndicatorPresentationTransition presentationTransition;
- TextIndicatorOptions options;
-};
-
-class TextIndicator : public RefCounted<TextIndicator> {
-public:
- // FIXME: These are fairly Mac-specific, and they don't really belong here.
- // But they're needed at TextIndicator creation time, so they can't go in TextIndicatorWindow.
- // Maybe they can live in some Theme code somewhere?
- constexpr static float defaultHorizontalMargin { 2 };
- constexpr static float defaultVerticalMargin { 1 };
-
- WEBCORE_EXPORT static Ref<TextIndicator> create(const TextIndicatorData&);
- WEBCORE_EXPORT static RefPtr<TextIndicator> createWithSelectionInFrame(Frame&, TextIndicatorOptions, TextIndicatorPresentationTransition, FloatSize margin = FloatSize(defaultHorizontalMargin, defaultVerticalMargin));
- WEBCORE_EXPORT static RefPtr<TextIndicator> createWithRange(const Range&, TextIndicatorOptions, TextIndicatorPresentationTransition, FloatSize margin = FloatSize(defaultHorizontalMargin, defaultVerticalMargin));
-
- WEBCORE_EXPORT ~TextIndicator();
-
- FloatRect selectionRectInRootViewCoordinates() const { return m_data.selectionRectInRootViewCoordinates; }
- FloatRect textBoundingRectInRootViewCoordinates() const { return m_data.textBoundingRectInRootViewCoordinates; }
- const Vector<FloatRect>& textRectsInBoundingRectCoordinates() const { return m_data.textRectsInBoundingRectCoordinates; }
- float contentImageScaleFactor() const { return m_data.contentImageScaleFactor; }
- Image* contentImageWithHighlight() const { return m_data.contentImageWithHighlight.get(); }
- Image* contentImage() const { return m_data.contentImage.get(); }
-
- TextIndicatorPresentationTransition presentationTransition() const { return m_data.presentationTransition; }
- void setPresentationTransition(TextIndicatorPresentationTransition transition) { m_data.presentationTransition = transition; }
-
- TextIndicatorData data() const { return m_data; }
-
-private:
- TextIndicator(const TextIndicatorData&);
-
- TextIndicatorData m_data;
-};
-
-} // namespace WebKit
-
-#endif // TextIndicator_h
diff --git a/Source/WebCore/page/UserContentController.cpp b/Source/WebCore/page/UserContentController.cpp
index dfe8e38f4..95fa5fdfd 100644
--- a/Source/WebCore/page/UserContentController.cpp
+++ b/Source/WebCore/page/UserContentController.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014-2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -28,30 +28,16 @@
#include "DOMWrapperWorld.h"
#include "Document.h"
-#include "DocumentLoader.h"
-#include "ExtensionStyleSheets.h"
#include "MainFrame.h"
#include "Page.h"
-#include "ResourceLoadInfo.h"
#include "UserScript.h"
#include "UserStyleSheet.h"
-#include <runtime/JSCellInlines.h>
-#include <runtime/StructureInlines.h>
-
-#if ENABLE(USER_MESSAGE_HANDLERS)
-#include "UserMessageHandlerDescriptor.h"
-#endif
-
-#if ENABLE(CONTENT_EXTENSIONS)
-#include "ContentExtensionCompiler.h"
-#include "ContentExtensionsBackend.h"
-#endif
namespace WebCore {
-Ref<UserContentController> UserContentController::create()
+RefPtr<UserContentController> UserContentController::create()
{
- return adoptRef(*new UserContentController);
+ return adoptRef(new UserContentController);
}
UserContentController::UserContentController()
@@ -82,7 +68,7 @@ void UserContentController::addUserScript(DOMWrapperWorld& world, std::unique_pt
auto& scriptsInWorld = m_userScripts->add(&world, nullptr).iterator->value;
if (!scriptsInWorld)
scriptsInWorld = std::make_unique<UserScriptVector>();
- scriptsInWorld->append(WTFMove(userScript));
+ scriptsInWorld->append(std::move(userScript));
}
void UserContentController::removeUserScript(DOMWrapperWorld& world, const URL& url)
@@ -120,7 +106,7 @@ void UserContentController::addUserStyleSheet(DOMWrapperWorld& world, std::uniqu
auto& styleSheetsInWorld = m_userStyleSheets->add(&world, nullptr).iterator->value;
if (!styleSheetsInWorld)
styleSheetsInWorld = std::make_unique<UserStyleSheetVector>();
- styleSheetsInWorld->append(WTFMove(userStyleSheet));
+ styleSheetsInWorld->append(std::move(userStyleSheet));
if (injectionTime == InjectInExistingDocuments)
invalidateInjectedStyleSheetCacheInAllFrames();
@@ -165,84 +151,6 @@ void UserContentController::removeUserStyleSheets(DOMWrapperWorld& world)
invalidateInjectedStyleSheetCacheInAllFrames();
}
-#if ENABLE(USER_MESSAGE_HANDLERS)
-void UserContentController::addUserMessageHandlerDescriptor(UserMessageHandlerDescriptor& descriptor)
-{
- if (!m_userMessageHandlerDescriptors)
- m_userMessageHandlerDescriptors = std::make_unique<UserMessageHandlerDescriptorMap>();
-
- m_userMessageHandlerDescriptors->add(std::make_pair(descriptor.name(), &descriptor.world()), &descriptor);
-}
-
-void UserContentController::removeUserMessageHandlerDescriptor(UserMessageHandlerDescriptor& descriptor)
-{
- if (!m_userMessageHandlerDescriptors)
- return;
-
- m_userMessageHandlerDescriptors->remove(std::make_pair(descriptor.name(), &descriptor.world()));
-}
-#endif
-
-#if ENABLE(CONTENT_EXTENSIONS)
-void UserContentController::addUserContentExtension(const String& name, RefPtr<ContentExtensions::CompiledContentExtension> contentExtension)
-{
- if (!m_contentExtensionBackend)
- m_contentExtensionBackend = std::make_unique<ContentExtensions::ContentExtensionsBackend>();
-
- m_contentExtensionBackend->addContentExtension(name, contentExtension);
-}
-
-void UserContentController::removeUserContentExtension(const String& name)
-{
- if (!m_contentExtensionBackend)
- return;
-
- m_contentExtensionBackend->removeContentExtension(name);
-}
-
-void UserContentController::removeAllUserContentExtensions()
-{
- if (!m_contentExtensionBackend)
- return;
-
- m_contentExtensionBackend->removeAllContentExtensions();
-}
-
-static bool contentExtensionsEnabled(const DocumentLoader& documentLoader)
-{
- if (auto frame = documentLoader.frame()) {
- if (frame->isMainFrame())
- return documentLoader.userContentExtensionsEnabled();
- if (auto mainDocumentLoader = frame->mainFrame().loader().documentLoader())
- return mainDocumentLoader->userContentExtensionsEnabled();
- }
-
- return true;
-}
-
-ContentExtensions::BlockedStatus UserContentController::processContentExtensionRulesForLoad(ResourceRequest& request, ResourceType resourceType, DocumentLoader& initiatingDocumentLoader)
-{
- if (!m_contentExtensionBackend)
- return ContentExtensions::BlockedStatus::NotBlocked;
-
- if (!contentExtensionsEnabled(initiatingDocumentLoader))
- return ContentExtensions::BlockedStatus::NotBlocked;
-
- return m_contentExtensionBackend->processContentExtensionRulesForLoad(request, resourceType, initiatingDocumentLoader);
-}
-
-Vector<ContentExtensions::Action> UserContentController::actionsForResourceLoad(const ResourceLoadInfo& resourceLoadInfo, DocumentLoader& initiatingDocumentLoader)
-{
- if (!m_contentExtensionBackend)
- return Vector<ContentExtensions::Action>();
-
- if (!contentExtensionsEnabled(initiatingDocumentLoader))
- return Vector<ContentExtensions::Action>();
-
- return m_contentExtensionBackend->actionsForResourceLoad(resourceLoadInfo);
-}
-#endif
-
void UserContentController::removeAllUserContent()
{
m_userScripts = nullptr;
@@ -257,7 +165,7 @@ void UserContentController::invalidateInjectedStyleSheetCacheInAllFrames()
{
for (auto& page : m_pages) {
for (Frame* frame = &page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
- frame->document()->extensionStyleSheets().invalidateInjectedStyleSheetCache();
+ frame->document()->styleSheetCollection().invalidateInjectedStyleSheetCache();
frame->document()->styleResolverChanged(DeferRecalcStyle);
}
}
diff --git a/Source/WebCore/page/UserContentController.h b/Source/WebCore/page/UserContentController.h
index 3b2158ba8..9ddb8d0e1 100644
--- a/Source/WebCore/page/UserContentController.h
+++ b/Source/WebCore/page/UserContentController.h
@@ -32,73 +32,35 @@
#include <wtf/RefCounted.h>
#include <wtf/RefPtr.h>
-#if ENABLE(USER_MESSAGE_HANDLERS)
-#include "UserMessageHandlerDescriptorTypes.h"
-#endif
-
-#if ENABLE(CONTENT_EXTENSIONS)
-#include "ContentExtensionActions.h"
-#endif
-
namespace WebCore {
class DOMWrapperWorld;
-class DocumentLoader;
class Page;
-class ResourceRequest;
-class StyleSheetContents;
class URL;
class UserScript;
class UserStyleSheet;
-class UserMessageHandlerDescriptor;
-
-enum class ResourceType : uint16_t;
-
-struct ResourceLoadInfo;
-
-namespace ContentExtensions {
-class CompiledContentExtension;
-class ContentExtensionsBackend;
-struct Action;
-}
class UserContentController : public RefCounted<UserContentController> {
public:
- WEBCORE_EXPORT static Ref<UserContentController> create();
- WEBCORE_EXPORT ~UserContentController();
+ static RefPtr<UserContentController> create();
+ ~UserContentController();
void addPage(Page&);
void removePage(Page&);
const UserScriptMap* userScripts() const { return m_userScripts.get(); }
- WEBCORE_EXPORT void addUserScript(DOMWrapperWorld&, std::unique_ptr<UserScript>);
- WEBCORE_EXPORT void removeUserScript(DOMWrapperWorld&, const URL&);
- WEBCORE_EXPORT void removeUserScripts(DOMWrapperWorld&);
+ void addUserScript(DOMWrapperWorld&, std::unique_ptr<UserScript>);
+ void removeUserScript(DOMWrapperWorld&, const URL&);
+ void removeUserScripts(DOMWrapperWorld&);
const UserStyleSheetMap* userStyleSheets() const { return m_userStyleSheets.get(); }
- WEBCORE_EXPORT void addUserStyleSheet(DOMWrapperWorld&, std::unique_ptr<UserStyleSheet>, UserStyleInjectionTime);
- WEBCORE_EXPORT void removeUserStyleSheet(DOMWrapperWorld&, const URL&);
- WEBCORE_EXPORT void removeUserStyleSheets(DOMWrapperWorld&);
-
- WEBCORE_EXPORT void removeAllUserContent();
-
-#if ENABLE(USER_MESSAGE_HANDLERS)
- const UserMessageHandlerDescriptorMap* userMessageHandlerDescriptors() const { return m_userMessageHandlerDescriptors.get(); }
-
- WEBCORE_EXPORT void addUserMessageHandlerDescriptor(UserMessageHandlerDescriptor&);
- WEBCORE_EXPORT void removeUserMessageHandlerDescriptor(UserMessageHandlerDescriptor&);
-#endif
-
-#if ENABLE(CONTENT_EXTENSIONS)
- WEBCORE_EXPORT void addUserContentExtension(const String& name, RefPtr<ContentExtensions::CompiledContentExtension>);
- WEBCORE_EXPORT void removeUserContentExtension(const String& name);
- WEBCORE_EXPORT void removeAllUserContentExtensions();
+ void addUserStyleSheet(DOMWrapperWorld&, std::unique_ptr<UserStyleSheet>, UserStyleInjectionTime);
+ void removeUserStyleSheet(DOMWrapperWorld&, const URL&);
+ void removeUserStyleSheets(DOMWrapperWorld&);
- ContentExtensions::BlockedStatus processContentExtensionRulesForLoad(ResourceRequest&, ResourceType, DocumentLoader& initiatingDocumentLoader);
- Vector<ContentExtensions::Action> actionsForResourceLoad(const ResourceLoadInfo&, DocumentLoader& initiatingDocumentLoader);
-#endif
+ void removeAllUserContent();
private:
UserContentController();
@@ -109,12 +71,6 @@ private:
std::unique_ptr<UserScriptMap> m_userScripts;
std::unique_ptr<UserStyleSheetMap> m_userStyleSheets;
-#if ENABLE(USER_MESSAGE_HANDLERS)
- std::unique_ptr<UserMessageHandlerDescriptorMap> m_userMessageHandlerDescriptors;
-#endif
-#if ENABLE(CONTENT_EXTENSIONS)
- std::unique_ptr<ContentExtensions::ContentExtensionsBackend> m_contentExtensionBackend;
-#endif
};
} // namespace WebCore
diff --git a/Source/WebCore/page/UserContentTypes.h b/Source/WebCore/page/UserContentTypes.h
index a32cf7c67..d012b8cbd 100644
--- a/Source/WebCore/page/UserContentTypes.h
+++ b/Source/WebCore/page/UserContentTypes.h
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
diff --git a/Source/WebCore/page/UserContentURLPattern.cpp b/Source/WebCore/page/UserContentURLPattern.cpp
index 953ce0ff4..fdaed1e50 100644
--- a/Source/WebCore/page/UserContentURLPattern.cpp
+++ b/Source/WebCore/page/UserContentURLPattern.cpp
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -27,7 +27,6 @@
#include "UserContentURLPattern.h"
#include "URL.h"
-#include <wtf/NeverDestroyed.h>
#include <wtf/StdLibExtras.h>
namespace WebCore {
@@ -38,8 +37,9 @@ bool UserContentURLPattern::matchesPatterns(const URL& url, const Vector<String>
// If there is no whitelist at all, then all URLs are assumed to be in the whitelist.
bool matchesWhitelist = whitelist.isEmpty();
if (!matchesWhitelist) {
- for (auto& entry : whitelist) {
- UserContentURLPattern contentPattern(entry);
+ size_t whitelistSize = whitelist.size();
+ for (size_t i = 0; i < whitelistSize; ++i) {
+ UserContentURLPattern contentPattern(whitelist[i]);
if (contentPattern.matches(url)) {
matchesWhitelist = true;
break;
@@ -49,8 +49,9 @@ bool UserContentURLPattern::matchesPatterns(const URL& url, const Vector<String>
bool matchesBlacklist = false;
if (!blacklist.isEmpty()) {
- for (auto& entry : blacklist) {
- UserContentURLPattern contentPattern(entry);
+ size_t blacklistSize = blacklist.size();
+ for (size_t i = 0; i < blacklistSize; ++i) {
+ UserContentURLPattern contentPattern(blacklist[i]);
if (contentPattern.matches(url)) {
matchesBlacklist = true;
break;
@@ -63,7 +64,7 @@ bool UserContentURLPattern::matchesPatterns(const URL& url, const Vector<String>
bool UserContentURLPattern::parse(const String& pattern)
{
- static NeverDestroyed<const String> schemeSeparator(ASCIILiteral("://"));
+ DEFINE_STATIC_LOCAL(const String, schemeSeparator, (ASCIILiteral("://")));
size_t schemeEndPos = pattern.find(schemeSeparator);
if (schemeEndPos == notFound)
@@ -71,16 +72,16 @@ bool UserContentURLPattern::parse(const String& pattern)
m_scheme = pattern.left(schemeEndPos);
- unsigned hostStartPos = schemeEndPos + schemeSeparator.get().length();
+ unsigned hostStartPos = schemeEndPos + schemeSeparator.length();
if (hostStartPos >= pattern.length())
return false;
int pathStartPos = 0;
- if (equalLettersIgnoringASCIICase(m_scheme, "file"))
+ if (equalIgnoringCase(m_scheme, "file"))
pathStartPos = hostStartPos;
else {
- size_t hostEndPos = pattern.find('/', hostStartPos);
+ size_t hostEndPos = pattern.find("/", hostStartPos);
if (hostEndPos == notFound)
return false;
@@ -98,7 +99,7 @@ bool UserContentURLPattern::parse(const String& pattern)
}
// No other '*' can occur in the host.
- if (m_host.find('*') != notFound)
+ if (m_host.find("*") != notFound)
return false;
pathStartPos = hostEndPos;
@@ -114,10 +115,10 @@ bool UserContentURLPattern::matches(const URL& test) const
if (m_invalid)
return false;
- if (!equalIgnoringASCIICase(test.protocol(), m_scheme))
+ if (!equalIgnoringCase(test.protocol(), m_scheme))
return false;
- if (!equalLettersIgnoringASCIICase(m_scheme, "file") && !matchesHost(test))
+ if (!equalIgnoringCase(m_scheme, "file") && !matchesHost(test))
return false;
return matchesPath(test);
@@ -126,7 +127,7 @@ bool UserContentURLPattern::matches(const URL& test) const
bool UserContentURLPattern::matchesHost(const URL& test) const
{
const String& host = test.host();
- if (equalIgnoringASCIICase(host, m_host))
+ if (equalIgnoringCase(host, m_host))
return true;
if (!m_matchSubdomains)
diff --git a/Source/WebCore/page/UserContentURLPattern.h b/Source/WebCore/page/UserContentURLPattern.h
index 8b8af6d80..a86892bce 100644
--- a/Source/WebCore/page/UserContentURLPattern.h
+++ b/Source/WebCore/page/UserContentURLPattern.h
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -45,7 +45,7 @@ public:
bool isValid() const { return !m_invalid; }
- WEBCORE_EXPORT bool matches(const URL&) const;
+ bool matches(const URL&) const;
const String& scheme() const { return m_scheme; }
const String& host() const { return m_host; }
@@ -56,7 +56,7 @@ public:
static bool matchesPatterns(const URL&, const Vector<String>& whitelist, const Vector<String>& blacklist);
private:
- WEBCORE_EXPORT bool parse(const String& pattern);
+ bool parse(const String& pattern);
bool matchesHost(const URL&) const;
bool matchesPath(const URL&) const;
diff --git a/Source/WebCore/page/UserMessageHandler.cpp b/Source/WebCore/page/UserMessageHandler.cpp
deleted file mode 100644
index 05c5a766d..000000000
--- a/Source/WebCore/page/UserMessageHandler.cpp
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "UserMessageHandler.h"
-
-#if ENABLE(USER_MESSAGE_HANDLERS)
-
-#include "ExceptionCode.h"
-#include "Frame.h"
-#include "SerializedScriptValue.h"
-
-namespace WebCore {
-
-UserMessageHandler::UserMessageHandler(Frame& frame, UserMessageHandlerDescriptor& descriptor)
- : FrameDestructionObserver(&frame)
- , m_descriptor(descriptor)
-{
-}
-
-UserMessageHandler::~UserMessageHandler()
-{
-}
-
-void UserMessageHandler::postMessage(PassRefPtr<SerializedScriptValue> value, ExceptionCode& ec)
-{
- // Check to see if the descriptor has been removed. This can happen if the host application has
- // removed the named message handler at the WebKit2 API level.
- if (!m_descriptor->client()) {
- ec = INVALID_ACCESS_ERR;
- return;
- }
-
- m_descriptor->client()->didPostMessage(*this, value.get());
-}
-
-const AtomicString& UserMessageHandler::name()
-{
- return m_descriptor->name();
-}
-
-DOMWrapperWorld& UserMessageHandler::world()
-{
- return m_descriptor->world();
-}
-
-} // namespace WebCore
-
-#endif // ENABLE(USER_MESSAGE_HANDLERS)
diff --git a/Source/WebCore/page/UserMessageHandler.h b/Source/WebCore/page/UserMessageHandler.h
deleted file mode 100644
index e9a8814d1..000000000
--- a/Source/WebCore/page/UserMessageHandler.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef UserMessageHandler_h
-#define UserMessageHandler_h
-
-#if ENABLE(USER_MESSAGE_HANDLERS)
-
-#include "FrameDestructionObserver.h"
-#include "UserMessageHandlerDescriptor.h"
-#include <bindings/ScriptValue.h>
-
-namespace WebCore {
-
-typedef int ExceptionCode;
-
-class UserMessageHandler : public RefCounted<UserMessageHandler>, public FrameDestructionObserver {
-public:
- static Ref<UserMessageHandler> create(Frame& frame, UserMessageHandlerDescriptor& descriptor)
- {
- return adoptRef(*new UserMessageHandler(frame, descriptor));
- }
- virtual ~UserMessageHandler();
-
- void postMessage(PassRefPtr<SerializedScriptValue>, ExceptionCode&);
-
- const AtomicString& name();
- DOMWrapperWorld& world();
- const UserMessageHandlerDescriptor& descriptor() const { return m_descriptor.get(); }
-
-private:
- UserMessageHandler(Frame&, UserMessageHandlerDescriptor&);
-
- Ref<UserMessageHandlerDescriptor> m_descriptor;
-};
-
-} // namespace WebCore
-
-#endif // ENABLE(USER_MESSAGE_HANDLERS)
-#endif // UserMessageHandler_h
diff --git a/Source/WebCore/page/UserMessageHandler.idl b/Source/WebCore/page/UserMessageHandler.idl
deleted file mode 100644
index b1a0387a2..000000000
--- a/Source/WebCore/page/UserMessageHandler.idl
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-[
- Conditional=USER_MESSAGE_HANDLERS
-] interface UserMessageHandler {
- [RaisesException] void postMessage(SerializedScriptValue message);
-};
diff --git a/Source/WebCore/page/UserMessageHandlerDescriptor.cpp b/Source/WebCore/page/UserMessageHandlerDescriptor.cpp
deleted file mode 100644
index 72f02bedb..000000000
--- a/Source/WebCore/page/UserMessageHandlerDescriptor.cpp
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "UserMessageHandlerDescriptor.h"
-
-#if ENABLE(USER_MESSAGE_HANDLERS)
-
-#include "DOMWrapperWorld.h"
-
-namespace WebCore {
-
-UserMessageHandlerDescriptor::UserMessageHandlerDescriptor(const AtomicString& name, DOMWrapperWorld& world, Client& client)
- : m_name(name)
- , m_world(world)
- , m_client(&client)
-{
-}
-
-UserMessageHandlerDescriptor::~UserMessageHandlerDescriptor()
-{
-}
-
-const AtomicString& UserMessageHandlerDescriptor::name()
-{
- return m_name;
-}
-
-DOMWrapperWorld& UserMessageHandlerDescriptor::world()
-{
- return m_world.get();
-}
-
-} // namespace WebCore
-
-#endif // ENABLE(USER_MESSAGE_HANDLERS)
diff --git a/Source/WebCore/page/UserMessageHandlerDescriptor.h b/Source/WebCore/page/UserMessageHandlerDescriptor.h
deleted file mode 100644
index 1f1f20b26..000000000
--- a/Source/WebCore/page/UserMessageHandlerDescriptor.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef UserMessageHandlerDescriptor_h
-#define UserMessageHandlerDescriptor_h
-
-#if ENABLE(USER_MESSAGE_HANDLERS)
-
-#include <wtf/PassRefPtr.h>
-#include <wtf/RefCounted.h>
-#include <wtf/RefPtr.h>
-#include <wtf/text/AtomicString.h>
-
-namespace WebCore {
-
-class Frame;
-class DOMWrapperWorld;
-class UserMessageHandler;
-class SerializedScriptValue;
-
-class UserMessageHandlerDescriptor : public RefCounted<UserMessageHandlerDescriptor> {
-public:
- class Client {
- public:
- virtual ~Client() { }
- virtual void didPostMessage(UserMessageHandler&, SerializedScriptValue*) = 0;
- };
-
- static Ref<UserMessageHandlerDescriptor> create(const AtomicString& name, DOMWrapperWorld& world, Client& client)
- {
- return adoptRef(*new UserMessageHandlerDescriptor(name, world, client));
- }
- WEBCORE_EXPORT ~UserMessageHandlerDescriptor();
-
- const AtomicString& name();
- DOMWrapperWorld& world();
-
- Client* client() const { return m_client; }
- void invalidateClient() { m_client = nullptr; }
-
-private:
- WEBCORE_EXPORT explicit UserMessageHandlerDescriptor(const AtomicString&, DOMWrapperWorld&, Client&);
-
- AtomicString m_name;
- Ref<DOMWrapperWorld> m_world;
- Client* m_client;
-};
-
-} // namespace WebCore
-
-#endif // ENABLE(USER_MESSAGE_HANDLERS)
-#endif // UserMessageHandlerDescriptor_h
diff --git a/Source/WebCore/page/UserMessageHandlerDescriptorTypes.h b/Source/WebCore/page/UserMessageHandlerDescriptorTypes.h
deleted file mode 100644
index eb8d163f4..000000000
--- a/Source/WebCore/page/UserMessageHandlerDescriptorTypes.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef UserMessageHandlerDescriptorTypes_h
-#define UserMessageHandlerDescriptorTypes_h
-
-#if ENABLE(USER_MESSAGE_HANDLERS)
-
-#include <wtf/HashMap.h>
-#include <wtf/RefPtr.h>
-#include <wtf/text/AtomicString.h>
-#include <wtf/text/AtomicStringHash.h>
-
-namespace WebCore {
-
-class DOMWrapperWorld;
-class UserMessageHandlerDescriptor;
-
-typedef HashMap<std::pair<AtomicString, RefPtr<DOMWrapperWorld>>, RefPtr<UserMessageHandlerDescriptor>> UserMessageHandlerDescriptorMap;
-
-} // namespace WebCore
-
-#endif // ENABLE(USER_MESSAGE_HANDLERS)
-#endif // UserMessageHandlerDescriptorTypes_h
diff --git a/Source/WebCore/page/UserMessageHandlersNamespace.cpp b/Source/WebCore/page/UserMessageHandlersNamespace.cpp
deleted file mode 100644
index 03321f5e2..000000000
--- a/Source/WebCore/page/UserMessageHandlersNamespace.cpp
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "UserMessageHandlersNamespace.h"
-
-#if ENABLE(USER_MESSAGE_HANDLERS)
-
-#include "DOMWrapperWorld.h"
-#include "Frame.h"
-#include "Page.h"
-#include "UserContentController.h"
-
-namespace WebCore {
-
-UserMessageHandlersNamespace::UserMessageHandlersNamespace(Frame& frame)
- : FrameDestructionObserver(&frame)
-{
-}
-
-UserMessageHandlersNamespace::~UserMessageHandlersNamespace()
-{
-}
-
-UserMessageHandler* UserMessageHandlersNamespace::handler(const AtomicString& name, DOMWrapperWorld& world)
-{
- if (!frame())
- return nullptr;
-
- Page* page = frame()->page();
- if (!page)
- return nullptr;
-
- const auto* userContentController = page->userContentController();
- if (!userContentController)
- return nullptr;
-
- const auto* userMessageHandlerDescriptors = userContentController->userMessageHandlerDescriptors();
- if (!userMessageHandlerDescriptors)
- return nullptr;
-
- RefPtr<UserMessageHandlerDescriptor> descriptor = userMessageHandlerDescriptors->get(std::make_pair(name, &world));
- if (!descriptor)
- return nullptr;
-
- for (auto& handler : m_messageHandlers) {
- if (&handler->descriptor() == descriptor.get())
- return &handler.get();
- }
-
- auto liveHandlers = userMessageHandlerDescriptors->values();
- m_messageHandlers.removeAllMatching([liveHandlers](const Ref<UserMessageHandler>& handler) {
- for (const auto& liveHandler : liveHandlers) {
- if (liveHandler.get() == &handler->descriptor())
- return true;
- }
- return false;
- });
-
- m_messageHandlers.append(UserMessageHandler::create(*frame(), *descriptor));
- return &m_messageHandlers.last().get();
-}
-
-} // namespace WebCore
-
-#endif // ENABLE(USER_MESSAGE_HANDLERS)
diff --git a/Source/WebCore/page/UserMessageHandlersNamespace.h b/Source/WebCore/page/UserMessageHandlersNamespace.h
deleted file mode 100644
index 4eecb503b..000000000
--- a/Source/WebCore/page/UserMessageHandlersNamespace.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef UserMessageHandlersNamespace_h
-#define UserMessageHandlersNamespace_h
-
-#if ENABLE(USER_MESSAGE_HANDLERS)
-
-#include "FrameDestructionObserver.h"
-#include "UserMessageHandler.h"
-#include <wtf/RefCounted.h>
-#include <wtf/RefPtr.h>
-#include <wtf/Vector.h>
-#include <wtf/text/AtomicString.h>
-
-namespace WebCore {
-
-class Frame;
-class UserMessageHandler;
-class DOMWrapperWorld;
-
-class UserMessageHandlersNamespace : public RefCounted<UserMessageHandlersNamespace>, public FrameDestructionObserver {
-public:
- static Ref<UserMessageHandlersNamespace> create(Frame& frame)
- {
- return adoptRef(*new UserMessageHandlersNamespace(frame));
- }
-
- virtual ~UserMessageHandlersNamespace();
-
- UserMessageHandler* handler(const AtomicString&, DOMWrapperWorld&);
-
-private:
- explicit UserMessageHandlersNamespace(Frame&);
-
- Vector<Ref<UserMessageHandler>> m_messageHandlers;
-};
-
-} // namespace WebCore
-
-#endif // ENABLE(USER_MESSAGE_HANDLERS)
-#endif // UserMessageHandlersNamespace_h
diff --git a/Source/WebCore/page/UserMessageHandlersNamespace.idl b/Source/WebCore/page/UserMessageHandlersNamespace.idl
deleted file mode 100644
index 7d2050fdf..000000000
--- a/Source/WebCore/page/UserMessageHandlersNamespace.idl
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-[
- JSCustomGetOwnPropertySlotAndDescriptor,
- Conditional=USER_MESSAGE_HANDLERS
-] interface UserMessageHandlersNamespace {
-};
diff --git a/Source/WebCore/page/UserScript.h b/Source/WebCore/page/UserScript.h
index 77f25c774..8a2b41187 100644
--- a/Source/WebCore/page/UserScript.h
+++ b/Source/WebCore/page/UserScript.h
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -42,11 +42,11 @@ public:
{
}
- UserScript(const String& source, const URL& url, Vector<String>&& whitelist, Vector<String>&& blacklist, UserScriptInjectionTime injectionTime, UserContentInjectedFrames injectedFrames)
+ UserScript(const String& source, const URL& url, const Vector<String>& whitelist, const Vector<String>& blacklist, UserScriptInjectionTime injectionTime, UserContentInjectedFrames injectedFrames)
: m_source(source)
, m_url(url)
- , m_whitelist(WTFMove(whitelist))
- , m_blacklist(WTFMove(blacklist))
+ , m_whitelist(whitelist)
+ , m_blacklist(blacklist)
, m_injectionTime(injectionTime)
, m_injectedFrames(injectedFrames)
{
diff --git a/Source/WebCore/page/UserScriptTypes.h b/Source/WebCore/page/UserScriptTypes.h
index 8212468cd..f85977e54 100644
--- a/Source/WebCore/page/UserScriptTypes.h
+++ b/Source/WebCore/page/UserScriptTypes.h
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
diff --git a/Source/WebCore/page/UserStyleSheet.h b/Source/WebCore/page/UserStyleSheet.h
index bb1b6534f..7234462cb 100644
--- a/Source/WebCore/page/UserStyleSheet.h
+++ b/Source/WebCore/page/UserStyleSheet.h
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -42,11 +42,11 @@ public:
{
}
- UserStyleSheet(const String& source, const URL& url, Vector<String>&& whitelist, Vector<String>&& blacklist, UserContentInjectedFrames injectedFrames, UserStyleLevel level)
+ UserStyleSheet(const String& source, const URL& url, const Vector<String>& whitelist, const Vector<String>& blacklist, UserContentInjectedFrames injectedFrames, UserStyleLevel level)
: m_source(source)
, m_url(url)
- , m_whitelist(WTFMove(whitelist))
- , m_blacklist(WTFMove(blacklist))
+ , m_whitelist(whitelist)
+ , m_blacklist(blacklist)
, m_injectedFrames(injectedFrames)
, m_level(level)
{
diff --git a/Source/WebCore/page/UserStyleSheetTypes.h b/Source/WebCore/page/UserStyleSheetTypes.h
index b5fd78431..207286464 100644
--- a/Source/WebCore/page/UserStyleSheetTypes.h
+++ b/Source/WebCore/page/UserStyleSheetTypes.h
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
diff --git a/Source/WebCore/page/ViewState.h b/Source/WebCore/page/ViewState.h
index c99e1f01a..788a7ff82 100644
--- a/Source/WebCore/page/ViewState.h
+++ b/Source/WebCore/page/ViewState.h
@@ -33,15 +33,14 @@ struct ViewState {
WindowIsActive = 1 << 0,
IsFocused = 1 << 1,
IsVisible = 1 << 2,
- IsVisibleOrOccluded = 1 << 3,
- IsInWindow = 1 << 4,
- IsVisuallyIdle = 1 << 5,
+ IsInWindow = 1 << 3,
+ IsVisuallyIdle = 1 << 4,
};
typedef unsigned Flags;
static const Flags NoFlags = 0;
- static const Flags AllFlags = WindowIsActive | IsFocused | IsVisible | IsVisibleOrOccluded | IsInWindow | IsVisuallyIdle;
+ static const Flags AllFlags = WindowIsActive | IsFocused | IsVisible | IsInWindow | IsVisuallyIdle;
};
} // namespace WebCore
diff --git a/Source/WebCore/page/ViewportConfiguration.cpp b/Source/WebCore/page/ViewportConfiguration.cpp
deleted file mode 100644
index a3b4c6c58..000000000
--- a/Source/WebCore/page/ViewportConfiguration.cpp
+++ /dev/null
@@ -1,480 +0,0 @@
-/*
- * Copyright (C) 2005-2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "ViewportConfiguration.h"
-
-#include <WebCore/TextStream.h>
-#include <wtf/Assertions.h>
-#include <wtf/MathExtras.h>
-#include <wtf/text/CString.h>
-
-#if PLATFORM(IOS)
-#include "PlatformScreen.h"
-#endif
-
-namespace WebCore {
-
-#if !ASSERT_DISABLED
-static bool constraintsAreAllRelative(const ViewportConfiguration::Parameters& configuration)
-{
- return !configuration.widthIsSet && !configuration.heightIsSet && !configuration.initialScaleIsSet;
-}
-#endif
-
-ViewportConfiguration::ViewportConfiguration()
- : m_minimumLayoutSize(1024, 768)
- , m_canIgnoreScalingConstraints(false)
- , m_forceAlwaysUserScalable(false)
-{
- // Setup a reasonable default configuration to avoid computing infinite scale/sizes.
- // Those are the original iPhone configuration.
- m_defaultConfiguration = ViewportConfiguration::webpageParameters();
- updateConfiguration();
-}
-
-void ViewportConfiguration::setDefaultConfiguration(const ViewportConfiguration::Parameters& defaultConfiguration)
-{
- ASSERT(!constraintsAreAllRelative(m_configuration));
- ASSERT(!defaultConfiguration.initialScaleIsSet || defaultConfiguration.initialScale > 0);
- ASSERT(defaultConfiguration.minimumScale > 0);
- ASSERT(defaultConfiguration.maximumScale >= defaultConfiguration.minimumScale);
-
- m_defaultConfiguration = defaultConfiguration;
- updateConfiguration();
-}
-
-bool ViewportConfiguration::setContentsSize(const IntSize& contentSize)
-{
- if (m_contentSize == contentSize)
- return false;
-
- m_contentSize = contentSize;
- updateConfiguration();
- return true;
-}
-
-bool ViewportConfiguration::setMinimumLayoutSize(const FloatSize& minimumLayoutSize)
-{
- if (m_minimumLayoutSize == minimumLayoutSize)
- return false;
-
- m_minimumLayoutSize = minimumLayoutSize;
- updateConfiguration();
- return true;
-}
-
-bool ViewportConfiguration::setViewportArguments(const ViewportArguments& viewportArguments)
-{
- if (m_viewportArguments == viewportArguments)
- return false;
-
- m_viewportArguments = viewportArguments;
- updateConfiguration();
- return true;
-}
-
-bool ViewportConfiguration::setCanIgnoreScalingConstraints(bool canIgnoreScalingConstraints)
-{
- if (canIgnoreScalingConstraints == m_canIgnoreScalingConstraints)
- return false;
-
- m_canIgnoreScalingConstraints = canIgnoreScalingConstraints;
- updateConfiguration();
- return true;
-}
-
-IntSize ViewportConfiguration::layoutSize() const
-{
- return IntSize(layoutWidth(), layoutHeight());
-}
-
-bool ViewportConfiguration::shouldIgnoreHorizontalScalingConstraints() const
-{
- if (!m_canIgnoreScalingConstraints)
- return false;
-
- if (!m_configuration.allowsShrinkToFit)
- return false;
-
- bool laidOutWiderThanViewport = m_contentSize.width() > layoutWidth();
- if (m_viewportArguments.width == ViewportArguments::ValueDeviceWidth)
- return laidOutWiderThanViewport;
-
- if (m_configuration.initialScaleIsSet && m_configuration.initialScale == 1)
- return laidOutWiderThanViewport;
-
- return false;
-}
-
-bool ViewportConfiguration::shouldIgnoreVerticalScalingConstraints() const
-{
- if (!m_canIgnoreScalingConstraints)
- return false;
-
- if (!m_configuration.allowsShrinkToFit)
- return false;
-
- bool laidOutTallerThanViewport = m_contentSize.height() > layoutHeight();
- if (m_viewportArguments.height == ViewportArguments::ValueDeviceHeight && m_viewportArguments.width == ViewportArguments::ValueAuto)
- return laidOutTallerThanViewport;
-
- return false;
-}
-
-bool ViewportConfiguration::shouldIgnoreScalingConstraints() const
-{
- return shouldIgnoreHorizontalScalingConstraints() || shouldIgnoreVerticalScalingConstraints();
-}
-
-double ViewportConfiguration::initialScaleFromSize(double width, double height, bool shouldIgnoreScalingConstraints) const
-{
- ASSERT(!constraintsAreAllRelative(m_configuration));
-
- // If the document has specified its own initial scale, use it regardless.
- // This is guaranteed to be sanity checked already, so no need for MIN/MAX.
- if (m_configuration.initialScaleIsSet && !shouldIgnoreScalingConstraints)
- return m_configuration.initialScale;
-
- // If not, it is up to us to determine the initial scale.
- // We want a scale small enough to fit the document width-wise.
- const FloatSize& minimumLayoutSize = m_minimumLayoutSize;
- double initialScale = 0;
- if (width > 0 && !shouldIgnoreVerticalScalingConstraints())
- initialScale = minimumLayoutSize.width() / width;
-
- // Prevent the initial scale from shrinking to a height smaller than our view's minimum height.
- if (height > 0 && height * initialScale < minimumLayoutSize.height() && !shouldIgnoreHorizontalScalingConstraints())
- initialScale = minimumLayoutSize.height() / height;
- return std::min(std::max(initialScale, shouldIgnoreScalingConstraints ? m_defaultConfiguration.minimumScale : m_configuration.minimumScale), m_configuration.maximumScale);
-}
-
-double ViewportConfiguration::initialScale() const
-{
- return initialScaleFromSize(m_contentSize.width() > 0 ? m_contentSize.width() : layoutWidth(), m_contentSize.height() > 0 ? m_contentSize.height() : layoutHeight(), shouldIgnoreScalingConstraints());
-}
-
-double ViewportConfiguration::initialScaleIgnoringContentSize() const
-{
- return initialScaleFromSize(layoutWidth(), layoutHeight(), false);
-}
-
-double ViewportConfiguration::minimumScale() const
-{
- // If we scale to fit, then this is our minimum scale as well.
- if (!m_configuration.initialScaleIsSet || shouldIgnoreScalingConstraints())
- return initialScale();
-
- // If not, we still need to sanity check our value.
- double minimumScale = m_configuration.minimumScale;
-
- const FloatSize& minimumLayoutSize = m_minimumLayoutSize;
- double contentWidth = m_contentSize.width();
- if (contentWidth > 0 && contentWidth * minimumScale < minimumLayoutSize.width() && !shouldIgnoreVerticalScalingConstraints())
- minimumScale = minimumLayoutSize.width() / contentWidth;
-
- double contentHeight = m_contentSize.height();
- if (contentHeight > 0 && contentHeight * minimumScale < minimumLayoutSize.height() && !shouldIgnoreHorizontalScalingConstraints())
- minimumScale = minimumLayoutSize.height() / contentHeight;
-
- minimumScale = std::min(std::max(minimumScale, m_configuration.minimumScale), m_configuration.maximumScale);
-
- return minimumScale;
-}
-
-bool ViewportConfiguration::allowsUserScaling() const
-{
- return m_forceAlwaysUserScalable || shouldIgnoreScalingConstraints() || m_configuration.allowsUserScaling;
-}
-
-ViewportConfiguration::Parameters ViewportConfiguration::webpageParameters()
-{
- Parameters parameters;
- parameters.width = 980;
- parameters.widthIsSet = true;
- parameters.allowsUserScaling = true;
- parameters.allowsShrinkToFit = true;
- parameters.minimumScale = 0.25;
- parameters.maximumScale = 5;
- return parameters;
-}
-
-ViewportConfiguration::Parameters ViewportConfiguration::textDocumentParameters()
-{
- Parameters parameters;
-
-#if PLATFORM(IOS)
- parameters.width = static_cast<int>(screenSize().width());
-#else
- // FIXME: this needs to be unified with ViewportArguments on all ports.
- parameters.width = 320;
-#endif
-
- parameters.widthIsSet = true;
- parameters.allowsUserScaling = true;
- parameters.allowsShrinkToFit = false;
- parameters.minimumScale = 0.25;
- parameters.maximumScale = 5;
- return parameters;
-}
-
-ViewportConfiguration::Parameters ViewportConfiguration::imageDocumentParameters()
-{
- Parameters parameters;
- parameters.width = 980;
- parameters.widthIsSet = true;
- parameters.allowsUserScaling = true;
- parameters.allowsShrinkToFit = false;
- parameters.minimumScale = 0.01;
- parameters.maximumScale = 5;
- return parameters;
-}
-
-ViewportConfiguration::Parameters ViewportConfiguration::xhtmlMobileParameters()
-{
- Parameters parameters = webpageParameters();
- parameters.width = 320;
- return parameters;
-}
-
-ViewportConfiguration::Parameters ViewportConfiguration::testingParameters()
-{
- Parameters parameters;
- parameters.initialScale = 1;
- parameters.initialScaleIsSet = true;
- parameters.allowsShrinkToFit = true;
- parameters.minimumScale = 1;
- parameters.maximumScale = 5;
- return parameters;
-}
-
-static inline bool viewportArgumentValueIsValid(float value)
-{
- return value > 0;
-}
-
-template<typename ValueType, typename ViewportArgumentsType>
-static inline void applyViewportArgument(ValueType& value, ViewportArgumentsType viewportArgumentValue, ValueType minimum, ValueType maximum)
-{
- if (viewportArgumentValueIsValid(viewportArgumentValue))
- value = std::min(maximum, std::max(minimum, static_cast<ValueType>(viewportArgumentValue)));
-}
-
-template<typename ValueType, typename ViewportArgumentsType>
-static inline void applyViewportArgument(ValueType& value, bool& valueIsSet, ViewportArgumentsType viewportArgumentValue, ValueType minimum, ValueType maximum)
-{
- if (viewportArgumentValueIsValid(viewportArgumentValue)) {
- value = std::min(maximum, std::max(minimum, static_cast<ValueType>(viewportArgumentValue)));
- valueIsSet = true;
- } else
- valueIsSet = false;
-}
-
-static inline bool booleanViewportArgumentIsSet(float value)
-{
- return !value || value == 1;
-}
-
-void ViewportConfiguration::updateConfiguration()
-{
- m_configuration = m_defaultConfiguration;
-
- const double minimumViewportArgumentsScaleFactor = 0.1;
- const double maximumViewportArgumentsScaleFactor = 10.0;
-
- bool viewportArgumentsOverridesInitialScale;
- bool viewportArgumentsOverridesWidth;
- bool viewportArgumentsOverridesHeight;
-
- applyViewportArgument(m_configuration.minimumScale, m_viewportArguments.minZoom, minimumViewportArgumentsScaleFactor, maximumViewportArgumentsScaleFactor);
- applyViewportArgument(m_configuration.maximumScale, m_viewportArguments.maxZoom, m_configuration.minimumScale, maximumViewportArgumentsScaleFactor);
- applyViewportArgument(m_configuration.initialScale, viewportArgumentsOverridesInitialScale, m_viewportArguments.zoom, m_configuration.minimumScale, m_configuration.maximumScale);
-
- double minimumViewportArgumentsDimension = 10;
- double maximumViewportArgumentsDimension = 10000;
- applyViewportArgument(m_configuration.width, viewportArgumentsOverridesWidth, viewportArgumentsLength(m_viewportArguments.width), minimumViewportArgumentsDimension, maximumViewportArgumentsDimension);
- applyViewportArgument(m_configuration.height, viewportArgumentsOverridesHeight, viewportArgumentsLength(m_viewportArguments.height), minimumViewportArgumentsDimension, maximumViewportArgumentsDimension);
-
- if (viewportArgumentsOverridesInitialScale || viewportArgumentsOverridesWidth || viewportArgumentsOverridesHeight) {
- m_configuration.initialScaleIsSet = viewportArgumentsOverridesInitialScale;
- m_configuration.widthIsSet = viewportArgumentsOverridesWidth;
- m_configuration.heightIsSet = viewportArgumentsOverridesHeight;
- }
-
- if (booleanViewportArgumentIsSet(m_viewportArguments.userZoom))
- m_configuration.allowsUserScaling = m_viewportArguments.userZoom != 0.;
-
- if (booleanViewportArgumentIsSet(m_viewportArguments.shrinkToFit))
- m_configuration.allowsShrinkToFit = m_viewportArguments.shrinkToFit != 0.;
-}
-
-double ViewportConfiguration::viewportArgumentsLength(double length) const
-{
- if (length == ViewportArguments::ValueDeviceWidth)
- return m_minimumLayoutSize.width();
- if (length == ViewportArguments::ValueDeviceHeight)
- return m_minimumLayoutSize.height();
- return length;
-}
-
-int ViewportConfiguration::layoutWidth() const
-{
- ASSERT(!constraintsAreAllRelative(m_configuration));
-
- const FloatSize& minimumLayoutSize = m_minimumLayoutSize;
- if (m_configuration.widthIsSet) {
- // If we scale to fit, then accept the viewport width with sanity checking.
- if (!m_configuration.initialScaleIsSet) {
- double maximumScale = this->maximumScale();
- double maximumContentWidthInViewportCoordinate = maximumScale * m_configuration.width;
- if (maximumContentWidthInViewportCoordinate < minimumLayoutSize.width()) {
- // The content zoomed to maxScale does not fit the the view. Return the minimum width
- // satisfying the constraint maximumScale.
- return std::round(minimumLayoutSize.width() / maximumScale);
- }
- return std::round(m_configuration.width);
- }
-
- // If not, make sure the viewport width and initial scale can co-exist.
- double initialContentWidthInViewportCoordinate = m_configuration.width * m_configuration.initialScale;
- if (initialContentWidthInViewportCoordinate < minimumLayoutSize.width()) {
- // The specified width does not fit in viewport. Return the minimum width that satisfy the initialScale constraint.
- return std::round(minimumLayoutSize.width() / m_configuration.initialScale);
- }
- return std::round(m_configuration.width);
- }
-
- // If the page has a real scale, then just return the minimum size over the initial scale.
- if (m_configuration.initialScaleIsSet && !m_configuration.heightIsSet)
- return std::round(minimumLayoutSize.width() / m_configuration.initialScale);
-
- if (minimumLayoutSize.height() > 0)
- return std::round(minimumLayoutSize.width() * layoutHeight() / minimumLayoutSize.height());
- return minimumLayoutSize.width();
-}
-
-int ViewportConfiguration::layoutHeight() const
-{
- ASSERT(!constraintsAreAllRelative(m_configuration));
-
- const FloatSize& minimumLayoutSize = m_minimumLayoutSize;
- if (m_configuration.heightIsSet) {
- // If we scale to fit, then accept the viewport height with sanity checking.
- if (!m_configuration.initialScaleIsSet) {
- double maximumScale = this->maximumScale();
- double maximumContentHeightInViewportCoordinate = maximumScale * m_configuration.height;
- if (maximumContentHeightInViewportCoordinate < minimumLayoutSize.height()) {
- // The content zoomed to maxScale does not fit the the view. Return the minimum height that
- // satisfy the constraint maximumScale.
- return std::round(minimumLayoutSize.height() / maximumScale);
- }
- return std::round(m_configuration.height);
- }
-
- // If not, make sure the viewport width and initial scale can co-exist.
- double initialContentHeightInViewportCoordinate = m_configuration.height * m_configuration.initialScale;
- if (initialContentHeightInViewportCoordinate < minimumLayoutSize.height()) {
- // The specified width does not fit in viewport. Return the minimum height that satisfy the initialScale constraint.
- return std::round(minimumLayoutSize.height() / m_configuration.initialScale);
- }
- return std::round(m_configuration.height);
- }
-
- // If the page has a real scale, then just return the minimum size over the initial scale.
- if (m_configuration.initialScaleIsSet && !m_configuration.widthIsSet)
- return std::round(minimumLayoutSize.height() / m_configuration.initialScale);
-
- if (minimumLayoutSize.width() > 0)
- return std::round(minimumLayoutSize.height() * layoutWidth() / minimumLayoutSize.width());
- return minimumLayoutSize.height();
-}
-
-#ifndef NDEBUG
-
-TextStream& operator<<(TextStream& ts, const ViewportConfiguration::Parameters& parameters)
-{
- ts.startGroup();
- ts << "width " << parameters.width << ", set: " << (parameters.widthIsSet ? "true" : "false");
- ts.endGroup();
-
- ts.startGroup();
- ts << "height " << parameters.height << ", set: " << (parameters.heightIsSet ? "true" : "false");
- ts.endGroup();
-
- ts.startGroup();
- ts << "initialScale " << parameters.initialScale << ", set: " << (parameters.initialScaleIsSet ? "true" : "false");
- ts.endGroup();
-
- ts.dumpProperty("minimumScale", parameters.minimumScale);
- ts.dumpProperty("maximumScale", parameters.maximumScale);
- ts.dumpProperty("allowsUserScaling", parameters.allowsUserScaling);
- ts.dumpProperty("allowsShrinkToFit", parameters.allowsShrinkToFit);
-
- return ts;
-}
-
-CString ViewportConfiguration::description() const
-{
- TextStream ts;
-
- ts.startGroup();
- ts << "viewport-configuration " << (void*)this;
- {
- TextStream::GroupScope scope(ts);
- ts << "viewport arguments";
- ts << m_viewportArguments;
- }
- {
- TextStream::GroupScope scope(ts);
- ts << "configuration";
- ts << m_configuration;
- }
- {
- TextStream::GroupScope scope(ts);
- ts << "default configuration";
- ts << m_defaultConfiguration;
- }
-
- ts.dumpProperty("contentSize", m_contentSize);
- ts.dumpProperty("minimumLayoutSize", m_minimumLayoutSize);
- ts.dumpProperty("computed initial scale", initialScale());
- ts.dumpProperty("computed minimum scale", minimumScale());
- ts.dumpProperty("computed layout size", layoutSize());
- ts.dumpProperty("ignoring horizontal scaling constraints", shouldIgnoreHorizontalScalingConstraints() ? "true" : "false");
- ts.dumpProperty("ignoring vertical scaling constraints", shouldIgnoreVerticalScalingConstraints() ? "true" : "false");
-
- ts.endGroup();
-
- return ts.release().utf8();
-}
-
-void ViewportConfiguration::dump() const
-{
- WTFLogAlways("%s", description().data());
-}
-
-#endif
-
-} // namespace WebCore
diff --git a/Source/WebCore/page/ViewportConfiguration.h b/Source/WebCore/page/ViewportConfiguration.h
deleted file mode 100644
index a0fbdc363..000000000
--- a/Source/WebCore/page/ViewportConfiguration.h
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Copyright (C) 2005-2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef ViewportConfiguration_h
-#define ViewportConfiguration_h
-
-#include "FloatSize.h"
-#include "IntSize.h"
-#include "ViewportArguments.h"
-#include <wtf/Noncopyable.h>
-
-namespace WebCore {
-
-class TextStream;
-
-class ViewportConfiguration {
- WTF_MAKE_NONCOPYABLE(ViewportConfiguration); WTF_MAKE_FAST_ALLOCATED;
-public:
- // FIXME: unify with ViewportArguments.
- struct Parameters {
- Parameters()
- : width(0)
- , height(0)
- , initialScale(0)
- , minimumScale(0)
- , maximumScale(0)
- , allowsUserScaling(false)
- , allowsShrinkToFit(false)
- , widthIsSet(false)
- , heightIsSet(false)
- , initialScaleIsSet(false)
- {
- }
-
- double width;
- double height;
- double initialScale;
- double minimumScale;
- double maximumScale;
- bool allowsUserScaling;
- bool allowsShrinkToFit;
-
- bool widthIsSet;
- bool heightIsSet;
- bool initialScaleIsSet;
- };
-
- WEBCORE_EXPORT ViewportConfiguration();
-
- const Parameters& defaultConfiguration() const { return m_defaultConfiguration; }
- WEBCORE_EXPORT void setDefaultConfiguration(const Parameters&);
-
- const IntSize& contentsSize() const { return m_contentSize; }
- WEBCORE_EXPORT bool setContentsSize(const IntSize&);
-
- const FloatSize& minimumLayoutSize() const { return m_minimumLayoutSize; }
- WEBCORE_EXPORT bool setMinimumLayoutSize(const FloatSize&);
-
- const ViewportArguments& viewportArguments() const { return m_viewportArguments; }
- WEBCORE_EXPORT bool setViewportArguments(const ViewportArguments&);
-
- WEBCORE_EXPORT bool setCanIgnoreScalingConstraints(bool);
- void setForceAlwaysUserScalable(bool forceAlwaysUserScalable) { m_forceAlwaysUserScalable = forceAlwaysUserScalable; }
-
- WEBCORE_EXPORT IntSize layoutSize() const;
- WEBCORE_EXPORT double initialScale() const;
- WEBCORE_EXPORT double initialScaleIgnoringContentSize() const;
- WEBCORE_EXPORT double minimumScale() const;
- double maximumScale() const { return m_configuration.maximumScale; }
- WEBCORE_EXPORT bool allowsUserScaling() const;
- bool allowsShrinkToFit() const;
-
- WEBCORE_EXPORT static Parameters webpageParameters();
- WEBCORE_EXPORT static Parameters textDocumentParameters();
- WEBCORE_EXPORT static Parameters imageDocumentParameters();
- WEBCORE_EXPORT static Parameters xhtmlMobileParameters();
- WEBCORE_EXPORT static Parameters testingParameters();
-
-#ifndef NDEBUG
- WTF::CString description() const;
- void dump() const;
-#endif
-
-private:
- void updateConfiguration();
- double viewportArgumentsLength(double length) const;
- double initialScaleFromSize(double width, double height, bool shouldIgnoreScalingConstraints) const;
- int layoutWidth() const;
- int layoutHeight() const;
-
- bool shouldIgnoreScalingConstraints() const;
- bool shouldIgnoreVerticalScalingConstraints() const;
- bool shouldIgnoreHorizontalScalingConstraints() const;
-
- Parameters m_configuration;
- Parameters m_defaultConfiguration;
- IntSize m_contentSize;
- FloatSize m_minimumLayoutSize;
- ViewportArguments m_viewportArguments;
-
- bool m_canIgnoreScalingConstraints;
- bool m_forceAlwaysUserScalable;
-};
-
-TextStream& operator<<(TextStream&, const ViewportConfiguration::Parameters&);
-
-} // namespace WebCore
-
-#endif // ViewportConfiguration_h
diff --git a/Source/WebCore/page/WebKitNamespace.idl b/Source/WebCore/page/VisitedLinkProvider.cpp
index f5444806f..3f9b2a128 100644
--- a/Source/WebCore/page/WebKitNamespace.idl
+++ b/Source/WebCore/page/VisitedLinkProvider.cpp
@@ -23,9 +23,17 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include "config.h"
+#include "VisitedLinkProvider.h"
-[
- Conditional=USER_MESSAGE_HANDLERS
-] interface WebKitNamespace {
- readonly attribute UserMessageHandlersNamespace messageHandlers;
-};
+namespace WebCore {
+
+VisitedLinkProvider::VisitedLinkProvider()
+{
+}
+
+VisitedLinkProvider::~VisitedLinkProvider()
+{
+}
+
+}
diff --git a/Source/WebCore/page/ViewStateChangeObserver.h b/Source/WebCore/page/VisitedLinkProvider.h
index 613fd2b18..bea670504 100644
--- a/Source/WebCore/page/ViewStateChangeObserver.h
+++ b/Source/WebCore/page/VisitedLinkProvider.h
@@ -23,22 +23,31 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef ViewStateChangeObserver_h
-#define ViewStateChangeObserver_h
+#ifndef VisitedLinkProvider_h
+#define VisitedLinkProvider_h
-#include "ViewState.h"
+#include <wtf/Forward.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
namespace WebCore {
-class ViewStateChangeObserver {
+typedef uint64_t LinkHash;
+class Page;
+class URL;
+
+class VisitedLinkProvider : public RefCounted<VisitedLinkProvider> {
public:
- virtual ~ViewStateChangeObserver()
+ static PassRefPtr<VisitedLinkProvider> create()
{
+ return adoptRef(new VisitedLinkProvider);
}
-
- virtual void viewStateDidChange(ViewState::Flags oldViewState, ViewState::Flags newViewState) = 0;
+ ~VisitedLinkProvider();
+
+private:
+ VisitedLinkProvider();
};
-} // namespace WebCore
+}
-#endif // ViewStateChangeObserver_h
+#endif // VisitedLinkProvider_h
diff --git a/Source/WebCore/page/VisitedLinkStore.cpp b/Source/WebCore/page/VisitedLinkStore.cpp
deleted file mode 100644
index 973b78ee6..000000000
--- a/Source/WebCore/page/VisitedLinkStore.cpp
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "VisitedLinkStore.h"
-
-#include "Page.h"
-
-namespace WebCore {
-
-VisitedLinkStore::VisitedLinkStore()
-{
-}
-
-VisitedLinkStore::~VisitedLinkStore()
-{
- ASSERT(m_pages.isEmpty());
-}
-
-void VisitedLinkStore::addPage(Page& page)
-{
- ASSERT(!m_pages.contains(&page));
-
- m_pages.add(&page);
-}
-
-void VisitedLinkStore::removePage(Page& page)
-{
- ASSERT(m_pages.contains(&page));
-
- m_pages.remove(&page);
-}
-
-void VisitedLinkStore::invalidateStylesForAllLinks()
-{
- for (auto& page : m_pages)
- page->invalidateStylesForAllLinks();
-}
-
-void VisitedLinkStore::invalidateStylesForLink(LinkHash linkHash)
-{
- for (auto& page : m_pages)
- page->invalidateStylesForLink(linkHash);
-}
-
-} // namespace WebCore
diff --git a/Source/WebCore/page/VisitedLinkStore.h b/Source/WebCore/page/VisitedLinkStore.h
deleted file mode 100644
index 4594a592e..000000000
--- a/Source/WebCore/page/VisitedLinkStore.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef VisitedLinkStore_h
-#define VisitedLinkStore_h
-
-#include <wtf/Forward.h>
-#include <wtf/HashSet.h>
-#include <wtf/RefCounted.h>
-
-namespace WebCore {
-
-typedef uint64_t LinkHash;
-class Page;
-class URL;
-
-class VisitedLinkStore : public RefCounted<VisitedLinkStore> {
-public:
- WEBCORE_EXPORT VisitedLinkStore();
- WEBCORE_EXPORT virtual ~VisitedLinkStore();
-
- // FIXME: These two members should only take the link hash.
- virtual bool isLinkVisited(Page&, LinkHash, const URL& baseURL, const AtomicString& attributeURL) = 0;
- virtual void addVisitedLink(Page&, LinkHash) = 0;
-
- void addPage(Page&);
- void removePage(Page&);
-
- WEBCORE_EXPORT void invalidateStylesForAllLinks();
- WEBCORE_EXPORT void invalidateStylesForLink(LinkHash);
-
-private:
- HashSet<Page*> m_pages;
-};
-
-} // namespace WebCore
-
-#endif // VisitedLinkStore_h
diff --git a/Source/WebCore/page/WebCoreKeyboardUIMode.h b/Source/WebCore/page/WebCoreKeyboardUIMode.h
index a75e7ee1c..187cf09df 100644
--- a/Source/WebCore/page/WebCoreKeyboardUIMode.h
+++ b/Source/WebCore/page/WebCoreKeyboardUIMode.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003 Apple Inc. All rights reserved.
+ * Copyright (C) 2003 Apple Computer, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
diff --git a/Source/WebCore/page/WebKitNamespace.cpp b/Source/WebCore/page/WebKitNamespace.cpp
deleted file mode 100644
index 2abd0adea..000000000
--- a/Source/WebCore/page/WebKitNamespace.cpp
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "WebKitNamespace.h"
-
-#if ENABLE(USER_MESSAGE_HANDLERS)
-
-#include "DOMWindow.h"
-#include "UserMessageHandlersNamespace.h"
-
-namespace WebCore {
-
-WebKitNamespace::WebKitNamespace(Frame& frame)
- : DOMWindowProperty(&frame)
- , m_messageHandlerNamespace(UserMessageHandlersNamespace::create(frame))
-{
-}
-
-WebKitNamespace::~WebKitNamespace()
-{
-}
-
-UserMessageHandlersNamespace* WebKitNamespace::messageHandlers()
-{
- return &m_messageHandlerNamespace.get();
-}
-
-} // namespace WebCore
-
-#endif // ENABLE(USER_MESSAGE_HANDLERS)
diff --git a/Source/WebCore/page/WebKitNamespace.h b/Source/WebCore/page/WebKitNamespace.h
deleted file mode 100644
index f85f41903..000000000
--- a/Source/WebCore/page/WebKitNamespace.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef WebKitNamespace_h
-#define WebKitNamespace_h
-
-#if ENABLE(USER_MESSAGE_HANDLERS)
-
-#include "DOMWindowProperty.h"
-#include <wtf/Ref.h>
-#include <wtf/RefCounted.h>
-
-namespace WebCore {
-
-class Frame;
-class UserMessageHandlersNamespace;
-
-class WebKitNamespace : public DOMWindowProperty, public RefCounted<WebKitNamespace> {
-public:
- static Ref<WebKitNamespace> create(Frame& frame)
- {
- return adoptRef(*new WebKitNamespace(frame));
- }
-
- virtual ~WebKitNamespace();
-
- UserMessageHandlersNamespace* messageHandlers();
-
-private:
- explicit WebKitNamespace(Frame&);
-
- Ref<UserMessageHandlersNamespace> m_messageHandlerNamespace;
-};
-
-} // namespace WebCore
-
-#endif // ENABLE(USER_MESSAGE_HANDLERS)
-#endif // WebKitNamespace_h
diff --git a/Source/WebCore/page/WebKitPoint.h b/Source/WebCore/page/WebKitPoint.h
index 64ffaed4b..ff5d442ae 100644
--- a/Source/WebCore/page/WebKitPoint.h
+++ b/Source/WebCore/page/WebKitPoint.h
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -34,13 +34,13 @@ namespace WebCore {
class WebKitPoint : public RefCounted<WebKitPoint> {
public:
- static Ref<WebKitPoint> create()
+ static PassRefPtr<WebKitPoint> create()
{
- return adoptRef(*new WebKitPoint);
+ return adoptRef(new WebKitPoint());
}
- static Ref<WebKitPoint> create(float x, float y)
+ static PassRefPtr<WebKitPoint> create(float x, float y)
{
- return adoptRef(*new WebKitPoint(x, y));
+ return adoptRef(new WebKitPoint(x, y));
}
float x() const { return m_x; }
diff --git a/Source/WebCore/page/WebKitPoint.idl b/Source/WebCore/page/WebKitPoint.idl
index c855b7ed3..44e3b10fc 100644
--- a/Source/WebCore/page/WebKitPoint.idl
+++ b/Source/WebCore/page/WebKitPoint.idl
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -25,10 +25,10 @@
[
CustomConstructor,
- CustomConstructor(unrestricted float x, unrestricted float y),
+ CustomConstructor(float x, float y),
ImplementationLacksVTable
] interface WebKitPoint {
- attribute unrestricted float x;
- attribute unrestricted float y;
+ attribute float x;
+ attribute float y;
};
diff --git a/Source/WebCore/page/WheelEventDeltaFilter.cpp b/Source/WebCore/page/WheelEventDeltaFilter.cpp
deleted file mode 100644
index 4d70bbfc6..000000000
--- a/Source/WebCore/page/WheelEventDeltaFilter.cpp
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "WheelEventDeltaFilter.h"
-
-#if PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101100
-#include "WheelEventDeltaFilterMac.h"
-#endif
-
-#include "FloatSize.h"
-#include "Logging.h"
-#include "TextStream.h"
-
-namespace WebCore {
-
-WheelEventDeltaFilter::WheelEventDeltaFilter()
-{
-}
-
-WheelEventDeltaFilter::~WheelEventDeltaFilter()
-{
-}
-
-std::unique_ptr<WheelEventDeltaFilter> WheelEventDeltaFilter::create()
-{
-#if PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101100
- return std::make_unique<WheelEventDeltaFilterMac>();
-#else
- return std::make_unique<BasicWheelEventDeltaFilter>();
-#endif
-}
-
-bool WheelEventDeltaFilter::isFilteringDeltas() const
-{
- return m_isFilteringDeltas;
-}
-
-FloatSize WheelEventDeltaFilter::filteredDelta() const
-{
- LOG_WITH_STREAM(Scrolling, stream << "BasicWheelEventDeltaFilter::filteredDelta returning " << m_currentFilteredDelta);
- return m_currentFilteredDelta;
-}
-
-BasicWheelEventDeltaFilter::BasicWheelEventDeltaFilter()
- : WheelEventDeltaFilter()
-{
-}
-
-const size_t basicWheelEventDeltaFilterWindowSize = 3;
-
-void BasicWheelEventDeltaFilter::updateFromDelta(const FloatSize& delta)
-{
- m_currentFilteredDelta = delta;
- if (!m_isFilteringDeltas)
- return;
-
- m_recentWheelEventDeltas.append(delta);
- if (m_recentWheelEventDeltas.size() > basicWheelEventDeltaFilterWindowSize)
- m_recentWheelEventDeltas.removeFirst();
-
- DominantScrollGestureDirection scrollDirection = dominantScrollGestureDirection();
- if (scrollDirection == DominantScrollGestureDirection::Vertical)
- m_currentFilteredDelta.setWidth(0);
- else if (scrollDirection == DominantScrollGestureDirection::Horizontal)
- m_currentFilteredDelta.setHeight(0);
-}
-
-void BasicWheelEventDeltaFilter::beginFilteringDeltas()
-{
- m_recentWheelEventDeltas.clear();
- m_isFilteringDeltas = true;
-}
-
-void BasicWheelEventDeltaFilter::endFilteringDeltas()
-{
- m_currentFilteredDelta = FloatSize(0, 0);
- m_isFilteringDeltas = false;
-}
-
-static inline bool deltaIsPredominantlyVertical(const FloatSize& delta)
-{
- return fabs(delta.height()) > fabs(delta.width());
-}
-
-DominantScrollGestureDirection BasicWheelEventDeltaFilter::dominantScrollGestureDirection() const
-{
- bool allVertical = m_recentWheelEventDeltas.size();
- bool allHorizontal = m_recentWheelEventDeltas.size();
-
- for (const auto& delta : m_recentWheelEventDeltas) {
- bool isVertical = deltaIsPredominantlyVertical(delta);
- allVertical &= isVertical;
- allHorizontal &= !isVertical;
- }
-
- if (allVertical)
- return DominantScrollGestureDirection::Vertical;
-
- if (allHorizontal)
- return DominantScrollGestureDirection::Horizontal;
-
- return DominantScrollGestureDirection::None;
-}
-
-};
diff --git a/Source/WebCore/page/WheelEventDeltaFilter.h b/Source/WebCore/page/WheelEventDeltaFilter.h
deleted file mode 100644
index 5f2a4b21a..000000000
--- a/Source/WebCore/page/WheelEventDeltaFilter.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef WheelEventDeltaFilter_h
-#define WheelEventDeltaFilter_h
-
-#include "FloatSize.h"
-#include <wtf/Deque.h>
-
-namespace WebCore {
-
-class PlatformWheelEvent;
-
-class WheelEventDeltaFilter {
-public:
- WheelEventDeltaFilter();
- virtual ~WheelEventDeltaFilter();
-
- WEBCORE_EXPORT static std::unique_ptr<WheelEventDeltaFilter> create();
- WEBCORE_EXPORT virtual void updateFromDelta(const FloatSize&) = 0;
- WEBCORE_EXPORT virtual void beginFilteringDeltas() = 0;
- WEBCORE_EXPORT virtual void endFilteringDeltas() = 0;
- WEBCORE_EXPORT bool isFilteringDeltas() const;
- WEBCORE_EXPORT FloatSize filteredDelta() const;
-
-protected:
- FloatSize m_currentFilteredDelta;
- bool m_isFilteringDeltas { false };
-};
-
-enum class DominantScrollGestureDirection {
- None,
- Vertical,
- Horizontal
-};
-
-class BasicWheelEventDeltaFilter final : public WheelEventDeltaFilter {
-public:
- BasicWheelEventDeltaFilter();
- virtual void updateFromDelta(const FloatSize&) override;
- virtual void beginFilteringDeltas() override;
- virtual void endFilteringDeltas() override;
-
-private:
- DominantScrollGestureDirection dominantScrollGestureDirection() const;
-
- Deque<FloatSize> m_recentWheelEventDeltas;
-};
-
-}
-
-#endif
diff --git a/Source/WebCore/page/WheelEventTestTrigger.cpp b/Source/WebCore/page/WheelEventTestTrigger.cpp
deleted file mode 100644
index 39887f135..000000000
--- a/Source/WebCore/page/WheelEventTestTrigger.cpp
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "WheelEventTestTrigger.h"
-
-#include "Logging.h"
-
-#if !LOG_DISABLED
-#include <wtf/text/CString.h>
-#include <wtf/text/StringBuilder.h>
-#endif
-
-namespace WebCore {
-
-WheelEventTestTrigger::WheelEventTestTrigger()
- : m_testTriggerTimer(RunLoop::current(), this, &WheelEventTestTrigger::triggerTestTimerFired)
-{
-}
-
-void WheelEventTestTrigger::clearAllTestDeferrals()
-{
- std::lock_guard<Lock> lock(m_testTriggerMutex);
- m_deferTestTriggerReasons.clear();
- m_testNotificationCallback = std::function<void()>();
- m_testTriggerTimer.stop();
- LOG(WheelEventTestTriggers, " (=) WheelEventTestTrigger::clearAllTestDeferrals: cleared all test state.");
-}
-
-void WheelEventTestTrigger::setTestCallbackAndStartNotificationTimer(std::function<void()> functionCallback)
-{
- {
- std::lock_guard<Lock> lock(m_testTriggerMutex);
- m_testNotificationCallback = WTFMove(functionCallback);
- }
-
- if (!m_testTriggerTimer.isActive())
- m_testTriggerTimer.startRepeating(1.0 / 60.0);
-}
-
-void WheelEventTestTrigger::deferTestsForReason(ScrollableAreaIdentifier identifier, DeferTestTriggerReason reason)
-{
- std::lock_guard<Lock> lock(m_testTriggerMutex);
- auto it = m_deferTestTriggerReasons.find(identifier);
- if (it == m_deferTestTriggerReasons.end())
- it = m_deferTestTriggerReasons.add(identifier, std::set<DeferTestTriggerReason>()).iterator;
-
- LOG(WheelEventTestTriggers, " (=) WheelEventTestTrigger::deferTestsForReason: id=%p, reason=%d", identifier, reason);
- it->value.insert(reason);
-}
-
-void WheelEventTestTrigger::removeTestDeferralForReason(ScrollableAreaIdentifier identifier, DeferTestTriggerReason reason)
-{
- std::lock_guard<Lock> lock(m_testTriggerMutex);
- auto it = m_deferTestTriggerReasons.find(identifier);
- if (it == m_deferTestTriggerReasons.end())
- return;
-
- LOG(WheelEventTestTriggers, " (=) WheelEventTestTrigger::removeTestDeferralForReason: id=%p, reason=%d", identifier, reason);
- it->value.erase(reason);
-
- if (it->value.empty())
- m_deferTestTriggerReasons.remove(it);
-}
-
-#if !LOG_DISABLED
-static void dumpState(WTF::HashMap<WheelEventTestTrigger::ScrollableAreaIdentifier, std::set<WheelEventTestTrigger::DeferTestTriggerReason>> reasons)
-{
- LOG(WheelEventTestTriggers, " WheelEventTestTrigger::dumpState:");
- for (const auto& scrollRegion : reasons) {
- LOG(WheelEventTestTriggers, " For scroll region %p", scrollRegion.key);
- StringBuilder reasons;
- for (const auto& reason : scrollRegion.value) {
- if (!reasons.isEmpty())
- reasons.append(", ");
- reasons.append(String::number(reason));
- }
- LOG(WheelEventTestTriggers, " Reasons: %s", reasons.toString().utf8().data());
- }
-}
-#endif
-
-void WheelEventTestTrigger::triggerTestTimerFired()
-{
- std::function<void()> functionCallback;
-
- {
- std::lock_guard<Lock> lock(m_testTriggerMutex);
- if (!m_deferTestTriggerReasons.isEmpty()) {
-#if !LOG_DISABLED
- if (isLogChannelEnabled("WheelEventTestTriggers"))
- dumpState(m_deferTestTriggerReasons);
-#endif
- return;
- }
-
- functionCallback = WTFMove(m_testNotificationCallback);
- m_testNotificationCallback = std::function<void()>();
- }
-
- m_testTriggerTimer.stop();
-
- LOG(WheelEventTestTriggers, " WheelEventTestTrigger::triggerTestTimerFired: FIRING TEST");
- if (functionCallback)
- functionCallback();
-}
-
-}
diff --git a/Source/WebCore/page/WindowBase64.idl b/Source/WebCore/page/WindowBase64.idl
index 35c432043..3404399b9 100644
--- a/Source/WebCore/page/WindowBase64.idl
+++ b/Source/WebCore/page/WindowBase64.idl
@@ -12,10 +12,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
diff --git a/Source/WebCore/page/WindowEventHandlers.idl b/Source/WebCore/page/WindowEventHandlers.idl
deleted file mode 100644
index 0e2f85f86..000000000
--- a/Source/WebCore/page/WindowEventHandlers.idl
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2015 Apple Inc. All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-// https://html.spec.whatwg.org/multipage/webappapis.html#windoweventhandlers
-[
- NoInterfaceObject,
-] interface WindowEventHandlers {
- // Commented out event handlers are defined by the HTML5 specification but
- // are not yet implemented.
-
- // [WindowEventHandler] attribute EventHandler onafterprint;.
- // [WindowEventHandler] attribute EventHandler onbeforeprint;.
- [WindowEventHandler] attribute EventHandler onbeforeunload;
- [WindowEventHandler] attribute EventHandler onhashchange;
- // [WindowEventHandler] attribute EventHandler onlanguagechange;.
- [WindowEventHandler] attribute EventHandler onmessage;
- [WindowEventHandler] attribute EventHandler onoffline;
- [WindowEventHandler] attribute EventHandler ononline;
- [WindowEventHandler] attribute EventHandler onpagehide;
- [WindowEventHandler] attribute EventHandler onpageshow;
- [WindowEventHandler] attribute EventHandler onpopstate;
- [WindowEventHandler] attribute EventHandler onstorage;
- [WindowEventHandler] attribute EventHandler onunload;
-
-
- // Additions that are not yet part of the standard.
-
- [NotEnumerable, WindowEventHandler, Conditional=ORIENTATION_EVENTS] attribute EventHandler onorientationchange;
-};
diff --git a/Source/WebCore/page/WindowFeatures.cpp b/Source/WebCore/page/WindowFeatures.cpp
index 7c76ae128..d93420161 100644
--- a/Source/WebCore/page/WindowFeatures.cpp
+++ b/Source/WebCore/page/WindowFeatures.cpp
@@ -25,123 +25,154 @@
#include "FloatRect.h"
#include <wtf/Assertions.h>
-#include <wtf/HashMap.h>
#include <wtf/MathExtras.h>
#include <wtf/text/StringHash.h>
namespace WebCore {
-typedef HashMap<String, String, ASCIICaseInsensitiveHash> DialogFeaturesMap;
-
-static void setWindowFeature(WindowFeatures&, StringView key, StringView value);
-
-static DialogFeaturesMap parseDialogFeaturesMap(const String&);
-static Optional<bool> boolFeature(const DialogFeaturesMap&, const char* key);
-static Optional<float> floatFeature(const DialogFeaturesMap&, const char* key, float min, float max);
-
-static bool isSeparator(UChar character)
+// Though isspace() considers \t and \v to be whitespace, Win IE doesn't when parsing window features.
+static bool isWindowFeaturesSeparator(UChar c)
{
- return character == ' ' || character == '\t' || character == '\n' || character == '\r' || character == '=' || character == ',';
+ return c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '=' || c == ',' || c == '\0';
}
-WindowFeatures parseWindowFeatures(StringView featuresString)
+WindowFeatures::WindowFeatures(const String& features)
+ : xSet(false)
+ , ySet(false)
+ , widthSet(false)
+ , heightSet(false)
+ , fullscreen(false)
+ , dialog(false)
{
- // The IE rule is: all features except for channelmode and fullscreen default to YES, but
- // if the user specifies a feature string, all features default to NO. (There is no public
- // standard that applies to this method.)
- //
- // <http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/open_0.asp>
- // We always allow a window to be resized, which is consistent with Firefox.
-
- WindowFeatures features;
-
- if (featuresString.isEmpty())
- return features;
-
- features.menuBarVisible = false;
- features.statusBarVisible = false;
- features.toolBarVisible = false;
- features.locationBarVisible = false;
- features.scrollbarsVisible = false;
-
- processFeaturesString(featuresString, [&features](StringView key, StringView value) {
- setWindowFeature(features, key, value);
- });
-
- return features;
-}
+ /*
+ The IE rule is: all features except for channelmode and fullscreen default to YES, but
+ if the user specifies a feature string, all features default to NO. (There is no public
+ standard that applies to this method.)
+
+ <http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/open_0.asp>
+ We always allow a window to be resized, which is consistent with Firefox.
+ */
+
+ if (features.length() == 0) {
+ menuBarVisible = true;
+ statusBarVisible = true;
+ toolBarVisible = true;
+ locationBarVisible = true;
+ scrollbarsVisible = true;
+ resizable = true;
+ return;
+ }
-void processFeaturesString(StringView features, std::function<void(StringView type, StringView value)> callback)
-{
- unsigned length = features.length();
- for (unsigned i = 0; i < length; ) {
- // skip to first non-separator
- while (i < length && isSeparator(features[i]))
- ++i;
- unsigned keyBegin = i;
+ menuBarVisible = false;
+ statusBarVisible = false;
+ toolBarVisible = false;
+ locationBarVisible = false;
+ scrollbarsVisible = false;
+ resizable = true;
+
+ // Tread lightly in this code -- it was specifically designed to mimic Win IE's parsing behavior.
+ int keyBegin, keyEnd;
+ int valueBegin, valueEnd;
+
+ int i = 0;
+ int length = features.length();
+ String buffer = features.lower();
+ while (i < length) {
+ // skip to first non-separator, but don't skip past the end of the string
+ while (isWindowFeaturesSeparator(buffer[i])) {
+ if (i >= length)
+ break;
+ i++;
+ }
+ keyBegin = i;
// skip to first separator
- while (i < length && !isSeparator(features[i]))
+ while (!isWindowFeaturesSeparator(buffer[i]))
i++;
- unsigned keyEnd = i;
+ keyEnd = i;
- // skip to first '=', but don't skip past a ','
- while (i < length && features[i] != '=' && features[i] != ',')
- ++i;
+ // skip to first '=', but don't skip past a ',' or the end of the string
+ while (buffer[i] != '=') {
+ if (buffer[i] == ',' || i >= length)
+ break;
+ i++;
+ }
- // skip to first non-separator, but don't skip past a ','
- while (i < length && isSeparator(features[i]) && features[i] != ',')
- ++i;
- unsigned valueBegin = i;
+ // skip to first non-separator, but don't skip past a ',' or the end of the string
+ while (isWindowFeaturesSeparator(buffer[i])) {
+ if (buffer[i] == ',' || i >= length)
+ break;
+ i++;
+ }
+ valueBegin = i;
// skip to first separator
- while (i < length && !isSeparator(features[i]))
- ++i;
- unsigned valueEnd = i;
+ while (!isWindowFeaturesSeparator(buffer[i]))
+ i++;
+ valueEnd = i;
- callback(features.substring(keyBegin, keyEnd - keyBegin), features.substring(valueBegin, valueEnd - valueBegin));
+ ASSERT_WITH_SECURITY_IMPLICATION(i <= length);
+
+ String keyString(buffer.substring(keyBegin, keyEnd - keyBegin));
+ String valueString(buffer.substring(valueBegin, valueEnd - valueBegin));
+ setWindowFeature(keyString, valueString);
}
}
-static void setWindowFeature(WindowFeatures& features, StringView key, StringView value)
+void WindowFeatures::setWindowFeature(const String& keyString, const String& valueString)
{
+ int value;
+
// Listing a key with no value is shorthand for key=yes
- int numericValue;
- if (value.isEmpty() || equalLettersIgnoringASCIICase(value, "yes"))
- numericValue = 1;
+ if (valueString.isEmpty() || valueString == "yes")
+ value = 1;
else
- numericValue = value.toInt();
+ value = valueString.toInt();
- // We treat key of "resizable" here as an additional feature rather than setting resizeable to true.
+ // We treat keyString of "resizable" here as an additional feature rather than setting resizeable to true.
// This is consistent with Firefox, but could also be handled at another level.
- if (equalLettersIgnoringASCIICase(key, "left") || equalLettersIgnoringASCIICase(key, "screenx"))
- features.x = numericValue;
- else if (equalLettersIgnoringASCIICase(key, "top") || equalLettersIgnoringASCIICase(key, "screeny"))
- features.y = numericValue;
- else if (equalLettersIgnoringASCIICase(key, "width") || equalLettersIgnoringASCIICase(key, "innerwidth"))
- features.width = numericValue;
- else if (equalLettersIgnoringASCIICase(key, "height") || equalLettersIgnoringASCIICase(key, "innerheight"))
- features.height = numericValue;
- else if (equalLettersIgnoringASCIICase(key, "menubar"))
- features.menuBarVisible = numericValue;
- else if (equalLettersIgnoringASCIICase(key, "toolbar"))
- features.toolBarVisible = numericValue;
- else if (equalLettersIgnoringASCIICase(key, "location"))
- features.locationBarVisible = numericValue;
- else if (equalLettersIgnoringASCIICase(key, "status"))
- features.statusBarVisible = numericValue;
- else if (equalLettersIgnoringASCIICase(key, "fullscreen"))
- features.fullscreen = numericValue;
- else if (equalLettersIgnoringASCIICase(key, "scrollbars"))
- features.scrollbarsVisible = numericValue;
- else if (numericValue == 1)
- features.additionalFeatures.append(key.toString());
+ if (keyString == "left" || keyString == "screenx") {
+ xSet = true;
+ x = value;
+ } else if (keyString == "top" || keyString == "screeny") {
+ ySet = true;
+ y = value;
+ } else if (keyString == "width" || keyString == "innerwidth") {
+ widthSet = true;
+ width = value;
+ } else if (keyString == "height" || keyString == "innerheight") {
+ heightSet = true;
+ height = value;
+ } else if (keyString == "menubar")
+ menuBarVisible = value;
+ else if (keyString == "toolbar")
+ toolBarVisible = value;
+ else if (keyString == "location")
+ locationBarVisible = value;
+ else if (keyString == "status")
+ statusBarVisible = value;
+ else if (keyString == "fullscreen")
+ fullscreen = value;
+ else if (keyString == "scrollbars")
+ scrollbarsVisible = value;
+ else if (value == 1)
+ additionalFeatures.append(keyString);
}
-WindowFeatures parseDialogFeatures(const String& dialogFeaturesString, const FloatRect& screenAvailableRect)
+WindowFeatures::WindowFeatures(const String& dialogFeaturesString, const FloatRect& screenAvailableRect)
+ : widthSet(true)
+ , heightSet(true)
+ , menuBarVisible(false)
+ , toolBarVisible(false)
+ , locationBarVisible(false)
+ , fullscreen(false)
+ , dialog(true)
{
- auto featuresMap = parseDialogFeaturesMap(dialogFeaturesString);
+ DialogFeaturesMap features;
+ parseDialogFeatures(dialogFeaturesString, features);
+
+ const bool trusted = false;
// The following features from Microsoft's documentation are not implemented:
// - default font settings
@@ -151,81 +182,66 @@ WindowFeatures parseDialogFeatures(const String& dialogFeaturesString, const Flo
// - help: boolFeature(features, "help", true), makes help icon appear in dialog (what does it do on Windows?)
// - unadorned: trusted && boolFeature(features, "unadorned");
- WindowFeatures features;
-
- features.menuBarVisible = false;
- features.toolBarVisible = false;
- features.locationBarVisible = false;
- features.dialog = true;
+ width = floatFeature(features, "dialogwidth", 100, screenAvailableRect.width(), 620); // default here came from frame size of dialog in MacIE
+ height = floatFeature(features, "dialogheight", 100, screenAvailableRect.height(), 450); // default here came from frame size of dialog in MacIE
- float width = floatFeature(featuresMap, "dialogwidth", 100, screenAvailableRect.width()).valueOr(620); // default here came from frame size of dialog in MacIE
- float height = floatFeature(featuresMap, "dialogheight", 100, screenAvailableRect.height()).valueOr(450); // default here came from frame size of dialog in MacIE
+ x = floatFeature(features, "dialogleft", screenAvailableRect.x(), screenAvailableRect.maxX() - width, -1);
+ xSet = x > 0;
+ y = floatFeature(features, "dialogtop", screenAvailableRect.y(), screenAvailableRect.maxY() - height, -1);
+ ySet = y > 0;
- features.width = width;
- features.height = height;
-
- features.x = floatFeature(featuresMap, "dialogleft", screenAvailableRect.x(), screenAvailableRect.maxX() - width);
- features.y = floatFeature(featuresMap, "dialogtop", screenAvailableRect.y(), screenAvailableRect.maxY() - height);
-
- if (boolFeature(featuresMap, "center").valueOr(true)) {
- if (!features.x)
- features.x = screenAvailableRect.x() + (screenAvailableRect.width() - width) / 2;
- if (!features.y)
- features.y = screenAvailableRect.y() + (screenAvailableRect.height() - height) / 2;
+ if (boolFeature(features, "center", true)) {
+ if (!xSet) {
+ x = screenAvailableRect.x() + (screenAvailableRect.width() - width) / 2;
+ xSet = true;
+ }
+ if (!ySet) {
+ y = screenAvailableRect.y() + (screenAvailableRect.height() - height) / 2;
+ ySet = true;
+ }
}
- features.resizable = boolFeature(featuresMap, "resizable").valueOr(false);
- features.scrollbarsVisible = boolFeature(featuresMap, "scroll").valueOr(true);
- features.statusBarVisible = boolFeature(featuresMap, "status").valueOr(false);
-
- return features;
+ resizable = boolFeature(features, "resizable");
+ scrollbarsVisible = boolFeature(features, "scroll", true);
+ statusBarVisible = boolFeature(features, "status", !trusted);
}
-static Optional<bool> boolFeature(const DialogFeaturesMap& features, const char* key)
+bool WindowFeatures::boolFeature(const DialogFeaturesMap& features, const char* key, bool defaultValue)
{
- auto it = features.find(key);
+ DialogFeaturesMap::const_iterator it = features.find(key);
if (it == features.end())
- return Nullopt;
-
- auto& value = it->value;
- return value.isNull()
- || value == "1"
- || equalLettersIgnoringASCIICase(value, "yes")
- || equalLettersIgnoringASCIICase(value, "on");
+ return defaultValue;
+ const String& value = it->value;
+ return value.isNull() || value == "1" || value == "yes" || value == "on";
}
-static Optional<float> floatFeature(const DialogFeaturesMap& features, const char* key, float min, float max)
+float WindowFeatures::floatFeature(const DialogFeaturesMap& features, const char* key, float min, float max, float defaultValue)
{
- auto it = features.find(key);
+ DialogFeaturesMap::const_iterator it = features.find(key);
if (it == features.end())
- return Nullopt;
-
+ return defaultValue;
// FIXME: The toDouble function does not offer a way to tell "0q" from string with no digits in it: Both
// return the number 0 and false for ok. But "0q" should yield the minimum rather than the default.
bool ok;
double parsedNumber = it->value.toDouble(&ok);
if ((!parsedNumber && !ok) || std::isnan(parsedNumber))
- return Nullopt;
+ return defaultValue;
if (parsedNumber < min || max <= min)
return min;
if (parsedNumber > max)
return max;
-
// FIXME: Seems strange to cast a double to int and then convert back to a float. Why is this a good idea?
return static_cast<int>(parsedNumber);
}
-static DialogFeaturesMap parseDialogFeaturesMap(const String& string)
+void WindowFeatures::parseDialogFeatures(const String& string, DialogFeaturesMap& map)
{
- // FIXME: Not clear why we take such a different approach to parsing dialog features
- // as opposed to window features (using a map, different parsing quirks).
-
- DialogFeaturesMap features;
-
Vector<String> vector;
string.split(';', vector);
+ size_t size = vector.size();
+ for (size_t i = 0; i < size; ++i) {
+ const String& featureString = vector[i];
- for (auto& featureString : vector) {
size_t separatorPosition = featureString.find('=');
size_t colonPosition = featureString.find(':');
if (separatorPosition != notFound && colonPosition != notFound)
@@ -233,19 +249,17 @@ static DialogFeaturesMap parseDialogFeaturesMap(const String& string)
if (separatorPosition == notFound)
separatorPosition = colonPosition;
- String key = featureString.left(separatorPosition).stripWhiteSpace();
+ String key = featureString.left(separatorPosition).stripWhiteSpace().lower();
// Null string for value indicates key without value.
String value;
if (separatorPosition != notFound) {
- value = featureString.substring(separatorPosition + 1).stripWhiteSpace();
+ value = featureString.substring(separatorPosition + 1).stripWhiteSpace().lower();
value = value.left(value.find(' '));
}
- features.set(key, value);
+ map.set(key, value);
}
-
- return features;
}
} // namespace WebCore
diff --git a/Source/WebCore/page/WindowFeatures.h b/Source/WebCore/page/WindowFeatures.h
index 0cb6d9ff9..43a0b1ba2 100644
--- a/Source/WebCore/page/WindowFeatures.h
+++ b/Source/WebCore/page/WindowFeatures.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003, 2007, 2010, 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2007, 2010 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Inc. ("Apple") nor the names of
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
@@ -29,9 +29,7 @@
#ifndef WindowFeatures_h
#define WindowFeatures_h
-#include <functional>
-#include <wtf/Optional.h>
-#include <wtf/Vector.h>
+#include <wtf/HashMap.h>
#include <wtf/text/WTFString.h>
namespace WebCore {
@@ -39,28 +37,52 @@ namespace WebCore {
class FloatRect;
struct WindowFeatures {
- Optional<float> x;
- Optional<float> y;
- Optional<float> width;
- Optional<float> height;
+ WindowFeatures()
+ : xSet(false)
+ , ySet(false)
+ , widthSet(false)
+ , heightSet(false)
+ , menuBarVisible(true)
+ , statusBarVisible(true)
+ , toolBarVisible(true)
+ , locationBarVisible(true)
+ , scrollbarsVisible(true)
+ , resizable(true)
+ , fullscreen(false)
+ , dialog(false)
+ {
+ }
+ explicit WindowFeatures(const String& windowFeaturesString);
+ WindowFeatures(const String& dialogFeaturesString, const FloatRect& screenAvailableRect);
- bool menuBarVisible { true };
- bool statusBarVisible { true };
- bool toolBarVisible { true };
- bool locationBarVisible { true };
- bool scrollbarsVisible { true };
- bool resizable { true };
+ float x;
+ bool xSet;
+ float y;
+ bool ySet;
+ float width;
+ bool widthSet;
+ float height;
+ bool heightSet;
- bool fullscreen { false };
- bool dialog { false };
+ bool menuBarVisible;
+ bool statusBarVisible;
+ bool toolBarVisible;
+ bool locationBarVisible;
+ bool scrollbarsVisible;
+ bool resizable;
- Vector<String> additionalFeatures;
-};
+ bool fullscreen;
+ bool dialog;
-WindowFeatures parseWindowFeatures(StringView windowFeaturesString);
-WindowFeatures parseDialogFeatures(const String& dialogFeaturesString, const FloatRect& screenAvailableRect);
+ Vector<String> additionalFeatures;
-void processFeaturesString(StringView features, std::function<void(StringView type, StringView value)> callback);
+private:
+ typedef HashMap<String, String> DialogFeaturesMap;
+ static void parseDialogFeatures(const String&, HashMap<String, String>&);
+ static bool boolFeature(const DialogFeaturesMap&, const char* key, bool defaultValue = false);
+ static float floatFeature(const DialogFeaturesMap&, const char* key, float min, float max, float defaultValue);
+ void setWindowFeature(const String& keyString, const String& valueString);
+};
} // namespace WebCore
diff --git a/Source/WebCore/page/WindowFocusAllowedIndicator.cpp b/Source/WebCore/page/WindowFocusAllowedIndicator.cpp
index ffa3aae47..f44de6a07 100644
--- a/Source/WebCore/page/WindowFocusAllowedIndicator.cpp
+++ b/Source/WebCore/page/WindowFocusAllowedIndicator.cpp
@@ -13,7 +13,7 @@
* THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
diff --git a/Source/WebCore/page/WindowFocusAllowedIndicator.h b/Source/WebCore/page/WindowFocusAllowedIndicator.h
index 7660195e9..86598d7d6 100644
--- a/Source/WebCore/page/WindowFocusAllowedIndicator.h
+++ b/Source/WebCore/page/WindowFocusAllowedIndicator.h
@@ -13,7 +13,7 @@
* THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
diff --git a/Source/WebCore/page/WindowTimers.idl b/Source/WebCore/page/WindowTimers.idl
index 56563a302..8465b880d 100644
--- a/Source/WebCore/page/WindowTimers.idl
+++ b/Source/WebCore/page/WindowTimers.idl
@@ -12,10 +12,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
diff --git a/Source/WebCore/page/WorkerNavigator.cpp b/Source/WebCore/page/WorkerNavigator.cpp
index fa8504ea8..eac5ddf3e 100644
--- a/Source/WebCore/page/WorkerNavigator.cpp
+++ b/Source/WebCore/page/WorkerNavigator.cpp
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
diff --git a/Source/WebCore/page/WorkerNavigator.h b/Source/WebCore/page/WorkerNavigator.h
index 3aeeaab8c..f25d8cd48 100644
--- a/Source/WebCore/page/WorkerNavigator.h
+++ b/Source/WebCore/page/WorkerNavigator.h
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -37,7 +37,7 @@ namespace WebCore {
class WorkerNavigator : public NavigatorBase, public RefCounted<WorkerNavigator>, public Supplementable<WorkerNavigator> {
public:
- static Ref<WorkerNavigator> create(const String& userAgent) { return adoptRef(*new WorkerNavigator(userAgent)); }
+ static PassRefPtr<WorkerNavigator> create(const String& userAgent) { return adoptRef(new WorkerNavigator(userAgent)); }
virtual ~WorkerNavigator();
virtual String userAgent() const;
diff --git a/Source/WebCore/page/WorkerNavigator.idl b/Source/WebCore/page/WorkerNavigator.idl
index 86a1a4a0b..e2a282de7 100644
--- a/Source/WebCore/page/WorkerNavigator.idl
+++ b/Source/WebCore/page/WorkerNavigator.idl
@@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Inc. ("Apple") nor the names of
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
@@ -29,6 +29,7 @@
[
NoInterfaceObject,
GenerateIsReachable=Impl,
+ JSNoStaticTables,
] interface WorkerNavigator {
readonly attribute DOMString appName;
readonly attribute DOMString appVersion;
diff --git a/Source/WebCore/page/animation/AnimationBase.cpp b/Source/WebCore/page/animation/AnimationBase.cpp
index acde6bb0a..dd3315ebb 100644
--- a/Source/WebCore/page/animation/AnimationBase.cpp
+++ b/Source/WebCore/page/animation/AnimationBase.cpp
@@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Inc. ("Apple") nor the names of
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
@@ -36,11 +36,9 @@
#include "Document.h"
#include "EventNames.h"
#include "FloatConversion.h"
-#include "GeometryUtilities.h"
#include "Logging.h"
#include "RenderBox.h"
#include "RenderStyle.h"
-#include "RenderView.h"
#include "UnitBezier.h"
#include <algorithm>
#include <wtf/CurrentTime.h>
@@ -70,10 +68,21 @@ static inline double solveStepsFunction(int numSteps, bool stepAtStart, double t
return floor(numSteps * t) / numSteps;
}
-AnimationBase::AnimationBase(Animation& animation, RenderElement* renderer, CompositeAnimation* compositeAnimation)
- : m_object(renderer)
- , m_compositeAnimation(compositeAnimation)
- , m_animation(animation)
+AnimationBase::AnimationBase(const Animation& transition, RenderElement* renderer, CompositeAnimation* compAnim)
+ : m_animState(AnimationStateNew)
+ , m_isAccelerated(false)
+ , m_transformFunctionListValid(false)
+#if ENABLE(CSS_FILTERS)
+ , m_filterFunctionListsMatch(false)
+#endif
+ , m_startTime(0)
+ , m_pauseTime(-1)
+ , m_requestedStartTime(0)
+ , m_totalDuration(-1)
+ , m_nextIterationDuration(-1)
+ , m_object(renderer)
+ , m_animation(const_cast<Animation*>(&transition))
+ , m_compAnim(compAnim)
{
// Compute the total duration
if (m_animation->iterationCount() > 0)
@@ -97,64 +106,44 @@ bool AnimationBase::playStatePlaying() const
return m_animation->playState() == AnimPlayStatePlaying;
}
-bool AnimationBase::animationsMatch(const Animation& animation) const
+bool AnimationBase::animationsMatch(const Animation* anim) const
{
- return m_animation->animationsMatch(animation);
+ return m_animation->animationsMatch(anim);
}
#if !LOG_DISABLED
-static const char* nameForState(AnimationBase::AnimationState state)
+static const char* nameForState(AnimationBase::AnimState state)
{
switch (state) {
- case AnimationBase::AnimationState::New: return "New";
- case AnimationBase::AnimationState::StartWaitTimer: return "StartWaitTimer";
- case AnimationBase::AnimationState::StartWaitStyleAvailable: return "StartWaitStyleAvailable";
- case AnimationBase::AnimationState::StartWaitResponse: return "StartWaitResponse";
- case AnimationBase::AnimationState::Looping: return "Looping";
- case AnimationBase::AnimationState::Ending: return "Ending";
- case AnimationBase::AnimationState::PausedNew: return "PausedNew";
- case AnimationBase::AnimationState::PausedWaitTimer: return "PausedWaitTimer";
- case AnimationBase::AnimationState::PausedWaitStyleAvailable: return "PausedWaitStyleAvailable";
- case AnimationBase::AnimationState::PausedWaitResponse: return "PausedWaitResponse";
- case AnimationBase::AnimationState::PausedRun: return "PausedRun";
- case AnimationBase::AnimationState::Done: return "Done";
- case AnimationBase::AnimationState::FillingForwards: return "FillingForwards";
- }
- return "";
-}
-
-static const char* nameForStateInput(AnimationBase::AnimationStateInput input)
-{
- switch (input) {
- case AnimationBase::AnimationStateInput::MakeNew: return "MakeNew";
- case AnimationBase::AnimationStateInput::StartAnimation: return "StartAnimation";
- case AnimationBase::AnimationStateInput::RestartAnimation: return "RestartAnimation";
- case AnimationBase::AnimationStateInput::StartTimerFired: return "StartTimerFired";
- case AnimationBase::AnimationStateInput::StyleAvailable: return "StyleAvailable";
- case AnimationBase::AnimationStateInput::StartTimeSet: return "StartTimeSet";
- case AnimationBase::AnimationStateInput::LoopTimerFired: return "LoopTimerFired";
- case AnimationBase::AnimationStateInput::EndTimerFired: return "EndTimerFired";
- case AnimationBase::AnimationStateInput::PauseOverride: return "PauseOverride";
- case AnimationBase::AnimationStateInput::ResumeOverride: return "ResumeOverride";
- case AnimationBase::AnimationStateInput::PlayStateRunning: return "PlayStateRunning";
- case AnimationBase::AnimationStateInput::PlayStatePaused: return "PlayStatePaused";
- case AnimationBase::AnimationStateInput::EndAnimation: return "EndAnimation";
+ case AnimationBase::AnimationStateNew: return "New";
+ case AnimationBase::AnimationStateStartWaitTimer: return "StartWaitTimer";
+ case AnimationBase::AnimationStateStartWaitStyleAvailable: return "StartWaitStyleAvailable";
+ case AnimationBase::AnimationStateStartWaitResponse: return "StartWaitResponse";
+ case AnimationBase::AnimationStateLooping: return "Looping";
+ case AnimationBase::AnimationStateEnding: return "Ending";
+ case AnimationBase::AnimationStatePausedNew: return "PausedNew";
+ case AnimationBase::AnimationStatePausedWaitTimer: return "PausedWaitTimer";
+ case AnimationBase::AnimationStatePausedWaitStyleAvailable: return "PausedWaitStyleAvailable";
+ case AnimationBase::AnimationStatePausedWaitResponse: return "PausedWaitResponse";
+ case AnimationBase::AnimationStatePausedRun: return "PausedRun";
+ case AnimationBase::AnimationStateDone: return "Done";
+ case AnimationBase::AnimationStateFillingForwards: return "FillingForwards";
}
return "";
}
#endif
-void AnimationBase::updateStateMachine(AnimationStateInput input, double param)
+void AnimationBase::updateStateMachine(AnimStateInput input, double param)
{
- if (!m_compositeAnimation)
+ if (!m_compAnim)
return;
- // If we get AnimationStateInput::RestartAnimation then we force a new animation, regardless of state.
- if (input == AnimationStateInput::MakeNew) {
- if (m_animationState == AnimationState::StartWaitStyleAvailable)
- m_compositeAnimation->animationController().removeFromAnimationsWaitingForStyle(this);
- LOG(Animations, "%p AnimationState %s -> New", this, nameForState(m_animationState));
- m_animationState = AnimationState::New;
+ // If we get AnimationStateInputRestartAnimation then we force a new animation, regardless of state.
+ if (input == AnimationStateInputMakeNew) {
+ if (m_animState == AnimationStateStartWaitStyleAvailable)
+ m_compAnim->animationController()->removeFromAnimationsWaitingForStyle(this);
+ LOG(Animations, "%p AnimationState %s -> New", this, nameForState(m_animState));
+ m_animState = AnimationStateNew;
m_startTime = 0;
m_pauseTime = -1;
m_requestedStartTime = 0;
@@ -163,11 +152,11 @@ void AnimationBase::updateStateMachine(AnimationStateInput input, double param)
return;
}
- if (input == AnimationStateInput::RestartAnimation) {
- if (m_animationState == AnimationState::StartWaitStyleAvailable)
- m_compositeAnimation->animationController().removeFromAnimationsWaitingForStyle(this);
- LOG(Animations, "%p AnimationState %s -> New", this, nameForState(m_animationState));
- m_animationState = AnimationState::New;
+ if (input == AnimationStateInputRestartAnimation) {
+ if (m_animState == AnimationStateStartWaitStyleAvailable)
+ m_compAnim->animationController()->removeFromAnimationsWaitingForStyle(this);
+ LOG(Animations, "%p AnimationState %s -> New", this, nameForState(m_animState));
+ m_animState = AnimationStateNew;
m_startTime = 0;
m_pauseTime = -1;
m_requestedStartTime = 0;
@@ -175,31 +164,31 @@ void AnimationBase::updateStateMachine(AnimationStateInput input, double param)
endAnimation();
if (!paused())
- updateStateMachine(AnimationStateInput::StartAnimation, -1);
+ updateStateMachine(AnimationStateInputStartAnimation, -1);
return;
}
- if (input == AnimationStateInput::EndAnimation) {
- if (m_animationState == AnimationState::StartWaitStyleAvailable)
- m_compositeAnimation->animationController().removeFromAnimationsWaitingForStyle(this);
- LOG(Animations, "%p AnimationState %s -> Done", this, nameForState(m_animationState));
- m_animationState = AnimationState::Done;
+ if (input == AnimationStateInputEndAnimation) {
+ if (m_animState == AnimationStateStartWaitStyleAvailable)
+ m_compAnim->animationController()->removeFromAnimationsWaitingForStyle(this);
+ LOG(Animations, "%p AnimationState %s -> Done", this, nameForState(m_animState));
+ m_animState = AnimationStateDone;
endAnimation();
return;
}
- if (input == AnimationStateInput::PauseOverride) {
- if (m_animationState == AnimationState::StartWaitResponse) {
- // If we are in AnimationState::StartWaitResponse, the animation will get canceled before
+ if (input == AnimationStateInputPauseOverride) {
+ if (m_animState == AnimationStateStartWaitResponse) {
+ // If we are in AnimationStateStartWaitResponse, the animation will get canceled before
// we get a response, so move to the next state.
endAnimation();
- updateStateMachine(AnimationStateInput::StartTimeSet, beginAnimationUpdateTime());
+ updateStateMachine(AnimationStateInputStartTimeSet, beginAnimationUpdateTime());
}
return;
}
- if (input == AnimationStateInput::ResumeOverride) {
- if (m_animationState == AnimationState::Looping || m_animationState == AnimationState::Ending) {
+ if (input == AnimationStateInputResumeOverride) {
+ if (m_animState == AnimationStateLooping || m_animState == AnimationStateEnding) {
// Start the animation
startAnimation(beginAnimationUpdateTime() - m_startTime);
}
@@ -207,54 +196,47 @@ void AnimationBase::updateStateMachine(AnimationStateInput input, double param)
}
// Execute state machine
- switch (m_animationState) {
- case AnimationState::New:
- ASSERT(input == AnimationStateInput::StartAnimation || input == AnimationStateInput::PlayStateRunning || input == AnimationStateInput::PlayStatePaused);
-
- if (input == AnimationStateInput::StartAnimation || input == AnimationStateInput::PlayStateRunning) {
+ switch (m_animState) {
+ case AnimationStateNew:
+ ASSERT(input == AnimationStateInputStartAnimation || input == AnimationStateInputPlayStateRunning || input == AnimationStateInputPlayStatePaused);
+ if (input == AnimationStateInputStartAnimation || input == AnimationStateInputPlayStateRunning) {
m_requestedStartTime = beginAnimationUpdateTime();
- LOG(Animations, "%p AnimationState %s -> StartWaitTimer", this, nameForState(m_animationState));
- m_animationState = AnimationState::StartWaitTimer;
+ LOG(Animations, "%p AnimationState %s -> StartWaitTimer", this, nameForState(m_animState));
+ m_animState = AnimationStateStartWaitTimer;
} else {
// We are pausing before we even started.
- LOG(Animations, "%p AnimationState %s -> AnimationState::PausedNew", this, nameForState(m_animationState));
- m_animationState = AnimationState::PausedNew;
- m_pauseTime = 0;
+ LOG(Animations, "%p AnimationState %s -> AnimationStatePausedNew", this, nameForState(m_animState));
+ m_animState = AnimationStatePausedNew;
}
-
-#if ENABLE(CSS_ANIMATIONS_LEVEL_2)
- if (m_animation->trigger() && m_animation->trigger()->isScrollAnimationTrigger())
- m_compositeAnimation->animationController().addToAnimationsDependentOnScroll(this);
-#endif
break;
- case AnimationState::StartWaitTimer:
- ASSERT(input == AnimationStateInput::StartTimerFired || input == AnimationStateInput::PlayStatePaused);
+ case AnimationStateStartWaitTimer:
+ ASSERT(input == AnimationStateInputStartTimerFired || input == AnimationStateInputPlayStatePaused);
- if (input == AnimationStateInput::StartTimerFired) {
+ if (input == AnimationStateInputStartTimerFired) {
ASSERT(param >= 0);
// Start timer has fired, tell the animation to start and wait for it to respond with start time
- LOG(Animations, "%p AnimationState %s -> StartWaitStyleAvailable (time is %f)", this, nameForState(m_animationState), param);
- m_animationState = AnimationState::StartWaitStyleAvailable;
- m_compositeAnimation->animationController().addToAnimationsWaitingForStyle(this);
+ LOG(Animations, "%p AnimationState %s -> StartWaitStyleAvailable", this, nameForState(m_animState));
+ m_animState = AnimationStateStartWaitStyleAvailable;
+ m_compAnim->animationController()->addToAnimationsWaitingForStyle(this);
// Trigger a render so we can start the animation
if (m_object && m_object->element())
- m_compositeAnimation->animationController().addElementChangeToDispatch(*m_object->element());
+ m_compAnim->animationController()->addElementChangeToDispatch(*m_object->element());
} else {
ASSERT(!paused());
// We're waiting for the start timer to fire and we got a pause. Cancel the timer, pause and wait
m_pauseTime = beginAnimationUpdateTime();
- LOG(Animations, "%p AnimationState %s -> PausedWaitTimer", this, nameForState(m_animationState));
- m_animationState = AnimationState::PausedWaitTimer;
+ LOG(Animations, "%p AnimationState %s -> PausedWaitTimer", this, nameForState(m_animState));
+ m_animState = AnimationStatePausedWaitTimer;
}
break;
- case AnimationState::StartWaitStyleAvailable:
- ASSERT(input == AnimationStateInput::StyleAvailable || input == AnimationStateInput::PlayStatePaused);
+ case AnimationStateStartWaitStyleAvailable:
+ ASSERT(input == AnimationStateInputStyleAvailable || input == AnimationStateInputPlayStatePaused);
- if (input == AnimationStateInput::StyleAvailable) {
+ if (input == AnimationStateInputStyleAvailable) {
// Start timer has fired, tell the animation to start and wait for it to respond with start time
- LOG(Animations, "%p AnimationState %s -> StartWaitResponse (time is %f)", this, nameForState(m_animationState), param);
- m_animationState = AnimationState::StartWaitResponse;
+ LOG(Animations, "%p AnimationState %s -> StartWaitResponse", this, nameForState(m_animState));
+ m_animState = AnimationStateStartWaitResponse;
overrideAnimations();
@@ -262,10 +244,10 @@ void AnimationBase::updateStateMachine(AnimationStateInput input, double param)
if (overridden()) {
// We won't try to start accelerated animations if we are overridden and
// just move on to the next state.
- LOG(Animations, "%p AnimationState %s -> StartWaitResponse", this, nameForState(m_animationState));
- m_animationState = AnimationState::StartWaitResponse;
+ LOG(Animations, "%p AnimationState %s -> StartWaitResponse", this, nameForState(m_animState));
+ m_animState = AnimationStateStartWaitResponse;
m_isAccelerated = false;
- updateStateMachine(AnimationStateInput::StartTimeSet, beginAnimationUpdateTime());
+ updateStateMachine(AnimationStateInputStartTimeSet, beginAnimationUpdateTime());
} else {
double timeOffset = 0;
// If the value for 'animation-delay' is negative then the animation appears to have started in the past.
@@ -273,23 +255,21 @@ void AnimationBase::updateStateMachine(AnimationStateInput input, double param)
timeOffset = -m_animation->delay();
bool started = startAnimation(timeOffset);
- m_compositeAnimation->animationController().addToAnimationsWaitingForStartTimeResponse(this, started);
+ m_compAnim->animationController()->addToAnimationsWaitingForStartTimeResponse(this, started);
m_isAccelerated = started;
}
} else {
// We're waiting for the style to be available and we got a pause. Pause and wait
m_pauseTime = beginAnimationUpdateTime();
- LOG(Animations, "%p AnimationState %s -> PausedWaitStyleAvailable", this, nameForState(m_animationState));
- m_animationState = AnimationState::PausedWaitStyleAvailable;
+ LOG(Animations, "%p AnimationState %s -> PausedWaitStyleAvailable", this, nameForState(m_animState));
+ m_animState = AnimationStatePausedWaitStyleAvailable;
}
break;
- case AnimationState::StartWaitResponse:
- ASSERT(input == AnimationStateInput::StartTimeSet || input == AnimationStateInput::PlayStatePaused);
-
- if (input == AnimationStateInput::StartTimeSet) {
- ASSERT(param > -0.001); // Sometimes Core Animation gives us a beginTime slightly into the future.
- LOG(Animations, "%p AnimationState %s -> StartTimeSet (time is %f)", this, nameForState(m_animationState), param);
+ case AnimationStateStartWaitResponse:
+ ASSERT(input == AnimationStateInputStartTimeSet || input == AnimationStateInputPlayStatePaused);
+ if (input == AnimationStateInputStartTimeSet) {
+ ASSERT(param >= 0);
// We have a start time, set it, unless the startTime is already set
if (m_startTime <= 0) {
m_startTime = param;
@@ -306,23 +286,21 @@ void AnimationBase::updateStateMachine(AnimationStateInput input, double param)
// Dispatch updateStyleIfNeeded so we can start the animation
if (m_object && m_object->element())
- m_compositeAnimation->animationController().addElementChangeToDispatch(*m_object->element());
+ m_compAnim->animationController()->addElementChangeToDispatch(*m_object->element());
} else {
// We are pausing while waiting for a start response. Cancel the animation and wait. When
// we unpause, we will act as though the start timer just fired
m_pauseTime = beginAnimationUpdateTime();
pauseAnimation(beginAnimationUpdateTime() - m_startTime);
- LOG(Animations, "%p AnimationState %s -> PausedWaitResponse", this, nameForState(m_animationState));
- m_animationState = AnimationState::PausedWaitResponse;
+ LOG(Animations, "%p AnimationState %s -> PausedWaitResponse", this, nameForState(m_animState));
+ m_animState = AnimationStatePausedWaitResponse;
}
break;
- case AnimationState::Looping:
- ASSERT(input == AnimationStateInput::LoopTimerFired || input == AnimationStateInput::PlayStatePaused);
+ case AnimationStateLooping:
+ ASSERT(input == AnimationStateInputLoopTimerFired || input == AnimationStateInputPlayStatePaused);
- if (input == AnimationStateInput::LoopTimerFired) {
+ if (input == AnimationStateInputLoopTimerFired) {
ASSERT(param >= 0);
- LOG(Animations, "%p AnimationState %s -> LoopTimerFired (time is %f)", this, nameForState(m_animationState), param);
-
// Loop timer fired, loop again or end.
onAnimationIteration(param);
@@ -332,144 +310,143 @@ void AnimationBase::updateStateMachine(AnimationStateInput input, double param)
// We are pausing while running. Cancel the animation and wait
m_pauseTime = beginAnimationUpdateTime();
pauseAnimation(beginAnimationUpdateTime() - m_startTime);
- LOG(Animations, "%p AnimationState %s -> PausedRun", this, nameForState(m_animationState));
- m_animationState = AnimationState::PausedRun;
+ LOG(Animations, "%p AnimationState %s -> PausedRun", this, nameForState(m_animState));
+ m_animState = AnimationStatePausedRun;
}
break;
- case AnimationState::Ending:
+ case AnimationStateEnding:
#if !LOG_DISABLED
- if (input != AnimationStateInput::EndTimerFired && input != AnimationStateInput::PlayStatePaused)
- LOG_ERROR("State is AnimationState::Ending, but input is not AnimationStateInput::EndTimerFired or AnimationStateInput::PlayStatePaused. It is %s.", nameForStateInput(input));
+ if (input != AnimationStateInputEndTimerFired && input != AnimationStateInputPlayStatePaused)
+ LOG_ERROR("State is AnimationStateEnding, but input is not AnimationStateInputEndTimerFired or AnimationStateInputPlayStatePaused. It is %d.", input);
#endif
- if (input == AnimationStateInput::EndTimerFired) {
+ if (input == AnimationStateInputEndTimerFired) {
+
ASSERT(param >= 0);
// End timer fired, finish up
onAnimationEnd(param);
- LOG(Animations, "%p AnimationState %s -> Done (time is %f)", this, nameForState(m_animationState), param);
- m_animationState = AnimationState::Done;
+ LOG(Animations, "%p AnimationState %s -> Done", this, nameForState(m_animState));
+ m_animState = AnimationStateDone;
if (m_object) {
if (m_animation->fillsForwards()) {
- LOG(Animations, "%p AnimationState %s -> FillingForwards", this, nameForState(m_animationState));
- m_animationState = AnimationState::FillingForwards;
+ LOG(Animations, "%p AnimationState %s -> FillingForwards", this, nameForState(m_animState));
+ m_animState = AnimationStateFillingForwards;
} else
resumeOverriddenAnimations();
// Fire off another style change so we can set the final value
if (m_object->element())
- m_compositeAnimation->animationController().addElementChangeToDispatch(*m_object->element());
+ m_compAnim->animationController()->addElementChangeToDispatch(*m_object->element());
}
} else {
// We are pausing while running. Cancel the animation and wait
m_pauseTime = beginAnimationUpdateTime();
pauseAnimation(beginAnimationUpdateTime() - m_startTime);
- LOG(Animations, "%p AnimationState %s -> PausedRun", this, nameForState(m_animationState));
- m_animationState = AnimationState::PausedRun;
+ LOG(Animations, "%p AnimationState %s -> PausedRun", this, nameForState(m_animState));
+ m_animState = AnimationStatePausedRun;
}
// |this| may be deleted here
break;
- case AnimationState::PausedWaitTimer:
- ASSERT(input == AnimationStateInput::PlayStateRunning);
+ case AnimationStatePausedWaitTimer:
+ ASSERT(input == AnimationStateInputPlayStateRunning);
ASSERT(paused());
// Update the times
m_startTime += beginAnimationUpdateTime() - m_pauseTime;
m_pauseTime = -1;
// we were waiting for the start timer to fire, go back and wait again
- LOG(Animations, "%p AnimationState %s -> New", this, nameForState(m_animationState));
- m_animationState = AnimationState::New;
- updateStateMachine(AnimationStateInput::StartAnimation, 0);
+ LOG(Animations, "%p AnimationState %s -> New", this, nameForState(m_animState));
+ m_animState = AnimationStateNew;
+ updateStateMachine(AnimationStateInputStartAnimation, 0);
break;
- case AnimationState::PausedNew:
- case AnimationState::PausedWaitResponse:
- case AnimationState::PausedWaitStyleAvailable:
- case AnimationState::PausedRun:
+ case AnimationStatePausedNew:
+ case AnimationStatePausedWaitResponse:
+ case AnimationStatePausedWaitStyleAvailable:
+ case AnimationStatePausedRun:
// We treat these two cases the same. The only difference is that, when we are in
- // AnimationState::PausedWaitResponse, we don't yet have a valid startTime, so we send 0 to startAnimation.
- // When the AnimationStateInput::StartTimeSet comes in and we were in AnimationState::PausedRun, we will notice
+ // AnimationStatePausedWaitResponse, we don't yet have a valid startTime, so we send 0 to startAnimation.
+ // When the AnimationStateInputStartTimeSet comes in and we were in AnimationStatePausedRun, we will notice
// that we have already set the startTime and will ignore it.
- ASSERT(input == AnimationStateInput::PlayStatePaused || input == AnimationStateInput::PlayStateRunning || input == AnimationStateInput::StartTimeSet || input == AnimationStateInput::StyleAvailable || input == AnimationStateInput::StartAnimation);
+ ASSERT(input == AnimationStateInputPlayStateRunning || input == AnimationStateInputStartTimeSet || input == AnimationStateInputStyleAvailable || input == AnimationStateInputStartAnimation);
ASSERT(paused());
- if (input == AnimationStateInput::PlayStateRunning) {
- if (m_animationState == AnimationState::PausedNew) {
+ if (input == AnimationStateInputPlayStateRunning) {
+ if (m_animState == AnimationStatePausedNew) {
// We were paused before we even started, and now we're supposed
// to start, so jump back to the New state and reset.
- LOG(Animations, "%p AnimationState %s -> AnimationState::New", this, nameForState(m_animationState));
- m_animationState = AnimationState::New;
- m_pauseTime = -1;
+ LOG(Animations, "%p AnimationState %s -> AnimationStateNew", this, nameForState(m_animState));
+ m_animState = AnimationStateNew;
updateStateMachine(input, param);
break;
}
// Update the times
- if (m_animationState == AnimationState::PausedRun)
+ if (m_animState == AnimationStatePausedRun)
m_startTime += beginAnimationUpdateTime() - m_pauseTime;
else
m_startTime = 0;
-
m_pauseTime = -1;
- if (m_animationState == AnimationState::PausedWaitStyleAvailable) {
- LOG(Animations, "%p AnimationState %s -> StartWaitStyleAvailable", this, nameForState(m_animationState));
- m_animationState = AnimationState::StartWaitStyleAvailable;
+ if (m_animState == AnimationStatePausedWaitStyleAvailable) {
+ LOG(Animations, "%p AnimationState %s -> StartWaitStyleAvailable", this, nameForState(m_animState));
+ m_animState = AnimationStateStartWaitStyleAvailable;
} else {
// We were either running or waiting for a begin time response from the animation.
// Either way we need to restart the animation (possibly with an offset if we
// had already been running) and wait for it to start.
- LOG(Animations, "%p AnimationState %s -> StartWaitResponse", this, nameForState(m_animationState));
- m_animationState = AnimationState::StartWaitResponse;
+ LOG(Animations, "%p AnimationState %s -> StartWaitResponse", this, nameForState(m_animState));
+ m_animState = AnimationStateStartWaitResponse;
// Start the animation
if (overridden()) {
// We won't try to start accelerated animations if we are overridden and
// just move on to the next state.
- updateStateMachine(AnimationStateInput::StartTimeSet, beginAnimationUpdateTime());
+ updateStateMachine(AnimationStateInputStartTimeSet, beginAnimationUpdateTime());
m_isAccelerated = true;
} else {
bool started = startAnimation(beginAnimationUpdateTime() - m_startTime);
- m_compositeAnimation->animationController().addToAnimationsWaitingForStartTimeResponse(this, started);
+ m_compAnim->animationController()->addToAnimationsWaitingForStartTimeResponse(this, started);
m_isAccelerated = started;
}
}
break;
}
- if (input == AnimationStateInput::StartTimeSet) {
- ASSERT(m_animationState == AnimationState::PausedWaitResponse);
+ if (input == AnimationStateInputStartTimeSet) {
+ ASSERT(m_animState == AnimationStatePausedWaitResponse);
// We are paused but we got the callback that notifies us that an accelerated animation started.
// We ignore the start time and just move into the paused-run state.
- LOG(Animations, "%p AnimationState %s -> PausedRun (time is %f)", this, nameForState(m_animationState), param);
- m_animationState = AnimationState::PausedRun;
+ LOG(Animations, "%p AnimationState %s -> PausedRun", this, nameForState(m_animState));
+ m_animState = AnimationStatePausedRun;
ASSERT(m_startTime == 0);
m_startTime = param;
m_pauseTime += m_startTime;
break;
}
- ASSERT(m_animationState == AnimationState::PausedNew || m_animationState == AnimationState::PausedWaitStyleAvailable);
+ ASSERT(m_animState == AnimationStatePausedWaitStyleAvailable);
// We are paused but we got the callback that notifies us that style has been updated.
- // We move to the AnimationState::PausedWaitResponse state
- LOG(Animations, "%p AnimationState %s -> PausedWaitResponse", this, nameForState(m_animationState));
- m_animationState = AnimationState::PausedWaitResponse;
+ // We move to the AnimationStatePausedWaitResponse state
+ LOG(Animations, "%p AnimationState %s -> PausedWaitResponse", this, nameForState(m_animState));
+ m_animState = AnimationStatePausedWaitResponse;
overrideAnimations();
break;
- case AnimationState::FillingForwards:
- case AnimationState::Done:
+ case AnimationStateFillingForwards:
+ case AnimationStateDone:
// We're done. Stay in this state until we are deleted
break;
}
}
-
+
void AnimationBase::fireAnimationEventsIfNeeded()
{
- if (!m_compositeAnimation)
+ if (!m_compAnim)
return;
// If we are waiting for the delay time to expire and it has, go to the next state
- if (m_animationState != AnimationState::StartWaitTimer && m_animationState != AnimationState::Looping && m_animationState != AnimationState::Ending)
+ if (m_animState != AnimationStateStartWaitTimer && m_animState != AnimationStateLooping && m_animState != AnimationStateEnding)
return;
// We have to make sure to keep a ref to the this pointer, because it could get destroyed
@@ -477,35 +454,16 @@ void AnimationBase::fireAnimationEventsIfNeeded()
// and it ref counts this object, we will keep a ref to that instead. That way the AnimationBase
// can still access the resources of its CompositeAnimation as needed.
Ref<AnimationBase> protect(*this);
- Ref<CompositeAnimation> protectCompositeAnimation(*m_compositeAnimation);
+ Ref<CompositeAnimation> protectCompositeAnimation(*m_compAnim);
// Check for start timeout
- if (m_animationState == AnimationState::StartWaitTimer) {
-#if ENABLE(CSS_ANIMATIONS_LEVEL_2)
- if (m_animation->trigger() && m_animation->trigger()->isScrollAnimationTrigger()) {
- if (m_object) {
- float offset = m_compositeAnimation->animationController().scrollPosition();
- ScrollAnimationTrigger& scrollTrigger = downcast<ScrollAnimationTrigger>(*m_animation->trigger().get());
- if (offset > scrollTrigger.startValue().value())
- updateStateMachine(AnimationStateInput::StartTimerFired, 0);
- }
-
- return;
- }
-#endif
+ if (m_animState == AnimationStateStartWaitTimer) {
if (beginAnimationUpdateTime() - m_requestedStartTime >= m_animation->delay())
- updateStateMachine(AnimationStateInput::StartTimerFired, 0);
+ updateStateMachine(AnimationStateInputStartTimerFired, 0);
return;
}
-
+
double elapsedDuration = beginAnimationUpdateTime() - m_startTime;
-#if ENABLE(CSS_ANIMATIONS_LEVEL_2)
- // If we are a triggered animation that depends on scroll, our elapsed
- // time is determined by the scroll position.
- if (m_animation->trigger() && m_animation->trigger()->isScrollAnimationTrigger())
- elapsedDuration = getElapsedTime();
-#endif
-
// FIXME: we need to ensure that elapsedDuration is never < 0. If it is, this suggests that
// we had a recalcStyle() outside of beginAnimationUpdate()/endAnimationUpdate().
// Also check in getTimeToNextEvent().
@@ -513,13 +471,13 @@ void AnimationBase::fireAnimationEventsIfNeeded()
// Check for end timeout
if (m_totalDuration >= 0 && elapsedDuration >= m_totalDuration) {
- // We may still be in AnimationState::Looping if we've managed to skip a
+ // We may still be in AnimationStateLooping if we've managed to skip a
// whole iteration, in which case we should jump to the end state.
- LOG(Animations, "%p AnimationState %s -> Ending", this, nameForState(m_animationState));
- m_animationState = AnimationState::Ending;
+ LOG(Animations, "%p AnimationState %s -> Ending", this, nameForState(m_animState));
+ m_animState = AnimationStateEnding;
// Fire an end event
- updateStateMachine(AnimationStateInput::EndTimerFired, m_totalDuration);
+ updateStateMachine(AnimationStateInputEndTimerFired, m_totalDuration);
} else {
// Check for iteration timeout
if (m_nextIterationDuration < 0) {
@@ -535,46 +493,35 @@ void AnimationBase::fireAnimationEventsIfNeeded()
m_nextIterationDuration = elapsedDuration + durationLeft;
// Send the event
- updateStateMachine(AnimationStateInput::LoopTimerFired, previous);
+ updateStateMachine(AnimationStateInputLoopTimerFired, previous);
}
}
}
void AnimationBase::updatePlayState(EAnimPlayState playState)
{
- if (!m_compositeAnimation)
+ if (!m_compAnim)
return;
// When we get here, we can have one of 4 desired states: running, paused, suspended, paused & suspended.
// The state machine can be in one of two states: running, paused.
// Set the state machine to the desired state.
- bool pause = playState == AnimPlayStatePaused || m_compositeAnimation->isSuspended();
+ bool pause = playState == AnimPlayStatePaused || m_compAnim->isSuspended();
if (pause == paused() && !isNew())
return;
- updateStateMachine(pause ? AnimationStateInput::PlayStatePaused : AnimationStateInput::PlayStateRunning, -1);
+ updateStateMachine(pause ? AnimationStateInputPlayStatePaused : AnimationStateInputPlayStateRunning, -1);
}
double AnimationBase::timeToNextService()
{
// Returns the time at which next service is required. -1 means no service is required. 0 means
// service is required now, and > 0 means service is required that many seconds in the future.
- if (paused() || isNew() || postActive() || fillingForwards())
+ if (paused() || isNew() || m_animState == AnimationStateFillingForwards)
return -1;
- if (m_animationState == AnimationState::StartWaitTimer) {
-#if ENABLE(CSS_ANIMATIONS_LEVEL_2)
- if (m_animation->trigger()->isScrollAnimationTrigger()) {
- if (m_object) {
- float currentScrollPosition = m_object->view().frameView().scrollPositionForFixedPosition().y().toFloat();
- ScrollAnimationTrigger& scrollTrigger = downcast<ScrollAnimationTrigger>(*m_animation->trigger().get());
- if (currentScrollPosition >= scrollTrigger.startValue().value() && (!scrollTrigger.hasEndValue() || currentScrollPosition <= scrollTrigger.endValue().value()))
- return 0;
- }
- return -1;
- }
-#endif
+ if (m_animState == AnimationStateStartWaitTimer) {
double timeFromNow = m_animation->delay() - (beginAnimationUpdateTime() - m_requestedStartTime);
return std::max(timeFromNow, 0.0);
}
@@ -619,40 +566,38 @@ double AnimationBase::fractionalTime(double scale, double elapsedTime, double of
return fractionalTime;
}
-double AnimationBase::progress(double scale, double offset, const TimingFunction* timingFunction) const
+double AnimationBase::progress(double scale, double offset, const TimingFunction* tf) const
{
if (preActive())
return 0;
- if (postActive())
- return 1;
-
double elapsedTime = getElapsedTime();
- double duration = m_animation->duration();
+ double dur = m_animation->duration();
if (m_animation->iterationCount() > 0)
- duration *= m_animation->iterationCount();
-
- if (fillingForwards())
- elapsedTime = duration;
+ dur *= m_animation->iterationCount();
- double fractionalTime = this->fractionalTime(scale, elapsedTime, offset);
+ if (postActive() || !m_animation->duration())
+ return 1.0;
- if (m_animation->iterationCount() > 0 && elapsedTime >= duration) {
- if (WTF::isIntegral(fractionalTime))
- return fractionalTime;
+ if (m_animation->iterationCount() > 0 && elapsedTime >= dur) {
+ const int integralIterationCount = static_cast<int>(m_animation->iterationCount());
+ const bool iterationCountHasFractional = m_animation->iterationCount() - integralIterationCount;
+ return (integralIterationCount % 2 || iterationCountHasFractional) ? 1.0 : 0.0;
}
- if (!timingFunction)
- timingFunction = m_animation->timingFunction().get();
+ const double fractionalTime = this->fractionalTime(scale, elapsedTime, offset);
- switch (timingFunction->type()) {
+ if (!tf)
+ tf = m_animation->timingFunction().get();
+
+ switch (tf->type()) {
case TimingFunction::CubicBezierFunction: {
- const CubicBezierTimingFunction* function = static_cast<const CubicBezierTimingFunction*>(timingFunction);
+ const CubicBezierTimingFunction* function = static_cast<const CubicBezierTimingFunction*>(tf);
return solveCubicBezierFunction(function->x1(), function->y1(), function->x2(), function->y2(), fractionalTime, m_animation->duration());
}
case TimingFunction::StepsFunction: {
- const StepsTimingFunction* stepsTimingFunction = static_cast<const StepsTimingFunction*>(timingFunction);
+ const StepsTimingFunction* stepsTimingFunction = static_cast<const StepsTimingFunction*>(tf);
return solveStepsFunction(stepsTimingFunction->numberOfSteps(), stepsTimingFunction->stepAtStart(), fractionalTime);
}
case TimingFunction::LinearFunction:
@@ -692,68 +637,50 @@ void AnimationBase::goIntoEndingOrLoopingState()
double t;
bool isLooping;
getTimeToNextEvent(t, isLooping);
- LOG(Animations, "%p AnimationState %s -> %s", this, nameForState(m_animationState), isLooping ? "Looping" : "Ending");
- m_animationState = isLooping ? AnimationState::Looping : AnimationState::Ending;
+ LOG(Animations, "%p AnimationState %s -> %s", this, nameForState(m_animState), isLooping ? "Looping" : "Ending");
+ m_animState = isLooping ? AnimationStateLooping : AnimationStateEnding;
}
void AnimationBase::freezeAtTime(double t)
{
- if (!m_compositeAnimation)
+ if (!m_compAnim)
return;
if (!m_startTime) {
// If we haven't started yet, make it as if we started.
- LOG(Animations, "%p AnimationState %s -> StartWaitResponse", this, nameForState(m_animationState));
- m_animationState = AnimationState::StartWaitResponse;
+ LOG(Animations, "%p AnimationState %s -> StartWaitResponse", this, nameForState(m_animState));
+ m_animState = AnimationStateStartWaitResponse;
onAnimationStartResponse(monotonicallyIncreasingTime());
}
- ASSERT(m_startTime); // If m_startTime is zero, we haven't started yet, so we'll get a bad pause time.
+ ASSERT(m_startTime); // if m_startTime is zero, we haven't started yet, so we'll get a bad pause time.
if (t <= m_animation->delay())
m_pauseTime = m_startTime;
else
m_pauseTime = m_startTime + t - m_animation->delay();
+#if USE(ACCELERATED_COMPOSITING)
if (m_object && m_object->isComposited())
- downcast<RenderBoxModelObject>(*m_object).suspendAnimations(m_pauseTime);
+ toRenderBoxModelObject(m_object)->suspendAnimations(m_pauseTime);
+#endif
}
double AnimationBase::beginAnimationUpdateTime() const
{
- if (!m_compositeAnimation)
+ if (!m_compAnim)
return 0;
- return m_compositeAnimation->animationController().beginAnimationUpdateTime();
+ return m_compAnim->animationController()->beginAnimationUpdateTime();
}
double AnimationBase::getElapsedTime() const
{
-#if ENABLE(CSS_ANIMATIONS_LEVEL_2)
- if (m_animation->trigger() && m_animation->trigger()->isScrollAnimationTrigger()) {
- ScrollAnimationTrigger& scrollTrigger = downcast<ScrollAnimationTrigger>(*m_animation->trigger().get());
- if (scrollTrigger.hasEndValue() && m_object) {
- float offset = m_compositeAnimation->animationController().scrollPosition();
- float startValue = scrollTrigger.startValue().value();
- if (offset < startValue)
- return 0;
- float endValue = scrollTrigger.endValue().value();
- if (offset > endValue)
- return m_animation->duration();
- return m_animation->duration() * (offset - startValue) / (endValue - startValue);
- }
- }
-#endif
-
- if (paused()) {
- double delayOffset = (!m_startTime && m_animation->delay() < 0) ? m_animation->delay() : 0;
- return m_pauseTime - m_startTime - delayOffset;
- }
-
+ if (paused())
+ return m_pauseTime - m_startTime;
if (m_startTime <= 0)
return 0;
-
- if (postActive() || fillingForwards())
- return m_totalDuration;
+ if (postActive())
+ return 1;
return beginAnimationUpdateTime() - m_startTime;
}
@@ -774,77 +701,4 @@ void AnimationBase::pause()
// FIXME: implement this method
}
-static bool containsRotation(const Vector<RefPtr<TransformOperation>>& operations)
-{
- for (const auto& operation : operations) {
- if (operation->type() == TransformOperation::ROTATE)
- return true;
- }
- return false;
-}
-
-bool AnimationBase::computeTransformedExtentViaTransformList(const FloatRect& rendererBox, const RenderStyle& style, LayoutRect& bounds) const
-{
- FloatRect floatBounds = bounds;
- FloatPoint transformOrigin;
-
- bool applyTransformOrigin = containsRotation(style.transform().operations()) || style.transform().affectedByTransformOrigin();
- if (applyTransformOrigin) {
- float offsetX = style.transformOriginX().isPercent() ? rendererBox.x() : 0;
- float offsetY = style.transformOriginY().isPercent() ? rendererBox.y() : 0;
-
- transformOrigin.setX(floatValueForLength(style.transformOriginX(), rendererBox.width()) + offsetX);
- transformOrigin.setY(floatValueForLength(style.transformOriginY(), rendererBox.height()) + offsetY);
- // Ignore transformOriginZ because we'll bail if we encounter any 3D transforms.
-
- floatBounds.moveBy(-transformOrigin);
- }
-
- for (const auto& operation : style.transform().operations()) {
- if (operation->type() == TransformOperation::ROTATE) {
- // For now, just treat this as a full rotation. This could take angle into account to reduce inflation.
- floatBounds = boundsOfRotatingRect(floatBounds);
- } else {
- TransformationMatrix transform;
- operation->apply(transform, rendererBox.size());
- if (!transform.isAffine())
- return false;
-
- if (operation->type() == TransformOperation::MATRIX || operation->type() == TransformOperation::MATRIX_3D) {
- TransformationMatrix::Decomposed2Type toDecomp;
- transform.decompose2(toDecomp);
- // Any rotation prevents us from using a simple start/end rect union.
- if (toDecomp.angle)
- return false;
- }
-
- floatBounds = transform.mapRect(floatBounds);
- }
- }
-
- if (applyTransformOrigin)
- floatBounds.moveBy(transformOrigin);
-
- bounds = LayoutRect(floatBounds);
- return true;
-}
-
-bool AnimationBase::computeTransformedExtentViaMatrix(const FloatRect& rendererBox, const RenderStyle& style, LayoutRect& bounds) const
-{
- TransformationMatrix transform;
- style.applyTransform(transform, rendererBox, RenderStyle::IncludeTransformOrigin);
- if (!transform.isAffine())
- return false;
-
- TransformationMatrix::Decomposed2Type fromDecomp;
- transform.decompose2(fromDecomp);
- // Any rotation prevents us from using a simple start/end rect union.
- if (fromDecomp.angle)
- return false;
-
- bounds = LayoutRect(transform.mapRect(bounds));
- return true;
-
-}
-
} // namespace WebCore
diff --git a/Source/WebCore/page/animation/AnimationBase.h b/Source/WebCore/page/animation/AnimationBase.h
index 77bf8a8a3..51673374d 100644
--- a/Source/WebCore/page/animation/AnimationBase.h
+++ b/Source/WebCore/page/animation/AnimationBase.h
@@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Inc. ("Apple") nor the names of
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
@@ -39,10 +39,10 @@
namespace WebCore {
+class AnimationBase;
+class AnimationController;
class CompositeAnimation;
class Element;
-class FloatRect;
-class LayoutRect;
class RenderElement;
class RenderStyle;
class TimingFunction;
@@ -50,17 +50,17 @@ class TimingFunction;
class AnimationBase : public RefCounted<AnimationBase> {
friend class CompositeAnimation;
friend class CSSPropertyAnimation;
- WTF_MAKE_FAST_ALLOCATED;
+
public:
- AnimationBase(Animation& transition, RenderElement*, CompositeAnimation*);
+ AnimationBase(const Animation& transition, RenderElement*, CompositeAnimation*);
virtual ~AnimationBase() { }
RenderElement* renderer() const { return m_object; }
void clear()
{
- endAnimation();
- m_object = nullptr;
- m_compositeAnimation = nullptr;
+ endAnimation();
+ m_object = 0;
+ m_compAnim = 0;
}
double duration() const;
@@ -68,129 +68,106 @@ public:
// Animations and Transitions go through the states below. When entering the STARTED state
// the animation is started. This may or may not require deferred response from the animator.
// If so, we stay in this state until that response is received (and it returns the start time).
- // Otherwise, we use the current time as the start time and go immediately to AnimationState::Looping
- // or AnimationState::Ending.
- enum class AnimationState {
- New, // animation just created, animation not running yet
- StartWaitTimer, // start timer running, waiting for fire
- StartWaitStyleAvailable, // waiting for style setup so we can start animations
- StartWaitResponse, // animation started, waiting for response
- Looping, // response received, animation running, loop timer running, waiting for fire
- Ending, // received, animation running, end timer running, waiting for fire
- PausedNew, // in pause mode when animation was created
- PausedWaitTimer, // in pause mode when animation started
- PausedWaitStyleAvailable, // in pause mode when waiting for style setup
- PausedWaitResponse, // animation paused when in STARTING state
- PausedRun, // animation paused when in LOOPING or ENDING state
- Done, // end timer fired, animation finished and removed
- FillingForwards // animation has ended and is retaining its final value
+ // Otherwise, we use the current time as the start time and go immediately to AnimationStateLooping
+ // or AnimationStateEnding.
+ enum AnimState {
+ AnimationStateNew, // animation just created, animation not running yet
+ AnimationStateStartWaitTimer, // start timer running, waiting for fire
+ AnimationStateStartWaitStyleAvailable, // waiting for style setup so we can start animations
+ AnimationStateStartWaitResponse, // animation started, waiting for response
+ AnimationStateLooping, // response received, animation running, loop timer running, waiting for fire
+ AnimationStateEnding, // received, animation running, end timer running, waiting for fire
+ AnimationStatePausedNew, // in pause mode when animation was created
+ AnimationStatePausedWaitTimer, // in pause mode when animation started
+ AnimationStatePausedWaitStyleAvailable, // in pause mode when waiting for style setup
+ AnimationStatePausedWaitResponse, // animation paused when in STARTING state
+ AnimationStatePausedRun, // animation paused when in LOOPING or ENDING state
+ AnimationStateDone, // end timer fired, animation finished and removed
+ AnimationStateFillingForwards // animation has ended and is retaining its final value
};
- enum class AnimationStateInput {
- MakeNew, // reset back to new from any state
- StartAnimation, // animation requests a start
- RestartAnimation, // force a restart from any state
- StartTimerFired, // start timer fired
- StyleAvailable, // style is setup, ready to start animating
- StartTimeSet, // m_startTime was set
- LoopTimerFired, // loop timer fired
- EndTimerFired, // end timer fired
- PauseOverride, // pause an animation due to override
- ResumeOverride, // resume an overridden animation
- PlayStateRunning, // play state paused -> running
- PlayStatePaused, // play state running -> paused
- EndAnimation // force an end from any state
+ enum AnimStateInput {
+ AnimationStateInputMakeNew, // reset back to new from any state
+ AnimationStateInputStartAnimation, // animation requests a start
+ AnimationStateInputRestartAnimation, // force a restart from any state
+ AnimationStateInputStartTimerFired, // start timer fired
+ AnimationStateInputStyleAvailable, // style is setup, ready to start animating
+ AnimationStateInputStartTimeSet, // m_startTime was set
+ AnimationStateInputLoopTimerFired, // loop timer fired
+ AnimationStateInputEndTimerFired, // end timer fired
+ AnimationStateInputPauseOverride, // pause an animation due to override
+ AnimationStateInputResumeOverride, // resume an overridden animation
+ AnimationStateInputPlayStateRunning, // play state paused -> running
+ AnimationStateInputPlayStatePaused, // play state running -> paused
+ AnimationStateInputEndAnimation // force an end from any state
};
- // Called when animation is in AnimationState::New to start animation
- void updateStateMachine(AnimationStateInput, double param);
+ // Called when animation is in AnimationStateNew to start animation
+ void updateStateMachine(AnimStateInput, double param);
// Animation has actually started, at passed time
void onAnimationStartResponse(double startTime)
{
- updateStateMachine(AnimationStateInput::StartTimeSet, startTime);
+ updateStateMachine(AnimationBase::AnimationStateInputStartTimeSet, startTime);
}
// Called to change to or from paused state
void updatePlayState(EAnimPlayState);
bool playStatePlaying() const;
- bool waitingToStart() const { return m_animationState == AnimationState::New || m_animationState == AnimationState::StartWaitTimer || m_animationState == AnimationState::PausedNew; }
+ bool waitingToStart() const { return m_animState == AnimationStateNew || m_animState == AnimationStateStartWaitTimer || m_animState == AnimationStatePausedNew; }
bool preActive() const
{
- return m_animationState == AnimationState::New || m_animationState == AnimationState::StartWaitTimer || m_animationState == AnimationState::StartWaitStyleAvailable || m_animationState == AnimationState::StartWaitResponse;
+ return m_animState == AnimationStateNew || m_animState == AnimationStateStartWaitTimer || m_animState == AnimationStateStartWaitStyleAvailable || m_animState == AnimationStateStartWaitResponse;
}
- bool postActive() const { return m_animationState == AnimationState::Done; }
- bool fillingForwards() const { return m_animationState == AnimationState::FillingForwards; }
+ bool postActive() const { return m_animState == AnimationStateDone; }
bool active() const { return !postActive() && !preActive(); }
bool running() const { return !isNew() && !postActive(); }
- bool paused() const { return m_pauseTime >= 0 || m_animationState == AnimationState::PausedNew; }
- bool inPausedState() const { return m_animationState >= AnimationState::PausedNew && m_animationState <= AnimationState::PausedRun; }
- bool isNew() const { return m_animationState == AnimationState::New || m_animationState == AnimationState::PausedNew; }
- bool waitingForStartTime() const { return m_animationState == AnimationState::StartWaitResponse; }
- bool waitingForStyleAvailable() const { return m_animationState == AnimationState::StartWaitStyleAvailable; }
-
- bool isAccelerated() const { return m_isAccelerated; }
+ bool paused() const { return m_pauseTime >= 0 || m_animState == AnimationStatePausedNew; }
+ bool isNew() const { return m_animState == AnimationStateNew || m_animState == AnimationStatePausedNew; }
+ bool waitingForStartTime() const { return m_animState == AnimationStateStartWaitResponse; }
+ bool waitingForStyleAvailable() const { return m_animState == AnimationStateStartWaitStyleAvailable; }
virtual double timeToNextService();
- double progress(double scale = 1, double offset = 0, const TimingFunction* = nullptr) const;
+ double progress(double scale, double offset, const TimingFunction*) const;
- // Returns true if the animation state changed.
- virtual bool animate(CompositeAnimation*, RenderElement*, const RenderStyle* /*currentStyle*/, RenderStyle* /*targetStyle*/, RefPtr<RenderStyle>& /*animatedStyle*/) = 0;
+ virtual void animate(CompositeAnimation*, RenderElement*, const RenderStyle* /*currentStyle*/, RenderStyle* /*targetStyle*/, RefPtr<RenderStyle>& /*animatedStyle*/) = 0;
virtual void getAnimatedStyle(RefPtr<RenderStyle>& /*animatedStyle*/) = 0;
- virtual bool computeExtentOfTransformAnimation(LayoutRect&) const = 0;
-
virtual bool shouldFireEvents() const { return false; }
void fireAnimationEventsIfNeeded();
- bool animationsMatch(const Animation&) const;
+ bool animationsMatch(const Animation*) const;
- const Animation& animation() const { return m_animation; }
- void setAnimation(Animation& animation) { m_animation = animation; }
+ void setAnimation(const Animation& animation) { m_animation = const_cast<Animation*>(&animation); }
// Return true if this animation is overridden. This will only be the case for
// ImplicitAnimations and is used to determine whether or not we should force
// set the start time. If an animation is overridden, it will probably not get
- // back the AnimationStateInput::StartTimeSet input.
+ // back the AnimationStateInputStartTimeSet input.
virtual bool overridden() const { return false; }
// Does this animation/transition involve the given property?
virtual bool affectsProperty(CSSPropertyID /*property*/) const { return false; }
- enum RunningStates {
- Delaying = 1 << 0,
- Paused = 1 << 1,
- Running = 1 << 2,
- };
- typedef unsigned RunningState;
- bool isAnimatingProperty(CSSPropertyID property, bool acceleratedOnly, RunningState runningState) const
+ bool isAnimatingProperty(CSSPropertyID property, bool acceleratedOnly, bool isRunningNow) const
{
if (acceleratedOnly && !m_isAccelerated)
return false;
+
+ if (isRunningNow)
+ return (!waitingToStart() && !postActive()) && affectsProperty(property);
- if (!affectsProperty(property))
- return false;
-
- if ((runningState & Delaying) && preActive())
- return true;
-
- if ((runningState & Paused) && inPausedState())
- return true;
-
- if ((runningState & Running) && !inPausedState() && (m_animationState >= AnimationState::StartWaitStyleAvailable && m_animationState < AnimationState::Done))
- return true;
-
- return false;
+ return !postActive() && affectsProperty(property);
}
- bool transformFunctionListsMatch() const { return m_transformFunctionListsMatch; }
+ // FIXME: rename this using the "lists match" terminology.
+ bool isTransformFunctionListValid() const { return m_transformFunctionListValid; }
+#if ENABLE(CSS_FILTERS)
bool filterFunctionListsMatch() const { return m_filterFunctionListsMatch; }
-#if ENABLE(FILTERS_LEVEL_2)
- bool backdropFilterFunctionListsMatch() const { return m_backdropFilterFunctionListsMatch; }
#endif
// Freeze the animation; used by DumpRenderTree.
@@ -209,14 +186,16 @@ public:
void styleAvailable()
{
ASSERT(waitingForStyleAvailable());
- updateStateMachine(AnimationStateInput::StyleAvailable, -1);
+ updateStateMachine(AnimationBase::AnimationStateInputStyleAvailable, -1);
}
+ const Animation& animation() const { return *m_animation; }
+
protected:
virtual void overrideAnimations() { }
virtual void resumeOverriddenAnimations() { }
- CompositeAnimation* compositeAnimation() { return m_compositeAnimation; }
+ CompositeAnimation* compositeAnimation() { return m_compAnim; }
// These are called when the corresponding timer fires so subclasses can do any extra work
virtual void onAnimationStart(double /*elapsedTime*/) { }
@@ -232,7 +211,7 @@ protected:
void goIntoEndingOrLoopingState();
- AnimationState state() const { return m_animationState; }
+ bool isAccelerated() const { return m_isAccelerated; }
static void setNeedsStyleRecalc(Element*);
@@ -240,27 +219,24 @@ protected:
double fractionalTime(double scale, double elapsedTime, double offset) const;
- // These return true if we can easily compute a bounding box by applying the style's transform to the bounds rect.
- bool computeTransformedExtentViaTransformList(const FloatRect& rendererBox, const RenderStyle&, LayoutRect& bounds) const;
- bool computeTransformedExtentViaMatrix(const FloatRect& rendererBox, const RenderStyle&, LayoutRect& bounds) const;
+ AnimState m_animState;
- RenderElement* m_object;
- CompositeAnimation* m_compositeAnimation; // Ideally this would be a reference, but it has to be cleared if an animation is destroyed inside an event callback.
- Ref<Animation> m_animation;
-
- double m_startTime { 0 };
- double m_pauseTime { -1 };
- double m_requestedStartTime { 0 };
- double m_totalDuration { -1 };
- double m_nextIterationDuration { -1 };
-
- AnimationState m_animationState { AnimationState::New };
- bool m_isAccelerated { false };
- bool m_transformFunctionListsMatch { false };
- bool m_filterFunctionListsMatch { false };
-#if ENABLE(FILTERS_LEVEL_2)
- bool m_backdropFilterFunctionListsMatch { false };
+ bool m_isAccelerated;
+ bool m_transformFunctionListValid;
+#if ENABLE(CSS_FILTERS)
+ bool m_filterFunctionListsMatch;
#endif
+ double m_startTime;
+ double m_pauseTime;
+ double m_requestedStartTime;
+
+ double m_totalDuration;
+ double m_nextIterationDuration;
+
+ RenderElement* m_object;
+
+ RefPtr<Animation> m_animation;
+ CompositeAnimation* m_compAnim;
};
} // namespace WebCore
diff --git a/Source/WebCore/page/animation/AnimationController.cpp b/Source/WebCore/page/animation/AnimationController.cpp
index 9bcb2fed1..5b8c90b8a 100644
--- a/Source/WebCore/page/animation/AnimationController.cpp
+++ b/Source/WebCore/page/animation/AnimationController.cpp
@@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Inc. ("Apple") nor the names of
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
@@ -31,7 +31,6 @@
#include "AnimationBase.h"
#include "AnimationControllerPrivate.h"
-#include "AnimationEvent.h"
#include "CSSParser.h"
#include "CSSPropertyAnimation.h"
#include "CompositeAnimation.h"
@@ -51,28 +50,13 @@ namespace WebCore {
static const double cAnimationTimerDelay = 0.025;
static const double cBeginAnimationUpdateTimeNotSet = -1;
-class AnimationPrivateUpdateBlock {
-public:
- AnimationPrivateUpdateBlock(AnimationControllerPrivate& animationController)
- : m_animationController(animationController)
- {
- m_animationController.beginAnimationUpdate();
- }
-
- ~AnimationPrivateUpdateBlock()
- {
- m_animationController.endAnimationUpdate();
- }
-
- AnimationControllerPrivate& m_animationController;
-};
-
AnimationControllerPrivate::AnimationControllerPrivate(Frame& frame)
- : m_animationTimer(*this, &AnimationControllerPrivate::animationTimerFired)
- , m_updateStyleIfNeededDispatcher(*this, &AnimationControllerPrivate::updateStyleIfNeededDispatcherFired)
+ : m_animationTimer(this, &AnimationControllerPrivate::animationTimerFired)
+ , m_updateStyleIfNeededDispatcher(this, &AnimationControllerPrivate::updateStyleIfNeededDispatcherFired)
, m_frame(frame)
, m_beginAnimationUpdateTime(cBeginAnimationUpdateTimeNotSet)
- , m_beginAnimationUpdateCount(0)
+ , m_animationsWaitingForStyle()
+ , m_animationsWaitingForStartTimeResponse()
, m_waitingForAsyncStartNotification(false)
, m_isSuspended(false)
, m_allowsNewAnimationsWhileSuspended(false)
@@ -83,51 +67,33 @@ AnimationControllerPrivate::~AnimationControllerPrivate()
{
}
-CompositeAnimation& AnimationControllerPrivate::ensureCompositeAnimation(RenderElement& renderer)
+CompositeAnimation& AnimationControllerPrivate::ensureCompositeAnimation(RenderElement* renderer)
{
- auto result = m_compositeAnimations.add(&renderer, nullptr);
- if (result.isNewEntry) {
- result.iterator->value = CompositeAnimation::create(*this);
- renderer.setIsCSSAnimating(true);
- }
-
+ auto result = m_compositeAnimations.add(renderer, nullptr);
+ if (result.isNewEntry)
+ result.iterator->value = CompositeAnimation::create(this);
return *result.iterator->value;
}
-bool AnimationControllerPrivate::clear(RenderElement& renderer)
+bool AnimationControllerPrivate::clear(RenderElement* renderer)
{
- LOG(Animations, "AnimationControllerPrivate %p clear: %p", this, &renderer);
-
- ASSERT(renderer.isCSSAnimating());
- ASSERT(m_compositeAnimations.contains(&renderer));
-
- Element* element = renderer.element();
-
- m_eventsToDispatch.removeAllMatching([element] (const EventToDispatch& info) {
- return info.element == element;
- });
-
- m_elementChangesToDispatch.removeAllMatching([element] (const Ref<Element>& currElement) {
- return &currElement.get() == element;
- });
-
// Return false if we didn't do anything OR we are suspended (so we don't try to
// do a setNeedsStyleRecalc() when suspended).
- RefPtr<CompositeAnimation> animation = m_compositeAnimations.take(&renderer);
- ASSERT(animation);
- renderer.setIsCSSAnimating(false);
+ RefPtr<CompositeAnimation> animation = m_compositeAnimations.take(renderer);
+ if (!animation)
+ return false;
animation->clearRenderer();
return animation->isSuspended();
}
double AnimationControllerPrivate::updateAnimations(SetChanged callSetChanged/* = DoNotCallSetChanged*/)
{
- AnimationPrivateUpdateBlock updateBlock(*this);
double timeToNextService = -1;
bool calledSetChanged = false;
- for (auto& compositeAnimation : m_compositeAnimations) {
- CompositeAnimation& animation = *compositeAnimation.value;
+ auto end = m_compositeAnimations.end();
+ for (auto it = m_compositeAnimations.begin(); it != end; ++it) {
+ CompositeAnimation& animation = *it->value;
if (!animation.isSuspended() && animation.hasAnimations()) {
double t = animation.timeToNextService();
if (t != -1 && (t < timeToNextService || timeToNextService == -1))
@@ -135,7 +101,7 @@ double AnimationControllerPrivate::updateAnimations(SetChanged callSetChanged/*
if (!timeToNextService) {
if (callSetChanged != CallSetChanged)
break;
- Element* element = compositeAnimation.key->element();
+ Element* element = it->key->element();
ASSERT(element);
ASSERT(!element->document().inPageCache());
element->setNeedsStyleRecalc(SyntheticStyleChange);
@@ -150,11 +116,11 @@ double AnimationControllerPrivate::updateAnimations(SetChanged callSetChanged/*
return timeToNextService;
}
-void AnimationControllerPrivate::updateAnimationTimerForRenderer(RenderElement& renderer)
+void AnimationControllerPrivate::updateAnimationTimerForRenderer(RenderElement* renderer)
{
double timeToNextService = 0;
- const CompositeAnimation* compositeAnimation = m_compositeAnimations.get(&renderer);
+ const CompositeAnimation* compositeAnimation = m_compositeAnimations.get(renderer);
if (!compositeAnimation->isSuspended() && compositeAnimation->hasAnimations())
timeToNextService = compositeAnimation->timeToNextService();
@@ -188,7 +154,7 @@ void AnimationControllerPrivate::updateAnimationTimer(SetChanged callSetChanged/
m_animationTimer.startOneShot(timeToNextService);
}
-void AnimationControllerPrivate::updateStyleIfNeededDispatcherFired()
+void AnimationControllerPrivate::updateStyleIfNeededDispatcherFired(Timer<AnimationControllerPrivate>&)
{
fireEventsAndUpdateStyle();
}
@@ -201,17 +167,18 @@ void AnimationControllerPrivate::fireEventsAndUpdateStyle()
bool updateStyle = !m_eventsToDispatch.isEmpty() || !m_elementChangesToDispatch.isEmpty();
// fire all the events
- Vector<EventToDispatch> eventsToDispatch = WTFMove(m_eventsToDispatch);
- for (auto& event : eventsToDispatch) {
- Element& element = *event.element;
- if (event.eventType == eventNames().transitionendEvent)
- element.dispatchEvent(TransitionEvent::create(event.eventType, event.name, event.elapsedTime, PseudoElement::pseudoElementNameForEvents(element.pseudoId())));
+ Vector<EventToDispatch> eventsToDispatch = std::move(m_eventsToDispatch);
+ Vector<EventToDispatch>::const_iterator eventsToDispatchEnd = eventsToDispatch.end();
+ for (Vector<EventToDispatch>::const_iterator it = eventsToDispatch.begin(); it != eventsToDispatchEnd; ++it) {
+ Element* element = it->element.get();
+ if (it->eventType == eventNames().transitionendEvent)
+ element->dispatchEvent(TransitionEvent::create(it->eventType, it->name, it->elapsedTime, PseudoElement::pseudoElementNameForEvents(element->pseudoId())));
else
- element.dispatchEvent(AnimationEvent::create(event.eventType, event.name, event.elapsedTime));
+ element->dispatchEvent(WebKitAnimationEvent::create(it->eventType, it->name, it->elapsedTime));
}
- for (auto& change : m_elementChangesToDispatch)
- change->setNeedsStyleRecalc(SyntheticStyleChange);
+ for (unsigned i = 0, size = m_elementChangesToDispatch.size(); i < size; ++i)
+ m_elementChangesToDispatch[i]->setNeedsStyleRecalc(SyntheticStyleChange);
m_elementChangesToDispatch.clear();
@@ -237,9 +204,9 @@ void AnimationControllerPrivate::addEventToDispatch(PassRefPtr<Element> element,
startUpdateStyleIfNeededDispatcher();
}
-void AnimationControllerPrivate::addElementChangeToDispatch(Ref<Element>&& element)
+void AnimationControllerPrivate::addElementChangeToDispatch(PassRef<Element> element)
{
- m_elementChangesToDispatch.append(WTFMove(element));
+ m_elementChangesToDispatch.append(std::move(element));
ASSERT(!m_elementChangesToDispatch.last()->document().inPageCache());
startUpdateStyleIfNeededDispatcher();
}
@@ -254,14 +221,11 @@ void AnimationControllerPrivate::animationFrameCallbackFired()
}
#endif
-void AnimationControllerPrivate::animationTimerFired()
+void AnimationControllerPrivate::animationTimerFired(Timer<AnimationControllerPrivate>&)
{
- // We need to keep the frame alive, since it owns us.
- Ref<Frame> protector(m_frame);
-
// Make sure animationUpdateTime is updated, so that it is current even if no
// styleChange has happened (e.g. accelerated animations)
- AnimationPrivateUpdateBlock updateBlock(*this);
+ setBeginAnimationUpdateTime(cBeginAnimationUpdateTimeNotSet);
// When the timer fires, all we do is call setChanged on all DOM nodes with running animations and then do an immediate
// updateStyleIfNeeded. It will then call back to us with new information.
@@ -272,20 +236,16 @@ void AnimationControllerPrivate::animationTimerFired()
fireEventsAndUpdateStyle();
}
-bool AnimationControllerPrivate::isRunningAnimationOnRenderer(RenderElement& renderer, CSSPropertyID property, AnimationBase::RunningState runningState) const
+bool AnimationControllerPrivate::isRunningAnimationOnRenderer(RenderElement* renderer, CSSPropertyID property, bool isRunningNow) const
{
- ASSERT(renderer.isCSSAnimating());
- ASSERT(m_compositeAnimations.contains(&renderer));
- const CompositeAnimation& animation = *m_compositeAnimations.get(&renderer);
- return animation.isAnimatingProperty(property, false, runningState);
+ const CompositeAnimation* animation = m_compositeAnimations.get(renderer);
+ return animation && animation->isAnimatingProperty(property, false, isRunningNow);
}
-bool AnimationControllerPrivate::isRunningAcceleratedAnimationOnRenderer(RenderElement& renderer, CSSPropertyID property, AnimationBase::RunningState runningState) const
+bool AnimationControllerPrivate::isRunningAcceleratedAnimationOnRenderer(RenderElement* renderer, CSSPropertyID property, bool isRunningNow) const
{
- ASSERT(renderer.isCSSAnimating());
- ASSERT(m_compositeAnimations.contains(&renderer));
- const CompositeAnimation& animation = *m_compositeAnimations.get(&renderer);
- return animation.isAnimatingProperty(property, true, runningState);
+ const CompositeAnimation* animation = m_compositeAnimations.get(renderer);
+ return animation && animation->isAnimatingProperty(property, true, isRunningNow);
}
void AnimationControllerPrivate::suspendAnimations()
@@ -318,11 +278,11 @@ void AnimationControllerPrivate::resumeAnimations()
void AnimationControllerPrivate::suspendAnimationsForDocument(Document* document)
{
- AnimationPrivateUpdateBlock updateBlock(*this);
+ setBeginAnimationUpdateTime(cBeginAnimationUpdateTimeNotSet);
- for (auto& animation : m_compositeAnimations) {
- if (&animation.key->document() == document)
- animation.value->suspendAnimations();
+ for (auto it = m_compositeAnimations.begin(), end = m_compositeAnimations.end(); it != end; ++it) {
+ if (&it->key->document() == document)
+ it->value->suspendAnimations();
}
updateAnimationTimer();
@@ -330,11 +290,11 @@ void AnimationControllerPrivate::suspendAnimationsForDocument(Document* document
void AnimationControllerPrivate::resumeAnimationsForDocument(Document* document)
{
- AnimationPrivateUpdateBlock updateBlock(*this);
+ setBeginAnimationUpdateTime(cBeginAnimationUpdateTimeNotSet);
- for (auto& animation : m_compositeAnimations) {
- if (&animation.key->document() == document)
- animation.value->resumeAnimations();
+ for (auto it = m_compositeAnimations.begin(), end = m_compositeAnimations.end(); it != end; ++it) {
+ if (&it->key->document() == document)
+ it->value->resumeAnimations();
}
updateAnimationTimer();
@@ -356,7 +316,7 @@ bool AnimationControllerPrivate::pauseAnimationAtTime(RenderElement* renderer, c
if (!renderer)
return false;
- CompositeAnimation& compositeAnimation = ensureCompositeAnimation(*renderer);
+ CompositeAnimation& compositeAnimation = ensureCompositeAnimation(renderer);
if (compositeAnimation.pauseAnimationAtTime(name, t)) {
renderer->element()->setNeedsStyleRecalc(SyntheticStyleChange);
startUpdateStyleIfNeededDispatcher();
@@ -371,7 +331,7 @@ bool AnimationControllerPrivate::pauseTransitionAtTime(RenderElement* renderer,
if (!renderer)
return false;
- CompositeAnimation& compositeAnimation = ensureCompositeAnimation(*renderer);
+ CompositeAnimation& compositeAnimation = ensureCompositeAnimation(renderer);
if (compositeAnimation.pauseTransitionAtTime(cssPropertyID(property), t)) {
renderer->element()->setNeedsStyleRecalc(SyntheticStyleChange);
startUpdateStyleIfNeededDispatcher();
@@ -383,72 +343,47 @@ bool AnimationControllerPrivate::pauseTransitionAtTime(RenderElement* renderer,
double AnimationControllerPrivate::beginAnimationUpdateTime()
{
- ASSERT(m_beginAnimationUpdateCount);
if (m_beginAnimationUpdateTime == cBeginAnimationUpdateTimeNotSet)
m_beginAnimationUpdateTime = monotonicallyIncreasingTime();
-
return m_beginAnimationUpdateTime;
}
-void AnimationControllerPrivate::beginAnimationUpdate()
-{
- if (!m_beginAnimationUpdateCount)
- setBeginAnimationUpdateTime(cBeginAnimationUpdateTimeNotSet);
- ++m_beginAnimationUpdateCount;
-}
-
void AnimationControllerPrivate::endAnimationUpdate()
{
- ASSERT(m_beginAnimationUpdateCount > 0);
- if (m_beginAnimationUpdateCount == 1) {
- styleAvailable();
- if (!m_waitingForAsyncStartNotification)
- startTimeResponse(beginAnimationUpdateTime());
- }
- --m_beginAnimationUpdateCount;
+ styleAvailable();
+ if (!m_waitingForAsyncStartNotification)
+ startTimeResponse(beginAnimationUpdateTime());
}
void AnimationControllerPrivate::receivedStartTimeResponse(double time)
{
- LOG(Animations, "AnimationControllerPrivate %p receivedStartTimeResponse %f", this, time);
-
m_waitingForAsyncStartNotification = false;
startTimeResponse(time);
}
-PassRefPtr<RenderStyle> AnimationControllerPrivate::getAnimatedStyleForRenderer(RenderElement& renderer)
+PassRefPtr<RenderStyle> AnimationControllerPrivate::getAnimatedStyleForRenderer(RenderElement* renderer)
{
- AnimationPrivateUpdateBlock animationUpdateBlock(*this);
+ if (!renderer)
+ return 0;
- ASSERT(renderer.isCSSAnimating());
- ASSERT(m_compositeAnimations.contains(&renderer));
- const CompositeAnimation& rendererAnimations = *m_compositeAnimations.get(&renderer);
- RefPtr<RenderStyle> animatingStyle = rendererAnimations.getAnimatedStyle();
+ const CompositeAnimation* rendererAnimations = m_compositeAnimations.get(renderer);
+ if (!rendererAnimations)
+ return &renderer->style();
+
+ RefPtr<RenderStyle> animatingStyle = rendererAnimations->getAnimatedStyle();
if (!animatingStyle)
- animatingStyle = &renderer.style();
+ animatingStyle = &renderer->style();
return animatingStyle.release();
}
-bool AnimationControllerPrivate::computeExtentOfAnimation(RenderElement& renderer, LayoutRect& bounds) const
-{
- ASSERT(renderer.isCSSAnimating());
- ASSERT(m_compositeAnimations.contains(&renderer));
-
- const CompositeAnimation& rendererAnimations = *m_compositeAnimations.get(&renderer);
- if (!rendererAnimations.isAnimatingProperty(CSSPropertyTransform, false, AnimationBase::Running | AnimationBase::Paused))
- return true;
-
- return rendererAnimations.computeExtentOfTransformAnimation(bounds);
-}
-
unsigned AnimationControllerPrivate::numberOfActiveAnimations(Document* document) const
{
unsigned count = 0;
- for (auto& animation : m_compositeAnimations) {
- if (&animation.key->document() == document)
- count += animation.value->numberOfActiveAnimations();
+ for (auto it = m_compositeAnimations.begin(), end = m_compositeAnimations.end(); it != end; ++it) {
+ if (&it->key->document() == document)
+ count += it->value->numberOfActiveAnimations();
}
return count;
@@ -498,7 +433,7 @@ void AnimationControllerPrivate::addToAnimationsWaitingForStartTimeResponse(Anim
if (willGetResponse)
m_waitingForAsyncStartNotification = true;
-
+
m_animationsWaitingForStartTimeResponse.add(animation);
}
@@ -523,55 +458,13 @@ void AnimationControllerPrivate::startTimeResponse(double time)
void AnimationControllerPrivate::animationWillBeRemoved(AnimationBase* animation)
{
- LOG(Animations, "AnimationControllerPrivate %p animationWillBeRemoved: %p", this, animation);
-
removeFromAnimationsWaitingForStyle(animation);
removeFromAnimationsWaitingForStartTimeResponse(animation);
-#if ENABLE(CSS_ANIMATIONS_LEVEL_2)
- removeFromAnimationsDependentOnScroll(animation);
-#endif
-
- bool anyAnimationsWaitingForAsyncStart = false;
- for (auto& animation : m_animationsWaitingForStartTimeResponse) {
- if (animation->waitingForStartTime() && animation->isAccelerated()) {
- anyAnimationsWaitingForAsyncStart = true;
- break;
- }
- }
-
- if (!anyAnimationsWaitingForAsyncStart)
- m_waitingForAsyncStartNotification = false;
-}
-
-#if ENABLE(CSS_ANIMATIONS_LEVEL_2)
-void AnimationControllerPrivate::addToAnimationsDependentOnScroll(AnimationBase* animation)
-{
- m_animationsDependentOnScroll.add(animation);
-}
-
-void AnimationControllerPrivate::removeFromAnimationsDependentOnScroll(AnimationBase* animation)
-{
- m_animationsDependentOnScroll.remove(animation);
-}
-
-void AnimationControllerPrivate::scrollWasUpdated()
-{
- auto* view = m_frame.view();
- if (!view || !wantsScrollUpdates())
- return;
-
- m_scrollPosition = view->scrollPositionForFixedPosition().y().toFloat();
-
- // FIXME: This is updating all the animations, rather than just the ones
- // that are dependent on scroll. We to go from our AnimationBase to its CompositeAnimation
- // so we can execute code similar to updateAnimations.
- // https://bugs.webkit.org/show_bug.cgi?id=144170
- updateAnimations(CallSetChanged);
}
-#endif
AnimationController::AnimationController(Frame& frame)
: m_data(std::make_unique<AnimationControllerPrivate>(frame))
+ , m_beginAnimationUpdateCount(0)
{
}
@@ -579,32 +472,33 @@ AnimationController::~AnimationController()
{
}
-void AnimationController::cancelAnimations(RenderElement& renderer)
+void AnimationController::cancelAnimations(RenderElement* renderer)
{
- if (!renderer.isCSSAnimating())
- return;
-
- if (!m_data->clear(renderer))
+ if (!m_data->hasAnimations())
return;
- Element* element = renderer.element();
- ASSERT(!element || !element->document().inPageCache());
- if (element)
- element->setNeedsStyleRecalc(SyntheticStyleChange);
+ if (m_data->clear(renderer)) {
+ Element* element = renderer->element();
+ ASSERT(!element || !element->document().inPageCache());
+ if (element)
+ element->setNeedsStyleRecalc(SyntheticStyleChange);
+ }
}
-bool AnimationController::updateAnimations(RenderElement& renderer, RenderStyle& newStyle, Ref<RenderStyle>& animatedStyle)
+PassRef<RenderStyle> AnimationController::updateAnimations(RenderElement& renderer, PassRef<RenderStyle> newStyle)
{
+ // Don't do anything if we're in the cache
+ if (renderer.document().inPageCache())
+ return newStyle;
+
RenderStyle* oldStyle = renderer.hasInitializedStyle() ? &renderer.style() : nullptr;
- if ((!oldStyle || (!oldStyle->animations() && !oldStyle->transitions())) && (!newStyle.animations() && !newStyle.transitions()))
- return false;
- if (renderer.document().inPageCache())
- return false;
+ if ((!oldStyle || (!oldStyle->animations() && !oldStyle->transitions())) && (!newStyle.get().animations() && !newStyle.get().transitions()))
+ return newStyle;
// Don't run transitions when printing.
if (renderer.view().printing())
- return false;
+ return newStyle;
// Fetch our current set of implicit animations from a hashtable. We then compare them
// against the animations in the style and make sure we're in sync. If destination values
@@ -614,53 +508,40 @@ bool AnimationController::updateAnimations(RenderElement& renderer, RenderStyle&
// We don't support anonymous pseudo elements like :first-line or :first-letter.
ASSERT(renderer.element());
- CompositeAnimation& rendererAnimations = m_data->ensureCompositeAnimation(renderer);
- bool animationStateChanged = rendererAnimations.animate(renderer, oldStyle, newStyle, animatedStyle);
+ Ref<RenderStyle> newStyleBeforeAnimation(std::move(newStyle));
- if (renderer.parent() || newStyle.animations() || (oldStyle && oldStyle->animations())) {
- m_data->updateAnimationTimerForRenderer(renderer);
+ CompositeAnimation& rendererAnimations = m_data->ensureCompositeAnimation(&renderer);
+ auto blendedStyle = rendererAnimations.animate(renderer, oldStyle, newStyleBeforeAnimation.get());
+
+ if (renderer.parent() || newStyleBeforeAnimation->animations() || (oldStyle && oldStyle->animations())) {
+ m_data->updateAnimationTimerForRenderer(&renderer);
#if ENABLE(REQUEST_ANIMATION_FRAME)
renderer.view().frameView().scheduleAnimation();
#endif
}
- if (animatedStyle.ptr() != &newStyle) {
+ if (&blendedStyle.get() != &newStyleBeforeAnimation.get()) {
// If the animations/transitions change opacity or transform, we need to update
// the style to impose the stacking rules. Note that this is also
// done in StyleResolver::adjustRenderStyle().
- if (animatedStyle.get().hasAutoZIndex() && (animatedStyle.get().opacity() < 1.0f || animatedStyle.get().hasTransform()))
- animatedStyle.get().setZIndex(0);
+ if (blendedStyle.get().hasAutoZIndex() && (blendedStyle.get().opacity() < 1.0f || blendedStyle.get().hasTransform()))
+ blendedStyle.get().setZIndex(0);
}
- return animationStateChanged;
+ return blendedStyle;
}
-PassRefPtr<RenderStyle> AnimationController::getAnimatedStyleForRenderer(RenderElement& renderer)
+PassRefPtr<RenderStyle> AnimationController::getAnimatedStyleForRenderer(RenderElement* renderer)
{
- if (!renderer.isCSSAnimating())
- return &renderer.style();
return m_data->getAnimatedStyleForRenderer(renderer);
}
-bool AnimationController::computeExtentOfAnimation(RenderElement& renderer, LayoutRect& bounds) const
-{
- if (!renderer.isCSSAnimating())
- return true;
-
- return m_data->computeExtentOfAnimation(renderer, bounds);
-}
-
-void AnimationController::notifyAnimationStarted(RenderElement& renderer, double startTime)
+void AnimationController::notifyAnimationStarted(RenderElement*, double startTime)
{
- LOG(Animations, "AnimationController %p notifyAnimationStarted on renderer %p, time=%f", this, &renderer, startTime);
- UNUSED_PARAM(renderer);
-
- AnimationUpdateBlock animationUpdateBlock(this);
m_data->receivedStartTimeResponse(startTime);
}
bool AnimationController::pauseAnimationAtTime(RenderElement* renderer, const AtomicString& name, double t)
{
- AnimationUpdateBlock animationUpdateBlock(this);
return m_data->pauseAnimationAtTime(renderer, name, t);
}
@@ -671,18 +552,17 @@ unsigned AnimationController::numberOfActiveAnimations(Document* document) const
bool AnimationController::pauseTransitionAtTime(RenderElement* renderer, const String& property, double t)
{
- AnimationUpdateBlock animationUpdateBlock(this);
return m_data->pauseTransitionAtTime(renderer, property, t);
}
-bool AnimationController::isRunningAnimationOnRenderer(RenderElement& renderer, CSSPropertyID property, AnimationBase::RunningState runningState) const
+bool AnimationController::isRunningAnimationOnRenderer(RenderElement* renderer, CSSPropertyID property, bool isRunningNow) const
{
- return renderer.isCSSAnimating() && m_data->isRunningAnimationOnRenderer(renderer, property, runningState);
+ return m_data->isRunningAnimationOnRenderer(renderer, property, isRunningNow);
}
-bool AnimationController::isRunningAcceleratedAnimationOnRenderer(RenderElement& renderer, CSSPropertyID property, AnimationBase::RunningState runningState) const
+bool AnimationController::isRunningAcceleratedAnimationOnRenderer(RenderElement* renderer, CSSPropertyID property, bool isRunningNow) const
{
- return renderer.isCSSAnimating() && m_data->isRunningAcceleratedAnimationOnRenderer(renderer, property, runningState);
+ return m_data->isRunningAcceleratedAnimationOnRenderer(renderer, property, isRunningNow);
}
bool AnimationController::isSuspended() const
@@ -728,43 +608,38 @@ void AnimationController::suspendAnimationsForDocument(Document* document)
void AnimationController::resumeAnimationsForDocument(Document* document)
{
LOG(Animations, "resuming animations for document %p", document);
- AnimationUpdateBlock animationUpdateBlock(this);
m_data->resumeAnimationsForDocument(document);
}
void AnimationController::startAnimationsIfNotSuspended(Document* document)
{
LOG(Animations, "animations may start for document %p", document);
-
- AnimationUpdateBlock animationUpdateBlock(this);
m_data->startAnimationsIfNotSuspended(document);
}
void AnimationController::beginAnimationUpdate()
{
- m_data->beginAnimationUpdate();
+ if (!m_beginAnimationUpdateCount)
+ m_data->setBeginAnimationUpdateTime(cBeginAnimationUpdateTimeNotSet);
+ ++m_beginAnimationUpdateCount;
}
void AnimationController::endAnimationUpdate()
{
- m_data->endAnimationUpdate();
+ ASSERT(m_beginAnimationUpdateCount > 0);
+ --m_beginAnimationUpdateCount;
+ if (!m_beginAnimationUpdateCount)
+ m_data->endAnimationUpdate();
}
bool AnimationController::supportsAcceleratedAnimationOfProperty(CSSPropertyID property)
{
+#if USE(ACCELERATED_COMPOSITING)
return CSSPropertyAnimation::animationOfPropertyIsAccelerated(property);
-}
-
-#if ENABLE(CSS_ANIMATIONS_LEVEL_2)
-bool AnimationController::wantsScrollUpdates() const
-{
- return m_data->wantsScrollUpdates();
-}
-
-void AnimationController::scrollWasUpdated()
-{
- m_data->scrollWasUpdated();
-}
+#else
+ UNUSED_PARAM(property);
+ return false;
#endif
+}
} // namespace WebCore
diff --git a/Source/WebCore/page/animation/AnimationController.h b/Source/WebCore/page/animation/AnimationController.h
index d69af92fa..c29af5d82 100644
--- a/Source/WebCore/page/animation/AnimationController.h
+++ b/Source/WebCore/page/animation/AnimationController.h
@@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Inc. ("Apple") nor the names of
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
@@ -29,48 +29,42 @@
#ifndef AnimationController_h
#define AnimationController_h
-#include "AnimationBase.h"
#include "CSSPropertyNames.h"
#include <wtf/Forward.h>
+#include <wtf/OwnPtr.h>
namespace WebCore {
+class AnimationBase;
class AnimationControllerPrivate;
class Document;
class Element;
class Frame;
-class LayoutRect;
class RenderElement;
class RenderStyle;
class AnimationController {
- WTF_MAKE_FAST_ALLOCATED;
public:
explicit AnimationController(Frame&);
~AnimationController();
- void cancelAnimations(RenderElement&);
- bool updateAnimations(RenderElement&, RenderStyle& newStyle, Ref<RenderStyle>& animatedStyle);
- PassRefPtr<RenderStyle> getAnimatedStyleForRenderer(RenderElement&);
-
- // If possible, compute the visual extent of any transform animation on the given renderer
- // using the given rect, returning the result in the rect. Return false if there is some
- // transform animation but we were unable to cheaply compute its affect on the extent.
- bool computeExtentOfAnimation(RenderElement&, LayoutRect&) const;
+ void cancelAnimations(RenderElement*);
+ PassRef<RenderStyle> updateAnimations(RenderElement&, PassRef<RenderStyle> newStyle);
+ PassRefPtr<RenderStyle> getAnimatedStyleForRenderer(RenderElement*);
// This is called when an accelerated animation or transition has actually started to animate.
- void notifyAnimationStarted(RenderElement&, double startTime);
+ void notifyAnimationStarted(RenderElement*, double startTime);
- WEBCORE_EXPORT bool pauseAnimationAtTime(RenderElement*, const AtomicString& name, double t); // To be used only for testing
- WEBCORE_EXPORT bool pauseTransitionAtTime(RenderElement*, const String& property, double t); // To be used only for testing
- WEBCORE_EXPORT unsigned numberOfActiveAnimations(Document*) const; // To be used only for testing
+ bool pauseAnimationAtTime(RenderElement*, const AtomicString& name, double t); // To be used only for testing
+ bool pauseTransitionAtTime(RenderElement*, const String& property, double t); // To be used only for testing
+ unsigned numberOfActiveAnimations(Document*) const; // To be used only for testing
- bool isRunningAnimationOnRenderer(RenderElement&, CSSPropertyID, AnimationBase::RunningState) const;
- bool isRunningAcceleratedAnimationOnRenderer(RenderElement&, CSSPropertyID, AnimationBase::RunningState) const;
+ bool isRunningAnimationOnRenderer(RenderElement*, CSSPropertyID, bool isRunningNow = true) const;
+ bool isRunningAcceleratedAnimationOnRenderer(RenderElement*, CSSPropertyID, bool isRunningNow = true) const;
- WEBCORE_EXPORT bool isSuspended() const;
- WEBCORE_EXPORT void suspendAnimations();
- WEBCORE_EXPORT void resumeAnimations();
+ bool isSuspended() const;
+ void suspendAnimations();
+ void resumeAnimations();
#if ENABLE(REQUEST_ANIMATION_FRAME)
void serviceAnimations();
#endif
@@ -82,18 +76,14 @@ public:
void beginAnimationUpdate();
void endAnimationUpdate();
- WEBCORE_EXPORT bool allowsNewAnimationsWhileSuspended() const;
- WEBCORE_EXPORT void setAllowsNewAnimationsWhileSuspended(bool);
+ bool allowsNewAnimationsWhileSuspended() const;
+ void setAllowsNewAnimationsWhileSuspended(bool);
static bool supportsAcceleratedAnimationOfProperty(CSSPropertyID);
-#if ENABLE(CSS_ANIMATIONS_LEVEL_2)
- bool wantsScrollUpdates() const;
- void scrollWasUpdated();
-#endif
-
private:
const std::unique_ptr<AnimationControllerPrivate> m_data;
+ int m_beginAnimationUpdateCount;
};
class AnimationUpdateBlock {
diff --git a/Source/WebCore/page/animation/AnimationControllerPrivate.h b/Source/WebCore/page/animation/AnimationControllerPrivate.h
index 093e29cb5..f03092280 100644
--- a/Source/WebCore/page/animation/AnimationControllerPrivate.h
+++ b/Source/WebCore/page/animation/AnimationControllerPrivate.h
@@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Inc. ("Apple") nor the names of
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
@@ -29,7 +29,6 @@
#ifndef AnimationControllerPrivate_h
#define AnimationControllerPrivate_h
-#include "AnimationBase.h"
#include "CSSPropertyNames.h"
#include "Timer.h"
#include <wtf/HashMap.h>
@@ -65,13 +64,13 @@ public:
double updateAnimations(SetChanged callSetChanged = DoNotCallSetChanged);
void updateAnimationTimer(SetChanged callSetChanged = DoNotCallSetChanged);
- CompositeAnimation& ensureCompositeAnimation(RenderElement&);
- bool clear(RenderElement&);
+ CompositeAnimation& ensureCompositeAnimation(RenderElement*);
+ bool clear(RenderElement*);
- void updateStyleIfNeededDispatcherFired();
+ void updateStyleIfNeededDispatcherFired(Timer<AnimationControllerPrivate>&);
void startUpdateStyleIfNeededDispatcher();
void addEventToDispatch(PassRefPtr<Element> element, const AtomicString& eventType, const String& name, double elapsedTime);
- void addElementChangeToDispatch(Ref<Element>&&);
+ void addElementChangeToDispatch(PassRef<Element>);
bool hasAnimations() const { return !m_compositeAnimations.isEmpty(); }
@@ -86,21 +85,17 @@ public:
void resumeAnimationsForDocument(Document*);
void startAnimationsIfNotSuspended(Document*);
- bool isRunningAnimationOnRenderer(RenderElement&, CSSPropertyID, AnimationBase::RunningState) const;
- bool isRunningAcceleratedAnimationOnRenderer(RenderElement&, CSSPropertyID, AnimationBase::RunningState) const;
+ bool isRunningAnimationOnRenderer(RenderElement*, CSSPropertyID, bool isRunningNow) const;
+ bool isRunningAcceleratedAnimationOnRenderer(RenderElement*, CSSPropertyID, bool isRunningNow) const;
bool pauseAnimationAtTime(RenderElement*, const AtomicString& name, double t);
bool pauseTransitionAtTime(RenderElement*, const String& property, double t);
unsigned numberOfActiveAnimations(Document*) const;
- PassRefPtr<RenderStyle> getAnimatedStyleForRenderer(RenderElement&);
-
- bool computeExtentOfAnimation(RenderElement&, LayoutRect&) const;
+ PassRefPtr<RenderStyle> getAnimatedStyleForRenderer(RenderElement* renderer);
double beginAnimationUpdateTime();
void setBeginAnimationUpdateTime(double t) { m_beginAnimationUpdateTime = t; }
-
- void beginAnimationUpdate();
void endAnimationUpdate();
void receivedStartTimeResponse(double);
@@ -112,30 +107,21 @@ public:
void animationWillBeRemoved(AnimationBase*);
- void updateAnimationTimerForRenderer(RenderElement&);
+ void updateAnimationTimerForRenderer(RenderElement*);
bool allowsNewAnimationsWhileSuspended() const { return m_allowsNewAnimationsWhileSuspended; }
void setAllowsNewAnimationsWhileSuspended(bool);
-#if ENABLE(CSS_ANIMATIONS_LEVEL_2)
- bool wantsScrollUpdates() const { return !m_animationsDependentOnScroll.isEmpty(); }
- void addToAnimationsDependentOnScroll(AnimationBase*);
- void removeFromAnimationsDependentOnScroll(AnimationBase*);
-
- void scrollWasUpdated();
- float scrollPosition() const { return m_scrollPosition; }
-#endif
-
private:
- void animationTimerFired();
+ void animationTimerFired(Timer<AnimationControllerPrivate>&);
void styleAvailable();
void fireEventsAndUpdateStyle();
void startTimeResponse(double t);
HashMap<RenderElement*, RefPtr<CompositeAnimation>> m_compositeAnimations;
- Timer m_animationTimer;
- Timer m_updateStyleIfNeededDispatcher;
+ Timer<AnimationControllerPrivate> m_animationTimer;
+ Timer<AnimationControllerPrivate> m_updateStyleIfNeededDispatcher;
Frame& m_frame;
class EventToDispatch {
@@ -151,12 +137,9 @@ private:
double m_beginAnimationUpdateTime;
- typedef HashSet<RefPtr<AnimationBase>> AnimationsSet;
- AnimationsSet m_animationsWaitingForStyle;
- AnimationsSet m_animationsWaitingForStartTimeResponse;
-
- int m_beginAnimationUpdateCount;
-
+ typedef HashSet<RefPtr<AnimationBase>> WaitingAnimationsSet;
+ WaitingAnimationsSet m_animationsWaitingForStyle;
+ WaitingAnimationsSet m_animationsWaitingForStartTimeResponse;
bool m_waitingForAsyncStartNotification;
bool m_isSuspended;
@@ -164,11 +147,6 @@ private:
// behavior of allowing new transitions and animations to
// run even when this object is suspended.
bool m_allowsNewAnimationsWhileSuspended;
-
-#if ENABLE(CSS_ANIMATIONS_LEVEL_2)
- AnimationsSet m_animationsDependentOnScroll;
- float m_scrollPosition { 0 };
-#endif
};
} // namespace WebCore
diff --git a/Source/WebCore/page/animation/CSSPropertyAnimation.cpp b/Source/WebCore/page/animation/CSSPropertyAnimation.cpp
index 11f7080e9..291129e93 100644
--- a/Source/WebCore/page/animation/CSSPropertyAnimation.cpp
+++ b/Source/WebCore/page/animation/CSSPropertyAnimation.cpp
@@ -11,7 +11,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Inc. ("Apple") nor the names of
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
@@ -51,11 +51,8 @@
#include "StylePropertyShorthand.h"
#include "StyleResolver.h"
#include <algorithm>
-#include <memory>
#include <wtf/MathExtras.h>
-#include <wtf/NeverDestroyed.h>
#include <wtf/Noncopyable.h>
-#include <wtf/PointerComparison.h>
#include <wtf/RefCounted.h>
namespace WebCore {
@@ -65,6 +62,11 @@ static inline int blendFunc(const AnimationBase*, int from, int to, double progr
return blend(from, to, progress);
}
+static inline unsigned blendFunc(const AnimationBase*, unsigned from, unsigned to, double progress)
+{
+ return blend(from, to, progress);
+}
+
static inline double blendFunc(const AnimationBase*, double from, double to, double progress)
{
return blend(from, to, progress);
@@ -82,7 +84,7 @@ static inline Color blendFunc(const AnimationBase*, const Color& from, const Col
static inline Length blendFunc(const AnimationBase*, const Length& from, const Length& to, double progress)
{
- return to.blend(from, progress);
+ return to.blend(from, narrowPrecisionToFloat(progress));
}
static inline LengthSize blendFunc(const AnimationBase* anim, const LengthSize& from, const LengthSize& to, double progress)
@@ -102,25 +104,25 @@ static inline ShadowStyle blendFunc(const AnimationBase* anim, ShadowStyle from,
return result > 0 ? Normal : Inset;
}
-static inline std::unique_ptr<ShadowData> blendFunc(const AnimationBase* anim, const ShadowData* from, const ShadowData* to, double progress)
+static inline PassOwnPtr<ShadowData> blendFunc(const AnimationBase* anim, const ShadowData* from, const ShadowData* to, double progress)
{
ASSERT(from && to);
if (from->style() != to->style())
- return std::make_unique<ShadowData>(*to);
-
- return std::make_unique<ShadowData>(blend(from->location(), to->location(), progress),
- blend(from->radius(), to->radius(), progress),
- blend(from->spread(), to->spread(), progress),
- blendFunc(anim, from->style(), to->style(), progress),
- from->isWebkitBoxShadow(),
- blend(from->color(), to->color(), progress));
+ return adoptPtr(new ShadowData(*to));
+
+ return adoptPtr(new ShadowData(blend(from->location(), to->location(), progress),
+ blend(from->radius(), to->radius(), progress),
+ blend(from->spread(), to->spread(), progress),
+ blendFunc(anim, from->style(), to->style(), progress),
+ from->isWebkitBoxShadow(),
+ blend(from->color(), to->color(), progress)));
}
-static inline TransformOperations blendFunc(const AnimationBase* animation, const TransformOperations& from, const TransformOperations& to, double progress)
+static inline TransformOperations blendFunc(const AnimationBase* anim, const TransformOperations& from, const TransformOperations& to, double progress)
{
- if (animation->transformFunctionListsMatch())
+ if (anim->isTransformFunctionListValid())
return to.blendByMatchingOperations(from, progress);
- return to.blendByUsingMatrixInterpolation(from, progress, is<RenderBox>(*animation->renderer()) ? downcast<RenderBox>(*animation->renderer()).borderBoxRect().size() : LayoutSize());
+ return to.blendByUsingMatrixInterpolation(from, progress, anim->renderer()->isBox() ? toRenderBox(anim->renderer())->borderBoxRect().size() : LayoutSize());
}
static inline PassRefPtr<ClipPathOperation> blendFunc(const AnimationBase*, ClipPathOperation* from, ClipPathOperation* to, double progress)
@@ -132,13 +134,13 @@ static inline PassRefPtr<ClipPathOperation> blendFunc(const AnimationBase*, Clip
if (from->type() != ClipPathOperation::Shape || to->type() != ClipPathOperation::Shape)
return to;
- const BasicShape& fromShape = downcast<ShapeClipPathOperation>(*from).basicShape();
- const BasicShape& toShape = downcast<ShapeClipPathOperation>(*to).basicShape();
+ const BasicShape* fromShape = static_cast<ShapeClipPathOperation*>(from)->basicShape();
+ const BasicShape* toShape = static_cast<ShapeClipPathOperation*>(to)->basicShape();
- if (!fromShape.canBlend(toShape))
+ if (!fromShape->canBlend(toShape))
return to;
- return ShapeClipPathOperation::create(toShape.blend(fromShape, progress));
+ return ShapeClipPathOperation::create(toShape->blend(fromShape, progress));
}
#if ENABLE(CSS_SHAPES)
@@ -147,27 +149,29 @@ static inline PassRefPtr<ShapeValue> blendFunc(const AnimationBase*, ShapeValue*
if (!from || !to)
return to;
- if (from->type() != ShapeValue::Type::Shape || to->type() != ShapeValue::Type::Shape)
+ // FIXME Bug 102723: Shape-inside should be able to animate a value of 'outside-shape' when shape-outside is set to a BasicShape
+ if (from->type() != ShapeValue::Shape || to->type() != ShapeValue::Shape)
return to;
- if (from->cssBox() != to->cssBox())
+ if (from->layoutBox() != to->layoutBox())
return to;
- const BasicShape& fromShape = *from->shape();
- const BasicShape& toShape = *to->shape();
+ const BasicShape* fromShape = from->shape();
+ const BasicShape* toShape = to->shape();
- if (!fromShape.canBlend(toShape))
+ if (!fromShape->canBlend(toShape))
return to;
- return ShapeValue::createShapeValue(toShape.blend(fromShape, progress), to->cssBox());
+ return ShapeValue::createShapeValue(toShape->blend(fromShape, progress), to->layoutBox());
}
#endif
-static inline PassRefPtr<FilterOperation> blendFunc(const AnimationBase* animation, FilterOperation* fromOp, FilterOperation* toOp, double progress, bool blendToPassthrough = false)
+#if ENABLE(CSS_FILTERS)
+static inline PassRefPtr<FilterOperation> blendFunc(const AnimationBase* anim, FilterOperation* fromOp, FilterOperation* toOp, double progress, bool blendToPassthrough = false)
{
ASSERT(toOp);
if (toOp->blendingNeedsRendererSize()) {
- LayoutSize size = is<RenderBox>(*animation->renderer()) ? downcast<RenderBox>(*animation->renderer()).borderBoxRect().size() : LayoutSize();
+ LayoutSize size = anim->renderer()->isBox() ? toRenderBox(anim->renderer())->borderBoxRect().size() : LayoutSize();
return toOp->blend(fromOp, progress, size, blendToPassthrough);
}
return toOp->blend(fromOp, progress, blendToPassthrough);
@@ -196,18 +200,12 @@ static inline FilterOperations blendFilterOperations(const AnimationBase* anim,
return result;
}
-static inline FilterOperations blendFunc(const AnimationBase* anim, const FilterOperations& from, const FilterOperations& to, double progress, bool animatingBackdropFilter = false)
+static inline FilterOperations blendFunc(const AnimationBase* anim, const FilterOperations& from, const FilterOperations& to, double progress)
{
FilterOperations result;
// If we have a filter function list, use that to do a per-function animation.
-#if ENABLE(FILTERS_LEVEL_2)
- if ((!animatingBackdropFilter && anim->filterFunctionListsMatch()) || (animatingBackdropFilter && anim->backdropFilterFunctionListsMatch()))
-#else
- UNUSED_PARAM(animatingBackdropFilter);
if (anim->filterFunctionListsMatch())
-#endif
-
result = blendFilterOperations(anim, from, to, progress);
else {
// If the filter function lists don't match, we could try to cross-fade, but don't yet have a way to represent that in CSS.
@@ -225,12 +223,13 @@ static inline PassRefPtr<StyleImage> blendFilter(const AnimationBase* anim, Cach
RefPtr<StyleCachedImage> styledImage = StyleCachedImage::create(image);
auto imageValue = CSSImageValue::create(image->url(), styledImage.get());
- auto filterValue = ComputedStyleExtractor::valueForFilter(anim->renderer()->style(), filterResult, DoNotAdjustPixelValues);
+ auto filterValue = ComputedStyleExtractor::valueForFilter(&anim->renderer()->style(), filterResult, DoNotAdjustPixelValues);
- auto result = CSSFilterImageValue::create(WTFMove(imageValue), WTFMove(filterValue));
+ auto result = CSSFilterImageValue::create(std::move(imageValue), std::move(filterValue));
result.get().setFilterOperations(filterResult);
- return StyleGeneratedImage::create(WTFMove(result));
+ return StyleGeneratedImage::create(std::move(result));
}
+#endif // ENABLE(CSS_FILTERS)
static inline EVisibility blendFunc(const AnimationBase* anim, EVisibility from, EVisibility to, double progress)
{
@@ -253,11 +252,11 @@ static inline LengthBox blendFunc(const AnimationBase* anim, const LengthBox& fr
return result;
}
+#if ENABLE(SVG)
static inline SVGLength blendFunc(const AnimationBase*, const SVGLength& from, const SVGLength& to, double progress)
{
return to.blend(from, narrowPrecisionToFloat(progress));
}
-
static inline Vector<SVGLength> blendFunc(const AnimationBase*, const Vector<SVGLength>& from, const Vector<SVGLength>& to, double progress)
{
size_t fromLength = from.size();
@@ -278,6 +277,7 @@ static inline Vector<SVGLength> blendFunc(const AnimationBase*, const Vector<SVG
result[i] = to[i % toLength].blend(from[i % fromLength], narrowPrecisionToFloat(progress));
return result;
}
+#endif
static inline PassRefPtr<StyleImage> crossfadeBlend(const AnimationBase*, StyleCachedImage* fromStyleImage, StyleCachedImage* toStyleImage, double progress)
{
@@ -291,9 +291,9 @@ static inline PassRefPtr<StyleImage> crossfadeBlend(const AnimationBase*, StyleC
auto fromImageValue = CSSImageValue::create(fromStyleImage->cachedImage()->url(), fromStyleImage);
auto toImageValue = CSSImageValue::create(toStyleImage->cachedImage()->url(), toStyleImage);
- auto crossfadeValue = CSSCrossfadeValue::create(WTFMove(fromImageValue), WTFMove(toImageValue));
+ auto crossfadeValue = CSSCrossfadeValue::create(std::move(fromImageValue), std::move(toImageValue));
crossfadeValue.get().setPercentage(CSSPrimitiveValue::create(progress, CSSPrimitiveValue::CSS_NUMBER));
- return StyleGeneratedImage::create(WTFMove(crossfadeValue));
+ return StyleGeneratedImage::create(std::move(crossfadeValue));
}
static inline PassRefPtr<StyleImage> blendFunc(const AnimationBase* anim, StyleImage* from, StyleImage* to, double progress)
@@ -302,52 +302,54 @@ static inline PassRefPtr<StyleImage> blendFunc(const AnimationBase* anim, StyleI
return to;
// Animation between two generated images. Cross fade for all other cases.
- if (is<StyleGeneratedImage>(*from) && is<StyleGeneratedImage>(*to)) {
- CSSImageGeneratorValue& fromGenerated = downcast<StyleGeneratedImage>(*from).imageValue();
- CSSImageGeneratorValue& toGenerated = downcast<StyleGeneratedImage>(*to).imageValue();
+ if (from->isGeneratedImage() && to->isGeneratedImage()) {
+ CSSImageGeneratorValue& fromGenerated = toStyleGeneratedImage(from)->imageValue();
+ CSSImageGeneratorValue& toGenerated = toStyleGeneratedImage(to)->imageValue();
- if (is<CSSFilterImageValue>(fromGenerated) && is<CSSFilterImageValue>(toGenerated)) {
+#if ENABLE(CSS_FILTERS)
+ if (fromGenerated.isFilterImageValue() && toGenerated.isFilterImageValue()) {
// Animation of generated images just possible if input images are equal.
// Otherwise fall back to cross fade animation.
- CSSFilterImageValue& fromFilter = downcast<CSSFilterImageValue>(fromGenerated);
- CSSFilterImageValue& toFilter = downcast<CSSFilterImageValue>(toGenerated);
+ CSSFilterImageValue& fromFilter = toCSSFilterImageValue(fromGenerated);
+ CSSFilterImageValue& toFilter = toCSSFilterImageValue(toGenerated);
if (fromFilter.equalInputImages(toFilter) && fromFilter.cachedImage())
return blendFilter(anim, fromFilter.cachedImage(), fromFilter.filterOperations(), toFilter.filterOperations(), progress);
}
+#endif
- if (is<CSSCrossfadeValue>(fromGenerated) && is<CSSCrossfadeValue>(toGenerated)) {
- CSSCrossfadeValue& fromCrossfade = downcast<CSSCrossfadeValue>(fromGenerated);
- CSSCrossfadeValue& toCrossfade = downcast<CSSCrossfadeValue>(toGenerated);
- if (fromCrossfade.equalInputImages(toCrossfade)) {
- if (auto crossfadeBlend = toCrossfade.blend(fromCrossfade, progress))
- return StyleGeneratedImage::create(*crossfadeBlend);
- }
+ if (fromGenerated.isCrossfadeValue() && toGenerated.isCrossfadeValue()) {
+ CSSCrossfadeValue& fromCrossfade = toCSSCrossfadeValue(fromGenerated);
+ CSSCrossfadeValue& toCrossfade = toCSSCrossfadeValue(toGenerated);
+ if (fromCrossfade.equalInputImages(toCrossfade))
+ return StyleGeneratedImage::create(*toCrossfade.blend(fromCrossfade, progress));
}
// FIXME: Add support for animation between two *gradient() functions.
// https://bugs.webkit.org/show_bug.cgi?id=119956
- } else if (is<StyleGeneratedImage>(*from) && is<StyleCachedImage>(*to)) {
- CSSImageGeneratorValue& fromGenerated = downcast<StyleGeneratedImage>(*from).imageValue();
- if (is<CSSFilterImageValue>(fromGenerated)) {
- CSSFilterImageValue& fromFilter = downcast<CSSFilterImageValue>(fromGenerated);
- if (fromFilter.cachedImage() && downcast<StyleCachedImage>(*to).cachedImage() == fromFilter.cachedImage())
+#if ENABLE(CSS_FILTERS)
+ } else if (from->isGeneratedImage() && to->isCachedImage()) {
+ CSSImageGeneratorValue& fromGenerated = toStyleGeneratedImage(from)->imageValue();
+ if (fromGenerated.isFilterImageValue()) {
+ CSSFilterImageValue& fromFilter = toCSSFilterImageValue(fromGenerated);
+ if (fromFilter.cachedImage() && static_cast<StyleCachedImage*>(to)->cachedImage() == fromFilter.cachedImage())
return blendFilter(anim, fromFilter.cachedImage(), fromFilter.filterOperations(), FilterOperations(), progress);
}
// FIXME: Add interpolation between cross-fade and image source.
- } else if (is<StyleCachedImage>(*from) && is<StyleGeneratedImage>(*to)) {
- CSSImageGeneratorValue& toGenerated = downcast<StyleGeneratedImage>(*to).imageValue();
- if (is<CSSFilterImageValue>(toGenerated)) {
- CSSFilterImageValue& toFilter = downcast<CSSFilterImageValue>(toGenerated);
- if (toFilter.cachedImage() && downcast<StyleCachedImage>(*from).cachedImage() == toFilter.cachedImage())
+ } else if (from->isCachedImage() && to->isGeneratedImage()) {
+ CSSImageGeneratorValue& toGenerated = toStyleGeneratedImage(to)->imageValue();
+ if (toGenerated.isFilterImageValue()) {
+ CSSFilterImageValue& toFilter = toCSSFilterImageValue(toGenerated);
+ if (toFilter.cachedImage() && static_cast<StyleCachedImage*>(from)->cachedImage() == toFilter.cachedImage())
return blendFilter(anim, toFilter.cachedImage(), FilterOperations(), toFilter.filterOperations(), progress);
}
+#endif
// FIXME: Add interpolation between image source and cross-fade.
}
// FIXME: Add support cross fade between cached and generated images.
// https://bugs.webkit.org/show_bug.cgi?id=78293
- if (is<StyleCachedImage>(*from) && is<StyleCachedImage>(*to))
- return crossfadeBlend(anim, downcast<StyleCachedImage>(from), downcast<StyleCachedImage>(to), progress);
+ if (from->isCachedImage() && to->isCachedImage())
+ return crossfadeBlend(anim, static_cast<StyleCachedImage*>(from), static_cast<StyleCachedImage*>(to), progress);
return to;
}
@@ -387,7 +389,9 @@ public:
CSSPropertyID property() const { return m_prop; }
+#if USE(ACCELERATED_COMPOSITING)
virtual bool animationIsAccelerated() const { return false; }
+#endif
private:
CSSPropertyID m_prop;
@@ -395,7 +399,6 @@ private:
template <typename T>
class PropertyWrapperGetter : public AnimationPropertyWrapperBase {
- WTF_MAKE_FAST_ALLOCATED;
public:
PropertyWrapperGetter(CSSPropertyID prop, T (RenderStyle::*getter)() const)
: AnimationPropertyWrapperBase(prop)
@@ -405,7 +408,9 @@ public:
virtual bool equals(const RenderStyle* a, const RenderStyle* b) const
{
- if (a == b)
+ // If the style pointers are the same, don't bother doing the test.
+ // If either is null, return false. If both are null, return true.
+ if ((!a && !b) || a == b)
return true;
if (!a || !b)
return false;
@@ -418,7 +423,6 @@ protected:
template <typename T>
class PropertyWrapper : public PropertyWrapperGetter<T> {
- WTF_MAKE_FAST_ALLOCATED;
public:
PropertyWrapper(CSSPropertyID prop, T (RenderStyle::*getter)() const, void (RenderStyle::*setter)(T))
: PropertyWrapperGetter<T>(prop, getter)
@@ -437,7 +441,6 @@ protected:
template <typename T>
class RefCountedPropertyWrapper : public PropertyWrapperGetter<T*> {
- WTF_MAKE_FAST_ALLOCATED;
public:
RefCountedPropertyWrapper(CSSPropertyID prop, T* (RenderStyle::*getter)() const, void (RenderStyle::*setter)(PassRefPtr<T>))
: PropertyWrapperGetter<T*>(prop, getter)
@@ -456,7 +459,6 @@ protected:
template <typename T>
class LengthPropertyWrapper : public PropertyWrapperGetter<const T&> {
- WTF_MAKE_FAST_ALLOCATED;
public:
LengthPropertyWrapper(CSSPropertyID prop, const T& (RenderStyle::*getter)() const, void (RenderStyle::*setter)(T))
: PropertyWrapperGetter<const T&>(prop, getter)
@@ -474,63 +476,24 @@ protected:
};
class PropertyWrapperClipPath : public RefCountedPropertyWrapper<ClipPathOperation> {
- WTF_MAKE_FAST_ALLOCATED;
public:
PropertyWrapperClipPath(CSSPropertyID prop, ClipPathOperation* (RenderStyle::*getter)() const, void (RenderStyle::*setter)(PassRefPtr<ClipPathOperation>))
: RefCountedPropertyWrapper<ClipPathOperation>(prop, getter, setter)
{
}
-
- virtual bool equals(const RenderStyle* a, const RenderStyle* b) const
- {
- // If the style pointers are the same, don't bother doing the test.
- // If either is null, return false. If both are null, return true.
- if (a == b)
- return true;
- if (!a || !b)
- return false;
-
- ClipPathOperation* clipPathA = (a->*m_getter)();
- ClipPathOperation* clipPathB = (b->*m_getter)();
- if (clipPathA == clipPathB)
- return true;
- if (!clipPathA || !clipPathB)
- return false;
- return *clipPathA == *clipPathB;
- }
};
#if ENABLE(CSS_SHAPES)
class PropertyWrapperShape : public RefCountedPropertyWrapper<ShapeValue> {
- WTF_MAKE_FAST_ALLOCATED;
public:
PropertyWrapperShape(CSSPropertyID prop, ShapeValue* (RenderStyle::*getter)() const, void (RenderStyle::*setter)(PassRefPtr<ShapeValue>))
: RefCountedPropertyWrapper<ShapeValue>(prop, getter, setter)
{
}
-
- virtual bool equals(const RenderStyle* a, const RenderStyle* b) const
- {
- // If the style pointers are the same, don't bother doing the test.
- // If either is null, return false. If both are null, return true.
- if (a == b)
- return true;
- if (!a || !b)
- return false;
-
- ShapeValue* shapeA = (a->*m_getter)();
- ShapeValue* shapeB = (b->*m_getter)();
- if (shapeA == shapeB)
- return true;
- if (!shapeA || !shapeB)
- return false;
- return *shapeA == *shapeB;
- }
};
#endif
class StyleImagePropertyWrapper : public RefCountedPropertyWrapper<StyleImage> {
- WTF_MAKE_FAST_ALLOCATED;
public:
StyleImagePropertyWrapper(CSSPropertyID prop, StyleImage* (RenderStyle::*getter)() const, void (RenderStyle::*setter)(PassRefPtr<StyleImage>))
: RefCountedPropertyWrapper<StyleImage>(prop, getter, setter)
@@ -539,6 +502,8 @@ public:
virtual bool equals(const RenderStyle* a, const RenderStyle* b) const
{
+ // If the style pointers are the same, don't bother doing the test.
+ // If either is null, return false. If both are null, return true.
if (a == b)
return true;
if (!a || !b)
@@ -546,12 +511,11 @@ public:
StyleImage* imageA = (a->*m_getter)();
StyleImage* imageB = (b->*m_getter)();
- return arePointingToEqualData(imageA, imageB);
+ return StyleImage::imagesEquivalent(imageA, imageB);
}
};
class PropertyWrapperColor : public PropertyWrapperGetter<Color> {
- WTF_MAKE_FAST_ALLOCATED;
public:
PropertyWrapperColor(CSSPropertyID prop, Color (RenderStyle::*getter)() const, void (RenderStyle::*setter)(const Color&))
: PropertyWrapperGetter<Color>(prop, getter)
@@ -569,8 +533,8 @@ protected:
};
+#if USE(ACCELERATED_COMPOSITING)
class PropertyWrapperAcceleratedOpacity : public PropertyWrapper<float> {
- WTF_MAKE_FAST_ALLOCATED;
public:
PropertyWrapperAcceleratedOpacity()
: PropertyWrapper<float>(CSSPropertyOpacity, &RenderStyle::opacity, &RenderStyle::setOpacity)
@@ -589,10 +553,9 @@ public:
};
class PropertyWrapperAcceleratedTransform : public PropertyWrapper<const TransformOperations&> {
- WTF_MAKE_FAST_ALLOCATED;
public:
PropertyWrapperAcceleratedTransform()
- : PropertyWrapper<const TransformOperations&>(CSSPropertyTransform, &RenderStyle::transform, &RenderStyle::setTransform)
+ : PropertyWrapper<const TransformOperations&>(CSSPropertyWebkitTransform, &RenderStyle::transform, &RenderStyle::setTransform)
{
}
@@ -604,11 +567,11 @@ public:
}
};
+#if ENABLE(CSS_FILTERS)
class PropertyWrapperAcceleratedFilter : public PropertyWrapper<const FilterOperations&> {
- WTF_MAKE_FAST_ALLOCATED;
public:
PropertyWrapperAcceleratedFilter()
- : PropertyWrapper<const FilterOperations&>(CSSPropertyFilter, &RenderStyle::filter, &RenderStyle::setFilter)
+ : PropertyWrapper<const FilterOperations&>(CSSPropertyWebkitFilter, &RenderStyle::filter, &RenderStyle::setFilter)
{
}
@@ -619,24 +582,8 @@ public:
dst->setFilter(blendFunc(anim, a->filter(), b->filter(), progress));
}
};
-
-#if ENABLE(FILTERS_LEVEL_2)
-class PropertyWrapperAcceleratedBackdropFilter : public PropertyWrapper<const FilterOperations&> {
- WTF_MAKE_FAST_ALLOCATED;
-public:
- PropertyWrapperAcceleratedBackdropFilter()
- : PropertyWrapper<const FilterOperations&>(CSSPropertyWebkitBackdropFilter, &RenderStyle::backdropFilter, &RenderStyle::setBackdropFilter)
- {
- }
-
- virtual bool animationIsAccelerated() const { return true; }
-
- virtual void blend(const AnimationBase* anim, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress) const
- {
- dst->setBackdropFilter(blendFunc(anim, a->backdropFilter(), b->backdropFilter(), progress, true));
- }
-};
#endif
+#endif // USE(ACCELERATED_COMPOSITING)
static inline size_t shadowListLength(const ShadowData* shadow)
{
@@ -648,24 +595,24 @@ static inline size_t shadowListLength(const ShadowData* shadow)
static inline const ShadowData* shadowForBlending(const ShadowData* srcShadow, const ShadowData* otherShadow)
{
- static NeverDestroyed<ShadowData> defaultShadowData(IntPoint(), 0, 0, Normal, false, Color::transparent);
- static NeverDestroyed<ShadowData> defaultInsetShadowData(IntPoint(), 0, 0, Inset, false, Color::transparent);
- static NeverDestroyed<ShadowData> defaultWebKitBoxShadowData(IntPoint(), 0, 0, Normal, true, Color::transparent);
- static NeverDestroyed<ShadowData> defaultInsetWebKitBoxShadowData(IntPoint(), 0, 0, Inset, true, Color::transparent);
+ DEFINE_STATIC_LOCAL(ShadowData, defaultShadowData, (IntPoint(), 0, 0, Normal, false, Color::transparent));
+ DEFINE_STATIC_LOCAL(ShadowData, defaultInsetShadowData, (IntPoint(), 0, 0, Inset, false, Color::transparent));
+
+ DEFINE_STATIC_LOCAL(ShadowData, defaultWebKitBoxShadowData, (IntPoint(), 0, 0, Normal, true, Color::transparent));
+ DEFINE_STATIC_LOCAL(ShadowData, defaultInsetWebKitBoxShadowData, (IntPoint(), 0, 0, Inset, true, Color::transparent));
if (srcShadow)
return srcShadow;
if (otherShadow->style() == Inset)
- return otherShadow->isWebkitBoxShadow() ? &defaultInsetWebKitBoxShadowData.get() : &defaultInsetShadowData.get();
+ return otherShadow->isWebkitBoxShadow() ? &defaultInsetWebKitBoxShadowData : &defaultInsetShadowData;
- return otherShadow->isWebkitBoxShadow() ? &defaultWebKitBoxShadowData.get() : &defaultShadowData.get();
+ return otherShadow->isWebkitBoxShadow() ? &defaultWebKitBoxShadowData : &defaultShadowData;
}
class PropertyWrapperShadow : public AnimationPropertyWrapperBase {
- WTF_MAKE_FAST_ALLOCATED;
public:
- PropertyWrapperShadow(CSSPropertyID prop, const ShadowData* (RenderStyle::*getter)() const, void (RenderStyle::*setter)(std::unique_ptr<ShadowData>, bool))
+ PropertyWrapperShadow(CSSPropertyID prop, const ShadowData* (RenderStyle::*getter)() const, void (RenderStyle::*setter)(PassOwnPtr<ShadowData>, bool))
: AnimationPropertyWrapperBase(prop)
, m_getter(getter)
, m_setter(setter)
@@ -674,11 +621,6 @@ public:
virtual bool equals(const RenderStyle* a, const RenderStyle* b) const
{
- if (a == b)
- return true;
- if (!a || !b)
- return false;
-
const ShadowData* shadowA = (a->*m_getter)();
const ShadowData* shadowB = (b->*m_getter)();
@@ -718,22 +660,22 @@ public:
}
private:
- std::unique_ptr<ShadowData> blendSimpleOrMatchedShadowLists(const AnimationBase* anim, double progress, const ShadowData* shadowA, const ShadowData* shadowB) const
+ PassOwnPtr<ShadowData> blendSimpleOrMatchedShadowLists(const AnimationBase* anim, double progress, const ShadowData* shadowA, const ShadowData* shadowB) const
{
- std::unique_ptr<ShadowData> newShadowData;
+ OwnPtr<ShadowData> newShadowData;
ShadowData* lastShadow = 0;
while (shadowA || shadowB) {
const ShadowData* srcShadow = shadowForBlending(shadowA, shadowB);
const ShadowData* dstShadow = shadowForBlending(shadowB, shadowA);
- std::unique_ptr<ShadowData> blendedShadow = blendFunc(anim, srcShadow, dstShadow, progress);
+ OwnPtr<ShadowData> blendedShadow = blendFunc(anim, srcShadow, dstShadow, progress);
ShadowData* blendedShadowPtr = blendedShadow.get();
if (!lastShadow)
- newShadowData = WTFMove(blendedShadow);
+ newShadowData = blendedShadow.release();
else
- lastShadow->setNext(WTFMove(blendedShadow));
+ lastShadow->setNext(blendedShadow.release());
lastShadow = blendedShadowPtr;
@@ -741,10 +683,10 @@ private:
shadowB = shadowB ? shadowB->next() : 0;
}
- return newShadowData;
+ return newShadowData.release();
}
- std::unique_ptr<ShadowData> blendMismatchedShadowLists(const AnimationBase* anim, double progress, const ShadowData* shadowA, const ShadowData* shadowB, int fromLength, int toLength) const
+ PassOwnPtr<ShadowData> blendMismatchedShadowLists(const AnimationBase* anim, double progress, const ShadowData* shadowA, const ShadowData* shadowB, int fromLength, int toLength) const
{
// The shadows in ShadowData are stored in reverse order, so when animating mismatched lists,
// reverse them and match from the end.
@@ -760,7 +702,7 @@ private:
shadowB = shadowB->next();
}
- std::unique_ptr<ShadowData> newShadowData;
+ OwnPtr<ShadowData> newShadowData;
int maxLength = std::max(fromLength, toLength);
for (int i = 0; i < maxLength; ++i) {
@@ -770,21 +712,20 @@ private:
const ShadowData* srcShadow = shadowForBlending(fromShadow, toShadow);
const ShadowData* dstShadow = shadowForBlending(toShadow, fromShadow);
- std::unique_ptr<ShadowData> blendedShadow = blendFunc(anim, srcShadow, dstShadow, progress);
+ OwnPtr<ShadowData> blendedShadow = blendFunc(anim, srcShadow, dstShadow, progress);
// Insert at the start of the list to preserve the order.
- blendedShadow->setNext(WTFMove(newShadowData));
- newShadowData = WTFMove(blendedShadow);
+ blendedShadow->setNext(newShadowData.release());
+ newShadowData = blendedShadow.release();
}
- return newShadowData;
+ return newShadowData.release();
}
const ShadowData* (RenderStyle::*m_getter)() const;
- void (RenderStyle::*m_setter)(std::unique_ptr<ShadowData>, bool);
+ void (RenderStyle::*m_setter)(PassOwnPtr<ShadowData>, bool);
};
class PropertyWrapperMaybeInvalidColor : public AnimationPropertyWrapperBase {
- WTF_MAKE_FAST_ALLOCATED;
public:
PropertyWrapperMaybeInvalidColor(CSSPropertyID prop, Color (RenderStyle::*getter)() const, void (RenderStyle::*setter)(const Color&))
: AnimationPropertyWrapperBase(prop)
@@ -795,11 +736,6 @@ public:
virtual bool equals(const RenderStyle* a, const RenderStyle* b) const
{
- if (a == b)
- return true;
- if (!a || !b)
- return false;
-
Color fromColor = (a->*m_getter)();
Color toColor = (b->*m_getter)();
@@ -837,20 +773,19 @@ private:
enum MaybeInvalidColorTag { MaybeInvalidColor };
class PropertyWrapperVisitedAffectedColor : public AnimationPropertyWrapperBase {
- WTF_MAKE_FAST_ALLOCATED;
public:
PropertyWrapperVisitedAffectedColor(CSSPropertyID prop, Color (RenderStyle::*getter)() const, void (RenderStyle::*setter)(const Color&),
Color (RenderStyle::*visitedGetter)() const, void (RenderStyle::*visitedSetter)(const Color&))
: AnimationPropertyWrapperBase(prop)
- , m_wrapper(std::make_unique<PropertyWrapperColor>(prop, getter, setter))
- , m_visitedWrapper(std::make_unique<PropertyWrapperColor>(prop, visitedGetter, visitedSetter))
+ , m_wrapper(adoptPtr(new PropertyWrapperColor(prop, getter, setter)))
+ , m_visitedWrapper(adoptPtr(new PropertyWrapperColor(prop, visitedGetter, visitedSetter)))
{
}
PropertyWrapperVisitedAffectedColor(CSSPropertyID prop, MaybeInvalidColorTag, Color (RenderStyle::*getter)() const, void (RenderStyle::*setter)(const Color&),
Color (RenderStyle::*visitedGetter)() const, void (RenderStyle::*visitedSetter)(const Color&))
: AnimationPropertyWrapperBase(prop)
- , m_wrapper(std::make_unique<PropertyWrapperMaybeInvalidColor>(prop, getter, setter))
- , m_visitedWrapper(std::make_unique<PropertyWrapperMaybeInvalidColor>(prop, visitedGetter, visitedSetter))
+ , m_wrapper(adoptPtr(new PropertyWrapperMaybeInvalidColor(prop, getter, setter)))
+ , m_visitedWrapper(adoptPtr(new PropertyWrapperMaybeInvalidColor(prop, visitedGetter, visitedSetter)))
{
}
virtual bool equals(const RenderStyle* a, const RenderStyle* b) const
@@ -864,13 +799,12 @@ public:
}
private:
- std::unique_ptr<AnimationPropertyWrapperBase> m_wrapper;
- std::unique_ptr<AnimationPropertyWrapperBase> m_visitedWrapper;
+ OwnPtr<AnimationPropertyWrapperBase> m_wrapper;
+ OwnPtr<AnimationPropertyWrapperBase> m_visitedWrapper;
};
// Wrapper base class for an animatable property in a FillLayer
class FillLayerAnimationPropertyWrapperBase {
- WTF_MAKE_FAST_ALLOCATED;
public:
FillLayerAnimationPropertyWrapperBase()
{
@@ -884,7 +818,6 @@ public:
template <typename T>
class FillLayerPropertyWrapperGetter : public FillLayerAnimationPropertyWrapperBase {
- WTF_MAKE_FAST_ALLOCATED;
WTF_MAKE_NONCOPYABLE(FillLayerPropertyWrapperGetter);
public:
FillLayerPropertyWrapperGetter(T (FillLayer::*getter)() const)
@@ -894,9 +827,11 @@ public:
virtual bool equals(const FillLayer* a, const FillLayer* b) const
{
- if (a == b)
- return true;
- if (!a || !b)
+ // If the style pointers are the same, don't bother doing the test.
+ // If either is null, return false. If both are null, return true.
+ if ((!a && !b) || a == b)
+ return true;
+ if (!a || !b)
return false;
return (a->*m_getter)() == (b->*m_getter)();
}
@@ -907,7 +842,6 @@ protected:
template <typename T>
class FillLayerPropertyWrapper : public FillLayerPropertyWrapperGetter<const T&> {
- WTF_MAKE_FAST_ALLOCATED;
public:
FillLayerPropertyWrapper(const T& (FillLayer::*getter)() const, void (FillLayer::*setter)(T))
: FillLayerPropertyWrapperGetter<const T&>(getter)
@@ -926,7 +860,6 @@ protected:
template <typename T>
class FillLayerRefCountedPropertyWrapper : public FillLayerPropertyWrapperGetter<T*> {
- WTF_MAKE_FAST_ALLOCATED;
public:
FillLayerRefCountedPropertyWrapper(T* (FillLayer::*getter)() const, void (FillLayer::*setter)(PassRefPtr<T>))
: FillLayerPropertyWrapperGetter<T*>(getter)
@@ -944,7 +877,6 @@ protected:
};
class FillLayerStyleImagePropertyWrapper : public FillLayerRefCountedPropertyWrapper<StyleImage> {
- WTF_MAKE_FAST_ALLOCATED;
public:
FillLayerStyleImagePropertyWrapper(StyleImage* (FillLayer::*getter)() const, void (FillLayer::*setter)(PassRefPtr<StyleImage>))
: FillLayerRefCountedPropertyWrapper<StyleImage>(getter, setter)
@@ -953,6 +885,8 @@ public:
virtual bool equals(const FillLayer* a, const FillLayer* b) const
{
+ // If the style pointers are the same, don't bother doing the test.
+ // If either is null, return false. If both are null, return true.
if (a == b)
return true;
if (!a || !b)
@@ -960,15 +894,14 @@ public:
StyleImage* imageA = (a->*m_getter)();
StyleImage* imageB = (b->*m_getter)();
- return arePointingToEqualData(imageA, imageB);
+ return StyleImage::imagesEquivalent(imageA, imageB);
}
};
class FillLayersPropertyWrapper : public AnimationPropertyWrapperBase {
- WTF_MAKE_FAST_ALLOCATED;
public:
typedef const FillLayer* (RenderStyle::*LayersGetter)() const;
- typedef FillLayer& (RenderStyle::*LayersAccessor)();
+ typedef FillLayer* (RenderStyle::*LayersAccessor)();
FillLayersPropertyWrapper(CSSPropertyID prop, LayersGetter getter, LayersAccessor accessor)
: AnimationPropertyWrapperBase(prop)
@@ -978,19 +911,19 @@ public:
switch (prop) {
case CSSPropertyBackgroundPositionX:
case CSSPropertyWebkitMaskPositionX:
- m_fillLayerPropertyWrapper = std::make_unique<FillLayerPropertyWrapper<Length>>(&FillLayer::xPosition, &FillLayer::setXPosition);
+ m_fillLayerPropertyWrapper = new FillLayerPropertyWrapper<Length>(&FillLayer::xPosition, &FillLayer::setXPosition);
break;
case CSSPropertyBackgroundPositionY:
case CSSPropertyWebkitMaskPositionY:
- m_fillLayerPropertyWrapper = std::make_unique<FillLayerPropertyWrapper<Length>>(&FillLayer::yPosition, &FillLayer::setYPosition);
+ m_fillLayerPropertyWrapper = new FillLayerPropertyWrapper<Length>(&FillLayer::yPosition, &FillLayer::setYPosition);
break;
case CSSPropertyBackgroundSize:
case CSSPropertyWebkitBackgroundSize:
case CSSPropertyWebkitMaskSize:
- m_fillLayerPropertyWrapper = std::make_unique<FillLayerPropertyWrapper<LengthSize>>(&FillLayer::sizeLength, &FillLayer::setSizeLength);
+ m_fillLayerPropertyWrapper = new FillLayerPropertyWrapper<LengthSize>(&FillLayer::sizeLength, &FillLayer::setSizeLength);
break;
case CSSPropertyBackgroundImage:
- m_fillLayerPropertyWrapper = std::make_unique<FillLayerStyleImagePropertyWrapper>(&FillLayer::image, &FillLayer::setImage);
+ m_fillLayerPropertyWrapper = new FillLayerStyleImagePropertyWrapper(&FillLayer::image, &FillLayer::setImage);
break;
default:
break;
@@ -999,11 +932,6 @@ public:
virtual bool equals(const RenderStyle* a, const RenderStyle* b) const
{
- if (a == b)
- return true;
- if (!a || !b)
- return false;
-
const FillLayer* fromLayer = (a->*m_layersGetter)();
const FillLayer* toLayer = (b->*m_layersGetter)();
@@ -1022,7 +950,7 @@ public:
{
const FillLayer* aLayer = (a->*m_layersGetter)();
const FillLayer* bLayer = (b->*m_layersGetter)();
- FillLayer* dstLayer = &(dst->*m_layersAccessor)();
+ FillLayer* dstLayer = (dst->*m_layersAccessor)();
while (aLayer && bLayer && dstLayer) {
m_fillLayerPropertyWrapper->blend(anim, dstLayer, aLayer, bLayer, progress);
@@ -1033,32 +961,27 @@ public:
}
private:
- std::unique_ptr<FillLayerAnimationPropertyWrapperBase> m_fillLayerPropertyWrapper;
+ FillLayerAnimationPropertyWrapperBase* m_fillLayerPropertyWrapper;
LayersGetter m_layersGetter;
LayersAccessor m_layersAccessor;
};
class ShorthandPropertyWrapper : public AnimationPropertyWrapperBase {
- WTF_MAKE_FAST_ALLOCATED;
public:
ShorthandPropertyWrapper(CSSPropertyID property, Vector<AnimationPropertyWrapperBase*> longhandWrappers)
: AnimationPropertyWrapperBase(property)
- , m_propertyWrappers(WTFMove(longhandWrappers))
{
+ m_propertyWrappers.swap(longhandWrappers);
}
virtual bool isShorthandWrapper() const { return true; }
virtual bool equals(const RenderStyle* a, const RenderStyle* b) const
{
- if (a == b)
- return true;
- if (!a || !b)
- return false;
-
- for (auto& wrapper : m_propertyWrappers) {
- if (!wrapper->equals(a, b))
+ Vector<AnimationPropertyWrapperBase*>::const_iterator end = m_propertyWrappers.end();
+ for (Vector<AnimationPropertyWrapperBase*>::const_iterator it = m_propertyWrappers.begin(); it != end; ++it) {
+ if (!(*it)->equals(a, b))
return false;
}
return true;
@@ -1066,27 +989,28 @@ public:
virtual void blend(const AnimationBase* anim, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress) const
{
- for (auto& wrapper : m_propertyWrappers)
- wrapper->blend(anim, dst, a, b, progress);
+ Vector<AnimationPropertyWrapperBase*>::const_iterator end = m_propertyWrappers.end();
+ for (Vector<AnimationPropertyWrapperBase*>::const_iterator it = m_propertyWrappers.begin(); it != end; ++it)
+ (*it)->blend(anim, dst, a, b, progress);
}
- const Vector<AnimationPropertyWrapperBase*>& propertyWrappers() const { return m_propertyWrappers; }
+ const Vector<AnimationPropertyWrapperBase*> propertyWrappers() const { return m_propertyWrappers; }
private:
Vector<AnimationPropertyWrapperBase*> m_propertyWrappers;
};
class PropertyWrapperFlex : public AnimationPropertyWrapperBase {
- WTF_MAKE_FAST_ALLOCATED;
public:
- PropertyWrapperFlex()
- : AnimationPropertyWrapperBase(CSSPropertyFlex)
+ PropertyWrapperFlex() : AnimationPropertyWrapperBase(CSSPropertyWebkitFlex)
{
}
virtual bool equals(const RenderStyle* a, const RenderStyle* b) const
{
- if (a == b)
+ // If the style pointers are the same, don't bother doing the test.
+ // If either is null, return false. If both are null, return true.
+ if ((!a && !b) || a == b)
return true;
if (!a || !b)
return false;
@@ -1102,8 +1026,8 @@ public:
}
};
+#if ENABLE(SVG)
class PropertyWrapperSVGPaint : public AnimationPropertyWrapperBase {
- WTF_MAKE_FAST_ALLOCATED;
public:
PropertyWrapperSVGPaint(CSSPropertyID prop, const SVGPaint::SVGPaintType& (RenderStyle::*paintTypeGetter)() const, Color (RenderStyle::*getter)() const, void (RenderStyle::*setter)(const Color&))
: AnimationPropertyWrapperBase(prop)
@@ -1115,11 +1039,6 @@ public:
virtual bool equals(const RenderStyle* a, const RenderStyle* b) const
{
- if (a == b)
- return true;
- if (!a || !b)
- return false;
-
if ((a->*m_paintTypeGetter)() != (b->*m_paintTypeGetter)())
return false;
@@ -1167,15 +1086,17 @@ private:
Color (RenderStyle::*m_getter)() const;
void (RenderStyle::*m_setter)(const Color&);
};
+#endif
class CSSPropertyAnimationWrapperMap {
- WTF_MAKE_FAST_ALLOCATED;
public:
- static CSSPropertyAnimationWrapperMap& singleton()
+ static CSSPropertyAnimationWrapperMap& instance()
{
// FIXME: This data is never destroyed. Maybe we should ref count it and toss it when the last AnimationController is destroyed?
- static NeverDestroyed<CSSPropertyAnimationWrapperMap> map;
- return map;
+ DEFINE_STATIC_LOCAL(OwnPtr<CSSPropertyAnimationWrapperMap>, map, ());
+ if (!map)
+ map = adoptPtr(new CSSPropertyAnimationWrapperMap);
+ return *map;
}
AnimationPropertyWrapperBase* wrapperForProperty(CSSPropertyID propertyID)
@@ -1203,19 +1124,15 @@ public:
private:
CSSPropertyAnimationWrapperMap();
- ~CSSPropertyAnimationWrapperMap() = delete;
-
unsigned char& indexFromPropertyID(CSSPropertyID propertyID)
{
return m_propertyToIdMap[propertyID - firstCSSProperty];
}
- Vector<std::unique_ptr<AnimationPropertyWrapperBase>> m_propertyWrappers;
+ Vector<OwnPtr<AnimationPropertyWrapperBase>> m_propertyWrappers;
unsigned char m_propertyToIdMap[numCSSProperties];
static const unsigned char cInvalidPropertyWrapperIndex = UCHAR_MAX;
-
- friend class WTF::NeverDestroyed<CSSPropertyAnimationWrapperMap>;
};
CSSPropertyAnimationWrapperMap::CSSPropertyAnimationWrapperMap()
@@ -1237,10 +1154,10 @@ CSSPropertyAnimationWrapperMap::CSSPropertyAnimationWrapperMap()
new PropertyWrapperFlex(),
- new PropertyWrapper<float>(CSSPropertyBorderLeftWidth, &RenderStyle::borderLeftWidth, &RenderStyle::setBorderLeftWidth),
- new PropertyWrapper<float>(CSSPropertyBorderRightWidth, &RenderStyle::borderRightWidth, &RenderStyle::setBorderRightWidth),
- new PropertyWrapper<float>(CSSPropertyBorderTopWidth, &RenderStyle::borderTopWidth, &RenderStyle::setBorderTopWidth),
- new PropertyWrapper<float>(CSSPropertyBorderBottomWidth, &RenderStyle::borderBottomWidth, &RenderStyle::setBorderBottomWidth),
+ new PropertyWrapper<unsigned>(CSSPropertyBorderLeftWidth, &RenderStyle::borderLeftWidth, &RenderStyle::setBorderLeftWidth),
+ new PropertyWrapper<unsigned>(CSSPropertyBorderRightWidth, &RenderStyle::borderRightWidth, &RenderStyle::setBorderRightWidth),
+ new PropertyWrapper<unsigned>(CSSPropertyBorderTopWidth, &RenderStyle::borderTopWidth, &RenderStyle::setBorderTopWidth),
+ new PropertyWrapper<unsigned>(CSSPropertyBorderBottomWidth, &RenderStyle::borderBottomWidth, &RenderStyle::setBorderBottomWidth),
new LengthPropertyWrapper<Length>(CSSPropertyMarginLeft, &RenderStyle::marginLeft, &RenderStyle::setMarginLeft),
new LengthPropertyWrapper<Length>(CSSPropertyMarginRight, &RenderStyle::marginRight, &RenderStyle::setMarginRight),
new LengthPropertyWrapper<Length>(CSSPropertyMarginTop, &RenderStyle::marginTop, &RenderStyle::setMarginTop),
@@ -1253,7 +1170,7 @@ CSSPropertyAnimationWrapperMap::CSSPropertyAnimationWrapperMap()
new PropertyWrapperVisitedAffectedColor(CSSPropertyBackgroundColor, &RenderStyle::backgroundColor, &RenderStyle::setBackgroundColor, &RenderStyle::visitedLinkBackgroundColor, &RenderStyle::setVisitedLinkBackgroundColor),
- new FillLayersPropertyWrapper(CSSPropertyBackgroundImage, &RenderStyle::backgroundLayers, &RenderStyle::ensureBackgroundLayers),
+ new FillLayersPropertyWrapper(CSSPropertyBackgroundImage, &RenderStyle::backgroundLayers, &RenderStyle::accessBackgroundLayers),
new StyleImagePropertyWrapper(CSSPropertyListStyleImage, &RenderStyle::listStyleImage, &RenderStyle::setListStyleImage),
new StyleImagePropertyWrapper(CSSPropertyWebkitMaskImage, &RenderStyle::maskImage, &RenderStyle::setMaskImage),
@@ -1265,14 +1182,14 @@ CSSPropertyAnimationWrapperMap::CSSPropertyAnimationWrapperMap()
new StyleImagePropertyWrapper(CSSPropertyWebkitMaskBoxImageSource, &RenderStyle::maskBoxImageSource, &RenderStyle::setMaskBoxImageSource),
new PropertyWrapper<const NinePieceImage&>(CSSPropertyWebkitMaskBoxImage, &RenderStyle::maskBoxImage, &RenderStyle::setMaskBoxImage),
- new FillLayersPropertyWrapper(CSSPropertyBackgroundPositionX, &RenderStyle::backgroundLayers, &RenderStyle::ensureBackgroundLayers),
- new FillLayersPropertyWrapper(CSSPropertyBackgroundPositionY, &RenderStyle::backgroundLayers, &RenderStyle::ensureBackgroundLayers),
- new FillLayersPropertyWrapper(CSSPropertyBackgroundSize, &RenderStyle::backgroundLayers, &RenderStyle::ensureBackgroundLayers),
- new FillLayersPropertyWrapper(CSSPropertyWebkitBackgroundSize, &RenderStyle::backgroundLayers, &RenderStyle::ensureBackgroundLayers),
+ new FillLayersPropertyWrapper(CSSPropertyBackgroundPositionX, &RenderStyle::backgroundLayers, &RenderStyle::accessBackgroundLayers),
+ new FillLayersPropertyWrapper(CSSPropertyBackgroundPositionY, &RenderStyle::backgroundLayers, &RenderStyle::accessBackgroundLayers),
+ new FillLayersPropertyWrapper(CSSPropertyBackgroundSize, &RenderStyle::backgroundLayers, &RenderStyle::accessBackgroundLayers),
+ new FillLayersPropertyWrapper(CSSPropertyWebkitBackgroundSize, &RenderStyle::backgroundLayers, &RenderStyle::accessBackgroundLayers),
- new FillLayersPropertyWrapper(CSSPropertyWebkitMaskPositionX, &RenderStyle::maskLayers, &RenderStyle::ensureMaskLayers),
- new FillLayersPropertyWrapper(CSSPropertyWebkitMaskPositionY, &RenderStyle::maskLayers, &RenderStyle::ensureMaskLayers),
- new FillLayersPropertyWrapper(CSSPropertyWebkitMaskSize, &RenderStyle::maskLayers, &RenderStyle::ensureMaskLayers),
+ new FillLayersPropertyWrapper(CSSPropertyWebkitMaskPositionX, &RenderStyle::maskLayers, &RenderStyle::accessMaskLayers),
+ new FillLayersPropertyWrapper(CSSPropertyWebkitMaskPositionY, &RenderStyle::maskLayers, &RenderStyle::accessMaskLayers),
+ new FillLayersPropertyWrapper(CSSPropertyWebkitMaskSize, &RenderStyle::maskLayers, &RenderStyle::accessMaskLayers),
new PropertyWrapper<float>(CSSPropertyFontSize,
// Must pass a specified size to setFontSize if Text Autosizing is enabled, but a computed size
@@ -1284,28 +1201,28 @@ CSSPropertyAnimationWrapperMap::CSSPropertyAnimationWrapperMap()
&RenderStyle::computedFontSize,
#endif
&RenderStyle::setFontSize),
- new PropertyWrapper<unsigned short>(CSSPropertyColumnRuleWidth, &RenderStyle::columnRuleWidth, &RenderStyle::setColumnRuleWidth),
- new PropertyWrapper<float>(CSSPropertyColumnGap, &RenderStyle::columnGap, &RenderStyle::setColumnGap),
- new PropertyWrapper<unsigned short>(CSSPropertyColumnCount, &RenderStyle::columnCount, &RenderStyle::setColumnCount),
- new PropertyWrapper<float>(CSSPropertyColumnWidth, &RenderStyle::columnWidth, &RenderStyle::setColumnWidth),
+ new PropertyWrapper<unsigned short>(CSSPropertyWebkitColumnRuleWidth, &RenderStyle::columnRuleWidth, &RenderStyle::setColumnRuleWidth),
+ new PropertyWrapper<float>(CSSPropertyWebkitColumnGap, &RenderStyle::columnGap, &RenderStyle::setColumnGap),
+ new PropertyWrapper<unsigned short>(CSSPropertyWebkitColumnCount, &RenderStyle::columnCount, &RenderStyle::setColumnCount),
+ new PropertyWrapper<float>(CSSPropertyWebkitColumnWidth, &RenderStyle::columnWidth, &RenderStyle::setColumnWidth),
new PropertyWrapper<short>(CSSPropertyWebkitBorderHorizontalSpacing, &RenderStyle::horizontalBorderSpacing, &RenderStyle::setHorizontalBorderSpacing),
new PropertyWrapper<short>(CSSPropertyWebkitBorderVerticalSpacing, &RenderStyle::verticalBorderSpacing, &RenderStyle::setVerticalBorderSpacing),
new PropertyWrapper<int>(CSSPropertyZIndex, &RenderStyle::zIndex, &RenderStyle::setZIndex),
new PropertyWrapper<short>(CSSPropertyOrphans, &RenderStyle::orphans, &RenderStyle::setOrphans),
new PropertyWrapper<short>(CSSPropertyWidows, &RenderStyle::widows, &RenderStyle::setWidows),
new LengthPropertyWrapper<Length>(CSSPropertyLineHeight, &RenderStyle::specifiedLineHeight, &RenderStyle::setLineHeight),
- new PropertyWrapper<float>(CSSPropertyOutlineOffset, &RenderStyle::outlineOffset, &RenderStyle::setOutlineOffset),
- new PropertyWrapper<float>(CSSPropertyOutlineWidth, &RenderStyle::outlineWidth, &RenderStyle::setOutlineWidth),
+ new PropertyWrapper<int>(CSSPropertyOutlineOffset, &RenderStyle::outlineOffset, &RenderStyle::setOutlineOffset),
+ new PropertyWrapper<unsigned short>(CSSPropertyOutlineWidth, &RenderStyle::outlineWidth, &RenderStyle::setOutlineWidth),
new PropertyWrapper<float>(CSSPropertyLetterSpacing, &RenderStyle::letterSpacing, &RenderStyle::setLetterSpacing),
new LengthPropertyWrapper<Length>(CSSPropertyWordSpacing, &RenderStyle::wordSpacing, &RenderStyle::setWordSpacing),
new LengthPropertyWrapper<Length>(CSSPropertyTextIndent, &RenderStyle::textIndent, &RenderStyle::setTextIndent),
- new PropertyWrapper<float>(CSSPropertyPerspective, &RenderStyle::perspective, &RenderStyle::setPerspective),
- new LengthPropertyWrapper<Length>(CSSPropertyPerspectiveOriginX, &RenderStyle::perspectiveOriginX, &RenderStyle::setPerspectiveOriginX),
- new LengthPropertyWrapper<Length>(CSSPropertyPerspectiveOriginY, &RenderStyle::perspectiveOriginY, &RenderStyle::setPerspectiveOriginY),
- new LengthPropertyWrapper<Length>(CSSPropertyTransformOriginX, &RenderStyle::transformOriginX, &RenderStyle::setTransformOriginX),
- new LengthPropertyWrapper<Length>(CSSPropertyTransformOriginY, &RenderStyle::transformOriginY, &RenderStyle::setTransformOriginY),
- new PropertyWrapper<float>(CSSPropertyTransformOriginZ, &RenderStyle::transformOriginZ, &RenderStyle::setTransformOriginZ),
+ new PropertyWrapper<float>(CSSPropertyWebkitPerspective, &RenderStyle::perspective, &RenderStyle::setPerspective),
+ new LengthPropertyWrapper<Length>(CSSPropertyWebkitPerspectiveOriginX, &RenderStyle::perspectiveOriginX, &RenderStyle::setPerspectiveOriginX),
+ new LengthPropertyWrapper<Length>(CSSPropertyWebkitPerspectiveOriginY, &RenderStyle::perspectiveOriginY, &RenderStyle::setPerspectiveOriginY),
+ new LengthPropertyWrapper<Length>(CSSPropertyWebkitTransformOriginX, &RenderStyle::transformOriginX, &RenderStyle::setTransformOriginX),
+ new LengthPropertyWrapper<Length>(CSSPropertyWebkitTransformOriginY, &RenderStyle::transformOriginY, &RenderStyle::setTransformOriginY),
+ new PropertyWrapper<float>(CSSPropertyWebkitTransformOriginZ, &RenderStyle::transformOriginZ, &RenderStyle::setTransformOriginZ),
new LengthPropertyWrapper<LengthSize>(CSSPropertyBorderTopLeftRadius, &RenderStyle::borderTopLeftRadius, &RenderStyle::setBorderTopLeftRadius),
new LengthPropertyWrapper<LengthSize>(CSSPropertyBorderTopRightRadius, &RenderStyle::borderTopRightRadius, &RenderStyle::setBorderTopRightRadius),
new LengthPropertyWrapper<LengthSize>(CSSPropertyBorderBottomLeftRadius, &RenderStyle::borderBottomLeftRadius, &RenderStyle::setBorderBottomLeftRadius),
@@ -1315,21 +1232,30 @@ CSSPropertyAnimationWrapperMap::CSSPropertyAnimationWrapperMap()
new LengthPropertyWrapper<LengthBox>(CSSPropertyClip, &RenderStyle::clip, &RenderStyle::setClip),
+#if USE(ACCELERATED_COMPOSITING)
new PropertyWrapperAcceleratedOpacity(),
new PropertyWrapperAcceleratedTransform(),
+#if ENABLE(CSS_FILTERS)
new PropertyWrapperAcceleratedFilter(),
-#if ENABLE(FILTERS_LEVEL_2)
- new PropertyWrapperAcceleratedBackdropFilter(),
#endif
+#else
+ new PropertyWrapper<float>(CSSPropertyOpacity, &RenderStyle::opacity, &RenderStyle::setOpacity),
+ new PropertyWrapper<const TransformOperations&>(CSSPropertyWebkitTransform, &RenderStyle::transform, &RenderStyle::setTransform),
+#if ENABLE(CSS_FILTERS)
+ new PropertyWrapper<const FilterOperations&>(CSSPropertyWebkitFilter, &RenderStyle::filter, &RenderStyle::setFilter),
+#endif
+#endif
+
new PropertyWrapperClipPath(CSSPropertyWebkitClipPath, &RenderStyle::clipPath, &RenderStyle::setClipPath),
#if ENABLE(CSS_SHAPES)
+ new PropertyWrapperShape(CSSPropertyWebkitShapeInside, &RenderStyle::shapeInside, &RenderStyle::setShapeInside),
new PropertyWrapperShape(CSSPropertyWebkitShapeOutside, &RenderStyle::shapeOutside, &RenderStyle::setShapeOutside),
new LengthPropertyWrapper<Length>(CSSPropertyWebkitShapeMargin, &RenderStyle::shapeMargin, &RenderStyle::setShapeMargin),
new PropertyWrapper<float>(CSSPropertyWebkitShapeImageThreshold, &RenderStyle::shapeImageThreshold, &RenderStyle::setShapeImageThreshold),
#endif
- new PropertyWrapperVisitedAffectedColor(CSSPropertyColumnRuleColor, MaybeInvalidColor, &RenderStyle::columnRuleColor, &RenderStyle::setColumnRuleColor, &RenderStyle::visitedLinkColumnRuleColor, &RenderStyle::setVisitedLinkColumnRuleColor),
+ new PropertyWrapperVisitedAffectedColor(CSSPropertyWebkitColumnRuleColor, MaybeInvalidColor, &RenderStyle::columnRuleColor, &RenderStyle::setColumnRuleColor, &RenderStyle::visitedLinkColumnRuleColor, &RenderStyle::setVisitedLinkColumnRuleColor),
new PropertyWrapperVisitedAffectedColor(CSSPropertyWebkitTextStrokeColor, MaybeInvalidColor, &RenderStyle::textStrokeColor, &RenderStyle::setTextStrokeColor, &RenderStyle::visitedLinkTextStrokeColor, &RenderStyle::setVisitedLinkTextStrokeColor),
new PropertyWrapperVisitedAffectedColor(CSSPropertyWebkitTextFillColor, MaybeInvalidColor, &RenderStyle::textFillColor, &RenderStyle::setTextFillColor, &RenderStyle::visitedLinkTextFillColor, &RenderStyle::setVisitedLinkTextFillColor),
new PropertyWrapperVisitedAffectedColor(CSSPropertyBorderLeftColor, MaybeInvalidColor, &RenderStyle::borderLeftColor, &RenderStyle::setBorderLeftColor, &RenderStyle::visitedLinkBorderLeftColor, &RenderStyle::setVisitedLinkBorderLeftColor),
@@ -1342,24 +1268,17 @@ CSSPropertyAnimationWrapperMap::CSSPropertyAnimationWrapperMap()
new PropertyWrapperShadow(CSSPropertyWebkitBoxShadow, &RenderStyle::boxShadow, &RenderStyle::setBoxShadow),
new PropertyWrapperShadow(CSSPropertyTextShadow, &RenderStyle::textShadow, &RenderStyle::setTextShadow),
+#if ENABLE(SVG)
new PropertyWrapperSVGPaint(CSSPropertyFill, &RenderStyle::fillPaintType, &RenderStyle::fillPaintColor, &RenderStyle::setFillPaintColor),
new PropertyWrapper<float>(CSSPropertyFillOpacity, &RenderStyle::fillOpacity, &RenderStyle::setFillOpacity),
new PropertyWrapperSVGPaint(CSSPropertyStroke, &RenderStyle::strokePaintType, &RenderStyle::strokePaintColor, &RenderStyle::setStrokePaintColor),
new PropertyWrapper<float>(CSSPropertyStrokeOpacity, &RenderStyle::strokeOpacity, &RenderStyle::setStrokeOpacity),
+ new PropertyWrapper<SVGLength>(CSSPropertyStrokeWidth, &RenderStyle::strokeWidth, &RenderStyle::setStrokeWidth),
new PropertyWrapper< Vector<SVGLength>>(CSSPropertyStrokeDasharray, &RenderStyle::strokeDashArray, &RenderStyle::setStrokeDashArray),
+ new PropertyWrapper<SVGLength>(CSSPropertyStrokeDashoffset, &RenderStyle::strokeDashOffset, &RenderStyle::setStrokeDashOffset),
new PropertyWrapper<float>(CSSPropertyStrokeMiterlimit, &RenderStyle::strokeMiterLimit, &RenderStyle::setStrokeMiterLimit),
- new LengthPropertyWrapper<Length>(CSSPropertyCx, &RenderStyle::cx, &RenderStyle::setCx),
- new LengthPropertyWrapper<Length>(CSSPropertyCy, &RenderStyle::cy, &RenderStyle::setCy),
- new LengthPropertyWrapper<Length>(CSSPropertyR, &RenderStyle::r, &RenderStyle::setR),
- new LengthPropertyWrapper<Length>(CSSPropertyRx, &RenderStyle::rx, &RenderStyle::setRx),
- new LengthPropertyWrapper<Length>(CSSPropertyRy, &RenderStyle::ry, &RenderStyle::setRy),
- new LengthPropertyWrapper<Length>(CSSPropertyStrokeDashoffset, &RenderStyle::strokeDashOffset, &RenderStyle::setStrokeDashOffset),
- new LengthPropertyWrapper<Length>(CSSPropertyStrokeWidth, &RenderStyle::strokeWidth, &RenderStyle::setStrokeWidth),
- new LengthPropertyWrapper<Length>(CSSPropertyX, &RenderStyle::x, &RenderStyle::setX),
- new LengthPropertyWrapper<Length>(CSSPropertyY, &RenderStyle::y, &RenderStyle::setY),
-
new PropertyWrapper<float>(CSSPropertyFloodOpacity, &RenderStyle::floodOpacity, &RenderStyle::setFloodOpacity),
new PropertyWrapperMaybeInvalidColor(CSSPropertyFloodColor, &RenderStyle::floodColor, &RenderStyle::setFloodColor),
@@ -1370,6 +1289,7 @@ CSSPropertyAnimationWrapperMap::CSSPropertyAnimationWrapperMap()
new PropertyWrapper<SVGLength>(CSSPropertyBaselineShift, &RenderStyle::baselineShiftValue, &RenderStyle::setBaselineShiftValue),
new PropertyWrapper<SVGLength>(CSSPropertyKerning, &RenderStyle::kerning, &RenderStyle::setKerning),
+#endif
};
const unsigned animatableLonghandPropertiesCount = WTF_ARRAY_LENGTH(animatableLonghandPropertyWrappers);
@@ -1391,9 +1311,9 @@ CSSPropertyAnimationWrapperMap::CSSPropertyAnimationWrapperMap()
CSSPropertyOutline,
CSSPropertyPadding,
CSSPropertyWebkitTextStroke,
- CSSPropertyColumnRule,
+ CSSPropertyWebkitColumnRule,
CSSPropertyWebkitBorderRadius,
- CSSPropertyTransformOrigin
+ CSSPropertyWebkitTransformOrigin
};
const unsigned animatableShorthandPropertiesCount = WTF_ARRAY_LENGTH(animatableShorthandProperties);
@@ -1403,7 +1323,7 @@ CSSPropertyAnimationWrapperMap::CSSPropertyAnimationWrapperMap()
//
// Compound properties that have components that should be animatable:
//
- // CSSPropertyColumns
+ // CSSPropertyWebkitColumns
// CSSPropertyWebkitBoxReflect
// Make sure unused slots have a value
@@ -1418,7 +1338,7 @@ CSSPropertyAnimationWrapperMap::CSSPropertyAnimationWrapperMap()
for (unsigned i = 0; i < animatableLonghandPropertiesCount; ++i) {
AnimationPropertyWrapperBase* wrapper = animatableLonghandPropertyWrappers[i];
- m_propertyWrappers.uncheckedAppend(std::unique_ptr<AnimationPropertyWrapperBase>(wrapper));
+ m_propertyWrappers.uncheckedAppend(adoptPtr(wrapper));
indexFromPropertyID(wrapper->property()) = i;
}
@@ -1439,7 +1359,7 @@ CSSPropertyAnimationWrapperMap::CSSPropertyAnimationWrapperMap()
longhandWrappers.uncheckedAppend(m_propertyWrappers[wrapperIndex].get());
}
- m_propertyWrappers.uncheckedAppend(std::make_unique<ShorthandPropertyWrapper>(propertyID, WTFMove(longhandWrappers)));
+ m_propertyWrappers.uncheckedAppend(adoptPtr(new ShorthandPropertyWrapper(propertyID, longhandWrappers)));
indexFromPropertyID(propertyID) = animatableLonghandPropertiesCount + i;
}
}
@@ -1450,8 +1370,11 @@ static bool gatherEnclosingShorthandProperties(CSSPropertyID property, Animation
return false;
ShorthandPropertyWrapper* shorthandWrapper = static_cast<ShorthandPropertyWrapper*>(wrapper);
+
bool contained = false;
- for (auto& currWrapper : shorthandWrapper->propertyWrappers()) {
+ for (size_t i = 0; i < shorthandWrapper->propertyWrappers().size(); ++i) {
+ AnimationPropertyWrapperBase* currWrapper = shorthandWrapper->propertyWrappers()[i];
+
if (gatherEnclosingShorthandProperties(property, currWrapper, propertySet) || currWrapper->property() == property)
contained = true;
}
@@ -1467,24 +1390,31 @@ bool CSSPropertyAnimation::blendProperties(const AnimationBase* anim, CSSPropert
{
ASSERT(prop != CSSPropertyInvalid);
- AnimationPropertyWrapperBase* wrapper = CSSPropertyAnimationWrapperMap::singleton().wrapperForProperty(prop);
+ AnimationPropertyWrapperBase* wrapper = CSSPropertyAnimationWrapperMap::instance().wrapperForProperty(prop);
if (wrapper) {
wrapper->blend(anim, dst, a, b, progress);
+#if USE(ACCELERATED_COMPOSITING)
return !wrapper->animationIsAccelerated() || !anim->isAccelerated();
+#else
+ return true;
+#endif
}
+
return false;
}
+#if USE(ACCELERATED_COMPOSITING)
bool CSSPropertyAnimation::animationOfPropertyIsAccelerated(CSSPropertyID prop)
{
- AnimationPropertyWrapperBase* wrapper = CSSPropertyAnimationWrapperMap::singleton().wrapperForProperty(prop);
+ AnimationPropertyWrapperBase* wrapper = CSSPropertyAnimationWrapperMap::instance().wrapperForProperty(prop);
return wrapper ? wrapper->animationIsAccelerated() : false;
}
+#endif
// Note: this is inefficient. It's only called from pauseTransitionAtTime().
HashSet<CSSPropertyID> CSSPropertyAnimation::animatableShorthandsAffectingProperty(CSSPropertyID property)
{
- CSSPropertyAnimationWrapperMap& map = CSSPropertyAnimationWrapperMap::singleton();
+ CSSPropertyAnimationWrapperMap& map = CSSPropertyAnimationWrapperMap::instance();
HashSet<CSSPropertyID> foundProperties;
for (unsigned i = 0; i < map.size(); ++i)
@@ -1495,7 +1425,7 @@ HashSet<CSSPropertyID> CSSPropertyAnimation::animatableShorthandsAffectingProper
bool CSSPropertyAnimation::propertiesEqual(CSSPropertyID prop, const RenderStyle* a, const RenderStyle* b)
{
- AnimationPropertyWrapperBase* wrapper = CSSPropertyAnimationWrapperMap::singleton().wrapperForProperty(prop);
+ AnimationPropertyWrapperBase* wrapper = CSSPropertyAnimationWrapperMap::instance().wrapperForProperty(prop);
if (wrapper)
return wrapper->equals(a, b);
return true;
@@ -1503,7 +1433,7 @@ bool CSSPropertyAnimation::propertiesEqual(CSSPropertyID prop, const RenderStyle
CSSPropertyID CSSPropertyAnimation::getPropertyAtIndex(int i, bool& isShorthand)
{
- CSSPropertyAnimationWrapperMap& map = CSSPropertyAnimationWrapperMap::singleton();
+ CSSPropertyAnimationWrapperMap& map = CSSPropertyAnimationWrapperMap::instance();
if (i < 0 || static_cast<unsigned>(i) >= map.size())
return CSSPropertyInvalid;
@@ -1515,7 +1445,7 @@ CSSPropertyID CSSPropertyAnimation::getPropertyAtIndex(int i, bool& isShorthand)
int CSSPropertyAnimation::getNumProperties()
{
- return CSSPropertyAnimationWrapperMap::singleton().size();
+ return CSSPropertyAnimationWrapperMap::instance().size();
}
}
diff --git a/Source/WebCore/page/animation/CSSPropertyAnimation.h b/Source/WebCore/page/animation/CSSPropertyAnimation.h
index d4c3e5b4a..c41c7dd90 100644
--- a/Source/WebCore/page/animation/CSSPropertyAnimation.h
+++ b/Source/WebCore/page/animation/CSSPropertyAnimation.h
@@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Inc. ("Apple") nor the names of
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
@@ -40,7 +40,9 @@ class RenderStyle;
class CSSPropertyAnimation {
public:
+#if USE(ACCELERATED_COMPOSITING)
static bool animationOfPropertyIsAccelerated(CSSPropertyID);
+#endif
static bool propertiesEqual(CSSPropertyID, const RenderStyle* a, const RenderStyle* b);
static CSSPropertyID getPropertyAtIndex(int, bool& isShorthand);
static int getNumProperties();
diff --git a/Source/WebCore/page/animation/CompositeAnimation.cpp b/Source/WebCore/page/animation/CompositeAnimation.cpp
index b8dec3f0e..e18779ea7 100644
--- a/Source/WebCore/page/animation/CompositeAnimation.cpp
+++ b/Source/WebCore/page/animation/CompositeAnimation.cpp
@@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Inc. ("Apple") nor the names of
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
@@ -37,15 +37,14 @@
#include "Logging.h"
#include "RenderElement.h"
#include "RenderStyle.h"
-#include <wtf/NeverDestroyed.h>
#include <wtf/text/CString.h>
namespace WebCore {
-CompositeAnimation::CompositeAnimation(AnimationControllerPrivate& animationController)
+CompositeAnimation::CompositeAnimation(AnimationControllerPrivate* animationController)
: m_animationController(animationController)
{
- m_suspended = m_animationController.isSuspended() && !m_animationController.allowsNewAnimationsWhileSuspended();
+ m_suspended = animationController->isSuspended() && !animationController->allowsNewAnimationsWhileSuspended();
}
CompositeAnimation::~CompositeAnimation()
@@ -63,16 +62,20 @@ void CompositeAnimation::clearRenderer()
if (!m_transitions.isEmpty()) {
// Clear the renderers from all running animations, in case we are in the middle of
// an animation callback (see https://bugs.webkit.org/show_bug.cgi?id=22052)
- for (auto& transition : m_transitions.values()) {
- animationController().animationWillBeRemoved(transition.get());
+ CSSPropertyTransitionsMap::const_iterator transitionsEnd = m_transitions.end();
+ for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != transitionsEnd; ++it) {
+ ImplicitAnimation* transition = it->value.get();
+ animationController()->animationWillBeRemoved(transition);
transition->clear();
}
}
if (!m_keyframeAnimations.isEmpty()) {
m_keyframeAnimations.checkConsistency();
- for (auto& animation : m_keyframeAnimations.values()) {
- animationController().animationWillBeRemoved(animation.get());
- animation->clear();
+ AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
+ for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
+ KeyframeAnimation* anim = it->value.get();
+ animationController()->animationWillBeRemoved(anim);
+ anim->clear();
}
}
}
@@ -85,15 +88,16 @@ void CompositeAnimation::updateTransitions(RenderElement* renderer, RenderStyle*
// Mark all existing transitions as no longer active. We will mark the still active ones
// in the next loop and then toss the ones that didn't get marked.
- for (auto& transition : m_transitions.values())
- transition->setActive(false);
+ CSSPropertyTransitionsMap::const_iterator end = m_transitions.end();
+ for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != end; ++it)
+ it->value->setActive(false);
RefPtr<RenderStyle> modifiedCurrentStyle;
// Check to see if we need to update the active transitions
if (targetStyle->transitions()) {
for (size_t i = 0; i < targetStyle->transitions()->size(); ++i) {
- Animation& animation = targetStyle->transitions()->animation(i);
+ const Animation& animation = targetStyle->transitions()->animation(i);
bool isActiveTransition = !m_suspended && (animation.duration() || animation.delay() > 0);
Animation::AnimationMode mode = animation.animationMode();
@@ -144,6 +148,7 @@ void CompositeAnimation::updateTransitions(RenderElement* renderer, RenderStyle*
// list. In this case, the latter one overrides the earlier one, so we
// behave as though this is a running animation being replaced.
if (!implAnim->isTargetPropertyEqual(prop, targetStyle)) {
+#if USE(ACCELERATED_COMPOSITING)
// For accelerated animations we need to return a new RenderStyle with the _current_ value
// of the property, so that restarted transitions use the correct starting point.
if (CSSPropertyAnimation::animationOfPropertyIsAccelerated(prop) && implAnim->isAccelerated()) {
@@ -152,8 +157,9 @@ void CompositeAnimation::updateTransitions(RenderElement* renderer, RenderStyle*
implAnim->blendPropertyValueInStyle(prop, modifiedCurrentStyle.get());
}
+#endif
LOG(Animations, "Removing existing ImplicitAnimation %p for property %s", implAnim, getPropertyName(prop));
- animationController().animationWillBeRemoved(implAnim);
+ animationController()->animationWillBeRemoved(implAnim);
m_transitions.remove(prop);
equal = false;
}
@@ -169,7 +175,7 @@ void CompositeAnimation::updateTransitions(RenderElement* renderer, RenderStyle*
if (!equal && isActiveTransition) {
// Add the new transition
RefPtr<ImplicitAnimation> implicitAnimation = ImplicitAnimation::create(animation, prop, renderer, this, modifiedCurrentStyle ? modifiedCurrentStyle.get() : fromStyle);
- LOG(Animations, "Created ImplicitAnimation %p on renderer %p for property %s duration %.2f delay %.2f", implicitAnimation.get(), renderer, getPropertyName(prop), animation.duration(), animation.delay());
+ LOG(Animations, "Created ImplicitAnimation %p for property %s duration %.2f delay %.2f", implicitAnimation.get(), getPropertyName(prop), animation.duration(), animation.delay());
m_transitions.set(prop, implicitAnimation.release());
}
@@ -182,17 +188,19 @@ void CompositeAnimation::updateTransitions(RenderElement* renderer, RenderStyle*
// Make a list of transitions to be removed
Vector<int> toBeRemoved;
- for (auto& transition : m_transitions.values()) {
- if (!transition->active()) {
- animationController().animationWillBeRemoved(transition.get());
- toBeRemoved.append(transition->animatingProperty());
- LOG(Animations, "Removing ImplicitAnimation %p from renderer %p for property %s", transition.get(), renderer, getPropertyName(transition->animatingProperty()));
+ end = m_transitions.end();
+ for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != end; ++it) {
+ ImplicitAnimation* anim = it->value.get();
+ if (!anim->active()) {
+ animationController()->animationWillBeRemoved(anim);
+ toBeRemoved.append(anim->animatingProperty());
+ LOG(Animations, "Removing ImplicitAnimation %p for property %s", anim, getPropertyName(anim->animatingProperty()));
}
}
// Now remove the transitions from the list
- for (auto propertyToRemove : toBeRemoved)
- m_transitions.remove(propertyToRemove);
+ for (size_t j = 0; j < toBeRemoved.size(); ++j)
+ m_transitions.remove(toBeRemoved[j]);
}
void CompositeAnimation::updateKeyframeAnimations(RenderElement* renderer, RenderStyle* currentStyle, RenderStyle* targetStyle)
@@ -202,133 +210,136 @@ void CompositeAnimation::updateKeyframeAnimations(RenderElement* renderer, Rende
return;
m_keyframeAnimations.checkConsistency();
-
- if (currentStyle && currentStyle->hasAnimations() && targetStyle->hasAnimations() && *(currentStyle->animations()) == *(targetStyle->animations()))
- return;
-
-#if ENABLE(CSS_ANIMATIONS_LEVEL_2)
- m_hasScrollTriggeredAnimation = false;
-#endif
-
- AnimationNameMap newAnimations;
- // Toss the animation order map.
- m_keyframeAnimationOrderMap.clear();
-
- static NeverDestroyed<const AtomicString> none("none", AtomicString::ConstructFromLiteral);
+ AnimationNameMap::const_iterator kfend = m_keyframeAnimations.end();
- // Now mark any still active animations as active and add any new animations.
- if (targetStyle->animations()) {
- int numAnims = targetStyle->animations()->size();
- for (int i = 0; i < numAnims; ++i) {
- Animation& animation = targetStyle->animations()->animation(i);
- AtomicString animationName(animation.name());
-
- if (!animation.isValidAnimation())
- continue;
+ if (currentStyle && currentStyle->hasAnimations() && targetStyle->hasAnimations() && *(currentStyle->animations()) == *(targetStyle->animations())) {
+ // The current and target animations are the same so we just need to toss any
+ // animation which is finished (postActive).
+ for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != kfend; ++it) {
+ if (it->value->postActive())
+ it->value->setIndex(-1);
+ }
+ } else {
+ // Mark all existing animations as no longer active.
+ for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != kfend; ++it)
+ it->value->setIndex(-1);
- // See if there is a current animation for this name.
- RefPtr<KeyframeAnimation> keyframeAnim = m_keyframeAnimations.get(animationName.impl());
- if (keyframeAnim) {
- newAnimations.add(keyframeAnim->name().impl(), keyframeAnim);
+ // Toss the animation order map.
+ m_keyframeAnimationOrderMap.clear();
- if (keyframeAnim->postActive())
+ DEFINE_STATIC_LOCAL(const AtomicString, none, ("none", AtomicString::ConstructFromLiteral));
+
+ // Now mark any still active animations as active and add any new animations.
+ if (targetStyle->animations()) {
+ int numAnims = targetStyle->animations()->size();
+ for (int i = 0; i < numAnims; ++i) {
+ const Animation& animation = targetStyle->animations()->animation(i);
+ AtomicString animationName(animation.name());
+
+ if (!animation.isValidAnimation())
continue;
-
-#if ENABLE(CSS_ANIMATIONS_LEVEL_2)
- if (animation.trigger()->isScrollAnimationTrigger())
- m_hasScrollTriggeredAnimation = true;
-#endif
-
- // Animations match, but play states may differ. Update if needed.
- keyframeAnim->updatePlayState(animation.playState());
-
- // Set the saved animation to this new one, just in case the play state has changed.
- keyframeAnim->setAnimation(animation);
- } else if ((animation.duration() || animation.delay()) && animation.iterationCount() && animationName != none) {
- keyframeAnim = KeyframeAnimation::create(animation, renderer, this, targetStyle);
- LOG(Animations, "Creating KeyframeAnimation %p on renderer %p with keyframes %s, duration %.2f, delay %.2f, iterations %.2f", keyframeAnim.get(), renderer, animation.name().utf8().data(), animation.duration(), animation.delay(), animation.iterationCount());
-
- if (m_suspended) {
- keyframeAnim->updatePlayState(AnimPlayStatePaused);
- LOG(Animations, " (created in suspended/paused state)");
- }
+
+ // See if there is a current animation for this name.
+ RefPtr<KeyframeAnimation> keyframeAnim = m_keyframeAnimations.get(animationName.impl());
+
+ if (keyframeAnim) {
+ // If this animation is postActive, skip it so it gets removed at the end of this function.
+ if (keyframeAnim->postActive())
+ continue;
+
+ // This one is still active.
+
+ // Animations match, but play states may differ. Update if needed.
+ keyframeAnim->updatePlayState(animation.playState());
+
+ // Set the saved animation to this new one, just in case the play state has changed.
+ keyframeAnim->setAnimation(animation);
+ keyframeAnim->setIndex(i);
+ } else if ((animation.duration() || animation.delay()) && animation.iterationCount() && animationName != none) {
+ keyframeAnim = KeyframeAnimation::create(animation, renderer, i, this, targetStyle);
+ LOG(Animations, "Creating KeyframeAnimation %p with keyframes %s, duration %.2f, delay %.2f, iterations %.2f", keyframeAnim.get(), animation.name().utf8().data(), animation.duration(), animation.delay(), animation.iterationCount());
+ if (m_suspended) {
+ keyframeAnim->updatePlayState(AnimPlayStatePaused);
+ LOG(Animations, " (created in suspended/paused state)");
+ }
#if !LOG_DISABLED
- for (auto propertyID : keyframeAnim->keyframes().properties())
- LOG(Animations, " property %s", getPropertyName(propertyID));
-#endif
-
-#if ENABLE(CSS_ANIMATIONS_LEVEL_2)
- if (animation.trigger()->isScrollAnimationTrigger())
- m_hasScrollTriggeredAnimation = true;
+ for (auto it = keyframeAnim->keyframes().beginProperties(), end = keyframeAnim->keyframes().endProperties(); it != end; ++it)
+ LOG(Animations, " property %s", getPropertyName(*it));
#endif
-
- newAnimations.set(keyframeAnim->name().impl(), keyframeAnim);
+ m_keyframeAnimations.set(keyframeAnim->name().impl(), keyframeAnim);
+ }
+
+ // Add this to the animation order map.
+ if (keyframeAnim)
+ m_keyframeAnimationOrderMap.append(keyframeAnim->name().impl());
}
-
- // Add this to the animation order map.
- if (keyframeAnim)
- m_keyframeAnimationOrderMap.append(keyframeAnim->name().impl());
}
}
// Make a list of animations to be removed.
- for (auto& animation : m_keyframeAnimations.values()) {
- if (!newAnimations.contains(animation->name().impl())) {
- animationController().animationWillBeRemoved(animation.get());
- animation->clear();
- LOG(Animations, "Removing KeyframeAnimation %p from renderer %p", animation.get(), renderer);
+ Vector<AtomicStringImpl*> animsToBeRemoved;
+ kfend = m_keyframeAnimations.end();
+ for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != kfend; ++it) {
+ KeyframeAnimation* keyframeAnim = it->value.get();
+ if (keyframeAnim->index() < 0) {
+ animsToBeRemoved.append(keyframeAnim->name().impl());
+ animationController()->animationWillBeRemoved(keyframeAnim);
+ keyframeAnim->clear();
+ LOG(Animations, "Removing KeyframeAnimation %p", keyframeAnim);
}
}
- std::swap(newAnimations, m_keyframeAnimations);
+ // Now remove the animations from the list.
+ for (size_t j = 0; j < animsToBeRemoved.size(); ++j)
+ m_keyframeAnimations.remove(animsToBeRemoved[j]);
}
-bool CompositeAnimation::animate(RenderElement& renderer, RenderStyle* currentStyle, RenderStyle& targetStyle, Ref<RenderStyle>& blendedStyle)
+PassRef<RenderStyle> CompositeAnimation::animate(RenderElement& renderer, RenderStyle* currentStyle, RenderStyle& targetStyle)
{
+ RefPtr<RenderStyle> resultStyle;
+
// We don't do any transitions if we don't have a currentStyle (on startup).
updateTransitions(&renderer, currentStyle, &targetStyle);
updateKeyframeAnimations(&renderer, currentStyle, &targetStyle);
m_keyframeAnimations.checkConsistency();
- RefPtr<RenderStyle> animatedStyle;
- bool animationStateChanged = false;
-
if (currentStyle) {
// Now that we have transition objects ready, let them know about the new goal state. We want them
// to fill in a RenderStyle*& only if needed.
- for (auto& transition : m_transitions.values()) {
- if (transition->animate(this, &renderer, currentStyle, &targetStyle, animatedStyle))
- animationStateChanged = true;
+ if (!m_transitions.isEmpty()) {
+ CSSPropertyTransitionsMap::const_iterator end = m_transitions.end();
+ for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != end; ++it) {
+ if (ImplicitAnimation* anim = it->value.get())
+ anim->animate(this, &renderer, currentStyle, &targetStyle, resultStyle);
+ }
}
}
// Now that we have animation objects ready, let them know about the new goal state. We want them
// to fill in a RenderStyle*& only if needed.
- for (auto& name : m_keyframeAnimationOrderMap) {
- RefPtr<KeyframeAnimation> keyframeAnim = m_keyframeAnimations.get(name);
- if (keyframeAnim && keyframeAnim->animate(this, &renderer, currentStyle, &targetStyle, animatedStyle))
- animationStateChanged = true;
+ for (Vector<AtomicStringImpl*>::const_iterator it = m_keyframeAnimationOrderMap.begin(); it != m_keyframeAnimationOrderMap.end(); ++it) {
+ RefPtr<KeyframeAnimation> keyframeAnim = m_keyframeAnimations.get(*it);
+ if (keyframeAnim)
+ keyframeAnim->animate(this, &renderer, currentStyle, &targetStyle, resultStyle);
}
- if (animatedStyle)
- blendedStyle = animatedStyle.releaseNonNull();
- else
- blendedStyle = targetStyle;
-
- return animationStateChanged;
+ return resultStyle ? resultStyle.releaseNonNull() : targetStyle;
}
PassRefPtr<RenderStyle> CompositeAnimation::getAnimatedStyle() const
{
RefPtr<RenderStyle> resultStyle;
- for (auto& transition : m_transitions.values())
- transition->getAnimatedStyle(resultStyle);
+ CSSPropertyTransitionsMap::const_iterator end = m_transitions.end();
+ for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != end; ++it) {
+ if (ImplicitAnimation* implicitAnimation = it->value.get())
+ implicitAnimation->getAnimatedStyle(resultStyle);
+ }
m_keyframeAnimations.checkConsistency();
- for (auto& name : m_keyframeAnimationOrderMap) {
- RefPtr<KeyframeAnimation> keyframeAnimation = m_keyframeAnimations.get(name);
+ for (Vector<AtomicStringImpl*>::const_iterator it = m_keyframeAnimationOrderMap.begin(); it != m_keyframeAnimationOrderMap.end(); ++it) {
+ RefPtr<KeyframeAnimation> keyframeAnimation = m_keyframeAnimations.get(*it);
if (keyframeAnimation)
keyframeAnimation->getAnimatedStyle(resultStyle);
}
@@ -343,8 +354,10 @@ double CompositeAnimation::timeToNextService() const
double minT = -1;
if (!m_transitions.isEmpty()) {
- for (auto& transition : m_transitions.values()) {
- double t = transition->timeToNextService();
+ CSSPropertyTransitionsMap::const_iterator transitionsEnd = m_transitions.end();
+ for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != transitionsEnd; ++it) {
+ ImplicitAnimation* transition = it->value.get();
+ double t = transition ? transition->timeToNextService() : -1;
if (t < minT || minT == -1)
minT = t;
if (minT == 0)
@@ -353,8 +366,10 @@ double CompositeAnimation::timeToNextService() const
}
if (!m_keyframeAnimations.isEmpty()) {
m_keyframeAnimations.checkConsistency();
- for (auto& animation : m_keyframeAnimations.values()) {
- double t = animation->timeToNextService();
+ AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
+ for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
+ KeyframeAnimation* animation = it->value.get();
+ double t = animation ? animation->timeToNextService() : -1;
if (t < minT || minT == -1)
minT = t;
if (minT == 0)
@@ -373,47 +388,17 @@ PassRefPtr<KeyframeAnimation> CompositeAnimation::getAnimationForProperty(CSSPro
// So we need to iterate through all animations
if (!m_keyframeAnimations.isEmpty()) {
m_keyframeAnimations.checkConsistency();
- for (auto& animation : m_keyframeAnimations.values()) {
- if (animation->hasAnimationForProperty(property))
- retval = animation;
+ AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
+ for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
+ RefPtr<KeyframeAnimation> anim = it->value;
+ if (anim->hasAnimationForProperty(property))
+ retval = anim;
}
}
return retval;
}
-bool CompositeAnimation::computeExtentOfTransformAnimation(LayoutRect& bounds) const
-{
- // If more than one transition and animation affect transform, give up.
- bool seenTransformAnimation = false;
-
- for (auto& animation : m_keyframeAnimations.values()) {
- if (!animation->hasAnimationForProperty(CSSPropertyTransform))
- continue;
-
- if (seenTransformAnimation)
- return false;
-
- seenTransformAnimation = true;
-
- if (!animation->computeExtentOfTransformAnimation(bounds))
- return false;
- }
-
- for (auto& transition : m_transitions.values()) {
- if (transition->animatingProperty() != CSSPropertyTransform || !transition->hasStyle())
- continue;
-
- if (seenTransformAnimation)
- return false;
-
- if (!transition->computeExtentOfTransformAnimation(bounds))
- return false;
- }
-
- return true;
-}
-
void CompositeAnimation::suspendAnimations()
{
if (m_suspended)
@@ -423,14 +408,18 @@ void CompositeAnimation::suspendAnimations()
if (!m_keyframeAnimations.isEmpty()) {
m_keyframeAnimations.checkConsistency();
- for (auto& animation : m_keyframeAnimations.values())
- animation->updatePlayState(AnimPlayStatePaused);
+ AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
+ for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
+ if (KeyframeAnimation* anim = it->value.get())
+ anim->updatePlayState(AnimPlayStatePaused);
+ }
}
-
if (!m_transitions.isEmpty()) {
- for (auto& transition : m_transitions.values()) {
- if (transition->hasStyle())
- transition->updatePlayState(AnimPlayStatePaused);
+ CSSPropertyTransitionsMap::const_iterator transitionsEnd = m_transitions.end();
+ for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != transitionsEnd; ++it) {
+ ImplicitAnimation* anim = it->value.get();
+ if (anim && anim->hasStyle())
+ anim->updatePlayState(AnimPlayStatePaused);
}
}
}
@@ -444,26 +433,32 @@ void CompositeAnimation::resumeAnimations()
if (!m_keyframeAnimations.isEmpty()) {
m_keyframeAnimations.checkConsistency();
- for (auto& animation : m_keyframeAnimations.values()) {
- if (animation->playStatePlaying())
- animation->updatePlayState(AnimPlayStatePlaying);
+ AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
+ for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
+ KeyframeAnimation* anim = it->value.get();
+ if (anim && anim->playStatePlaying())
+ anim->updatePlayState(AnimPlayStatePlaying);
}
}
if (!m_transitions.isEmpty()) {
- for (auto& transition : m_transitions.values()) {
- if (transition->hasStyle())
- transition->updatePlayState(AnimPlayStatePlaying);
+ CSSPropertyTransitionsMap::const_iterator transitionsEnd = m_transitions.end();
+ for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != transitionsEnd; ++it) {
+ ImplicitAnimation* anim = it->value.get();
+ if (anim && anim->hasStyle())
+ anim->updatePlayState(AnimPlayStatePlaying);
}
}
}
void CompositeAnimation::overrideImplicitAnimations(CSSPropertyID property)
{
+ CSSPropertyTransitionsMap::const_iterator end = m_transitions.end();
if (!m_transitions.isEmpty()) {
- for (auto& transition : m_transitions.values()) {
- if (transition->animatingProperty() == property)
- transition->setOverridden(true);
+ for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != end; ++it) {
+ ImplicitAnimation* anim = it->value.get();
+ if (anim && anim->animatingProperty() == property)
+ anim->setOverridden(true);
}
}
}
@@ -471,26 +466,32 @@ void CompositeAnimation::overrideImplicitAnimations(CSSPropertyID property)
void CompositeAnimation::resumeOverriddenImplicitAnimations(CSSPropertyID property)
{
if (!m_transitions.isEmpty()) {
- for (auto& transition : m_transitions.values()) {
- if (transition->animatingProperty() == property)
- transition->setOverridden(false);
+ CSSPropertyTransitionsMap::const_iterator end = m_transitions.end();
+ for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != end; ++it) {
+ ImplicitAnimation* anim = it->value.get();
+ if (anim && anim->animatingProperty() == property)
+ anim->setOverridden(false);
}
}
}
-bool CompositeAnimation::isAnimatingProperty(CSSPropertyID property, bool acceleratedOnly, AnimationBase::RunningState runningState) const
+bool CompositeAnimation::isAnimatingProperty(CSSPropertyID property, bool acceleratedOnly, bool isRunningNow) const
{
if (!m_keyframeAnimations.isEmpty()) {
m_keyframeAnimations.checkConsistency();
- for (auto& animation : m_keyframeAnimations.values()) {
- if (animation->isAnimatingProperty(property, acceleratedOnly, runningState))
+ AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
+ for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
+ KeyframeAnimation* anim = it->value.get();
+ if (anim && anim->isAnimatingProperty(property, acceleratedOnly, isRunningNow))
return true;
}
}
if (!m_transitions.isEmpty()) {
- for (auto& transition : m_transitions.values()) {
- if (transition->isAnimatingProperty(property, acceleratedOnly, runningState))
+ CSSPropertyTransitionsMap::const_iterator transitionsEnd = m_transitions.end();
+ for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != transitionsEnd; ++it) {
+ ImplicitAnimation* anim = it->value.get();
+ if (anim && anim->isAnimatingProperty(property, acceleratedOnly, isRunningNow))
return true;
}
}
@@ -505,8 +506,13 @@ bool CompositeAnimation::pauseAnimationAtTime(const AtomicString& name, double t
if (!keyframeAnim || !keyframeAnim->running())
return false;
- keyframeAnim->freezeAtTime(t);
- return true;
+ double count = keyframeAnim->m_animation->iterationCount();
+ if ((t >= 0.0) && ((count == Animation::IterationCountInfinite) || (t <= count * keyframeAnim->duration()))) {
+ keyframeAnim->freezeAtTime(t);
+ return true;
+ }
+
+ return false;
}
bool CompositeAnimation::pauseTransitionAtTime(CSSPropertyID property, double t)
@@ -520,8 +526,9 @@ bool CompositeAnimation::pauseTransitionAtTime(CSSPropertyID property, double t)
// This code is only used for testing, so performance is not critical here.
HashSet<CSSPropertyID> shorthandProperties = CSSPropertyAnimation::animatableShorthandsAffectingProperty(property);
bool anyPaused = false;
- for (auto propertyID : shorthandProperties) {
- if (pauseTransitionAtTime(propertyID, t))
+ HashSet<CSSPropertyID>::const_iterator end = shorthandProperties.end();
+ for (HashSet<CSSPropertyID>::const_iterator it = shorthandProperties.begin(); it != end; ++it) {
+ if (pauseTransitionAtTime(*it, t))
anyPaused = true;
}
return anyPaused;
@@ -542,15 +549,23 @@ unsigned CompositeAnimation::numberOfActiveAnimations() const
{
unsigned count = 0;
- m_keyframeAnimations.checkConsistency();
- for (auto& animation : m_keyframeAnimations.values()) {
- if (animation->running())
- ++count;
+ if (!m_keyframeAnimations.isEmpty()) {
+ m_keyframeAnimations.checkConsistency();
+ AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
+ for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
+ KeyframeAnimation* anim = it->value.get();
+ if (anim->running())
+ ++count;
+ }
}
- for (auto& transition : m_transitions.values()) {
- if (transition->running())
- ++count;
+ if (!m_transitions.isEmpty()) {
+ CSSPropertyTransitionsMap::const_iterator transitionsEnd = m_transitions.end();
+ for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != transitionsEnd; ++it) {
+ ImplicitAnimation* anim = it->value.get();
+ if (anim->running())
+ ++count;
+ }
}
return count;
diff --git a/Source/WebCore/page/animation/CompositeAnimation.h b/Source/WebCore/page/animation/CompositeAnimation.h
index b61144fa9..48c679ef2 100644
--- a/Source/WebCore/page/animation/CompositeAnimation.h
+++ b/Source/WebCore/page/animation/CompositeAnimation.h
@@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Inc. ("Apple") nor the names of
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
@@ -45,24 +45,22 @@ class RenderStyle;
// A CompositeAnimation represents a collection of animations that are running
// on a single RenderElement, such as a number of properties transitioning at once.
class CompositeAnimation : public RefCounted<CompositeAnimation> {
- WTF_MAKE_FAST_ALLOCATED;
public:
- static Ref<CompositeAnimation> create(AnimationControllerPrivate& animationController)
+ static PassRefPtr<CompositeAnimation> create(AnimationControllerPrivate* animationController)
{
- return adoptRef(*new CompositeAnimation(animationController));
+ return adoptRef(new CompositeAnimation(animationController));
};
~CompositeAnimation();
void clearRenderer();
- bool animate(RenderElement&, RenderStyle* currentStyle, RenderStyle& targetStyle, Ref<RenderStyle>& blendedStyle);
+ PassRef<RenderStyle> animate(RenderElement&, RenderStyle* currentStyle, RenderStyle& targetStyle);
PassRefPtr<RenderStyle> getAnimatedStyle() const;
- bool computeExtentOfTransformAnimation(LayoutRect&) const;
double timeToNextService() const;
- AnimationControllerPrivate& animationController() const { return m_animationController; }
+ AnimationControllerPrivate* animationController() const { return m_animationController; }
void suspendAnimations();
void resumeAnimations();
@@ -70,7 +68,7 @@ public:
bool hasAnimations() const { return !m_transitions.isEmpty() || !m_keyframeAnimations.isEmpty(); }
- bool isAnimatingProperty(CSSPropertyID, bool acceleratedOnly, AnimationBase::RunningState) const;
+ bool isAnimatingProperty(CSSPropertyID, bool acceleratedOnly, bool isRunningNow) const;
PassRefPtr<KeyframeAnimation> getAnimationForProperty(CSSPropertyID) const;
@@ -81,27 +79,20 @@ public:
bool pauseTransitionAtTime(CSSPropertyID, double);
unsigned numberOfActiveAnimations() const;
-#if ENABLE(CSS_ANIMATIONS_LEVEL_2)
- bool hasScrollTriggeredAnimation() const { return m_hasScrollTriggeredAnimation; }
-#endif
-
private:
- CompositeAnimation(AnimationControllerPrivate&);
+ CompositeAnimation(AnimationControllerPrivate*);
void updateTransitions(RenderElement*, RenderStyle* currentStyle, RenderStyle* targetStyle);
void updateKeyframeAnimations(RenderElement*, RenderStyle* currentStyle, RenderStyle* targetStyle);
typedef HashMap<int, RefPtr<ImplicitAnimation>> CSSPropertyTransitionsMap;
- typedef HashMap<AtomicStringImpl*, RefPtr<KeyframeAnimation>> AnimationNameMap;
+ typedef HashMap<AtomicStringImpl*, RefPtr<KeyframeAnimation>> AnimationNameMap;
- AnimationControllerPrivate& m_animationController;
+ AnimationControllerPrivate* m_animationController;
CSSPropertyTransitionsMap m_transitions;
AnimationNameMap m_keyframeAnimations;
Vector<AtomicStringImpl*> m_keyframeAnimationOrderMap;
bool m_suspended;
-#if ENABLE(CSS_ANIMATIONS_LEVEL_2)
- bool m_hasScrollTriggeredAnimation { false };
-#endif
};
} // namespace WebCore
diff --git a/Source/WebCore/page/animation/ImplicitAnimation.cpp b/Source/WebCore/page/animation/ImplicitAnimation.cpp
index 4eae7b4ac..af1d78819 100644
--- a/Source/WebCore/page/animation/ImplicitAnimation.cpp
+++ b/Source/WebCore/page/animation/ImplicitAnimation.cpp
@@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Inc. ("Apple") nor the names of
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
@@ -32,18 +32,19 @@
#include "CSSPropertyAnimation.h"
#include "CompositeAnimation.h"
#include "EventNames.h"
-#include "GeometryUtilities.h"
#include "ImplicitAnimation.h"
#include "KeyframeAnimation.h"
-#include "RenderBox.h"
+#include "RenderBoxModelObject.h"
namespace WebCore {
-ImplicitAnimation::ImplicitAnimation(Animation& transition, CSSPropertyID animatingProperty, RenderElement* renderer, CompositeAnimation* compAnim, RenderStyle* fromStyle)
+ImplicitAnimation::ImplicitAnimation(const Animation& transition, CSSPropertyID animatingProperty, RenderElement* renderer, CompositeAnimation* compAnim, RenderStyle* fromStyle)
: AnimationBase(transition, renderer, compAnim)
- , m_fromStyle(fromStyle)
, m_transitionProperty(transition.property())
, m_animatingProperty(animatingProperty)
+ , m_overridden(false)
+ , m_active(true)
+ , m_fromStyle(fromStyle)
{
ASSERT(animatingProperty != CSSPropertyInvalid);
}
@@ -60,14 +61,12 @@ bool ImplicitAnimation::shouldSendEventForListener(Document::ListenerType inList
return m_object->document().hasListenerType(inListenerType);
}
-bool ImplicitAnimation::animate(CompositeAnimation*, RenderElement*, const RenderStyle*, RenderStyle* targetStyle, RefPtr<RenderStyle>& animatedStyle)
+void ImplicitAnimation::animate(CompositeAnimation*, RenderElement*, const RenderStyle*, RenderStyle* targetStyle, RefPtr<RenderStyle>& animatedStyle)
{
// If we get this far and the animation is done, it means we are cleaning up a just finished animation.
// So just return. Everything is already all cleaned up.
if (postActive())
- return false;
-
- AnimationState oldState = state();
+ return;
// Reset to start the transition if we are new
if (isNew())
@@ -78,21 +77,20 @@ bool ImplicitAnimation::animate(CompositeAnimation*, RenderElement*, const Rende
if (!animatedStyle)
animatedStyle = RenderStyle::clone(targetStyle);
- bool needsAnim = CSSPropertyAnimation::blendProperties(this, m_animatingProperty, animatedStyle.get(), m_fromStyle.get(), m_toStyle.get(), progress());
+#if USE(ACCELERATED_COMPOSITING)
+ bool needsAnim = CSSPropertyAnimation::blendProperties(this, m_animatingProperty, animatedStyle.get(), m_fromStyle.get(), m_toStyle.get(), progress(1, 0, 0));
// FIXME: we also need to detect cases where we have to software animate for other reasons,
// such as a child using inheriting the transform. https://bugs.webkit.org/show_bug.cgi?id=23902
- if (!needsAnim) {
+ if (!needsAnim)
// If we are running an accelerated animation, set a flag in the style which causes the style
// to compare as different to any other style. This ensures that changes to the property
// that is animating are correctly detected during the animation (e.g. when a transition
// gets interrupted).
- // FIXME: still need this hack?
animatedStyle->setIsRunningAcceleratedAnimation();
- }
+#endif
// Fire the start timeout if needed
fireAnimationEventsIfNeeded();
- return state() != oldState;
}
void ImplicitAnimation::getAnimatedStyle(RefPtr<RenderStyle>& animatedStyle)
@@ -100,46 +98,17 @@ void ImplicitAnimation::getAnimatedStyle(RefPtr<RenderStyle>& animatedStyle)
if (!animatedStyle)
animatedStyle = RenderStyle::clone(m_toStyle.get());
- CSSPropertyAnimation::blendProperties(this, m_animatingProperty, animatedStyle.get(), m_fromStyle.get(), m_toStyle.get(), progress());
-}
-
-bool ImplicitAnimation::computeExtentOfTransformAnimation(LayoutRect& bounds) const
-{
- ASSERT(hasStyle());
-
- if (!is<RenderBox>(m_object))
- return true; // Non-boxes don't get transformed;
-
- ASSERT(m_animatingProperty == CSSPropertyTransform);
-
- RenderBox& box = downcast<RenderBox>(*m_object);
- FloatRect rendererBox = snapRectToDevicePixels(box.borderBoxRect(), box.document().deviceScaleFactor());
-
- LayoutRect startBounds = bounds;
- LayoutRect endBounds = bounds;
-
- if (transformFunctionListsMatch()) {
- if (!computeTransformedExtentViaTransformList(rendererBox, *m_fromStyle, startBounds))
- return false;
-
- if (!computeTransformedExtentViaTransformList(rendererBox, *m_toStyle, endBounds))
- return false;
- } else {
- if (!computeTransformedExtentViaMatrix(rendererBox, *m_fromStyle, startBounds))
- return false;
-
- if (!computeTransformedExtentViaMatrix(rendererBox, *m_toStyle, endBounds))
- return false;
- }
-
- bounds = unionRect(startBounds, endBounds);
- return true;
+ CSSPropertyAnimation::blendProperties(this, m_animatingProperty, animatedStyle.get(), m_fromStyle.get(), m_toStyle.get(), progress(1, 0, 0));
}
bool ImplicitAnimation::startAnimation(double timeOffset)
{
+#if USE(ACCELERATED_COMPOSITING)
if (m_object && m_object->isComposited())
- return downcast<RenderBoxModelObject>(*m_object).startTransition(timeOffset, m_animatingProperty, m_fromStyle.get(), m_toStyle.get());
+ return toRenderBoxModelObject(m_object)->startTransition(timeOffset, m_animatingProperty, m_fromStyle.get(), m_toStyle.get());
+#else
+ UNUSED_PARAM(timeOffset);
+#endif
return false;
}
@@ -148,8 +117,12 @@ void ImplicitAnimation::pauseAnimation(double timeOffset)
if (!m_object)
return;
+#if USE(ACCELERATED_COMPOSITING)
if (m_object->isComposited())
- downcast<RenderBoxModelObject>(*m_object).transitionPaused(timeOffset, m_animatingProperty);
+ toRenderBoxModelObject(m_object)->transitionPaused(timeOffset, m_animatingProperty);
+#else
+ UNUSED_PARAM(timeOffset);
+#endif
// Restore the original (unanimated) style
if (!paused())
setNeedsStyleRecalc(m_object->element());
@@ -157,8 +130,10 @@ void ImplicitAnimation::pauseAnimation(double timeOffset)
void ImplicitAnimation::endAnimation()
{
+#if USE(ACCELERATED_COMPOSITING)
if (m_object && m_object->isComposited())
- downcast<RenderBoxModelObject>(*m_object).transitionFinished(m_animatingProperty);
+ toRenderBoxModelObject(m_object)->transitionFinished(m_animatingProperty);
+#endif
}
void ImplicitAnimation::onAnimationEnd(double elapsedTime)
@@ -168,7 +143,7 @@ void ImplicitAnimation::onAnimationEnd(double elapsedTime)
// running. But now that the transition has completed, we need to update this style with its new
// destination. If we didn't, the next time through we would think a transition had started
// (comparing the old unanimated style with the new final style of the transition).
- RefPtr<KeyframeAnimation> keyframeAnim = m_compositeAnimation->getAnimationForProperty(m_animatingProperty);
+ RefPtr<KeyframeAnimation> keyframeAnim = m_compAnim->getAnimationForProperty(m_animatingProperty);
if (keyframeAnim)
keyframeAnim->setUnanimatedStyle(m_toStyle);
@@ -192,7 +167,7 @@ bool ImplicitAnimation::sendTransitionEvent(const AtomicString& eventType, doubl
return false;
// Schedule event handling
- m_compositeAnimation->animationController().addEventToDispatch(element, eventType, propertyName, elapsedTime);
+ m_compAnim->animationController()->addEventToDispatch(element, eventType, propertyName, elapsedTime);
// Restore the original (unanimated) style
if (eventType == eventNames().transitionendEvent && element->renderer())
@@ -214,13 +189,12 @@ void ImplicitAnimation::reset(RenderStyle* to)
// Restart the transition
if (m_fromStyle && m_toStyle)
- updateStateMachine(AnimationStateInput::RestartAnimation, -1);
+ updateStateMachine(AnimationStateInputRestartAnimation, -1);
// set the transform animation list
validateTransformFunctionList();
+#if ENABLE(CSS_FILTERS)
checkForMatchingFilterFunctionLists();
-#if ENABLE(FILTERS_LEVEL_2)
- checkForMatchingBackdropFilterFunctionLists();
#endif
}
@@ -230,7 +204,7 @@ void ImplicitAnimation::setOverridden(bool b)
return;
m_overridden = b;
- updateStateMachine(m_overridden ? AnimationStateInput::PauseOverride : AnimationStateInput::ResumeOverride, -1);
+ updateStateMachine(m_overridden ? AnimationStateInputPauseOverride : AnimationStateInputResumeOverride, -1);
}
bool ImplicitAnimation::affectsProperty(CSSPropertyID property) const
@@ -255,12 +229,12 @@ void ImplicitAnimation::blendPropertyValueInStyle(CSSPropertyID prop, RenderStyl
if (!m_toStyle)
return;
- CSSPropertyAnimation::blendProperties(this, prop, currentStyle, m_fromStyle.get(), m_toStyle.get(), progress());
+ CSSPropertyAnimation::blendProperties(this, prop, currentStyle, m_fromStyle.get(), m_toStyle.get(), progress(1, 0, 0));
}
void ImplicitAnimation::validateTransformFunctionList()
{
- m_transformFunctionListsMatch = false;
+ m_transformFunctionListValid = false;
if (!m_fromStyle || !m_toStyle)
return;
@@ -274,53 +248,44 @@ void ImplicitAnimation::validateTransformFunctionList()
if (val->operations().isEmpty())
return;
- // An empty transform list matches anything.
+ // An emtpy transform list matches anything.
if (val != toVal && !toVal->operations().isEmpty() && !val->operationsMatch(*toVal))
return;
// Transform lists match.
- m_transformFunctionListsMatch = true;
-}
-
-static bool filterOperationsMatch(const FilterOperations* fromOperations, const FilterOperations& toOperations)
-{
- if (fromOperations->operations().isEmpty())
- fromOperations = &toOperations;
-
- if (fromOperations->operations().isEmpty())
- return false;
-
- if (fromOperations != &toOperations && !toOperations.operations().isEmpty() && !fromOperations->operationsMatch(toOperations))
- return false;
-
- return true;
+ m_transformFunctionListValid = true;
}
+#if ENABLE(CSS_FILTERS)
void ImplicitAnimation::checkForMatchingFilterFunctionLists()
{
m_filterFunctionListsMatch = false;
-
+
if (!m_fromStyle || !m_toStyle)
return;
+
+ const FilterOperations* val = &m_fromStyle->filter();
+ const FilterOperations* toVal = &m_toStyle->filter();
- m_filterFunctionListsMatch = filterOperationsMatch(&m_fromStyle->filter(), m_toStyle->filter());
-}
-
-#if ENABLE(FILTERS_LEVEL_2)
-void ImplicitAnimation::checkForMatchingBackdropFilterFunctionLists()
-{
- m_backdropFilterFunctionListsMatch = false;
+ if (val->operations().isEmpty())
+ val = toVal;
- if (!m_fromStyle || !m_toStyle)
+ if (val->operations().isEmpty())
+ return;
+
+ // An emtpy filter list matches anything.
+ if (val != toVal && !toVal->operations().isEmpty() && !val->operationsMatch(*toVal))
return;
- m_backdropFilterFunctionListsMatch = filterOperationsMatch(&m_fromStyle->backdropFilter(), m_toStyle->backdropFilter());
+ // Filter lists match.
+ m_filterFunctionListsMatch = true;
}
#endif
double ImplicitAnimation::timeToNextService()
{
double t = AnimationBase::timeToNextService();
+#if USE(ACCELERATED_COMPOSITING)
if (t != 0 || preActive())
return t;
@@ -330,6 +295,7 @@ double ImplicitAnimation::timeToNextService()
bool isLooping;
getTimeToNextEvent(t, isLooping);
}
+#endif
return t;
}
diff --git a/Source/WebCore/page/animation/ImplicitAnimation.h b/Source/WebCore/page/animation/ImplicitAnimation.h
index a9a30f1e2..df651141e 100644
--- a/Source/WebCore/page/animation/ImplicitAnimation.h
+++ b/Source/WebCore/page/animation/ImplicitAnimation.h
@@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Inc. ("Apple") nor the names of
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
@@ -41,9 +41,9 @@ class RenderElement;
// for a single RenderElement.
class ImplicitAnimation : public AnimationBase {
public:
- static Ref<ImplicitAnimation> create(Animation& animation, CSSPropertyID animatingProperty, RenderElement* renderer, CompositeAnimation* compositeAnimation, RenderStyle* fromStyle)
+ static PassRefPtr<ImplicitAnimation> create(const Animation& animation, CSSPropertyID animatingProperty, RenderElement* renderer, CompositeAnimation* compositeAnimation, RenderStyle* fromStyle)
{
- return adoptRef(*new ImplicitAnimation(animation, animatingProperty, renderer, compositeAnimation, fromStyle));
+ return adoptRef(new ImplicitAnimation(animation, animatingProperty, renderer, compositeAnimation, fromStyle));
};
CSSPropertyID transitionProperty() const { return m_transitionProperty; }
@@ -54,12 +54,10 @@ public:
virtual void pauseAnimation(double timeOffset) override;
virtual void endAnimation() override;
- virtual bool animate(CompositeAnimation*, RenderElement*, const RenderStyle* currentStyle, RenderStyle* targetStyle, RefPtr<RenderStyle>& animatedStyle) override;
+ virtual void animate(CompositeAnimation*, RenderElement*, const RenderStyle* currentStyle, RenderStyle* targetStyle, RefPtr<RenderStyle>& animatedStyle) override;
virtual void getAnimatedStyle(RefPtr<RenderStyle>& animatedStyle) override;
virtual void reset(RenderStyle* to);
- bool computeExtentOfTransformAnimation(LayoutRect&) const override;
-
void setOverridden(bool);
virtual bool overridden() const override { return m_overridden; }
@@ -81,24 +79,22 @@ protected:
bool sendTransitionEvent(const AtomicString&, double elapsedTime);
void validateTransformFunctionList();
+#if ENABLE(CSS_FILTERS)
void checkForMatchingFilterFunctionLists();
-#if ENABLE(FILTERS_LEVEL_2)
- void checkForMatchingBackdropFilterFunctionLists();
#endif
private:
- ImplicitAnimation(Animation&, CSSPropertyID, RenderElement*, CompositeAnimation*, RenderStyle*);
+ ImplicitAnimation(const Animation&, CSSPropertyID, RenderElement*, CompositeAnimation*, RenderStyle*);
virtual ~ImplicitAnimation();
- // The two styles that we are blending.
- RefPtr<RenderStyle> m_fromStyle;
- RefPtr<RenderStyle> m_toStyle;
-
CSSPropertyID m_transitionProperty; // Transition property as specified in the RenderStyle.
CSSPropertyID m_animatingProperty; // Specific property for this ImplicitAnimation
+ bool m_overridden; // true when there is a keyframe animation that overrides the transitioning property
+ bool m_active; // used for culling the list of transitions
- bool m_active { true }; // Used for culling the list of transitions.
- bool m_overridden { false }; // True when there is a keyframe animation that overrides the transitioning property
+ // The two styles that we are blending.
+ RefPtr<RenderStyle> m_fromStyle;
+ RefPtr<RenderStyle> m_toStyle;
};
} // namespace WebCore
diff --git a/Source/WebCore/page/animation/KeyframeAnimation.cpp b/Source/WebCore/page/animation/KeyframeAnimation.cpp
index 0bd966d85..8f661c6c3 100644
--- a/Source/WebCore/page/animation/KeyframeAnimation.cpp
+++ b/Source/WebCore/page/animation/KeyframeAnimation.cpp
@@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Inc. ("Apple") nor the names of
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
@@ -34,27 +34,27 @@
#include "CSSPropertyNames.h"
#include "CompositeAnimation.h"
#include "EventNames.h"
-#include "GeometryUtilities.h"
-#include "RenderBox.h"
+#include "RenderBoxModelObject.h"
#include "RenderStyle.h"
#include "StyleResolver.h"
namespace WebCore {
-KeyframeAnimation::KeyframeAnimation(Animation& animation, RenderElement* renderer, CompositeAnimation* compositeAnimation, RenderStyle* unanimatedStyle)
- : AnimationBase(animation, renderer, compositeAnimation)
+KeyframeAnimation::KeyframeAnimation(const Animation& animation, RenderElement* renderer, int index, CompositeAnimation* compAnim, RenderStyle* unanimatedStyle)
+ : AnimationBase(animation, renderer, compAnim)
, m_keyframes(animation.name())
+ , m_index(index)
+ , m_startEventDispatched(false)
, m_unanimatedStyle(unanimatedStyle)
{
// Get the keyframe RenderStyles
if (m_object && m_object->element())
- m_object->element()->styleResolver().keyframeStylesForAnimation(*m_object->element(), unanimatedStyle, m_keyframes);
+ m_object->document().ensureStyleResolver().keyframeStylesForAnimation(m_object->element(), unanimatedStyle, m_keyframes);
// Update the m_transformFunctionListValid flag based on whether the function lists in the keyframes match.
validateTransformFunctionList();
+#if ENABLE(CSS_FILTERS)
checkForMatchingFilterFunctionLists();
-#if ENABLE(FILTERS_LEVEL_2)
- checkForMatchingBackdropFilterFunctionLists();
#endif
}
@@ -65,23 +65,38 @@ KeyframeAnimation::~KeyframeAnimation()
endAnimation();
}
-void KeyframeAnimation::fetchIntervalEndpointsForProperty(CSSPropertyID property, const RenderStyle*& fromStyle, const RenderStyle*& toStyle, double& prog) const
+static const Animation* getAnimationFromStyleByName(const RenderStyle* style, const AtomicString& name)
{
- size_t numKeyframes = m_keyframes.size();
- if (!numKeyframes)
- return;
+ if (!style->animations())
+ return 0;
+
+ for (size_t i = 0; i < style->animations()->size(); i++) {
+ if (name == style->animations()->animation(i).name())
+ return &style->animations()->animation(i);
+ }
+ return 0;
+}
+
+void KeyframeAnimation::fetchIntervalEndpointsForProperty(CSSPropertyID property, const RenderStyle*& fromStyle, const RenderStyle*& toStyle, double& prog) const
+{
// Find the first key
double elapsedTime = getElapsedTime();
if (m_animation->duration() && m_animation->iterationCount() != Animation::IterationCountInfinite)
elapsedTime = std::min(elapsedTime, m_animation->duration() * m_animation->iterationCount());
const double fractionalTime = this->fractionalTime(1, elapsedTime, 0);
+
+ size_t numKeyframes = m_keyframes.size();
+ if (!numKeyframes)
+ return;
+
ASSERT(!m_keyframes[0].key());
ASSERT(m_keyframes[m_keyframes.size() - 1].key() == 1);
-
+
int prevIndex = -1;
int nextIndex = -1;
+
// FIXME: with a lot of keys, this linear search will be slow. We could binary search.
for (size_t i = 0; i < numKeyframes; ++i) {
const KeyframeValue& currKeyFrame = m_keyframes[i];
@@ -93,11 +108,16 @@ void KeyframeAnimation::fetchIntervalEndpointsForProperty(CSSPropertyID property
nextIndex = i;
break;
}
+
prevIndex = i;
}
+ double scale = 1;
+ double offset = 0;
+
if (prevIndex == -1)
prevIndex = 0;
+
if (nextIndex == -1)
nextIndex = m_keyframes.size() - 1;
@@ -106,32 +126,32 @@ void KeyframeAnimation::fetchIntervalEndpointsForProperty(CSSPropertyID property
fromStyle = prevKeyframe.style();
toStyle = nextKeyframe.style();
+
+ offset = prevKeyframe.key();
+ scale = 1.0 / (nextKeyframe.key() - prevKeyframe.key());
- double offset = prevKeyframe.key();
- double scale = 1.0 / (nextIndex == prevIndex ? 1 : (nextKeyframe.key() - prevKeyframe.key()));
+ const TimingFunction* timingFunction = 0;
+ if (const Animation* matchedAnimation = getAnimationFromStyleByName(fromStyle, name()))
+ timingFunction = matchedAnimation->timingFunction().get();
- prog = progress(scale, offset, prevKeyframe.timingFunction(name()));
+ prog = progress(scale, offset, timingFunction);
}
-bool KeyframeAnimation::animate(CompositeAnimation* compositeAnimation, RenderElement*, const RenderStyle*, RenderStyle* targetStyle, RefPtr<RenderStyle>& animatedStyle)
+void KeyframeAnimation::animate(CompositeAnimation* compositeAnimation, RenderElement*, const RenderStyle*, RenderStyle* targetStyle, RefPtr<RenderStyle>& animatedStyle)
{
// Fire the start timeout if needed
fireAnimationEventsIfNeeded();
// If we have not yet started, we will not have a valid start time, so just start the animation if needed.
- if (isNew()) {
- if (m_animation->playState() == AnimPlayStatePlaying && !compositeAnimation->isSuspended())
- updateStateMachine(AnimationStateInput::StartAnimation, -1);
- else if (m_animation->playState() == AnimPlayStatePaused)
- updateStateMachine(AnimationStateInput::PlayStatePaused, -1);
- }
+ if (isNew() && m_animation->playState() == AnimPlayStatePlaying && !compositeAnimation->isSuspended())
+ updateStateMachine(AnimationStateInputStartAnimation, -1);
// If we get this far and the animation is done, it means we are cleaning up a just finished animation.
// If so, we need to send back the targetStyle.
if (postActive()) {
if (!animatedStyle)
animatedStyle = const_cast<RenderStyle*>(targetStyle);
- return false;
+ return;
}
// If we are waiting for the start timer, we don't want to change the style yet.
@@ -140,16 +160,14 @@ bool KeyframeAnimation::animate(CompositeAnimation* compositeAnimation, RenderEl
// Special case 2 - if there is a backwards fill mode, then we want to continue
// through to the style blend so that we get the fromStyle.
if (waitingToStart() && m_animation->delay() > 0 && !m_animation->fillsBackwards())
- return false;
+ return;
// If we have no keyframes, don't animate.
if (!m_keyframes.size()) {
- updateStateMachine(AnimationStateInput::EndAnimation, -1);
- return false;
+ updateStateMachine(AnimationStateInputEndAnimation, -1);
+ return;
}
- AnimationState oldState = state();
-
// Run a cycle of animation.
// We know we will need a new render style, so make one if needed.
if (!animatedStyle)
@@ -157,29 +175,30 @@ bool KeyframeAnimation::animate(CompositeAnimation* compositeAnimation, RenderEl
// FIXME: we need to be more efficient about determining which keyframes we are animating between.
// We should cache the last pair or something.
- for (auto propertyID : m_keyframes.properties()) {
+ HashSet<CSSPropertyID>::const_iterator endProperties = m_keyframes.endProperties();
+ for (HashSet<CSSPropertyID>::const_iterator it = m_keyframes.beginProperties(); it != endProperties; ++it) {
// Get the from/to styles and progress between
- const RenderStyle* fromStyle = nullptr;
- const RenderStyle* toStyle = nullptr;
- double progress = 0;
- fetchIntervalEndpointsForProperty(propertyID, fromStyle, toStyle, progress);
+ const RenderStyle* fromStyle = 0;
+ const RenderStyle* toStyle = 0;
+ double progress = 0.0;
+ fetchIntervalEndpointsForProperty(*it, fromStyle, toStyle, progress);
- bool needsAnim = CSSPropertyAnimation::blendProperties(this, propertyID, animatedStyle.get(), fromStyle, toStyle, progress);
+#if USE(ACCELERATED_COMPOSITING)
+ bool needsAnim = CSSPropertyAnimation::blendProperties(this, *it, animatedStyle.get(), fromStyle, toStyle, progress);
if (!needsAnim)
// If we are running an accelerated animation, set a flag in the style
// to indicate it. This can be used to make sure we get an updated
// style for hit testing, etc.
- // FIXME: still need this?
animatedStyle->setIsRunningAcceleratedAnimation();
+#endif
}
-
- return state() != oldState;
}
void KeyframeAnimation::getAnimatedStyle(RefPtr<RenderStyle>& animatedStyle)
{
- // If we're done, or in the delay phase and we're not backwards filling, tell the caller to use the current style.
- if (postActive() || (waitingToStart() && m_animation->delay() > 0 && !m_animation->fillsBackwards()))
+ // If we're in the delay phase and we're not backwards filling, tell the caller
+ // to use the current style.
+ if (waitingToStart() && m_animation->delay() > 0 && !m_animation->fillsBackwards())
return;
if (!m_keyframes.size())
@@ -188,51 +207,18 @@ void KeyframeAnimation::getAnimatedStyle(RefPtr<RenderStyle>& animatedStyle)
if (!animatedStyle)
animatedStyle = RenderStyle::clone(&m_object->style());
- for (auto propertyID : m_keyframes.properties()) {
+ HashSet<CSSPropertyID>::const_iterator endProperties = m_keyframes.endProperties();
+ for (HashSet<CSSPropertyID>::const_iterator it = m_keyframes.beginProperties(); it != endProperties; ++it) {
// Get the from/to styles and progress between
- const RenderStyle* fromStyle = nullptr;
- const RenderStyle* toStyle = nullptr;
- double progress = 0;
- fetchIntervalEndpointsForProperty(propertyID, fromStyle, toStyle, progress);
+ const RenderStyle* fromStyle = 0;
+ const RenderStyle* toStyle = 0;
+ double progress = 0.0;
+ fetchIntervalEndpointsForProperty(*it, fromStyle, toStyle, progress);
- CSSPropertyAnimation::blendProperties(this, propertyID, animatedStyle.get(), fromStyle, toStyle, progress);
+ CSSPropertyAnimation::blendProperties(this, *it, animatedStyle.get(), fromStyle, toStyle, progress);
}
}
-bool KeyframeAnimation::computeExtentOfTransformAnimation(LayoutRect& bounds) const
-{
- ASSERT(m_keyframes.containsProperty(CSSPropertyTransform));
-
- if (!is<RenderBox>(m_object))
- return true; // Non-boxes don't get transformed;
-
- RenderBox& box = downcast<RenderBox>(*m_object);
- FloatRect rendererBox = snapRectToDevicePixels(box.borderBoxRect(), box.document().deviceScaleFactor());
-
- FloatRect cumulativeBounds = bounds;
-
- for (auto& keyframe : m_keyframes.keyframes()) {
- if (!keyframe.containsProperty(CSSPropertyTransform))
- continue;
-
- LayoutRect keyframeBounds = bounds;
-
- bool canCompute;
- if (transformFunctionListsMatch())
- canCompute = computeTransformedExtentViaTransformList(rendererBox, *keyframe.style(), keyframeBounds);
- else
- canCompute = computeTransformedExtentViaMatrix(rendererBox, *keyframe.style(), keyframeBounds);
-
- if (!canCompute)
- return false;
-
- cumulativeBounds.unite(keyframeBounds);
- }
-
- bounds = LayoutRect(cumulativeBounds);
- return true;
-}
-
bool KeyframeAnimation::hasAnimationForProperty(CSSPropertyID property) const
{
return m_keyframes.containsProperty(property);
@@ -240,8 +226,13 @@ bool KeyframeAnimation::hasAnimationForProperty(CSSPropertyID property) const
bool KeyframeAnimation::startAnimation(double timeOffset)
{
- if (m_object && m_object->isComposited())
- return downcast<RenderBoxModelObject>(*m_object).startAnimation(timeOffset, m_animation.ptr(), m_keyframes);
+#if USE(ACCELERATED_COMPOSITING)
+ if (m_object && m_object->isComposited()) {
+ return toRenderBoxModelObject(m_object)->startAnimation(timeOffset, m_animation.get(), m_keyframes);
+ }
+#else
+ UNUSED_PARAM(timeOffset);
+#endif
return false;
}
@@ -250,9 +241,12 @@ void KeyframeAnimation::pauseAnimation(double timeOffset)
if (!m_object)
return;
+#if USE(ACCELERATED_COMPOSITING)
if (m_object->isComposited())
- downcast<RenderBoxModelObject>(*m_object).animationPaused(timeOffset, m_keyframes.animationName());
-
+ toRenderBoxModelObject(m_object)->animationPaused(timeOffset, m_keyframes.animationName());
+#else
+ UNUSED_PARAM(timeOffset);
+#endif
// Restore the original (unanimated) style
if (!paused())
setNeedsStyleRecalc(m_object->element());
@@ -263,9 +257,10 @@ void KeyframeAnimation::endAnimation()
if (!m_object)
return;
+#if USE(ACCELERATED_COMPOSITING)
if (m_object->isComposited())
- downcast<RenderBoxModelObject>(*m_object).animationFinished(m_keyframes.animationName());
-
+ toRenderBoxModelObject(m_object)->animationFinished(m_keyframes.animationName());
+#endif
// Restore the original (unanimated) style
if (!paused())
setNeedsStyleRecalc(m_object->element());
@@ -278,17 +273,17 @@ bool KeyframeAnimation::shouldSendEventForListener(Document::ListenerType listen
void KeyframeAnimation::onAnimationStart(double elapsedTime)
{
- sendAnimationEvent(eventNames().animationstartEvent, elapsedTime);
+ sendAnimationEvent(eventNames().webkitAnimationStartEvent, elapsedTime);
}
void KeyframeAnimation::onAnimationIteration(double elapsedTime)
{
- sendAnimationEvent(eventNames().animationiterationEvent, elapsedTime);
+ sendAnimationEvent(eventNames().webkitAnimationIterationEvent, elapsedTime);
}
void KeyframeAnimation::onAnimationEnd(double elapsedTime)
{
- sendAnimationEvent(eventNames().animationendEvent, elapsedTime);
+ sendAnimationEvent(eventNames().webkitAnimationEndEvent, elapsedTime);
// End the animation if we don't fill forwards. Forward filling
// animations are ended properly in the class destructor.
if (!m_animation->fillsForwards())
@@ -298,12 +293,12 @@ void KeyframeAnimation::onAnimationEnd(double elapsedTime)
bool KeyframeAnimation::sendAnimationEvent(const AtomicString& eventType, double elapsedTime)
{
Document::ListenerType listenerType;
- if (eventType == eventNames().webkitAnimationIterationEvent || eventType == eventNames().animationiterationEvent)
+ if (eventType == eventNames().webkitAnimationIterationEvent)
listenerType = Document::ANIMATIONITERATION_LISTENER;
- else if (eventType == eventNames().webkitAnimationEndEvent || eventType == eventNames().animationendEvent)
+ else if (eventType == eventNames().webkitAnimationEndEvent)
listenerType = Document::ANIMATIONEND_LISTENER;
else {
- ASSERT(eventType == eventNames().webkitAnimationStartEvent || eventType == eventNames().animationstartEvent);
+ ASSERT(eventType == eventNames().webkitAnimationStartEvent);
if (m_startEventDispatched)
return false;
m_startEventDispatched = true;
@@ -319,10 +314,10 @@ bool KeyframeAnimation::sendAnimationEvent(const AtomicString& eventType, double
return false;
// Schedule event handling
- m_compositeAnimation->animationController().addEventToDispatch(element, eventType, m_keyframes.animationName(), elapsedTime);
+ m_compAnim->animationController()->addEventToDispatch(element, eventType, m_keyframes.animationName(), elapsedTime);
// Restore the original (unanimated) style
- if ((eventType == eventNames().webkitAnimationEndEvent || eventType == eventNames().animationendEvent) && element->renderer())
+ if (eventType == eventNames().webkitAnimationEndEvent && element->renderer())
setNeedsStyleRecalc(element.get());
return true; // Did dispatch an event
@@ -334,15 +329,17 @@ bool KeyframeAnimation::sendAnimationEvent(const AtomicString& eventType, double
void KeyframeAnimation::overrideAnimations()
{
// This will override implicit animations that match the properties in the keyframe animation
- for (auto propertyID : m_keyframes.properties())
- compositeAnimation()->overrideImplicitAnimations(propertyID);
+ HashSet<CSSPropertyID>::const_iterator end = m_keyframes.endProperties();
+ for (HashSet<CSSPropertyID>::const_iterator it = m_keyframes.beginProperties(); it != end; ++it)
+ compositeAnimation()->overrideImplicitAnimations(*it);
}
void KeyframeAnimation::resumeOverriddenAnimations()
{
// This will resume overridden implicit animations
- for (auto propertyID : m_keyframes.properties())
- compositeAnimation()->resumeOverriddenImplicitAnimations(propertyID);
+ HashSet<CSSPropertyID>::const_iterator end = m_keyframes.endProperties();
+ for (HashSet<CSSPropertyID>::const_iterator it = m_keyframes.beginProperties(); it != end; ++it)
+ compositeAnimation()->resumeOverriddenImplicitAnimations(*it);
}
bool KeyframeAnimation::affectsProperty(CSSPropertyID property) const
@@ -352,9 +349,9 @@ bool KeyframeAnimation::affectsProperty(CSSPropertyID property) const
void KeyframeAnimation::validateTransformFunctionList()
{
- m_transformFunctionListsMatch = false;
+ m_transformFunctionListValid = false;
- if (m_keyframes.size() < 2 || !m_keyframes.containsProperty(CSSPropertyTransform))
+ if (m_keyframes.size() < 2 || !m_keyframes.containsProperty(CSSPropertyWebkitTransform))
return;
// Empty transforms match anything, so find the first non-empty entry as the reference
@@ -387,14 +384,16 @@ void KeyframeAnimation::validateTransformFunctionList()
return;
}
- m_transformFunctionListsMatch = true;
+ // Keyframes are valid
+ m_transformFunctionListValid = true;
}
+#if ENABLE(CSS_FILTERS)
void KeyframeAnimation::checkForMatchingFilterFunctionLists()
{
m_filterFunctionListsMatch = false;
- if (m_keyframes.size() < 2 || !m_keyframes.containsProperty(CSSPropertyFilter))
+ if (m_keyframes.size() < 2 || !m_keyframes.containsProperty(CSSPropertyWebkitFilter))
return;
// Empty filters match anything, so find the first non-empty entry as the reference
@@ -402,7 +401,8 @@ void KeyframeAnimation::checkForMatchingFilterFunctionLists()
size_t firstNonEmptyFilterKeyframeIndex = numKeyframes;
for (size_t i = 0; i < numKeyframes; ++i) {
- if (m_keyframes[i].style()->filter().operations().size()) {
+ const KeyframeValue& currentKeyframe = m_keyframes[i];
+ if (currentKeyframe.style()->filter().operations().size()) {
firstNonEmptyFilterKeyframeIndex = i;
break;
}
@@ -410,74 +410,39 @@ void KeyframeAnimation::checkForMatchingFilterFunctionLists()
if (firstNonEmptyFilterKeyframeIndex == numKeyframes)
return;
-
- auto& firstVal = m_keyframes[firstNonEmptyFilterKeyframeIndex].style()->filter();
+
+ const FilterOperations* firstVal = &m_keyframes[firstNonEmptyFilterKeyframeIndex].style()->filter();
for (size_t i = firstNonEmptyFilterKeyframeIndex + 1; i < numKeyframes; ++i) {
- auto& value = m_keyframes[i].style()->filter();
-
+ const KeyframeValue& currentKeyframe = m_keyframes[i];
+ const FilterOperations* val = &currentKeyframe.style()->filter();
+
// An emtpy filter list matches anything.
- if (value.operations().isEmpty())
+ if (val->operations().isEmpty())
continue;
-
- if (!firstVal.operationsMatch(value))
+
+ if (!firstVal->operationsMatch(*val))
return;
}
-
+
m_filterFunctionListsMatch = true;
}
-
-#if ENABLE(FILTERS_LEVEL_2)
-void KeyframeAnimation::checkForMatchingBackdropFilterFunctionLists()
-{
- m_backdropFilterFunctionListsMatch = false;
-
- if (m_keyframes.size() < 2 || !m_keyframes.containsProperty(CSSPropertyWebkitBackdropFilter))
- return;
-
- // Empty filters match anything, so find the first non-empty entry as the reference
- size_t numKeyframes = m_keyframes.size();
- size_t firstNonEmptyFilterKeyframeIndex = numKeyframes;
-
- for (size_t i = 0; i < numKeyframes; ++i) {
- if (m_keyframes[i].style()->backdropFilter().operations().size()) {
- firstNonEmptyFilterKeyframeIndex = i;
- break;
- }
- }
-
- if (firstNonEmptyFilterKeyframeIndex == numKeyframes)
- return;
-
- auto& firstVal = m_keyframes[firstNonEmptyFilterKeyframeIndex].style()->backdropFilter();
-
- for (size_t i = firstNonEmptyFilterKeyframeIndex + 1; i < numKeyframes; ++i) {
- auto& value = m_keyframes[i].style()->backdropFilter();
-
- // An emtpy filter list matches anything.
- if (value.operations().isEmpty())
- continue;
-
- if (!firstVal.operationsMatch(value))
- return;
- }
-
- m_backdropFilterFunctionListsMatch = true;
-}
#endif
double KeyframeAnimation::timeToNextService()
{
double t = AnimationBase::timeToNextService();
+#if USE(ACCELERATED_COMPOSITING)
if (t != 0 || preActive())
return t;
// A return value of 0 means we need service. But if we only have accelerated animations we
// only need service at the end of the transition
+ HashSet<CSSPropertyID>::const_iterator endProperties = m_keyframes.endProperties();
bool acceleratedPropertiesOnly = true;
- for (auto propertyID : m_keyframes.properties()) {
- if (!CSSPropertyAnimation::animationOfPropertyIsAccelerated(propertyID) || !isAccelerated()) {
+ for (HashSet<CSSPropertyID>::const_iterator it = m_keyframes.beginProperties(); it != endProperties; ++it) {
+ if (!CSSPropertyAnimation::animationOfPropertyIsAccelerated(*it) || !isAccelerated()) {
acceleratedPropertiesOnly = false;
break;
}
@@ -487,7 +452,7 @@ double KeyframeAnimation::timeToNextService()
bool isLooping;
getTimeToNextEvent(t, isLooping);
}
-
+#endif
return t;
}
diff --git a/Source/WebCore/page/animation/KeyframeAnimation.h b/Source/WebCore/page/animation/KeyframeAnimation.h
index 946dcb34e..34ebd9951 100644
--- a/Source/WebCore/page/animation/KeyframeAnimation.h
+++ b/Source/WebCore/page/animation/KeyframeAnimation.h
@@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Inc. ("Apple") nor the names of
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
@@ -40,19 +40,19 @@ class RenderStyle;
// A KeyframeAnimation tracks the state of an explicit animation for a single RenderElement.
class KeyframeAnimation final : public AnimationBase {
public:
- static Ref<KeyframeAnimation> create(Animation& animation, RenderElement* renderer, CompositeAnimation* compositeAnimation, RenderStyle* unanimatedStyle)
+ static RefPtr<KeyframeAnimation> create(const Animation& animation, RenderElement* renderer, int index, CompositeAnimation* compositeAnimation, RenderStyle* unanimatedStyle)
{
- return adoptRef(*new KeyframeAnimation(animation, renderer, compositeAnimation, unanimatedStyle));
+ return adoptRef(new KeyframeAnimation(animation, renderer, index, compositeAnimation, unanimatedStyle));
}
- virtual bool animate(CompositeAnimation*, RenderElement*, const RenderStyle* currentStyle, RenderStyle* targetStyle, RefPtr<RenderStyle>& animatedStyle) override;
+ virtual void animate(CompositeAnimation*, RenderElement*, const RenderStyle* currentStyle, RenderStyle* targetStyle, RefPtr<RenderStyle>& animatedStyle) override;
virtual void getAnimatedStyle(RefPtr<RenderStyle>&) override;
- bool computeExtentOfTransformAnimation(LayoutRect&) const override;
-
const KeyframeList& keyframes() const { return m_keyframes; }
const AtomicString& name() const { return m_keyframes.animationName(); }
+ int index() const { return m_index; }
+ void setIndex(int i) { m_index = i; }
bool hasAnimationForProperty(CSSPropertyID) const;
@@ -77,27 +77,27 @@ protected:
virtual bool affectsProperty(CSSPropertyID) const override;
- bool computeExtentOfAnimationForMatrixAnimation(const FloatRect& rendererBox, LayoutRect&) const;
-
- bool computeExtentOfAnimationForMatchingTransformLists(const FloatRect& rendererBox, LayoutRect&) const;
-
void validateTransformFunctionList();
+#if ENABLE(CSS_FILTERS)
void checkForMatchingFilterFunctionLists();
-#if ENABLE(FILTERS_LEVEL_2)
- void checkForMatchingBackdropFilterFunctionLists();
#endif
private:
- KeyframeAnimation(Animation&, RenderElement*, CompositeAnimation*, RenderStyle* unanimatedStyle);
+ KeyframeAnimation(const Animation&, RenderElement*, int index, CompositeAnimation*, RenderStyle* unanimatedStyle);
virtual ~KeyframeAnimation();
// Get the styles for the given property surrounding the current animation time and the progress between them.
void fetchIntervalEndpointsForProperty(CSSPropertyID, const RenderStyle*& fromStyle, const RenderStyle*& toStyle, double& progress) const;
+ // The keyframes that we are blending.
KeyframeList m_keyframes;
- RefPtr<RenderStyle> m_unanimatedStyle; // The style just before we started animation
- bool m_startEventDispatched { false };
+ // The order in which this animation appears in the animation-name style.
+ int m_index;
+ bool m_startEventDispatched;
+
+ // The style just before we started animation
+ RefPtr<RenderStyle> m_unanimatedStyle;
};
} // namespace WebCore
diff --git a/Source/WebCore/page/csp/ContentSecurityPolicy.cpp b/Source/WebCore/page/csp/ContentSecurityPolicy.cpp
deleted file mode 100644
index 19bf207fa..000000000
--- a/Source/WebCore/page/csp/ContentSecurityPolicy.cpp
+++ /dev/null
@@ -1,525 +0,0 @@
-/*
- * Copyright (C) 2011 Google, Inc. All rights reserved.
- * Copyright (C) 2013, 2016 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "ContentSecurityPolicy.h"
-
-#include "ContentSecurityPolicyDirective.h"
-#include "ContentSecurityPolicyDirectiveList.h"
-#include "ContentSecurityPolicySource.h"
-#include "ContentSecurityPolicySourceList.h"
-#include "DOMStringList.h"
-#include "Document.h"
-#include "DocumentLoader.h"
-#include "FormData.h"
-#include "FormDataList.h"
-#include "Frame.h"
-#include "InspectorInstrumentation.h"
-#include "JSMainThreadExecState.h"
-#include "ParsingUtilities.h"
-#include "PingLoader.h"
-#include "RuntimeEnabledFeatures.h"
-#include "SchemeRegistry.h"
-#include "SecurityOrigin.h"
-#include "SecurityPolicyViolationEvent.h"
-#include <inspector/InspectorValues.h>
-#include <inspector/ScriptCallStack.h>
-#include <inspector/ScriptCallStackFactory.h>
-#include <wtf/text/TextPosition.h>
-
-using namespace Inspector;
-
-namespace WebCore {
-
-ContentSecurityPolicy::ContentSecurityPolicy(ScriptExecutionContext& scriptExecutionContext)
- : m_scriptExecutionContext(&scriptExecutionContext)
- , m_sandboxFlags(SandboxNone)
-{
- ASSERT(scriptExecutionContext.securityOrigin());
- updateSourceSelf(*scriptExecutionContext.securityOrigin());
-}
-
-ContentSecurityPolicy::ContentSecurityPolicy(const SecurityOrigin& securityOrigin)
- : m_sandboxFlags(SandboxNone)
-{
- updateSourceSelf(securityOrigin);
-}
-
-ContentSecurityPolicy::~ContentSecurityPolicy()
-{
-}
-
-void ContentSecurityPolicy::copyStateFrom(const ContentSecurityPolicy* other)
-{
- ASSERT(m_policies.isEmpty());
- for (auto& policy : other->m_policies)
- didReceiveHeader(policy->header(), policy->headerType(), ContentSecurityPolicy::PolicyFrom::Inherited);
-}
-
-ContentSecurityPolicyResponseHeaders ContentSecurityPolicy::responseHeaders() const
-{
- ContentSecurityPolicyResponseHeaders result;
- result.m_headers.reserveInitialCapacity(m_policies.size());
- for (auto& policy : m_policies)
- result.m_headers.uncheckedAppend({ policy->header(), policy->headerType() });
- return result;
-}
-
-void ContentSecurityPolicy::didReceiveHeaders(const ContentSecurityPolicyResponseHeaders& headers)
-{
- for (auto& header : headers.m_headers)
- didReceiveHeader(header.first, header.second, ContentSecurityPolicy::PolicyFrom::HTTPHeader);
-}
-
-void ContentSecurityPolicy::didReceiveHeader(const String& header, ContentSecurityPolicyHeaderType type, ContentSecurityPolicy::PolicyFrom policyFrom)
-{
- // RFC2616, section 4.2 specifies that headers appearing multiple times can
- // be combined with a comma. Walk the header string, and parse each comma
- // separated chunk as a separate header.
- auto characters = StringView(header).upconvertedCharacters();
- const UChar* begin = characters;
- const UChar* position = begin;
- const UChar* end = begin + header.length();
- while (position < end) {
- skipUntil<UChar>(position, end, ',');
-
- // header1,header2 OR header1
- // ^ ^
- std::unique_ptr<ContentSecurityPolicyDirectiveList> policy = ContentSecurityPolicyDirectiveList::create(*this, String(begin, position - begin), type, policyFrom);
- if (!policy->allowEval(0, ContentSecurityPolicy::ReportingStatus::SuppressReport))
- m_lastPolicyEvalDisabledErrorMessage = policy->evalDisabledErrorMessage();
-
- m_policies.append(policy.release());
-
- // Skip the comma, and begin the next header from the current position.
- ASSERT(position == end || *position == ',');
- skipExactly<UChar>(position, end, ',');
- begin = position;
- }
-
- if (m_scriptExecutionContext)
- applyPolicyToScriptExecutionContext();
-}
-
-void ContentSecurityPolicy::updateSourceSelf(const SecurityOrigin& securityOrigin)
-{
- m_selfSourceProtocol = securityOrigin.protocol();
- m_selfSource = std::make_unique<ContentSecurityPolicySource>(*this, m_selfSourceProtocol, securityOrigin.host(), securityOrigin.port(), emptyString(), false, false);
-}
-
-void ContentSecurityPolicy::applyPolicyToScriptExecutionContext()
-{
- ASSERT(m_scriptExecutionContext);
-
- // Update source self as the security origin may have changed between the time we were created and now.
- // For instance, we may have been initially created for an about:blank iframe that later inherited the
- // security origin of its owner document.
- ASSERT(m_scriptExecutionContext->securityOrigin());
- updateSourceSelf(*m_scriptExecutionContext->securityOrigin());
-
- if (!m_lastPolicyEvalDisabledErrorMessage.isNull())
- m_scriptExecutionContext->disableEval(m_lastPolicyEvalDisabledErrorMessage);
- if (m_sandboxFlags != SandboxNone && is<Document>(m_scriptExecutionContext))
- m_scriptExecutionContext->enforceSandboxFlags(m_sandboxFlags);
-}
-
-void ContentSecurityPolicy::setOverrideAllowInlineStyle(bool value)
-{
- m_overrideInlineStyleAllowed = value;
-}
-
-bool ContentSecurityPolicy::urlMatchesSelf(const URL& url) const
-{
- return m_selfSource->matches(url);
-}
-
-bool ContentSecurityPolicy::protocolMatchesSelf(const URL& url) const
-{
- if (equalLettersIgnoringASCIICase(m_selfSourceProtocol, "http"))
- return url.protocolIsInHTTPFamily();
- return equalIgnoringASCIICase(url.protocol(), m_selfSourceProtocol);
-}
-
-template<bool (ContentSecurityPolicyDirectiveList::*allowed)(ContentSecurityPolicy::ReportingStatus) const>
-bool isAllowedByAll(const CSPDirectiveListVector& policies, ContentSecurityPolicy::ReportingStatus reportingStatus)
-{
- for (auto& policy : policies) {
- if (!(policy.get()->*allowed)(reportingStatus))
- return false;
- }
- return true;
-}
-
-template<bool (ContentSecurityPolicyDirectiveList::*allowed)(JSC::ExecState* state, ContentSecurityPolicy::ReportingStatus) const>
-bool isAllowedByAllWithState(const CSPDirectiveListVector& policies, JSC::ExecState* state, ContentSecurityPolicy::ReportingStatus reportingStatus)
-{
- for (auto& policy : policies) {
- if (!(policy.get()->*allowed)(state, reportingStatus))
- return false;
- }
- return true;
-}
-
-template<bool (ContentSecurityPolicyDirectiveList::*allowed)(const String&, const WTF::OrdinalNumber&, ContentSecurityPolicy::ReportingStatus) const>
-bool isAllowedByAllWithContext(const CSPDirectiveListVector& policies, const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStatus)
-{
- for (auto& policy : policies) {
- if (!(policy.get()->*allowed)(contextURL, contextLine, reportingStatus))
- return false;
- }
- return true;
-}
-
-template<bool (ContentSecurityPolicyDirectiveList::*allowFromURL)(const URL&, ContentSecurityPolicy::ReportingStatus) const>
-bool isAllowedByAllWithURL(const CSPDirectiveListVector& policies, const URL& url, ContentSecurityPolicy::ReportingStatus reportingStatus)
-{
- if (SchemeRegistry::schemeShouldBypassContentSecurityPolicy(url.protocol()))
- return true;
-
- for (auto& policy : policies) {
- if (!(policy.get()->*allowFromURL)(url, reportingStatus))
- return false;
- }
- return true;
-}
-
-bool ContentSecurityPolicy::allowJavaScriptURLs(const String& contextURL, const WTF::OrdinalNumber& contextLine, bool overrideContentSecurityPolicy, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- return overrideContentSecurityPolicy || isAllowedByAllWithContext<&ContentSecurityPolicyDirectiveList::allowJavaScriptURLs>(m_policies, contextURL, contextLine, reportingStatus);
-}
-
-bool ContentSecurityPolicy::allowInlineEventHandlers(const String& contextURL, const WTF::OrdinalNumber& contextLine, bool overrideContentSecurityPolicy, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- return overrideContentSecurityPolicy || isAllowedByAllWithContext<&ContentSecurityPolicyDirectiveList::allowInlineEventHandlers>(m_policies, contextURL, contextLine, reportingStatus);
-}
-
-bool ContentSecurityPolicy::allowInlineScript(const String& contextURL, const WTF::OrdinalNumber& contextLine, bool overrideContentSecurityPolicy, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- return overrideContentSecurityPolicy || isAllowedByAllWithContext<&ContentSecurityPolicyDirectiveList::allowInlineScript>(m_policies, contextURL, contextLine, reportingStatus);
-}
-
-bool ContentSecurityPolicy::allowInlineStyle(const String& contextURL, const WTF::OrdinalNumber& contextLine, bool overrideContentSecurityPolicy, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- return overrideContentSecurityPolicy || m_overrideInlineStyleAllowed || isAllowedByAllWithContext<&ContentSecurityPolicyDirectiveList::allowInlineStyle>(m_policies, contextURL, contextLine, reportingStatus);
-}
-
-bool ContentSecurityPolicy::allowEval(JSC::ExecState* state, bool overrideContentSecurityPolicy, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- return overrideContentSecurityPolicy || isAllowedByAllWithState<&ContentSecurityPolicyDirectiveList::allowEval>(m_policies, state, reportingStatus);
-}
-
-String ContentSecurityPolicy::evalDisabledErrorMessage() const
-{
- for (auto& policy : m_policies) {
- if (!policy->allowEval(0, ContentSecurityPolicy::ReportingStatus::SuppressReport))
- return policy->evalDisabledErrorMessage();
- }
- return String();
-}
-
-bool ContentSecurityPolicy::allowPluginType(const String& type, const String& typeAttribute, const URL& url, bool overrideContentSecurityPolicy, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- if (overrideContentSecurityPolicy)
- return true;
- for (auto& policy : m_policies) {
- if (!policy->allowPluginType(type, typeAttribute, url, reportingStatus))
- return false;
- }
- return true;
-}
-
-bool ContentSecurityPolicy::allowScriptFromSource(const URL& url, bool overrideContentSecurityPolicy, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- return overrideContentSecurityPolicy || isAllowedByAllWithURL<&ContentSecurityPolicyDirectiveList::allowScriptFromSource>(m_policies, url, reportingStatus);
-}
-
-bool ContentSecurityPolicy::allowObjectFromSource(const URL& url, bool overrideContentSecurityPolicy, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- return overrideContentSecurityPolicy || isAllowedByAllWithURL<&ContentSecurityPolicyDirectiveList::allowObjectFromSource>(m_policies, url, reportingStatus);
-}
-
-bool ContentSecurityPolicy::allowChildFrameFromSource(const URL& url, bool overrideContentSecurityPolicy, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- return overrideContentSecurityPolicy || isAllowedByAllWithURL<&ContentSecurityPolicyDirectiveList::allowChildFrameFromSource>(m_policies, url, reportingStatus);
-}
-
-bool ContentSecurityPolicy::allowChildContextFromSource(const URL& url, bool overrideContentSecurityPolicy, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- return overrideContentSecurityPolicy || isAllowedByAllWithURL<&ContentSecurityPolicyDirectiveList::allowChildContextFromSource>(m_policies, url, reportingStatus);
-}
-
-bool ContentSecurityPolicy::allowImageFromSource(const URL& url, bool overrideContentSecurityPolicy, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- return overrideContentSecurityPolicy || isAllowedByAllWithURL<&ContentSecurityPolicyDirectiveList::allowImageFromSource>(m_policies, url, reportingStatus);
-}
-
-bool ContentSecurityPolicy::allowStyleFromSource(const URL& url, bool overrideContentSecurityPolicy, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- return overrideContentSecurityPolicy || isAllowedByAllWithURL<&ContentSecurityPolicyDirectiveList::allowStyleFromSource>(m_policies, url, reportingStatus);
-}
-
-bool ContentSecurityPolicy::allowFontFromSource(const URL& url, bool overrideContentSecurityPolicy, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- return overrideContentSecurityPolicy || isAllowedByAllWithURL<&ContentSecurityPolicyDirectiveList::allowFontFromSource>(m_policies, url, reportingStatus);
-}
-
-bool ContentSecurityPolicy::allowMediaFromSource(const URL& url, bool overrideContentSecurityPolicy, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- return overrideContentSecurityPolicy || isAllowedByAllWithURL<&ContentSecurityPolicyDirectiveList::allowMediaFromSource>(m_policies, url, reportingStatus);
-}
-
-bool ContentSecurityPolicy::allowConnectToSource(const URL& url, bool overrideContentSecurityPolicy, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- return overrideContentSecurityPolicy || isAllowedByAllWithURL<&ContentSecurityPolicyDirectiveList::allowConnectToSource>(m_policies, url, reportingStatus);
-}
-
-bool ContentSecurityPolicy::allowFormAction(const URL& url, bool overrideContentSecurityPolicy, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- return overrideContentSecurityPolicy || isAllowedByAllWithURL<&ContentSecurityPolicyDirectiveList::allowFormAction>(m_policies, url, reportingStatus);
-}
-
-bool ContentSecurityPolicy::allowBaseURI(const URL& url, bool overrideContentSecurityPolicy, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- return overrideContentSecurityPolicy || isAllowedByAllWithURL<&ContentSecurityPolicyDirectiveList::allowBaseURI>(m_policies, url, reportingStatus);
-}
-
-bool ContentSecurityPolicy::isActive() const
-{
- return !m_policies.isEmpty();
-}
-
-ContentSecurityPolicy::ReflectedXSSDisposition ContentSecurityPolicy::reflectedXSSDisposition() const
-{
- ReflectedXSSDisposition disposition = ReflectedXSSUnset;
- for (auto& policy : m_policies) {
- if (policy->reflectedXSSDisposition() > disposition)
- disposition = std::max(disposition, policy->reflectedXSSDisposition());
- }
- return disposition;
-}
-
-void ContentSecurityPolicy::gatherReportURIs(DOMStringList& list) const
-{
- ASSERT(m_scriptExecutionContext);
- for (auto& policy : m_policies) {
- for (auto& url : policy->reportURIs())
- list.append(m_scriptExecutionContext->completeURL(url).string());
- }
-}
-
-static String stripURLForUseInReport(Document& document, const URL& url)
-{
- if (!url.isValid())
- return String();
- if (!url.isHierarchical() || url.protocolIs("file"))
- return url.protocol();
- return document.securityOrigin()->canRequest(url) ? url.strippedForUseAsReferrer() : SecurityOrigin::create(url).get().toString();
-}
-
-void ContentSecurityPolicy::reportViolation(const String& directiveText, const String& effectiveDirective, const String& consoleMessage, const URL& blockedURL, const Vector<String>& reportURIs, const String& header, const String& contextURL, const WTF::OrdinalNumber& contextLine, JSC::ExecState* state) const
-{
- logToConsole(consoleMessage, contextURL, contextLine, state);
-
- // FIXME: Support sending reports from worker.
- if (!is<Document>(m_scriptExecutionContext))
- return;
-
- Document& document = downcast<Document>(*m_scriptExecutionContext);
- Frame* frame = document.frame();
- if (!frame)
- return;
-
- String documentURI = document.url().strippedForUseAsReferrer();
- String referrer = document.referrer();
- String blockedURI = stripURLForUseInReport(document, blockedURL);
- String violatedDirective = directiveText;
- String originalPolicy = header;
- ASSERT(document.loader());
- unsigned short statusCode = document.url().protocolIs("http") && document.loader() ? document.loader()->response().httpStatusCode() : 0;
-
- String sourceFile;
- int lineNumber = 0;
- int columnNumber = 0;
- RefPtr<ScriptCallStack> stack = createScriptCallStack(JSMainThreadExecState::currentState(), 2);
- const ScriptCallFrame* callFrame = stack->firstNonNativeCallFrame();
- if (callFrame && callFrame->lineNumber()) {
- sourceFile = stripURLForUseInReport(document, URL(URL(), callFrame->sourceURL()));
- lineNumber = callFrame->lineNumber();
- columnNumber = callFrame->columnNumber();
- }
-
- // 1. Dispatch violation event.
- bool canBubble = false;
- bool cancelable = false;
- document.enqueueDocumentEvent(SecurityPolicyViolationEvent::create(eventNames().securitypolicyviolationEvent, canBubble, cancelable, documentURI, referrer, blockedURI, violatedDirective, effectiveDirective, originalPolicy, sourceFile, statusCode, lineNumber, columnNumber));
-
- // 2. Send violation report (if applicable).
- if (reportURIs.isEmpty())
- return;
-
- // We need to be careful here when deciding what information to send to the
- // report-uri. Currently, we send only the current document's URL and the
- // directive that was violated. The document's URL is safe to send because
- // it's the document itself that's requesting that it be sent. You could
- // make an argument that we shouldn't send HTTPS document URLs to HTTP
- // report-uris (for the same reasons that we suppress the Referer in that
- // case), but the Referer is sent implicitly whereas this request is only
- // sent explicitly. As for which directive was violated, that's pretty
- // harmless information.
-
- RefPtr<InspectorObject> cspReport = InspectorObject::create();
- cspReport->setString(ASCIILiteral("document-uri"), documentURI);
- cspReport->setString(ASCIILiteral("referrer"), referrer);
- cspReport->setString(ASCIILiteral("violated-directive"), directiveText);
- cspReport->setString(ASCIILiteral("effective-directive"), effectiveDirective);
- cspReport->setString(ASCIILiteral("original-policy"), originalPolicy);
- cspReport->setString(ASCIILiteral("blocked-uri"), blockedURI);
- cspReport->setInteger(ASCIILiteral("status-code"), statusCode);
- if (!sourceFile.isNull()) {
- cspReport->setString(ASCIILiteral("source-file"), sourceFile);
- cspReport->setInteger(ASCIILiteral("line-number"), lineNumber);
- cspReport->setInteger(ASCIILiteral("column-number"), columnNumber);
- }
-
- RefPtr<InspectorObject> reportObject = InspectorObject::create();
- reportObject->setObject(ASCIILiteral("csp-report"), cspReport.release());
-
- RefPtr<FormData> report = FormData::create(reportObject->toJSONString().utf8());
- for (const auto& url : reportURIs)
- PingLoader::sendViolationReport(*frame, document.completeURL(url), report.copyRef(), ViolationReportType::ContentSecurityPolicy);
-}
-
-void ContentSecurityPolicy::reportUnsupportedDirective(const String& name) const
-{
- String message;
- if (equalLettersIgnoringASCIICase(name, "allow"))
- message = ASCIILiteral("The 'allow' directive has been replaced with 'default-src'. Please use that directive instead, as 'allow' has no effect.");
- else if (equalLettersIgnoringASCIICase(name, "options"))
- message = ASCIILiteral("The 'options' directive has been replaced with 'unsafe-inline' and 'unsafe-eval' source expressions for the 'script-src' and 'style-src' directives. Please use those directives instead, as 'options' has no effect.");
- else if (equalLettersIgnoringASCIICase(name, "policy-uri"))
- message = ASCIILiteral("The 'policy-uri' directive has been removed from the specification. Please specify a complete policy via the Content-Security-Policy header.");
- else
- message = makeString("Unrecognized Content-Security-Policy directive '", name, "'.\n"); // FIXME: Why does this include a newline?
-
- logToConsole(message);
-}
-
-void ContentSecurityPolicy::reportDirectiveAsSourceExpression(const String& directiveName, const String& sourceExpression) const
-{
- logToConsole("The Content Security Policy directive '" + directiveName + "' contains '" + sourceExpression + "' as a source expression. Did you mean '" + directiveName + " ...; " + sourceExpression + "...' (note the semicolon)?");
-}
-
-void ContentSecurityPolicy::reportDuplicateDirective(const String& name) const
-{
- logToConsole(makeString("Ignoring duplicate Content-Security-Policy directive '", name, "'.\n"));
-}
-
-void ContentSecurityPolicy::reportInvalidPluginTypes(const String& pluginType) const
-{
- String message;
- if (pluginType.isNull())
- message = "'plugin-types' Content Security Policy directive is empty; all plugins will be blocked.\n";
- else
- message = makeString("Invalid plugin type in 'plugin-types' Content Security Policy directive: '", pluginType, "'.\n");
- logToConsole(message);
-}
-
-void ContentSecurityPolicy::reportInvalidSandboxFlags(const String& invalidFlags) const
-{
- logToConsole("Error while parsing the 'sandbox' Content Security Policy directive: " + invalidFlags);
-}
-
-void ContentSecurityPolicy::reportInvalidReflectedXSS(const String& invalidValue) const
-{
- logToConsole("The 'reflected-xss' Content Security Policy directive has the invalid value \"" + invalidValue + "\". Value values are \"allow\", \"filter\", and \"block\".");
-}
-
-void ContentSecurityPolicy::reportInvalidDirectiveInReportOnlyMode(const String& directiveName) const
-{
- logToConsole("The Content Security Policy directive '" + directiveName + "' is ignored when delivered in a report-only policy.");
-}
-
-void ContentSecurityPolicy::reportInvalidDirectiveInHTTPEquivMeta(const String& directiveName) const
-{
- logToConsole("The Content Security Policy directive '" + directiveName + "' is ignored when delivered via an HTML meta element.");
-}
-
-void ContentSecurityPolicy::reportInvalidDirectiveValueCharacter(const String& directiveName, const String& value) const
-{
- String message = makeString("The value for Content Security Policy directive '", directiveName, "' contains an invalid character: '", value, "'. Non-whitespace characters outside ASCII 0x21-0x7E must be percent-encoded, as described in RFC 3986, section 2.1: http://tools.ietf.org/html/rfc3986#section-2.1.");
- logToConsole(message);
-}
-
-void ContentSecurityPolicy::reportInvalidPathCharacter(const String& directiveName, const String& value, const char invalidChar) const
-{
- ASSERT(invalidChar == '#' || invalidChar == '?');
-
- String ignoring;
- if (invalidChar == '?')
- ignoring = "The query component, including the '?', will be ignored.";
- else
- ignoring = "The fragment identifier, including the '#', will be ignored.";
-
- String message = makeString("The source list for Content Security Policy directive '", directiveName, "' contains a source with an invalid path: '", value, "'. ", ignoring);
- logToConsole(message);
-}
-
-void ContentSecurityPolicy::reportInvalidSourceExpression(const String& directiveName, const String& source) const
-{
- String message = makeString("The source list for Content Security Policy directive '", directiveName, "' contains an invalid source: '", source, "'. It will be ignored.");
- if (equalLettersIgnoringASCIICase(source, "'none'"))
- message = makeString(message, " Note that 'none' has no effect unless it is the only expression in the source list.");
- logToConsole(message);
-}
-
-void ContentSecurityPolicy::reportMissingReportURI(const String& policy) const
-{
- logToConsole("The Content Security Policy '" + policy + "' was delivered in report-only mode, but does not specify a 'report-uri'; the policy will have no effect. Please either add a 'report-uri' directive, or deliver the policy via the 'Content-Security-Policy' header.");
-}
-
-void ContentSecurityPolicy::logToConsole(const String& message, const String& contextURL, const WTF::OrdinalNumber& contextLine, JSC::ExecState* state) const
-{
- // FIXME: <http://webkit.org/b/114317> ContentSecurityPolicy::logToConsole should include a column number
- if (m_scriptExecutionContext)
- m_scriptExecutionContext->addConsoleMessage(MessageSource::Security, MessageLevel::Error, message, contextURL, contextLine.oneBasedInt(), 0, state);
-}
-
-void ContentSecurityPolicy::reportBlockedScriptExecutionToInspector(const String& directiveText) const
-{
- if (m_scriptExecutionContext)
- InspectorInstrumentation::scriptExecutionBlockedByCSP(m_scriptExecutionContext, directiveText);
-}
-
-bool ContentSecurityPolicy::experimentalFeaturesEnabled() const
-{
-#if ENABLE(CSP_NEXT)
- return RuntimeEnabledFeatures::sharedFeatures().experimentalContentSecurityPolicyFeaturesEnabled();
-#else
- return false;
-#endif
-}
-
-}
diff --git a/Source/WebCore/page/csp/ContentSecurityPolicy.h b/Source/WebCore/page/csp/ContentSecurityPolicy.h
deleted file mode 100644
index 14c60f5c4..000000000
--- a/Source/WebCore/page/csp/ContentSecurityPolicy.h
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Copyright (C) 2011 Google, Inc. All rights reserved.
- * Copyright (C) 2016 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef ContentSecurityPolicy_h
-#define ContentSecurityPolicy_h
-
-#include "ContentSecurityPolicyResponseHeaders.h"
-#include "ScriptState.h"
-#include <wtf/Vector.h>
-#include <wtf/text/TextPosition.h>
-
-namespace WTF {
-class OrdinalNumber;
-}
-
-namespace WebCore {
-
-class ContentSecurityPolicyDirectiveList;
-class ContentSecurityPolicySource;
-class DOMStringList;
-class ScriptExecutionContext;
-class SecurityOrigin;
-class URL;
-
-typedef Vector<std::unique_ptr<ContentSecurityPolicyDirectiveList>> CSPDirectiveListVector;
-typedef int SandboxFlags;
-
-class ContentSecurityPolicy {
- WTF_MAKE_FAST_ALLOCATED;
-public:
- explicit ContentSecurityPolicy(ScriptExecutionContext&);
- explicit ContentSecurityPolicy(const SecurityOrigin&);
- ~ContentSecurityPolicy();
-
- void copyStateFrom(const ContentSecurityPolicy*);
-
- // Be sure to update the behavior of XSSAuditor::combineXSSProtectionHeaderAndCSP whenever you change this enum's content or ordering.
- enum ReflectedXSSDisposition {
- ReflectedXSSUnset = 0,
- AllowReflectedXSS,
- ReflectedXSSInvalid,
- FilterReflectedXSS,
- BlockReflectedXSS
- };
- ReflectedXSSDisposition reflectedXSSDisposition() const;
-
- enum class PolicyFrom {
- HTTPEquivMeta,
- HTTPHeader,
- Inherited,
- };
- ContentSecurityPolicyResponseHeaders responseHeaders() const;
- void didReceiveHeaders(const ContentSecurityPolicyResponseHeaders&);
- void processHTTPEquiv(const String& content, ContentSecurityPolicyHeaderType type) { didReceiveHeader(content, type, ContentSecurityPolicy::PolicyFrom::HTTPEquivMeta); }
-
- enum class ReportingStatus {
- SendReport,
- SuppressReport
- };
- bool allowJavaScriptURLs(const String& contextURL, const WTF::OrdinalNumber& contextLine, bool overrideContentSecurityPolicy = false, ContentSecurityPolicy::ReportingStatus = ContentSecurityPolicy::ReportingStatus::SendReport) const;
- bool allowInlineEventHandlers(const String& contextURL, const WTF::OrdinalNumber& contextLine, bool overrideContentSecurityPolicy = false, ContentSecurityPolicy::ReportingStatus = ContentSecurityPolicy::ReportingStatus::SendReport) const;
- bool allowInlineScript(const String& contextURL, const WTF::OrdinalNumber& contextLine, bool overrideContentSecurityPolicy = false, ContentSecurityPolicy::ReportingStatus = ContentSecurityPolicy::ReportingStatus::SendReport) const;
- bool allowInlineStyle(const String& contextURL, const WTF::OrdinalNumber& contextLine, bool overrideContentSecurityPolicy = false, ContentSecurityPolicy::ReportingStatus = ContentSecurityPolicy::ReportingStatus::SendReport) const;
- bool allowEval(JSC::ExecState* = nullptr, bool overrideContentSecurityPolicy = false, ContentSecurityPolicy::ReportingStatus = ContentSecurityPolicy::ReportingStatus::SendReport) const;
- bool allowPluginType(const String& type, const String& typeAttribute, const URL&, bool overrideContentSecurityPolicy = false, ContentSecurityPolicy::ReportingStatus = ContentSecurityPolicy::ReportingStatus::SendReport) const;
- bool allowScriptFromSource(const URL&, bool overrideContentSecurityPolicy = false, ContentSecurityPolicy::ReportingStatus = ContentSecurityPolicy::ReportingStatus::SendReport) const;
- bool allowObjectFromSource(const URL&, bool overrideContentSecurityPolicy = false, ContentSecurityPolicy::ReportingStatus = ContentSecurityPolicy::ReportingStatus::SendReport) const;
- bool allowChildFrameFromSource(const URL&, bool overrideContentSecurityPolicy = false, ContentSecurityPolicy::ReportingStatus = ContentSecurityPolicy::ReportingStatus::SendReport) const;
- bool allowChildContextFromSource(const URL&, bool overrideContentSecurityPolicy = false, ContentSecurityPolicy::ReportingStatus = ContentSecurityPolicy::ReportingStatus::SendReport) const;
- bool allowImageFromSource(const URL&, bool overrideContentSecurityPolicy = false, ContentSecurityPolicy::ReportingStatus = ContentSecurityPolicy::ReportingStatus::SendReport) const;
- bool allowStyleFromSource(const URL&, bool overrideContentSecurityPolicy = false, ContentSecurityPolicy::ReportingStatus = ContentSecurityPolicy::ReportingStatus::SendReport) const;
- bool allowFontFromSource(const URL&, bool overrideContentSecurityPolicy = false, ContentSecurityPolicy::ReportingStatus = ContentSecurityPolicy::ReportingStatus::SendReport) const;
- bool allowMediaFromSource(const URL&, bool overrideContentSecurityPolicy = false, ContentSecurityPolicy::ReportingStatus = ContentSecurityPolicy::ReportingStatus::SendReport) const;
- bool allowConnectToSource(const URL&, bool overrideContentSecurityPolicy = false, ContentSecurityPolicy::ReportingStatus = ContentSecurityPolicy::ReportingStatus::SendReport) const;
- bool allowFormAction(const URL&, bool overrideContentSecurityPolicy = false, ContentSecurityPolicy::ReportingStatus = ContentSecurityPolicy::ReportingStatus::SendReport) const;
- bool allowBaseURI(const URL&, bool overrideContentSecurityPolicy = false, ContentSecurityPolicy::ReportingStatus = ContentSecurityPolicy::ReportingStatus::SendReport) const;
-
- void setOverrideAllowInlineStyle(bool);
-
- bool isActive() const;
-
- void gatherReportURIs(DOMStringList&) const;
-
- String evalDisabledErrorMessage() const;
-
- bool experimentalFeaturesEnabled() const;
-
- // The following functions are used by internal data structures to call back into this object when parsing, validating,
- // and applying a Content Security Policy.
- // FIXME: We should make the various directives serve only as state stores for the parsed policy and remove these functions.
- // This class should traverse the directives, validating the policy, and applying it to the script execution context.
-
- // Used by ContentSecurityPolicyMediaListDirective
- void reportInvalidPluginTypes(const String&) const;
-
- // Used by ContentSecurityPolicySourceList
- void reportDirectiveAsSourceExpression(const String& directiveName, const String& sourceExpression) const;
- void reportInvalidPathCharacter(const String& directiveName, const String& value, const char) const;
- void reportInvalidSourceExpression(const String& directiveName, const String& source) const;
- bool urlMatchesSelf(const URL&) const;
-
- // Used by ContentSecurityPolicyDirectiveList
- void reportDuplicateDirective(const String&) const;
- void reportInvalidDirectiveValueCharacter(const String& directiveName, const String& value) const;
- void reportInvalidSandboxFlags(const String&) const;
- void reportInvalidReflectedXSS(const String&) const;
- void reportInvalidDirectiveInReportOnlyMode(const String&) const;
- void reportInvalidDirectiveInHTTPEquivMeta(const String&) const;
- void reportMissingReportURI(const String&) const;
- void reportUnsupportedDirective(const String&) const;
- void reportViolation(const String& directiveText, const String& effectiveDirective, const String& consoleMessage, const URL& blockedURL, const Vector<String>& reportURIs, const String& header, const String& contextURL = String(), const WTF::OrdinalNumber& contextLine = WTF::OrdinalNumber::beforeFirst(), JSC::ExecState* = nullptr) const;
- void reportBlockedScriptExecutionToInspector(const String& directiveText) const;
- void enforceSandboxFlags(SandboxFlags sandboxFlags) { m_sandboxFlags |= sandboxFlags; }
-
- // Used by ContentSecurityPolicySource
- bool protocolMatchesSelf(const URL&) const;
-
-private:
- void logToConsole(const String& message, const String& contextURL = String(), const WTF::OrdinalNumber& contextLine = WTF::OrdinalNumber::beforeFirst(), JSC::ExecState* = nullptr) const;
- void updateSourceSelf(const SecurityOrigin&);
- void applyPolicyToScriptExecutionContext();
-
- void didReceiveHeader(const String&, ContentSecurityPolicyHeaderType, ContentSecurityPolicy::PolicyFrom);
-
- ScriptExecutionContext* m_scriptExecutionContext { nullptr };
- std::unique_ptr<ContentSecurityPolicySource> m_selfSource;
- String m_selfSourceProtocol;
- CSPDirectiveListVector m_policies;
- String m_lastPolicyEvalDisabledErrorMessage;
- SandboxFlags m_sandboxFlags;
- bool m_overrideInlineStyleAllowed { false };
-};
-
-}
-
-#endif
diff --git a/Source/WebCore/page/csp/ContentSecurityPolicyDirectiveList.cpp b/Source/WebCore/page/csp/ContentSecurityPolicyDirectiveList.cpp
deleted file mode 100644
index 01cfa5134..000000000
--- a/Source/WebCore/page/csp/ContentSecurityPolicyDirectiveList.cpp
+++ /dev/null
@@ -1,624 +0,0 @@
-/*
- * Copyright (C) 2011 Google, Inc. All rights reserved.
- * Copyright (C) 2016 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "ContentSecurityPolicyDirectiveList.h"
-
-#include "ParsingUtilities.h"
-#include "SecurityContext.h"
-#include <wtf/NeverDestroyed.h>
-
-namespace WebCore {
-
-// CSP 1.0 Directives
-static const char connectSrc[] = "connect-src";
-static const char defaultSrc[] = "default-src";
-static const char fontSrc[] = "font-src";
-static const char frameSrc[] = "frame-src";
-static const char imgSrc[] = "img-src";
-static const char mediaSrc[] = "media-src";
-static const char objectSrc[] = "object-src";
-static const char reportURI[] = "report-uri";
-static const char sandbox[] = "sandbox";
-static const char scriptSrc[] = "script-src";
-static const char styleSrc[] = "style-src";
-
-// CSP 1.1 Directives
-static const char baseURI[] = "base-uri";
-static const char childSrc[] = "child-src";
-static const char formAction[] = "form-action";
-static const char pluginTypes[] = "plugin-types";
-#if ENABLE(CSP_NEXT)
-static const char reflectedXSS[] = "reflected-xss";
-#endif
-
-#if ENABLE(CSP_NEXT)
-
-static inline bool isExperimentalDirectiveName(const String& name)
-{
- return equalLettersIgnoringASCIICase(name, reflectedXSS);
-}
-
-#else
-
-static inline bool isExperimentalDirectiveName(const String&)
-{
- return false;
-}
-
-#endif
-
-bool isCSPDirectiveName(const String& name)
-{
- return equalLettersIgnoringASCIICase(name, baseURI)
- || equalLettersIgnoringASCIICase(name, connectSrc)
- || equalLettersIgnoringASCIICase(name, defaultSrc)
- || equalLettersIgnoringASCIICase(name, fontSrc)
- || equalLettersIgnoringASCIICase(name, formAction)
- || equalLettersIgnoringASCIICase(name, frameSrc)
- || equalLettersIgnoringASCIICase(name, imgSrc)
- || equalLettersIgnoringASCIICase(name, mediaSrc)
- || equalLettersIgnoringASCIICase(name, objectSrc)
- || equalLettersIgnoringASCIICase(name, pluginTypes)
- || equalLettersIgnoringASCIICase(name, reportURI)
- || equalLettersIgnoringASCIICase(name, sandbox)
- || equalLettersIgnoringASCIICase(name, scriptSrc)
- || equalLettersIgnoringASCIICase(name, styleSrc)
- || isExperimentalDirectiveName(name);
-}
-
-static bool isDirectiveNameCharacter(UChar c)
-{
- return isASCIIAlphanumeric(c) || c == '-';
-}
-
-static bool isDirectiveValueCharacter(UChar c)
-{
- return isASCIISpace(c) || (c >= 0x21 && c <= 0x7e); // Whitespace + VCHAR
-}
-
-static bool isNotASCIISpace(UChar c)
-{
- return !isASCIISpace(c);
-}
-
-ContentSecurityPolicyDirectiveList::ContentSecurityPolicyDirectiveList(ContentSecurityPolicy& policy, ContentSecurityPolicyHeaderType type)
- : m_policy(policy)
- , m_headerType(type)
- , m_reportOnly(false)
- , m_haveSandboxPolicy(false)
- , m_reflectedXSSDisposition(ContentSecurityPolicy::ReflectedXSSUnset)
-{
- m_reportOnly = (type == ContentSecurityPolicyHeaderType::Report || type == ContentSecurityPolicyHeaderType::PrefixedReport);
-}
-
-std::unique_ptr<ContentSecurityPolicyDirectiveList> ContentSecurityPolicyDirectiveList::create(ContentSecurityPolicy& policy, const String& header, ContentSecurityPolicyHeaderType type, ContentSecurityPolicy::PolicyFrom from)
-{
- auto directives = std::make_unique<ContentSecurityPolicyDirectiveList>(policy, type);
- directives->parse(header, from);
-
- if (!directives->checkEval(directives->operativeDirective(directives->m_scriptSrc.get()))) {
- String message = makeString("Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: \"", directives->operativeDirective(directives->m_scriptSrc.get())->text(), "\".\n");
- directives->setEvalDisabledErrorMessage(message);
- }
-
- if (directives->isReportOnly() && directives->reportURIs().isEmpty())
- policy.reportMissingReportURI(header);
-
- return directives;
-}
-
-void ContentSecurityPolicyDirectiveList::reportViolation(const String& directiveText, const String& effectiveDirective, const String& consoleMessage, const URL& blockedURL, const String& contextURL, const WTF::OrdinalNumber& contextLine, JSC::ExecState* state) const
-{
- String message = m_reportOnly ? "[Report Only] " + consoleMessage : consoleMessage;
- m_policy.reportViolation(directiveText, effectiveDirective, message, blockedURL, m_reportURIs, m_header, contextURL, contextLine, state);
-}
-
-bool ContentSecurityPolicyDirectiveList::checkEval(ContentSecurityPolicySourceListDirective* directive) const
-{
- return !directive || directive->allowEval();
-}
-
-bool ContentSecurityPolicyDirectiveList::checkInline(ContentSecurityPolicySourceListDirective* directive) const
-{
- return !directive || directive->allowInline();
-}
-
-bool ContentSecurityPolicyDirectiveList::checkSource(ContentSecurityPolicySourceListDirective* directive, const URL& url) const
-{
- return !directive || directive->allows(url);
-}
-
-bool ContentSecurityPolicyDirectiveList::checkMediaType(ContentSecurityPolicyMediaListDirective* directive, const String& type, const String& typeAttribute) const
-{
- if (!directive)
- return true;
- if (typeAttribute.isEmpty() || typeAttribute.stripWhiteSpace() != type)
- return false;
- return directive->allows(type);
-}
-
-ContentSecurityPolicySourceListDirective* ContentSecurityPolicyDirectiveList::operativeDirective(ContentSecurityPolicySourceListDirective* directive) const
-{
- return directive ? directive : m_defaultSrc.get();
-}
-
-bool ContentSecurityPolicyDirectiveList::checkEvalAndReportViolation(ContentSecurityPolicySourceListDirective* directive, const String& consoleMessage, const String& contextURL, const WTF::OrdinalNumber& contextLine, JSC::ExecState* state) const
-{
- if (checkEval(directive))
- return true;
-
- String suffix = String();
- if (directive == m_defaultSrc.get())
- suffix = " Note that 'script-src' was not explicitly set, so 'default-src' is used as a fallback.";
-
- reportViolation(directive->text(), scriptSrc, consoleMessage + "\"" + directive->text() + "\"." + suffix + "\n", URL(), contextURL, contextLine, state);
- if (!m_reportOnly) {
- m_policy.reportBlockedScriptExecutionToInspector(directive->text());
- return false;
- }
- return true;
-}
-
-bool ContentSecurityPolicyDirectiveList::checkMediaTypeAndReportViolation(ContentSecurityPolicyMediaListDirective* directive, const String& type, const String& typeAttribute, const String& consoleMessage) const
-{
- if (checkMediaType(directive, type, typeAttribute))
- return true;
-
- String message = makeString(consoleMessage, '\'', directive->text(), "\'.");
- if (typeAttribute.isEmpty())
- message = message + " When enforcing the 'plugin-types' directive, the plugin's media type must be explicitly declared with a 'type' attribute on the containing element (e.g. '<object type=\"[TYPE GOES HERE]\" ...>').";
-
- reportViolation(directive->text(), pluginTypes, message + "\n", URL());
- return denyIfEnforcingPolicy();
-}
-
-bool ContentSecurityPolicyDirectiveList::checkInlineAndReportViolation(ContentSecurityPolicySourceListDirective* directive, const String& consoleMessage, const String& contextURL, const WTF::OrdinalNumber& contextLine, bool isScript) const
-{
- if (checkInline(directive))
- return true;
-
- String suffix = String();
- if (directive == m_defaultSrc.get())
- suffix = makeString(" Note that '", (isScript ? "script" : "style"), "-src' was not explicitly set, so 'default-src' is used as a fallback.");
-
- reportViolation(directive->text(), isScript ? scriptSrc : styleSrc, consoleMessage + "\"" + directive->text() + "\"." + suffix + "\n", URL(), contextURL, contextLine);
-
- if (!m_reportOnly) {
- if (isScript)
- m_policy.reportBlockedScriptExecutionToInspector(directive->text());
- return false;
- }
- return true;
-}
-
-bool ContentSecurityPolicyDirectiveList::checkSourceAndReportViolation(ContentSecurityPolicySourceListDirective* directive, const URL& url, const String& effectiveDirective) const
-{
- if (checkSource(directive, url))
- return true;
-
- const char* prefix;
- if (baseURI == effectiveDirective)
- prefix = "Refused to set the document's base URI to '";
- else if (childSrc == effectiveDirective)
- prefix = "Refused to create a child context containing '";
- else if (connectSrc == effectiveDirective)
- prefix = "Refused to connect to '";
- else if (fontSrc == effectiveDirective)
- prefix = "Refused to load the font '";
- else if (formAction == effectiveDirective)
- prefix = "Refused to send form data to '";
- else if (frameSrc == effectiveDirective)
- prefix = "Refused to load frame '";
- else if (imgSrc == effectiveDirective)
- prefix = "Refused to load the image '";
- else if (mediaSrc == effectiveDirective)
- prefix = "Refused to load media from '";
- else if (objectSrc == effectiveDirective)
- prefix = "Refused to load plugin data from '";
- else if (scriptSrc == effectiveDirective)
- prefix = "Refused to load the script '";
- else if (styleSrc == effectiveDirective)
- prefix = "Refused to load the stylesheet '";
- else
- prefix = "";
-
- String suffix;
- if (directive == m_defaultSrc.get())
- suffix = " Note that '" + effectiveDirective + "' was not explicitly set, so 'default-src' is used as a fallback.";
-
- reportViolation(directive->text(), effectiveDirective, makeString(prefix, url.stringCenterEllipsizedToLength(), "' because it violates the following Content Security Policy directive: \"", directive->text(), "\".", suffix, '\n'), url);
- return denyIfEnforcingPolicy();
-}
-
-bool ContentSecurityPolicyDirectiveList::allowJavaScriptURLs(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- static NeverDestroyed<String> consoleMessage(ASCIILiteral("Refused to execute JavaScript URL because it violates the following Content Security Policy directive: "));
- if (reportingStatus == ContentSecurityPolicy::ReportingStatus::SendReport)
- return checkInlineAndReportViolation(operativeDirective(m_scriptSrc.get()), consoleMessage, contextURL, contextLine, true);
- return m_reportOnly || checkInline(operativeDirective(m_scriptSrc.get()));
-}
-
-bool ContentSecurityPolicyDirectiveList::allowInlineEventHandlers(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- static NeverDestroyed<String> consoleMessage(ASCIILiteral("Refused to execute inline event handler because it violates the following Content Security Policy directive: "));
- if (reportingStatus == ContentSecurityPolicy::ReportingStatus::SendReport)
- return checkInlineAndReportViolation(operativeDirective(m_scriptSrc.get()), consoleMessage, contextURL, contextLine, true);
- return m_reportOnly || checkInline(operativeDirective(m_scriptSrc.get()));
-}
-
-bool ContentSecurityPolicyDirectiveList::allowInlineScript(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- static NeverDestroyed<String> consoleMessage(ASCIILiteral("Refused to execute inline script because it violates the following Content Security Policy directive: "));
- if (reportingStatus == ContentSecurityPolicy::ReportingStatus::SendReport)
- return checkInlineAndReportViolation(operativeDirective(m_scriptSrc.get()), consoleMessage, contextURL, contextLine, true);
- return m_reportOnly || checkInline(operativeDirective(m_scriptSrc.get()));
-}
-
-bool ContentSecurityPolicyDirectiveList::allowInlineStyle(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- static NeverDestroyed<String> consoleMessage(ASCIILiteral("Refused to apply inline style because it violates the following Content Security Policy directive: "));
- if (reportingStatus == ContentSecurityPolicy::ReportingStatus::SendReport)
- return checkInlineAndReportViolation(operativeDirective(m_styleSrc.get()), consoleMessage, contextURL, contextLine, false);
- return m_reportOnly || checkInline(operativeDirective(m_styleSrc.get()));
-}
-
-bool ContentSecurityPolicyDirectiveList::allowEval(JSC::ExecState* state, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- static NeverDestroyed<String> consoleMessage(ASCIILiteral("Refused to evaluate script because it violates the following Content Security Policy directive: "));
- if (reportingStatus == ContentSecurityPolicy::ReportingStatus::SendReport)
- return checkEvalAndReportViolation(operativeDirective(m_scriptSrc.get()), consoleMessage, String(), WTF::OrdinalNumber::beforeFirst(), state);
- return m_reportOnly || checkEval(operativeDirective(m_scriptSrc.get()));
-}
-
-bool ContentSecurityPolicyDirectiveList::allowPluginType(const String& type, const String& typeAttribute, const URL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- if (reportingStatus == ContentSecurityPolicy::ReportingStatus::SendReport)
- return checkMediaTypeAndReportViolation(m_pluginTypes.get(), type, typeAttribute, "Refused to load '" + url.stringCenterEllipsizedToLength() + "' (MIME type '" + typeAttribute + "') because it violates the following Content Security Policy Directive: ");
- return m_reportOnly || checkMediaType(m_pluginTypes.get(), type, typeAttribute);
-}
-
-bool ContentSecurityPolicyDirectiveList::allowScriptFromSource(const URL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- if (reportingStatus == ContentSecurityPolicy::ReportingStatus::SendReport)
- return checkSourceAndReportViolation(operativeDirective(m_scriptSrc.get()), url, scriptSrc);
- return m_reportOnly || checkSource(operativeDirective(m_scriptSrc.get()), url);
-}
-
-bool ContentSecurityPolicyDirectiveList::allowObjectFromSource(const URL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- if (url.isBlankURL())
- return true;
- if (reportingStatus == ContentSecurityPolicy::ReportingStatus::SendReport)
- return checkSourceAndReportViolation(operativeDirective(m_objectSrc.get()), url, objectSrc);
- return m_reportOnly || checkSource(operativeDirective(m_objectSrc.get()), url);
-}
-
-bool ContentSecurityPolicyDirectiveList::allowChildContextFromSource(const URL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- if (reportingStatus == ContentSecurityPolicy::ReportingStatus::SendReport)
- return checkSourceAndReportViolation(operativeDirective(m_childSrc.get()), url, childSrc);
- return m_reportOnly || checkSource(operativeDirective(m_childSrc.get()), url);
-}
-
-bool ContentSecurityPolicyDirectiveList::allowChildFrameFromSource(const URL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- if (url.isBlankURL())
- return true;
-
- // We must enforce the frame-src directive (if specified) before enforcing the child-src directive for a nested browsing
- // context by <https://w3c.github.io/webappsec-csp/2/#directive-child-src-nested> (29 August 2015).
- ContentSecurityPolicySourceListDirective* directiveToEnforce = operativeDirective(m_frameSrc ? m_frameSrc.get() : m_childSrc.get());
- if (reportingStatus == ContentSecurityPolicy::ReportingStatus::SendReport)
- return checkSourceAndReportViolation(directiveToEnforce, url, frameSrc);
- return m_reportOnly || checkSource(directiveToEnforce, url);
-}
-
-bool ContentSecurityPolicyDirectiveList::allowImageFromSource(const URL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- if (reportingStatus == ContentSecurityPolicy::ReportingStatus::SendReport)
- return checkSourceAndReportViolation(operativeDirective(m_imgSrc.get()), url, imgSrc);
- return m_reportOnly || checkSource(operativeDirective(m_imgSrc.get()), url);
-}
-
-bool ContentSecurityPolicyDirectiveList::allowStyleFromSource(const URL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- if (reportingStatus == ContentSecurityPolicy::ReportingStatus::SendReport)
- return checkSourceAndReportViolation(operativeDirective(m_styleSrc.get()), url, styleSrc);
- return m_reportOnly || checkSource(operativeDirective(m_styleSrc.get()), url);
-}
-
-bool ContentSecurityPolicyDirectiveList::allowFontFromSource(const URL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- if (reportingStatus == ContentSecurityPolicy::ReportingStatus::SendReport)
- return checkSourceAndReportViolation(operativeDirective(m_fontSrc.get()), url, fontSrc);
- return m_reportOnly || checkSource(operativeDirective(m_fontSrc.get()), url);
-}
-
-bool ContentSecurityPolicyDirectiveList::allowMediaFromSource(const URL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- if (reportingStatus == ContentSecurityPolicy::ReportingStatus::SendReport)
- return checkSourceAndReportViolation(operativeDirective(m_mediaSrc.get()), url, mediaSrc);
- return m_reportOnly || checkSource(operativeDirective(m_mediaSrc.get()), url);
-}
-
-bool ContentSecurityPolicyDirectiveList::allowConnectToSource(const URL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- if (reportingStatus == ContentSecurityPolicy::ReportingStatus::SendReport)
- return checkSourceAndReportViolation(operativeDirective(m_connectSrc.get()), url, connectSrc);
- return m_reportOnly || checkSource(operativeDirective(m_connectSrc.get()), url);
-}
-
-bool ContentSecurityPolicyDirectiveList::allowFormAction(const URL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- if (reportingStatus == ContentSecurityPolicy::ReportingStatus::SendReport)
- return checkSourceAndReportViolation(m_formAction.get(), url, formAction);
- return m_reportOnly || checkSource(m_formAction.get(), url);
-}
-
-bool ContentSecurityPolicyDirectiveList::allowBaseURI(const URL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- if (reportingStatus == ContentSecurityPolicy::ReportingStatus::SendReport)
- return checkSourceAndReportViolation(m_baseURI.get(), url, baseURI);
- return m_reportOnly || checkSource(m_baseURI.get(), url);
-}
-
-// policy = directive-list
-// directive-list = [ directive *( ";" [ directive ] ) ]
-//
-void ContentSecurityPolicyDirectiveList::parse(const String& policy, ContentSecurityPolicy::PolicyFrom policyFrom)
-{
- m_header = policy;
- if (policy.isEmpty())
- return;
-
- auto characters = StringView(policy).upconvertedCharacters();
- const UChar* position = characters;
- const UChar* end = position + policy.length();
-
- while (position < end) {
- const UChar* directiveBegin = position;
- skipUntil<UChar>(position, end, ';');
-
- String name, value;
- if (parseDirective(directiveBegin, position, name, value)) {
- ASSERT(!name.isEmpty());
- switch (policyFrom) {
- case ContentSecurityPolicy::PolicyFrom::HTTPEquivMeta:
- if (equalLettersIgnoringASCIICase(name, sandbox) || equalLettersIgnoringASCIICase(name, reportURI)) {
- m_policy.reportInvalidDirectiveInHTTPEquivMeta(name);
- break;
- }
- FALLTHROUGH;
- default:
- addDirective(name, value);
- break;
- }
- }
-
- ASSERT(position == end || *position == ';');
- skipExactly<UChar>(position, end, ';');
- }
-}
-
-// directive = *WSP [ directive-name [ WSP directive-value ] ]
-// directive-name = 1*( ALPHA / DIGIT / "-" )
-// directive-value = *( WSP / <VCHAR except ";"> )
-//
-bool ContentSecurityPolicyDirectiveList::parseDirective(const UChar* begin, const UChar* end, String& name, String& value)
-{
- ASSERT(name.isEmpty());
- ASSERT(value.isEmpty());
-
- const UChar* position = begin;
- skipWhile<UChar, isASCIISpace>(position, end);
-
- // Empty directive (e.g. ";;;"). Exit early.
- if (position == end)
- return false;
-
- const UChar* nameBegin = position;
- skipWhile<UChar, isDirectiveNameCharacter>(position, end);
-
- // The directive-name must be non-empty.
- if (nameBegin == position) {
- skipWhile<UChar, isNotASCIISpace>(position, end);
- m_policy.reportUnsupportedDirective(String(nameBegin, position - nameBegin));
- return false;
- }
-
- name = String(nameBegin, position - nameBegin);
-
- if (position == end)
- return true;
-
- if (!skipExactly<UChar, isASCIISpace>(position, end)) {
- skipWhile<UChar, isNotASCIISpace>(position, end);
- m_policy.reportUnsupportedDirective(String(nameBegin, position - nameBegin));
- return false;
- }
-
- skipWhile<UChar, isASCIISpace>(position, end);
-
- const UChar* valueBegin = position;
- skipWhile<UChar, isDirectiveValueCharacter>(position, end);
-
- if (position != end) {
- m_policy.reportInvalidDirectiveValueCharacter(name, String(valueBegin, end - valueBegin));
- return false;
- }
-
- // The directive-value may be empty.
- if (valueBegin == position)
- return true;
-
- value = String(valueBegin, position - valueBegin);
- return true;
-}
-
-void ContentSecurityPolicyDirectiveList::parseReportURI(const String& name, const String& value)
-{
- if (!m_reportURIs.isEmpty()) {
- m_policy.reportDuplicateDirective(name);
- return;
- }
-
- auto characters = StringView(value).upconvertedCharacters();
- const UChar* position = characters;
- const UChar* end = position + value.length();
-
- while (position < end) {
- skipWhile<UChar, isASCIISpace>(position, end);
-
- const UChar* urlBegin = position;
- skipWhile<UChar, isNotASCIISpace>(position, end);
-
- if (urlBegin < position)
- m_reportURIs.append(value.substring(urlBegin - characters, position - urlBegin));
- }
-}
-
-
-template<class CSPDirectiveType>
-void ContentSecurityPolicyDirectiveList::setCSPDirective(const String& name, const String& value, std::unique_ptr<CSPDirectiveType>& directive)
-{
- if (directive) {
- m_policy.reportDuplicateDirective(name);
- return;
- }
- directive = std::make_unique<CSPDirectiveType>(name, value, m_policy);
-}
-
-void ContentSecurityPolicyDirectiveList::applySandboxPolicy(const String& name, const String& sandboxPolicy)
-{
- if (m_reportOnly) {
- m_policy.reportInvalidDirectiveInReportOnlyMode(name);
- return;
- }
- if (m_haveSandboxPolicy) {
- m_policy.reportDuplicateDirective(name);
- return;
- }
- m_haveSandboxPolicy = true;
- String invalidTokens;
- m_policy.enforceSandboxFlags(SecurityContext::parseSandboxPolicy(sandboxPolicy, invalidTokens));
- if (!invalidTokens.isNull())
- m_policy.reportInvalidSandboxFlags(invalidTokens);
-}
-
-void ContentSecurityPolicyDirectiveList::parseReflectedXSS(const String& name, const String& value)
-{
- if (m_reflectedXSSDisposition != ContentSecurityPolicy::ReflectedXSSUnset) {
- m_policy.reportDuplicateDirective(name);
- m_reflectedXSSDisposition = ContentSecurityPolicy::ReflectedXSSInvalid;
- return;
- }
-
- if (value.isEmpty()) {
- m_reflectedXSSDisposition = ContentSecurityPolicy::ReflectedXSSInvalid;
- m_policy.reportInvalidReflectedXSS(value);
- return;
- }
-
- auto characters = StringView(value).upconvertedCharacters();
- const UChar* position = characters;
- const UChar* end = position + value.length();
-
- skipWhile<UChar, isASCIISpace>(position, end);
- const UChar* begin = position;
- skipWhile<UChar, isNotASCIISpace>(position, end);
-
- // value1
- // ^
- if (equalLettersIgnoringASCIICase(begin, position - begin, "allow"))
- m_reflectedXSSDisposition = ContentSecurityPolicy::AllowReflectedXSS;
- else if (equalLettersIgnoringASCIICase(begin, position - begin, "filter"))
- m_reflectedXSSDisposition = ContentSecurityPolicy::FilterReflectedXSS;
- else if (equalLettersIgnoringASCIICase(begin, position - begin, "block"))
- m_reflectedXSSDisposition = ContentSecurityPolicy::BlockReflectedXSS;
- else {
- m_reflectedXSSDisposition = ContentSecurityPolicy::ReflectedXSSInvalid;
- m_policy.reportInvalidReflectedXSS(value);
- return;
- }
-
- skipWhile<UChar, isASCIISpace>(position, end);
- if (position == end && m_reflectedXSSDisposition != ContentSecurityPolicy::ReflectedXSSUnset)
- return;
-
- // value1 value2
- // ^
- m_reflectedXSSDisposition = ContentSecurityPolicy::ReflectedXSSInvalid;
- m_policy.reportInvalidReflectedXSS(value);
-}
-
-void ContentSecurityPolicyDirectiveList::addDirective(const String& name, const String& value)
-{
- ASSERT(!name.isEmpty());
-
- if (equalLettersIgnoringASCIICase(name, defaultSrc))
- setCSPDirective<ContentSecurityPolicySourceListDirective>(name, value, m_defaultSrc);
- else if (equalLettersIgnoringASCIICase(name, scriptSrc))
- setCSPDirective<ContentSecurityPolicySourceListDirective>(name, value, m_scriptSrc);
- else if (equalLettersIgnoringASCIICase(name, objectSrc))
- setCSPDirective<ContentSecurityPolicySourceListDirective>(name, value, m_objectSrc);
- else if (equalLettersIgnoringASCIICase(name, frameSrc))
- setCSPDirective<ContentSecurityPolicySourceListDirective>(name, value, m_frameSrc);
- else if (equalLettersIgnoringASCIICase(name, imgSrc))
- setCSPDirective<ContentSecurityPolicySourceListDirective>(name, value, m_imgSrc);
- else if (equalLettersIgnoringASCIICase(name, styleSrc))
- setCSPDirective<ContentSecurityPolicySourceListDirective>(name, value, m_styleSrc);
- else if (equalLettersIgnoringASCIICase(name, fontSrc))
- setCSPDirective<ContentSecurityPolicySourceListDirective>(name, value, m_fontSrc);
- else if (equalLettersIgnoringASCIICase(name, mediaSrc))
- setCSPDirective<ContentSecurityPolicySourceListDirective>(name, value, m_mediaSrc);
- else if (equalLettersIgnoringASCIICase(name, connectSrc))
- setCSPDirective<ContentSecurityPolicySourceListDirective>(name, value, m_connectSrc);
- else if (equalLettersIgnoringASCIICase(name, childSrc))
- setCSPDirective<ContentSecurityPolicySourceListDirective>(name, value, m_childSrc);
- else if (equalLettersIgnoringASCIICase(name, formAction))
- setCSPDirective<ContentSecurityPolicySourceListDirective>(name, value, m_formAction);
- else if (equalLettersIgnoringASCIICase(name, baseURI))
- setCSPDirective<ContentSecurityPolicySourceListDirective>(name, value, m_baseURI);
- else if (equalLettersIgnoringASCIICase(name, pluginTypes))
- setCSPDirective<ContentSecurityPolicyMediaListDirective>(name, value, m_pluginTypes);
- else if (equalLettersIgnoringASCIICase(name, sandbox))
- applySandboxPolicy(name, value);
- else if (equalLettersIgnoringASCIICase(name, reportURI))
- parseReportURI(name, value);
-#if ENABLE(CSP_NEXT)
- else if (m_policy.experimentalFeaturesEnabled()) {
- if (equalLettersIgnoringASCIICase(name, reflectedXSS))
- parseReflectedXSS(name, value);
- else
- m_policy.reportUnsupportedDirective(name);
- }
-#endif
- else
- m_policy.reportUnsupportedDirective(name);
-}
-
-} // namespace WebCore
diff --git a/Source/WebCore/page/csp/ContentSecurityPolicyDirectiveList.h b/Source/WebCore/page/csp/ContentSecurityPolicyDirectiveList.h
deleted file mode 100644
index 2a98b2d09..000000000
--- a/Source/WebCore/page/csp/ContentSecurityPolicyDirectiveList.h
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (C) 2011 Google, Inc. All rights reserved.
- * Copyright (C) 2016 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef ContentSecurityPolicyDirectiveList_h
-#define ContentSecurityPolicyDirectiveList_h
-
-#include "ContentSecurityPolicy.h"
-#include "ContentSecurityPolicyMediaListDirective.h"
-#include "ContentSecurityPolicySourceListDirective.h"
-#include "URL.h"
-#include <wtf/Noncopyable.h>
-
-namespace WebCore {
-
-bool isCSPDirectiveName(const String&);
-
-class ContentSecurityPolicyDirectiveList {
- WTF_MAKE_FAST_ALLOCATED;
- WTF_MAKE_NONCOPYABLE(ContentSecurityPolicyDirectiveList)
-public:
- static std::unique_ptr<ContentSecurityPolicyDirectiveList> create(ContentSecurityPolicy&, const String&, ContentSecurityPolicyHeaderType, ContentSecurityPolicy::PolicyFrom);
- ContentSecurityPolicyDirectiveList(ContentSecurityPolicy&, ContentSecurityPolicyHeaderType);
-
- const String& header() const { return m_header; }
- ContentSecurityPolicyHeaderType headerType() const { return m_headerType; }
-
- bool allowJavaScriptURLs(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus) const;
- bool allowInlineEventHandlers(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus) const;
- bool allowInlineScript(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus) const;
- bool allowInlineStyle(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus) const;
- bool allowEval(JSC::ExecState*, ContentSecurityPolicy::ReportingStatus) const;
- bool allowPluginType(const String& type, const String& typeAttribute, const URL&, ContentSecurityPolicy::ReportingStatus) const;
-
- bool allowScriptFromSource(const URL&, ContentSecurityPolicy::ReportingStatus) const;
- bool allowObjectFromSource(const URL&, ContentSecurityPolicy::ReportingStatus) const;
- bool allowChildFrameFromSource(const URL&, ContentSecurityPolicy::ReportingStatus) const;
- bool allowChildContextFromSource(const URL&, ContentSecurityPolicy::ReportingStatus) const;
- bool allowImageFromSource(const URL&, ContentSecurityPolicy::ReportingStatus) const;
- bool allowStyleFromSource(const URL&, ContentSecurityPolicy::ReportingStatus) const;
- bool allowFontFromSource(const URL&, ContentSecurityPolicy::ReportingStatus) const;
- bool allowMediaFromSource(const URL&, ContentSecurityPolicy::ReportingStatus) const;
- bool allowConnectToSource(const URL&, ContentSecurityPolicy::ReportingStatus) const;
- bool allowFormAction(const URL&, ContentSecurityPolicy::ReportingStatus) const;
- bool allowBaseURI(const URL&, ContentSecurityPolicy::ReportingStatus) const;
-
- const String& evalDisabledErrorMessage() const { return m_evalDisabledErrorMessage; }
- ContentSecurityPolicy::ReflectedXSSDisposition reflectedXSSDisposition() const { return m_reflectedXSSDisposition; }
- bool isReportOnly() const { return m_reportOnly; }
- const Vector<String>& reportURIs() const { return m_reportURIs; }
-
-private:
- void parse(const String&, ContentSecurityPolicy::PolicyFrom);
-
- bool parseDirective(const UChar* begin, const UChar* end, String& name, String& value);
- void parseReportURI(const String& name, const String& value);
- void parsePluginTypes(const String& name, const String& value);
- void parseReflectedXSS(const String& name, const String& value);
- void addDirective(const String& name, const String& value);
- void applySandboxPolicy(const String& name, const String& sandboxPolicy);
-
- template <class CSPDirectiveType>
- void setCSPDirective(const String& name, const String& value, std::unique_ptr<CSPDirectiveType>&);
-
- ContentSecurityPolicySourceListDirective* operativeDirective(ContentSecurityPolicySourceListDirective*) const;
- void reportViolation(const String& directiveText, const String& effectiveDirective, const String& consoleMessage, const URL& blockedURL = URL(), const String& contextURL = String(), const WTF::OrdinalNumber& contextLine = WTF::OrdinalNumber::beforeFirst(), JSC::ExecState* = nullptr) const;
-
- bool checkEval(ContentSecurityPolicySourceListDirective*) const;
- bool checkInline(ContentSecurityPolicySourceListDirective*) const;
- bool checkSource(ContentSecurityPolicySourceListDirective*, const URL&) const;
- bool checkMediaType(ContentSecurityPolicyMediaListDirective*, const String& type, const String& typeAttribute) const;
-
- void setEvalDisabledErrorMessage(const String& errorMessage) { m_evalDisabledErrorMessage = errorMessage; }
-
- bool checkEvalAndReportViolation(ContentSecurityPolicySourceListDirective*, const String& consoleMessage, const String& contextURL = String(), const WTF::OrdinalNumber& contextLine = WTF::OrdinalNumber::beforeFirst(), JSC::ExecState* = nullptr) const;
- bool checkInlineAndReportViolation(ContentSecurityPolicySourceListDirective*, const String& consoleMessage, const String& contextURL, const WTF::OrdinalNumber& contextLine, bool isScript) const;
-
- bool checkSourceAndReportViolation(ContentSecurityPolicySourceListDirective*, const URL&, const String& effectiveDirective) const;
- bool checkMediaTypeAndReportViolation(ContentSecurityPolicyMediaListDirective*, const String& type, const String& typeAttribute, const String& consoleMessage) const;
-
- bool denyIfEnforcingPolicy() const { return m_reportOnly; }
-
- // FIXME: Make this a const reference once we teach applySandboxPolicy() to store its policy as opposed to applying it directly onto ContentSecurityPolicy.
- ContentSecurityPolicy& m_policy;
-
- String m_header;
- ContentSecurityPolicyHeaderType m_headerType;
-
- bool m_reportOnly;
- bool m_haveSandboxPolicy;
- ContentSecurityPolicy::ReflectedXSSDisposition m_reflectedXSSDisposition;
-
- std::unique_ptr<ContentSecurityPolicyMediaListDirective> m_pluginTypes;
- std::unique_ptr<ContentSecurityPolicySourceListDirective> m_baseURI;
- std::unique_ptr<ContentSecurityPolicySourceListDirective> m_connectSrc;
- std::unique_ptr<ContentSecurityPolicySourceListDirective> m_childSrc;
- std::unique_ptr<ContentSecurityPolicySourceListDirective> m_defaultSrc;
- std::unique_ptr<ContentSecurityPolicySourceListDirective> m_fontSrc;
- std::unique_ptr<ContentSecurityPolicySourceListDirective> m_formAction;
- std::unique_ptr<ContentSecurityPolicySourceListDirective> m_frameSrc;
- std::unique_ptr<ContentSecurityPolicySourceListDirective> m_imgSrc;
- std::unique_ptr<ContentSecurityPolicySourceListDirective> m_mediaSrc;
- std::unique_ptr<ContentSecurityPolicySourceListDirective> m_objectSrc;
- std::unique_ptr<ContentSecurityPolicySourceListDirective> m_scriptSrc;
- std::unique_ptr<ContentSecurityPolicySourceListDirective> m_styleSrc;
-
- Vector<String> m_reportURIs;
-
- String m_evalDisabledErrorMessage;
-};
-
-} // namespace WebCore
-
-#endif /* ContentSecurityPolicyDirectiveList_h */
diff --git a/Source/WebCore/page/csp/ContentSecurityPolicyMediaListDirective.cpp b/Source/WebCore/page/csp/ContentSecurityPolicyMediaListDirective.cpp
deleted file mode 100644
index 2af393598..000000000
--- a/Source/WebCore/page/csp/ContentSecurityPolicyMediaListDirective.cpp
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (C) 2011 Google, Inc. All rights reserved.
- * Copyright (C) 2016 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "ContentSecurityPolicyMediaListDirective.h"
-
-#include "ContentSecurityPolicy.h"
-#include "ParsingUtilities.h"
-#include <wtf/text/StringHash.h>
-
-namespace WebCore {
-
-static bool isMediaTypeCharacter(UChar c)
-{
- return !isASCIISpace(c) && c != '/';
-}
-
-static bool isNotASCIISpace(UChar c)
-{
- return !isASCIISpace(c);
-}
-
-ContentSecurityPolicyMediaListDirective::ContentSecurityPolicyMediaListDirective(const String& name, const String& value, const ContentSecurityPolicy& policy)
- : ContentSecurityPolicyDirective(name, value, policy)
-{
- parse(value);
-}
-
-bool ContentSecurityPolicyMediaListDirective::allows(const String& type) const
-{
- return m_pluginTypes.contains(type);
-}
-
-void ContentSecurityPolicyMediaListDirective::parse(const String& value)
-{
- auto characters = StringView(value).upconvertedCharacters();
- const UChar* begin = characters;
- const UChar* position = begin;
- const UChar* end = begin + value.length();
-
- // 'plugin-types ____;' OR 'plugin-types;'
- if (value.isEmpty()) {
- policy().reportInvalidPluginTypes(value);
- return;
- }
-
- while (position < end) {
- // _____ OR _____mime1/mime1
- // ^ ^
- skipWhile<UChar, isASCIISpace>(position, end);
- if (position == end)
- return;
-
- // mime1/mime1 mime2/mime2
- // ^
- begin = position;
- if (!skipExactly<UChar, isMediaTypeCharacter>(position, end)) {
- skipWhile<UChar, isNotASCIISpace>(position, end);
- policy().reportInvalidPluginTypes(String(begin, position - begin));
- continue;
- }
- skipWhile<UChar, isMediaTypeCharacter>(position, end);
-
- // mime1/mime1 mime2/mime2
- // ^
- if (!skipExactly<UChar>(position, end, '/')) {
- skipWhile<UChar, isNotASCIISpace>(position, end);
- policy().reportInvalidPluginTypes(String(begin, position - begin));
- continue;
- }
-
- // mime1/mime1 mime2/mime2
- // ^
- if (!skipExactly<UChar, isMediaTypeCharacter>(position, end)) {
- skipWhile<UChar, isNotASCIISpace>(position, end);
- policy().reportInvalidPluginTypes(String(begin, position - begin));
- continue;
- }
- skipWhile<UChar, isMediaTypeCharacter>(position, end);
-
- // mime1/mime1 mime2/mime2 OR mime1/mime1 OR mime1/mime1/error
- // ^ ^ ^
- if (position < end && isNotASCIISpace(*position)) {
- skipWhile<UChar, isNotASCIISpace>(position, end);
- policy().reportInvalidPluginTypes(String(begin, position - begin));
- continue;
- }
- m_pluginTypes.add(String(begin, position - begin));
-
- ASSERT(position == end || isASCIISpace(*position));
- }
-}
-
-} // namespace WebCore
diff --git a/Source/WebCore/page/csp/ContentSecurityPolicyResponseHeaders.cpp b/Source/WebCore/page/csp/ContentSecurityPolicyResponseHeaders.cpp
deleted file mode 100644
index 0b67b91d4..000000000
--- a/Source/WebCore/page/csp/ContentSecurityPolicyResponseHeaders.cpp
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2016 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "ContentSecurityPolicyResponseHeaders.h"
-
-#include "HTTPHeaderNames.h"
-#include "ResourceResponse.h"
-
-namespace WebCore {
-
-ContentSecurityPolicyResponseHeaders::ContentSecurityPolicyResponseHeaders(const ResourceResponse& response)
-{
- String policyValue = response.httpHeaderField(HTTPHeaderName::ContentSecurityPolicy);
- if (!policyValue.isEmpty())
- m_headers.append({ policyValue, ContentSecurityPolicyHeaderType::Enforce });
-
- policyValue = response.httpHeaderField(HTTPHeaderName::ContentSecurityPolicyReportOnly);
- if (!policyValue.isEmpty())
- m_headers.append({ policyValue, ContentSecurityPolicyHeaderType::Report });
-
- policyValue = response.httpHeaderField(HTTPHeaderName::XWebKitCSP);
- if (!policyValue.isEmpty())
- m_headers.append({ policyValue, ContentSecurityPolicyHeaderType::PrefixedEnforce });
-
- policyValue = response.httpHeaderField(HTTPHeaderName::XWebKitCSPReportOnly);
- if (!policyValue.isEmpty())
- m_headers.append({ policyValue, ContentSecurityPolicyHeaderType::PrefixedReport });
-}
-
-ContentSecurityPolicyResponseHeaders ContentSecurityPolicyResponseHeaders::isolatedCopy() const
-{
- ContentSecurityPolicyResponseHeaders isolatedCopy;
- isolatedCopy.m_headers.reserveInitialCapacity(m_headers.size());
- for (auto& header : m_headers)
- isolatedCopy.m_headers.uncheckedAppend({ header.first.isolatedCopy(), header.second });
- return isolatedCopy;
-}
-
-} // namespace WebCore
diff --git a/Source/WebCore/page/csp/ContentSecurityPolicyResponseHeaders.h b/Source/WebCore/page/csp/ContentSecurityPolicyResponseHeaders.h
deleted file mode 100644
index 50c7c4a7f..000000000
--- a/Source/WebCore/page/csp/ContentSecurityPolicyResponseHeaders.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2016 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef ContentSecurityPolicyResponseHeaders_h
-#define ContentSecurityPolicyResponseHeaders_h
-
-#include <wtf/Vector.h>
-#include <wtf/text/WTFString.h>
-
-namespace WebCore {
-
-class ContentSecurityPolicy;
-class ResourceResponse;
-
-enum class ContentSecurityPolicyHeaderType {
- Report,
- Enforce,
- PrefixedReport,
- PrefixedEnforce,
-};
-
-class ContentSecurityPolicyResponseHeaders {
-public:
- ContentSecurityPolicyResponseHeaders(const ResourceResponse&);
-
- ContentSecurityPolicyResponseHeaders isolatedCopy() const;
-
-private:
- friend class ContentSecurityPolicy;
-
- ContentSecurityPolicyResponseHeaders() = default;
-
- Vector<std::pair<String, ContentSecurityPolicyHeaderType>> m_headers;
-};
-
-} // namespace WebCore
-
-#endif /* ContentSecurityPolicyResponseHeaders_h */
diff --git a/Source/WebCore/page/csp/ContentSecurityPolicySource.cpp b/Source/WebCore/page/csp/ContentSecurityPolicySource.cpp
deleted file mode 100644
index 26c2cee33..000000000
--- a/Source/WebCore/page/csp/ContentSecurityPolicySource.cpp
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (C) 2011 Google, Inc. All rights reserved.
- * Copyright (C) 2016 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "ContentSecurityPolicySource.h"
-
-#include "ContentSecurityPolicy.h"
-#include "URL.h"
-
-namespace WebCore {
-
-ContentSecurityPolicySource::ContentSecurityPolicySource(const ContentSecurityPolicy& policy, const String& scheme, const String& host, int port, const String& path, bool hostHasWildcard, bool portHasWildcard)
- : m_policy(policy)
- , m_scheme(scheme)
- , m_host(host)
- , m_port(port)
- , m_path(path)
- , m_hostHasWildcard(hostHasWildcard)
- , m_portHasWildcard(portHasWildcard)
-{
-}
-
-bool ContentSecurityPolicySource::matches(const URL& url) const
-{
- if (!schemeMatches(url))
- return false;
- if (isSchemeOnly())
- return true;
- return hostMatches(url) && portMatches(url) && pathMatches(url);
-}
-
-bool ContentSecurityPolicySource::schemeMatches(const URL& url) const
-{
- if (m_scheme.isEmpty())
- return m_policy.protocolMatchesSelf(url);
- return equalIgnoringASCIICase(url.protocol(), m_scheme);
-}
-
-bool ContentSecurityPolicySource::hostMatches(const URL& url) const
-{
- const String& host = url.host();
- if (equalIgnoringASCIICase(host, m_host))
- return true;
- return m_hostHasWildcard && host.endsWith("." + m_host, false);
-
-}
-
-bool ContentSecurityPolicySource::pathMatches(const URL& url) const
-{
- if (m_path.isEmpty())
- return true;
-
- String path = decodeURLEscapeSequences(url.path());
-
- if (m_path.endsWith("/"))
- return path.startsWith(m_path);
-
- return path == m_path;
-}
-
-bool ContentSecurityPolicySource::portMatches(const URL& url) const
-{
- if (m_portHasWildcard)
- return true;
-
- int port = url.port();
-
- if (port == m_port)
- return true;
-
- if (!port)
- return isDefaultPortForProtocol(m_port, url.protocol());
-
- if (!m_port)
- return isDefaultPortForProtocol(port, url.protocol());
-
- return false;
-}
-
-bool ContentSecurityPolicySource::isSchemeOnly() const
-{
- return m_host.isEmpty();
-}
-
-} // namespace WebCore
diff --git a/Source/WebCore/page/csp/ContentSecurityPolicySource.h b/Source/WebCore/page/csp/ContentSecurityPolicySource.h
deleted file mode 100644
index 5c779d545..000000000
--- a/Source/WebCore/page/csp/ContentSecurityPolicySource.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2011 Google, Inc. All rights reserved.
- * Copyright (C) 2016 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef ContentSecurityPolicySource_h
-#define ContentSecurityPolicySource_h
-
-#include <wtf/text/WTFString.h>
-
-namespace WebCore {
-
-class ContentSecurityPolicy;
-class URL;
-
-class ContentSecurityPolicySource {
-public:
- ContentSecurityPolicySource(const ContentSecurityPolicy&, const String& scheme, const String& host, int port, const String& path, bool hostHasWildcard, bool portHasWildcard);
-
- bool matches(const URL&) const;
-
-private:
- bool schemeMatches(const URL&) const;
- bool hostMatches(const URL&) const;
- bool pathMatches(const URL&) const;
- bool portMatches(const URL&) const;
- bool isSchemeOnly() const;
-
- const ContentSecurityPolicy& m_policy;
- String m_scheme;
- String m_host;
- int m_port;
- String m_path;
-
- bool m_hostHasWildcard;
- bool m_portHasWildcard;
-};
-
-} // namespace WebCore
-
-#endif /* ContentSecurityPolicySource_h */
diff --git a/Source/WebCore/page/csp/ContentSecurityPolicySourceList.cpp b/Source/WebCore/page/csp/ContentSecurityPolicySourceList.cpp
deleted file mode 100644
index 408b40e2b..000000000
--- a/Source/WebCore/page/csp/ContentSecurityPolicySourceList.cpp
+++ /dev/null
@@ -1,388 +0,0 @@
-/*
- * Copyright (C) 2011 Google, Inc. All rights reserved.
- * Copyright (C) 2016 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "ContentSecurityPolicySourceList.h"
-
-#include "ContentSecurityPolicy.h"
-#include "ContentSecurityPolicyDirectiveList.h"
-#include "ParsingUtilities.h"
-#include "SecurityOrigin.h"
-#include "URL.h"
-#include <wtf/ASCIICType.h>
-
-namespace WebCore {
-
-static bool isSourceCharacter(UChar c)
-{
- return !isASCIISpace(c);
-}
-
-static bool isHostCharacter(UChar c)
-{
- return isASCIIAlphanumeric(c) || c == '-';
-}
-
-static bool isPathComponentCharacter(UChar c)
-{
- return c != '?' && c != '#';
-}
-
-static bool isSchemeContinuationCharacter(UChar c)
-{
- return isASCIIAlphanumeric(c) || c == '+' || c == '-' || c == '.';
-}
-
-static bool isNotColonOrSlash(UChar c)
-{
- return c != ':' && c != '/';
-}
-
-static bool isSourceListNone(const String& value)
-{
- auto characters = StringView(value).upconvertedCharacters();
- const UChar* begin = characters;
- const UChar* end = characters + value.length();
- skipWhile<UChar, isASCIISpace>(begin, end);
-
- const UChar* position = begin;
- skipWhile<UChar, isSourceCharacter>(position, end);
- if (!equalLettersIgnoringASCIICase(begin, position - begin, "'none'"))
- return false;
-
- skipWhile<UChar, isASCIISpace>(position, end);
- if (position != end)
- return false;
-
- return true;
-}
-
-ContentSecurityPolicySourceList::ContentSecurityPolicySourceList(const ContentSecurityPolicy& policy, const String& directiveName)
- : m_policy(policy)
- , m_directiveName(directiveName)
-{
-}
-
-void ContentSecurityPolicySourceList::parse(const String& value)
-{
- // We represent 'none' as an empty m_list.
- if (isSourceListNone(value))
- return;
- auto characters = StringView(value).upconvertedCharacters();
- parse(characters, characters + value.length());
-}
-
-bool ContentSecurityPolicySourceList::isProtocolAllowedByStar(const URL& url) const
-{
- // Although not allowed by the Content Security Policy Level 3 spec., we allow a data URL to match
- // "img-src *" and either a data URL or blob URL to match "media-src *" for web compatibility.
- // FIXME: We should not hardcode the directive names. We should make use of the constants in ContentSecurityPolicyDirectiveList.cpp.
- // See <https://bugs.webkit.org/show_bug.cgi?id=155133>.
- bool isAllowed = url.protocolIsInHTTPFamily();
- if (equalLettersIgnoringASCIICase(m_directiveName, "img-src"))
- isAllowed |= url.protocolIsData();
- else if (equalLettersIgnoringASCIICase(m_directiveName, "media-src"))
- isAllowed |= url.protocolIsData() || url.protocolIsBlob();
- return isAllowed;
-}
-
-bool ContentSecurityPolicySourceList::matches(const URL& url)
-{
- if (m_allowStar && isProtocolAllowedByStar(url))
- return true;
-
- if (m_allowSelf && m_policy.urlMatchesSelf(url))
- return true;
-
- for (auto& entry : m_list) {
- if (entry.matches(url))
- return true;
- }
-
- return false;
-}
-
-// source-list = *WSP [ source *( 1*WSP source ) *WSP ]
-// / *WSP "'none'" *WSP
-//
-void ContentSecurityPolicySourceList::parse(const UChar* begin, const UChar* end)
-{
- const UChar* position = begin;
-
- while (position < end) {
- skipWhile<UChar, isASCIISpace>(position, end);
- if (position == end)
- return;
-
- const UChar* beginSource = position;
- skipWhile<UChar, isSourceCharacter>(position, end);
-
- String scheme, host, path;
- int port = 0;
- bool hostHasWildcard = false;
- bool portHasWildcard = false;
-
- if (parseSource(beginSource, position, scheme, host, port, path, hostHasWildcard, portHasWildcard)) {
- // Wildcard hosts and keyword sources ('self', 'unsafe-inline',
- // etc.) aren't stored in m_list, but as attributes on the source
- // list itself.
- if (scheme.isEmpty() && host.isEmpty())
- continue;
- if (isCSPDirectiveName(host))
- m_policy.reportDirectiveAsSourceExpression(m_directiveName, host);
- m_list.append(ContentSecurityPolicySource(m_policy, scheme, host, port, path, hostHasWildcard, portHasWildcard));
- } else
- m_policy.reportInvalidSourceExpression(m_directiveName, String(beginSource, position - beginSource));
-
- ASSERT(position == end || isASCIISpace(*position));
- }
-}
-
-// source = scheme ":"
-// / ( [ scheme "://" ] host [ port ] [ path ] )
-// / "'self'"
-//
-bool ContentSecurityPolicySourceList::parseSource(const UChar* begin, const UChar* end, String& scheme, String& host, int& port, String& path, bool& hostHasWildcard, bool& portHasWildcard)
-{
- if (begin == end)
- return false;
-
- if (equalLettersIgnoringASCIICase(begin, end - begin, "'none'"))
- return false;
-
- if (end - begin == 1 && *begin == '*') {
- m_allowStar = true;
- return true;
- }
-
- if (equalLettersIgnoringASCIICase(begin, end - begin, "'self'")) {
- m_allowSelf = true;
- return true;
- }
-
- if (equalLettersIgnoringASCIICase(begin, end - begin, "'unsafe-inline'")) {
- m_allowInline = true;
- return true;
- }
-
- if (equalLettersIgnoringASCIICase(begin, end - begin, "'unsafe-eval'")) {
- m_allowEval = true;
- return true;
- }
-
- const UChar* position = begin;
- const UChar* beginHost = begin;
- const UChar* beginPath = end;
- const UChar* beginPort = nullptr;
-
- skipWhile<UChar, isNotColonOrSlash>(position, end);
-
- if (position == end) {
- // host
- // ^
- return parseHost(beginHost, position, host, hostHasWildcard);
- }
-
- if (position < end && *position == '/') {
- // host/path || host/ || /
- // ^ ^ ^
- return parseHost(beginHost, position, host, hostHasWildcard) && parsePath(position, end, path);
- }
-
- if (position < end && *position == ':') {
- if (end - position == 1) {
- // scheme:
- // ^
- return parseScheme(begin, position, scheme);
- }
-
- if (position[1] == '/') {
- // scheme://host || scheme://
- // ^ ^
- if (!parseScheme(begin, position, scheme)
- || !skipExactly<UChar>(position, end, ':')
- || !skipExactly<UChar>(position, end, '/')
- || !skipExactly<UChar>(position, end, '/'))
- return false;
- if (position == end)
- return false;
- beginHost = position;
- skipWhile<UChar, isNotColonOrSlash>(position, end);
- }
-
- if (position < end && *position == ':') {
- // host:port || scheme://host:port
- // ^ ^
- beginPort = position;
- skipUntil<UChar>(position, end, '/');
- }
- }
-
- if (position < end && *position == '/') {
- // scheme://host/path || scheme://host:port/path
- // ^ ^
- if (position == beginHost)
- return false;
-
- beginPath = position;
- }
-
- if (!parseHost(beginHost, beginPort ? beginPort : beginPath, host, hostHasWildcard))
- return false;
-
- if (!beginPort)
- port = 0;
- else {
- if (!parsePort(beginPort, beginPath, port, portHasWildcard))
- return false;
- }
-
- if (beginPath != end) {
- if (!parsePath(beginPath, end, path))
- return false;
- }
-
- return true;
-}
-
-// ; <scheme> production from RFC 3986
-// scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
-//
-bool ContentSecurityPolicySourceList::parseScheme(const UChar* begin, const UChar* end, String& scheme)
-{
- ASSERT(begin <= end);
- ASSERT(scheme.isEmpty());
-
- if (begin == end)
- return false;
-
- const UChar* position = begin;
-
- if (!skipExactly<UChar, isASCIIAlpha>(position, end))
- return false;
-
- skipWhile<UChar, isSchemeContinuationCharacter>(position, end);
-
- if (position != end)
- return false;
-
- scheme = String(begin, end - begin);
- return true;
-}
-
-// host = [ "*." ] 1*host-char *( "." 1*host-char )
-// / "*"
-// host-char = ALPHA / DIGIT / "-"
-//
-bool ContentSecurityPolicySourceList::parseHost(const UChar* begin, const UChar* end, String& host, bool& hostHasWildcard)
-{
- ASSERT(begin <= end);
- ASSERT(host.isEmpty());
- ASSERT(!hostHasWildcard);
-
- if (begin == end)
- return false;
-
- const UChar* position = begin;
-
- if (skipExactly<UChar>(position, end, '*')) {
- hostHasWildcard = true;
-
- if (position == end)
- return true;
-
- if (!skipExactly<UChar>(position, end, '.'))
- return false;
- }
-
- const UChar* hostBegin = position;
-
- while (position < end) {
- if (!skipExactly<UChar, isHostCharacter>(position, end))
- return false;
-
- skipWhile<UChar, isHostCharacter>(position, end);
-
- if (position < end && !skipExactly<UChar>(position, end, '.'))
- return false;
- }
-
- ASSERT(position == end);
- host = String(hostBegin, end - hostBegin);
- return true;
-}
-
-bool ContentSecurityPolicySourceList::parsePath(const UChar* begin, const UChar* end, String& path)
-{
- ASSERT(begin <= end);
- ASSERT(path.isEmpty());
-
- const UChar* position = begin;
- skipWhile<UChar, isPathComponentCharacter>(position, end);
- // path/to/file.js?query=string || path/to/file.js#anchor
- // ^ ^
- if (position < end)
- m_policy.reportInvalidPathCharacter(m_directiveName, String(begin, end - begin), *position);
-
- path = decodeURLEscapeSequences(String(begin, position - begin));
-
- ASSERT(position <= end);
- ASSERT(position == end || (*position == '#' || *position == '?'));
- return true;
-}
-
-// port = ":" ( 1*DIGIT / "*" )
-//
-bool ContentSecurityPolicySourceList::parsePort(const UChar* begin, const UChar* end, int& port, bool& portHasWildcard)
-{
- ASSERT(begin <= end);
- ASSERT(!port);
- ASSERT(!portHasWildcard);
-
- if (!skipExactly<UChar>(begin, end, ':'))
- ASSERT_NOT_REACHED();
-
- if (begin == end)
- return false;
-
- if (end - begin == 1 && *begin == '*') {
- port = 0;
- portHasWildcard = true;
- return true;
- }
-
- const UChar* position = begin;
- skipWhile<UChar, isASCIIDigit>(position, end);
-
- if (position != end)
- return false;
-
- bool ok;
- port = charactersToIntStrict(begin, end - begin, &ok);
- return ok;
-}
-
-} // namespace WebCore
diff --git a/Source/WebCore/page/csp/ContentSecurityPolicySourceList.h b/Source/WebCore/page/csp/ContentSecurityPolicySourceList.h
deleted file mode 100644
index fdb9b7e09..000000000
--- a/Source/WebCore/page/csp/ContentSecurityPolicySourceList.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2011 Google, Inc. All rights reserved.
- * Copyright (C) 2016 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef ContentSecurityPolicySourceList_h
-#define ContentSecurityPolicySourceList_h
-
-#include "ContentSecurityPolicySource.h"
-#include <wtf/Vector.h>
-#include <wtf/text/WTFString.h>
-
-namespace WebCore {
-
-class ContentSecurityPolicy;
-class URL;
-
-class ContentSecurityPolicySourceList {
-public:
- ContentSecurityPolicySourceList(const ContentSecurityPolicy&, const String& directiveName);
-
- void parse(const String&);
- bool matches(const URL&);
- bool allowInline() const { return m_allowInline; }
- bool allowEval() const { return m_allowEval; }
- bool allowSelf() const { return m_allowSelf; }
-
-private:
- void parse(const UChar* begin, const UChar* end);
-
- bool parseSource(const UChar* begin, const UChar* end, String& scheme, String& host, int& port, String& path, bool& hostHasWildcard, bool& portHasWildcard);
- bool parseScheme(const UChar* begin, const UChar* end, String& scheme);
- bool parseHost(const UChar* begin, const UChar* end, String& host, bool& hostHasWildcard);
- bool parsePort(const UChar* begin, const UChar* end, int& port, bool& portHasWildcard);
- bool parsePath(const UChar* begin, const UChar* end, String& path);
-
- bool isProtocolAllowedByStar(const URL&) const;
-
- const ContentSecurityPolicy& m_policy;
- Vector<ContentSecurityPolicySource> m_list;
- String m_directiveName;
- bool m_allowSelf { false };
- bool m_allowStar { false };
- bool m_allowInline { false };
- bool m_allowEval { false };
-};
-
-} // namespace WebCore
-
-#endif /* ContentSecurityPolicySourceList_h */
diff --git a/Source/WebCore/page/csp/ContentSecurityPolicySourceListDirective.h b/Source/WebCore/page/csp/ContentSecurityPolicySourceListDirective.h
deleted file mode 100644
index 9d4e2114c..000000000
--- a/Source/WebCore/page/csp/ContentSecurityPolicySourceListDirective.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2011 Google, Inc. All rights reserved.
- * Copyright (C) 2016 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef ContentSecurityPolicySourceListDirective_h
-#define ContentSecurityPolicySourceListDirective_h
-
-#include "ContentSecurityPolicyDirective.h"
-#include "ContentSecurityPolicySourceList.h"
-
-namespace WebCore {
-
-class ContentSecurityPolicy;
-
-class ContentSecurityPolicySourceListDirective : public ContentSecurityPolicyDirective {
-public:
- ContentSecurityPolicySourceListDirective(const String& name, const String& value, const ContentSecurityPolicy&);
-
- bool allows(const URL&);
- bool allowInline() const { return m_sourceList.allowInline(); }
- bool allowEval() const { return m_sourceList.allowEval(); }
-
-private:
- ContentSecurityPolicySourceList m_sourceList;
-};
-
-} // namespace WebCore
-
-#endif /* ContentSecurityPolicySourceListDirective_h */
diff --git a/Source/WebCore/page/gtk/DragControllerGtk.cpp b/Source/WebCore/page/gtk/DragControllerGtk.cpp
index e66b0e38e..69606a4ba 100644
--- a/Source/WebCore/page/gtk/DragControllerGtk.cpp
+++ b/Source/WebCore/page/gtk/DragControllerGtk.cpp
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -26,18 +26,13 @@
#include "config.h"
#include "DragController.h"
-#include "DataObjectGtk.h"
-#include "DataTransfer.h"
-#include "Document.h"
-#include "DocumentFragment.h"
+#include "Clipboard.h"
#include "DragData.h"
-#include "Editor.h"
#include "Element.h"
#include "Frame.h"
#include "FrameView.h"
#include "Page.h"
#include "Pasteboard.h"
-#include "markup.h"
namespace WebCore {
@@ -58,7 +53,7 @@ bool DragController::isCopyKeyDown(DragData&)
DragOperation DragController::dragOperation(DragData& dragData)
{
// FIXME: This logic is incomplete
- if (dragData.containsURL())
+ if (dragData.containsURL(0))
return DragOperationCopy;
return DragOperationNone;
@@ -74,17 +69,9 @@ void DragController::cleanupAfterSystemDrag()
{
}
-void DragController::declareAndWriteDragImage(DataTransfer& dataTransfer, Element& element, const URL& url, const String& label)
+void DragController::declareAndWriteDragImage(Clipboard& clipboard, Element& element, const URL& url, const String& label)
{
- Frame* frame = element.document().frame();
- ASSERT(frame);
- frame->editor().writeImageToPasteboard(dataTransfer.pasteboard(), element, url, label);
+ clipboard.pasteboard().writeImage(element, url, label);
}
-#if ENABLE(ATTACHMENT_ELEMENT)
-void DragController::declareAndWriteAttachment(DataTransfer&, Element&, const URL&)
-{
-}
-#endif
-
}
diff --git a/Source/WebCore/page/gtk/EventHandlerGtk.cpp b/Source/WebCore/page/gtk/EventHandlerGtk.cpp
index 3a007710d..e6e45625c 100644
--- a/Source/WebCore/page/gtk/EventHandlerGtk.cpp
+++ b/Source/WebCore/page/gtk/EventHandlerGtk.cpp
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -26,7 +26,7 @@
#include "config.h"
#include "EventHandler.h"
-#include "DataTransfer.h"
+#include "Clipboard.h"
#include "FloatPoint.h"
#include "FocusController.h"
#include "Frame.h"
@@ -46,7 +46,7 @@ namespace WebCore {
const double EventHandler::TextDragDelay = 0.0;
#endif
-bool EventHandler::tabsToAllFormControls(KeyboardEvent*) const
+bool EventHandler::tabsToAllFormControls(KeyboardEvent* event) const
{
// We always allow tabs to all controls
return true;
@@ -61,10 +61,10 @@ void EventHandler::focusDocumentView()
bool EventHandler::passWidgetMouseDownEventToWidget(const MouseEventWithHitTestResults& event)
{
// Figure out which view to send the event to.
- RenderObject* target = event.targetNode() ? event.targetNode()->renderer() : nullptr;
- if (!is<RenderWidget>(target))
+ RenderObject* target = event.targetNode() ? event.targetNode()->renderer() : 0;
+ if (!target || !target->isWidget())
return false;
- return passMouseDownEventToWidget(downcast<RenderWidget>(*target).widget());
+ return passMouseDownEventToWidget(toRenderWidget(target)->widget());
}
bool EventHandler::passWidgetMouseDownEventToWidget(RenderWidget* renderWidget)
@@ -72,7 +72,7 @@ bool EventHandler::passWidgetMouseDownEventToWidget(RenderWidget* renderWidget)
return passMouseDownEventToWidget(renderWidget->widget());
}
-bool EventHandler::passMouseDownEventToWidget(Widget*)
+bool EventHandler::passMouseDownEventToWidget(Widget* widget)
{
notImplemented();
return false;
@@ -87,18 +87,19 @@ bool EventHandler::eventActivatedView(const PlatformMouseEvent&) const
return false;
}
-bool EventHandler::passWheelEventToWidget(const PlatformWheelEvent& event, Widget& widget)
+bool EventHandler::passWheelEventToWidget(const PlatformWheelEvent& event, Widget* widget)
{
- if (!is<FrameView>(widget))
+ ASSERT(widget);
+ if (!widget->isFrameView())
return false;
- return downcast<FrameView>(widget).frame().eventHandler().handleWheelEvent(event);
+ return toFrameView(widget)->frame().eventHandler().handleWheelEvent(event);
}
#if ENABLE(DRAG_SUPPORT)
-PassRefPtr<DataTransfer> EventHandler::createDraggingDataTransfer() const
+PassRefPtr<Clipboard> EventHandler::createDraggingClipboard() const
{
- return DataTransfer::createForDragAndDrop();
+ return Clipboard::createForDragAndDrop();
}
#endif
@@ -129,13 +130,9 @@ unsigned EventHandler::accessKeyModifiers()
// horizontal scrollbar while scrolling with the wheel; we need to
// add the deltas and ticks here so that this behavior is consistent
// for styled scrollbars.
-bool EventHandler::shouldTurnVerticalTicksIntoHorizontal(const HitTestResult& result, const PlatformWheelEvent& event) const
+bool EventHandler::shouldTurnVerticalTicksIntoHorizontal(const HitTestResult& result, const PlatformWheelEvent&) const
{
- FrameView* view = m_frame.view();
- Scrollbar* scrollbar = view ? view->scrollbarAtPoint(event.position()) : nullptr;
- if (!scrollbar)
- scrollbar = result.scrollbar();
- return scrollbar && scrollbar->orientation() == HorizontalScrollbar;
+ return result.scrollbar() && result.scrollbar()->orientation() == HorizontalScrollbar;
}
}
diff --git a/Source/WebCore/page/make_settings.pl b/Source/WebCore/page/make_settings.pl
index 5846ca616..b01c1f7b3 100755
--- a/Source/WebCore/page/make_settings.pl
+++ b/Source/WebCore/page/make_settings.pl
@@ -14,7 +14,7 @@
# THIS SOFTWARE IS PROVIDED BY GOOGLE, INC. `AS IS'' AND ANY
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -239,18 +239,12 @@ sub printGetterAndSetter($$$$)
{
my ($file, $settingName, $type, $setNeedsStyleRecalcInAllFrames) = @_;
my $setterFunctionName = setterFunctionName($settingName);
-
- my $webcoreExport = "";
- if ($setNeedsStyleRecalcInAllFrames) {
- $webcoreExport = "WEBCORE_EXPORT"; # Export is only needed if the definition is not in the header.
- }
-
if (lc(substr($type, 0, 1)) eq substr($type, 0, 1)) {
print $file " $type $settingName() const { return m_$settingName; } \\\n";
- print $file " $webcoreExport void $setterFunctionName($type $settingName)";
+ print $file " void $setterFunctionName($type $settingName)";
} else {
print $file " const $type& $settingName() { return m_$settingName; } \\\n";
- print $file " $webcoreExport void $setterFunctionName(const $type& $settingName)";
+ print $file " void $setterFunctionName(const $type& $settingName)";
}
if ($setNeedsStyleRecalcInAllFrames) {
print $file "; \\\n";
@@ -389,7 +383,8 @@ sub generateInternalSettingsHeaderFile($)
#ifndef InternalSettingsGenerated_h
#define InternalSettingsGenerated_h
-#include "Supplementable.h"
+#include "RefCountedSupplement.h"
+#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
#include <wtf/text/WTFString.h>
diff --git a/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.cpp b/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.cpp
deleted file mode 100644
index 0291a4fd0..000000000
--- a/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.cpp
+++ /dev/null
@@ -1,631 +0,0 @@
-/*
- * Copyright (C) 2014-2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#if ENABLE(ASYNC_SCROLLING)
-#include "AsyncScrollingCoordinator.h"
-
-#include "EditorClient.h"
-#include "Frame.h"
-#include "FrameView.h"
-#include "GraphicsLayer.h"
-#include "Logging.h"
-#include "MainFrame.h"
-#include "Page.h"
-#include "ScrollAnimator.h"
-#include "ScrollingConstraints.h"
-#include "ScrollingStateFixedNode.h"
-#include "ScrollingStateFrameScrollingNode.h"
-#include "ScrollingStateOverflowScrollingNode.h"
-#include "ScrollingStateStickyNode.h"
-#include "ScrollingStateTree.h"
-#include "WheelEventTestTrigger.h"
-
-namespace WebCore {
-
-AsyncScrollingCoordinator::AsyncScrollingCoordinator(Page* page)
- : ScrollingCoordinator(page)
- , m_updateNodeScrollPositionTimer(*this, &AsyncScrollingCoordinator::updateScrollPositionAfterAsyncScrollTimerFired)
- , m_scrollingStateTree(std::make_unique<ScrollingStateTree>(this))
-{
-}
-
-AsyncScrollingCoordinator::~AsyncScrollingCoordinator()
-{
-}
-
-void AsyncScrollingCoordinator::scrollingStateTreePropertiesChanged()
-{
- scheduleTreeStateCommit();
-}
-
-static inline void setStateScrollingNodeSnapOffsetsAsFloat(ScrollingStateScrollingNode& node, ScrollEventAxis axis, const Vector<LayoutUnit>* snapOffsets, float deviceScaleFactor)
-{
- // FIXME: Incorporate current page scale factor in snapping to device pixel. Perhaps we should just convert to float here and let UI process do the pixel snapping?
- Vector<float> snapOffsetsAsFloat;
- if (snapOffsets) {
- snapOffsetsAsFloat.reserveInitialCapacity(snapOffsets->size());
- for (auto& offset : *snapOffsets)
- snapOffsetsAsFloat.uncheckedAppend(roundToDevicePixel(offset, deviceScaleFactor, false));
- }
- if (axis == ScrollEventAxis::Horizontal)
- node.setHorizontalSnapOffsets(snapOffsetsAsFloat);
- else
- node.setVerticalSnapOffsets(snapOffsetsAsFloat);
-}
-
-void AsyncScrollingCoordinator::setNonFastScrollableRegionDirty()
-{
- m_nonFastScrollableRegionDirty = true;
- // We have to schedule a commit, but the computed non-fast region may not have actually changed.
- scheduleTreeStateCommit();
-}
-
-void AsyncScrollingCoordinator::willCommitTree()
-{
- updateNonFastScrollableRegion();
-}
-
-void AsyncScrollingCoordinator::updateNonFastScrollableRegion()
-{
- if (!m_nonFastScrollableRegionDirty)
- return;
-
- if (!m_scrollingStateTree->rootStateNode())
- return;
-
- m_scrollingStateTree->rootStateNode()->setNonFastScrollableRegion(absoluteNonFastScrollableRegion());
- m_nonFastScrollableRegionDirty = false;
-}
-
-void AsyncScrollingCoordinator::frameViewLayoutUpdated(FrameView& frameView)
-{
- ASSERT(isMainThread());
- ASSERT(m_page);
-
- // If there isn't a root node yet, don't do anything. We'll be called again after creating one.
- if (!m_scrollingStateTree->rootStateNode())
- return;
-
- // Compute the region of the page that we can't do fast scrolling for. This currently includes
- // all scrollable areas, such as subframes, overflow divs and list boxes. We need to do this even if the
- // frame view whose layout was updated is not the main frame.
- // In the future, we may want to have the ability to set non-fast scrolling regions for more than
- // just the root node. But right now, this concept only applies to the root.
- m_scrollingStateTree->rootStateNode()->setNonFastScrollableRegion(absoluteNonFastScrollableRegion());
- m_nonFastScrollableRegionDirty = false;
-
- if (!coordinatesScrollingForFrameView(frameView))
- return;
-
- ScrollingStateFrameScrollingNode* node = downcast<ScrollingStateFrameScrollingNode>(m_scrollingStateTree->stateNodeForID(frameView.scrollLayerID()));
- if (!node)
- return;
-
- Scrollbar* verticalScrollbar = frameView.verticalScrollbar();
- Scrollbar* horizontalScrollbar = frameView.horizontalScrollbar();
- node->setScrollbarPaintersFromScrollbars(verticalScrollbar, horizontalScrollbar);
-
- node->setFrameScaleFactor(frameView.frame().frameScaleFactor());
- node->setHeaderHeight(frameView.headerHeight());
- node->setFooterHeight(frameView.footerHeight());
- node->setTopContentInset(frameView.topContentInset());
-
- node->setScrollOrigin(frameView.scrollOrigin());
- node->setScrollableAreaSize(frameView.visibleContentRect().size());
- node->setTotalContentsSize(frameView.totalContentsSize());
- node->setReachableContentsSize(frameView.totalContentsSize());
- node->setFixedElementsLayoutRelativeToFrame(frameView.fixedElementsLayoutRelativeToFrame());
-
-#if ENABLE(CSS_SCROLL_SNAP)
- frameView.updateSnapOffsets();
- updateScrollSnapPropertiesWithFrameView(frameView);
-#endif
-
-#if PLATFORM(COCOA)
- Page* page = frameView.frame().page();
- if (page && page->expectsWheelEventTriggers()) {
- LOG(WheelEventTestTriggers, " AsyncScrollingCoordinator::frameViewLayoutUpdated: Expects wheel event test trigger=%d", page->expectsWheelEventTriggers());
- node->setExpectsWheelEventTestTrigger(page->expectsWheelEventTriggers());
- }
-#endif
-
- ScrollableAreaParameters scrollParameters;
- scrollParameters.horizontalScrollElasticity = frameView.horizontalScrollElasticity();
- scrollParameters.verticalScrollElasticity = frameView.verticalScrollElasticity();
- scrollParameters.hasEnabledHorizontalScrollbar = horizontalScrollbar && horizontalScrollbar->enabled();
- scrollParameters.hasEnabledVerticalScrollbar = verticalScrollbar && verticalScrollbar->enabled();
- scrollParameters.horizontalScrollbarMode = frameView.horizontalScrollbarMode();
- scrollParameters.verticalScrollbarMode = frameView.verticalScrollbarMode();
-
- node->setScrollableAreaParameters(scrollParameters);
-}
-
-void AsyncScrollingCoordinator::frameViewNonFastScrollableRegionChanged(FrameView&)
-{
- if (!m_scrollingStateTree->rootStateNode())
- return;
-
- setNonFastScrollableRegionDirty();
-}
-
-void AsyncScrollingCoordinator::frameViewRootLayerDidChange(FrameView& frameView)
-{
- ASSERT(isMainThread());
- ASSERT(m_page);
-
- if (!coordinatesScrollingForFrameView(frameView))
- return;
-
- // FIXME: In some navigation scenarios, the FrameView has no RenderView or that RenderView has not been composited.
- // This needs cleaning up: https://bugs.webkit.org/show_bug.cgi?id=132724
- if (!frameView.scrollLayerID())
- return;
-
- // If the root layer does not have a ScrollingStateNode, then we should create one.
- ensureRootStateNodeForFrameView(frameView);
- ASSERT(m_scrollingStateTree->rootStateNode());
-
- ScrollingCoordinator::frameViewRootLayerDidChange(frameView);
-
- ScrollingStateFrameScrollingNode* node = downcast<ScrollingStateFrameScrollingNode>(m_scrollingStateTree->stateNodeForID(frameView.scrollLayerID()));
- node->setLayer(scrollLayerForFrameView(frameView));
- node->setScrolledContentsLayer(rootContentLayerForFrameView(frameView));
- node->setCounterScrollingLayer(counterScrollingLayerForFrameView(frameView));
- node->setInsetClipLayer(insetClipLayerForFrameView(frameView));
- node->setContentShadowLayer(contentShadowLayerForFrameView(frameView));
- node->setHeaderLayer(headerLayerForFrameView(frameView));
- node->setFooterLayer(footerLayerForFrameView(frameView));
- node->setScrollBehaviorForFixedElements(frameView.scrollBehaviorForFixedElements());
-}
-
-bool AsyncScrollingCoordinator::requestScrollPositionUpdate(FrameView& frameView, const IntPoint& scrollPosition)
-{
- ASSERT(isMainThread());
- ASSERT(m_page);
-
- if (!coordinatesScrollingForFrameView(frameView))
- return false;
-
- bool isProgrammaticScroll = frameView.inProgrammaticScroll();
- if (isProgrammaticScroll || frameView.frame().document()->inPageCache())
- updateScrollPositionAfterAsyncScroll(frameView.scrollLayerID(), scrollPosition, isProgrammaticScroll, SetScrollingLayerPosition);
-
- // If this frame view's document is being put into the page cache, we don't want to update our
- // main frame scroll position. Just let the FrameView think that we did.
- if (frameView.frame().document()->inPageCache())
- return true;
-
- ScrollingStateScrollingNode* stateNode = downcast<ScrollingStateScrollingNode>(m_scrollingStateTree->stateNodeForID(frameView.scrollLayerID()));
- if (!stateNode)
- return false;
-
- stateNode->setRequestedScrollPosition(scrollPosition, isProgrammaticScroll);
- return true;
-}
-
-void AsyncScrollingCoordinator::scheduleUpdateScrollPositionAfterAsyncScroll(ScrollingNodeID nodeID, const FloatPoint& scrollPosition, bool programmaticScroll, SetOrSyncScrollingLayerPosition scrollingLayerPositionAction)
-{
- ScheduledScrollUpdate scrollUpdate(nodeID, scrollPosition, programmaticScroll, scrollingLayerPositionAction);
-
- // For programmatic scrolls, requestScrollPositionUpdate() has already called updateScrollPositionAfterAsyncScroll().
- if (programmaticScroll)
- return;
-
- if (m_updateNodeScrollPositionTimer.isActive()) {
- if (m_scheduledScrollUpdate.matchesUpdateType(scrollUpdate)) {
- m_scheduledScrollUpdate.scrollPosition = scrollPosition;
- return;
- }
-
- // If the parameters don't match what was previously scheduled, dispatch immediately.
- m_updateNodeScrollPositionTimer.stop();
- updateScrollPositionAfterAsyncScroll(m_scheduledScrollUpdate.nodeID, m_scheduledScrollUpdate.scrollPosition, m_scheduledScrollUpdate.isProgrammaticScroll, m_scheduledScrollUpdate.updateLayerPositionAction);
- updateScrollPositionAfterAsyncScroll(nodeID, scrollPosition, programmaticScroll, scrollingLayerPositionAction);
- return;
- }
-
- m_scheduledScrollUpdate = scrollUpdate;
- m_updateNodeScrollPositionTimer.startOneShot(0);
-}
-
-void AsyncScrollingCoordinator::updateScrollPositionAfterAsyncScrollTimerFired()
-{
- updateScrollPositionAfterAsyncScroll(m_scheduledScrollUpdate.nodeID, m_scheduledScrollUpdate.scrollPosition, m_scheduledScrollUpdate.isProgrammaticScroll, m_scheduledScrollUpdate.updateLayerPositionAction);
-}
-
-FrameView* AsyncScrollingCoordinator::frameViewForScrollingNode(ScrollingNodeID scrollingNodeID) const
-{
- if (!m_scrollingStateTree->rootStateNode())
- return nullptr;
-
- if (scrollingNodeID == m_scrollingStateTree->rootStateNode()->scrollingNodeID())
- return m_page->mainFrame().view();
-
- ScrollingStateNode* stateNode = m_scrollingStateTree->stateNodeForID(scrollingNodeID);
- if (!stateNode)
- return nullptr;
-
- // Find the enclosing frame scrolling node.
- ScrollingStateNode* parentNode = stateNode;
- while (parentNode && parentNode->nodeType() != FrameScrollingNode)
- parentNode = parentNode->parent();
-
- if (!parentNode)
- return nullptr;
-
- // Walk the frame tree to find the matching FrameView. This is not ideal, but avoids back pointers to FrameViews
- // from ScrollingTreeStateNodes.
- for (Frame* frame = &m_page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
- if (FrameView* view = frame->view()) {
- if (view->scrollLayerID() == parentNode->scrollingNodeID())
- return view;
- }
- }
-
- return nullptr;
-}
-
-void AsyncScrollingCoordinator::updateScrollPositionAfterAsyncScroll(ScrollingNodeID scrollingNodeID, const FloatPoint& scrollPosition, bool programmaticScroll, SetOrSyncScrollingLayerPosition scrollingLayerPositionAction)
-{
- ASSERT(isMainThread());
-
- if (!m_page)
- return;
-
- FrameView* frameViewPtr = frameViewForScrollingNode(scrollingNodeID);
- if (!frameViewPtr)
- return;
-
- FrameView& frameView = *frameViewPtr;
-
- if (scrollingNodeID == frameView.scrollLayerID()) {
- bool oldProgrammaticScroll = frameView.inProgrammaticScroll();
- frameView.setInProgrammaticScroll(programmaticScroll);
-
- frameView.setConstrainsScrollingToContentEdge(false);
- frameView.notifyScrollPositionChanged(roundedIntPoint(scrollPosition));
- frameView.setConstrainsScrollingToContentEdge(true);
-
- frameView.setInProgrammaticScroll(oldProgrammaticScroll);
-
- if (GraphicsLayer* scrollLayer = scrollLayerForFrameView(frameView)) {
- GraphicsLayer* counterScrollingLayer = counterScrollingLayerForFrameView(frameView);
- GraphicsLayer* insetClipLayer = insetClipLayerForFrameView(frameView);
- GraphicsLayer* contentShadowLayer = contentShadowLayerForFrameView(frameView);
- GraphicsLayer* scrolledContentsLayer = rootContentLayerForFrameView(frameView);
- GraphicsLayer* headerLayer = headerLayerForFrameView(frameView);
- GraphicsLayer* footerLayer = footerLayerForFrameView(frameView);
- LayoutPoint scrollPositionForFixed = frameView.scrollPositionForFixedPosition();
-
- float topContentInset = frameView.topContentInset();
- FloatPoint positionForInsetClipLayer = FloatPoint(0, FrameView::yPositionForInsetClipLayer(scrollPosition, topContentInset));
- FloatPoint positionForContentsLayer = frameView.positionForRootContentLayer();
- FloatPoint positionForHeaderLayer = FloatPoint(scrollPositionForFixed.x(), FrameView::yPositionForHeaderLayer(scrollPosition, topContentInset));
- FloatPoint positionForFooterLayer = FloatPoint(scrollPositionForFixed.x(),
- FrameView::yPositionForFooterLayer(scrollPosition, topContentInset, frameView.totalContentsSize().height(), frameView.footerHeight()));
-
- if (programmaticScroll || scrollingLayerPositionAction == SetScrollingLayerPosition) {
- scrollLayer->setPosition(-frameView.scrollPosition());
- if (counterScrollingLayer)
- counterScrollingLayer->setPosition(scrollPositionForFixed);
- if (insetClipLayer)
- insetClipLayer->setPosition(positionForInsetClipLayer);
- if (contentShadowLayer)
- contentShadowLayer->setPosition(positionForContentsLayer);
- if (scrolledContentsLayer)
- scrolledContentsLayer->setPosition(positionForContentsLayer);
- if (headerLayer)
- headerLayer->setPosition(positionForHeaderLayer);
- if (footerLayer)
- footerLayer->setPosition(positionForFooterLayer);
- } else {
- scrollLayer->syncPosition(-frameView.scrollPosition());
- if (counterScrollingLayer)
- counterScrollingLayer->syncPosition(scrollPositionForFixed);
- if (insetClipLayer)
- insetClipLayer->syncPosition(positionForInsetClipLayer);
- if (contentShadowLayer)
- contentShadowLayer->syncPosition(positionForContentsLayer);
- if (scrolledContentsLayer)
- scrolledContentsLayer->syncPosition(positionForContentsLayer);
- if (headerLayer)
- headerLayer->syncPosition(positionForHeaderLayer);
- if (footerLayer)
- footerLayer->syncPosition(positionForFooterLayer);
-
- LayoutRect viewportRect = frameView.viewportConstrainedVisibleContentRect();
- syncChildPositions(viewportRect);
- }
- }
-
-#if PLATFORM(COCOA)
- if (m_page->expectsWheelEventTriggers()) {
- frameView.scrollAnimator().setWheelEventTestTrigger(m_page->testTrigger());
- if (const auto& trigger = m_page->testTrigger())
- trigger->removeTestDeferralForReason(reinterpret_cast<WheelEventTestTrigger::ScrollableAreaIdentifier>(scrollingNodeID), WheelEventTestTrigger::ScrollingThreadSyncNeeded);
- }
-#endif
-
- return;
- }
-
- // Overflow-scroll area.
- if (ScrollableArea* scrollableArea = frameView.scrollableAreaForScrollLayerID(scrollingNodeID)) {
- scrollableArea->setIsUserScroll(scrollingLayerPositionAction == SyncScrollingLayerPosition);
- scrollableArea->scrollToOffsetWithoutAnimation(scrollPosition);
- scrollableArea->setIsUserScroll(false);
- if (scrollingLayerPositionAction == SetScrollingLayerPosition)
- m_page->editorClient().overflowScrollPositionChanged();
-
-#if PLATFORM(COCOA)
- if (m_page->expectsWheelEventTriggers()) {
- frameView.scrollAnimator().setWheelEventTestTrigger(m_page->testTrigger());
- if (const auto& trigger = m_page->testTrigger())
- trigger->removeTestDeferralForReason(reinterpret_cast<WheelEventTestTrigger::ScrollableAreaIdentifier>(scrollingNodeID), WheelEventTestTrigger::ScrollingThreadSyncNeeded);
- }
-#endif
- }
-}
-
-void AsyncScrollingCoordinator::scrollableAreaScrollbarLayerDidChange(ScrollableArea& scrollableArea, ScrollbarOrientation orientation)
-{
- ASSERT(isMainThread());
- ASSERT(m_page);
-
- if (&scrollableArea != static_cast<ScrollableArea*>(m_page->mainFrame().view()))
- return;
-
- if (orientation == VerticalScrollbar)
- scrollableArea.verticalScrollbarLayerDidChange();
- else
- scrollableArea.horizontalScrollbarLayerDidChange();
-}
-
-ScrollingNodeID AsyncScrollingCoordinator::attachToStateTree(ScrollingNodeType nodeType, ScrollingNodeID newNodeID, ScrollingNodeID parentID)
-{
- return m_scrollingStateTree->attachNode(nodeType, newNodeID, parentID);
-}
-
-void AsyncScrollingCoordinator::detachFromStateTree(ScrollingNodeID nodeID)
-{
- m_scrollingStateTree->detachNode(nodeID);
-}
-
-void AsyncScrollingCoordinator::clearStateTree()
-{
- m_scrollingStateTree->clear();
-}
-
-void AsyncScrollingCoordinator::syncChildPositions(const LayoutRect& viewportRect)
-{
- if (!m_scrollingStateTree->rootStateNode())
- return;
-
- auto children = m_scrollingStateTree->rootStateNode()->children();
- if (!children)
- return;
-
- // FIXME: We'll have to traverse deeper into the tree at some point.
- for (auto& child : *children)
- child->syncLayerPositionForViewportRect(viewportRect);
-}
-
-void AsyncScrollingCoordinator::ensureRootStateNodeForFrameView(FrameView& frameView)
-{
- ASSERT(frameView.scrollLayerID());
- attachToStateTree(FrameScrollingNode, frameView.scrollLayerID(), 0);
-}
-
-void AsyncScrollingCoordinator::updateFrameScrollingNode(ScrollingNodeID nodeID, GraphicsLayer* layer, GraphicsLayer* scrolledContentsLayer, GraphicsLayer* counterScrollingLayer, GraphicsLayer* insetClipLayer, const ScrollingGeometry* scrollingGeometry)
-{
- ScrollingStateFrameScrollingNode* node = downcast<ScrollingStateFrameScrollingNode>(m_scrollingStateTree->stateNodeForID(nodeID));
- ASSERT(node);
- if (!node)
- return;
-
- node->setLayer(layer);
- node->setInsetClipLayer(insetClipLayer);
- node->setScrolledContentsLayer(scrolledContentsLayer);
- node->setCounterScrollingLayer(counterScrollingLayer);
-
- if (scrollingGeometry) {
- node->setScrollOrigin(scrollingGeometry->scrollOrigin);
- node->setScrollPosition(scrollingGeometry->scrollPosition);
- node->setTotalContentsSize(scrollingGeometry->contentSize);
- node->setReachableContentsSize(scrollingGeometry->reachableContentSize);
- node->setScrollableAreaSize(scrollingGeometry->scrollableAreaSize);
- }
-}
-
-void AsyncScrollingCoordinator::updateOverflowScrollingNode(ScrollingNodeID nodeID, GraphicsLayer* layer, GraphicsLayer* scrolledContentsLayer, const ScrollingGeometry* scrollingGeometry)
-{
- ScrollingStateOverflowScrollingNode* node = downcast<ScrollingStateOverflowScrollingNode>(m_scrollingStateTree->stateNodeForID(nodeID));
- ASSERT(node);
- if (!node)
- return;
-
- node->setLayer(layer);
- node->setScrolledContentsLayer(scrolledContentsLayer);
-
- if (scrollingGeometry) {
- node->setScrollOrigin(scrollingGeometry->scrollOrigin);
- node->setScrollPosition(scrollingGeometry->scrollPosition);
- node->setTotalContentsSize(scrollingGeometry->contentSize);
- node->setReachableContentsSize(scrollingGeometry->reachableContentSize);
- node->setScrollableAreaSize(scrollingGeometry->scrollableAreaSize);
-#if ENABLE(CSS_SCROLL_SNAP)
- setStateScrollingNodeSnapOffsetsAsFloat(*node, ScrollEventAxis::Horizontal, &scrollingGeometry->horizontalSnapOffsets, m_page->deviceScaleFactor());
- setStateScrollingNodeSnapOffsetsAsFloat(*node, ScrollEventAxis::Vertical, &scrollingGeometry->verticalSnapOffsets, m_page->deviceScaleFactor());
- node->setCurrentHorizontalSnapPointIndex(scrollingGeometry->currentHorizontalSnapPointIndex);
- node->setCurrentVerticalSnapPointIndex(scrollingGeometry->currentVerticalSnapPointIndex);
-#endif
- }
-}
-
-void AsyncScrollingCoordinator::updateViewportConstrainedNode(ScrollingNodeID nodeID, const ViewportConstraints& constraints, GraphicsLayer* graphicsLayer)
-{
- ASSERT(supportsFixedPositionLayers());
-
- ScrollingStateNode* node = m_scrollingStateTree->stateNodeForID(nodeID);
- if (!node)
- return;
-
- switch (constraints.constraintType()) {
- case ViewportConstraints::FixedPositionConstraint: {
- ScrollingStateFixedNode& fixedNode = downcast<ScrollingStateFixedNode>(*node);
- fixedNode.setLayer(graphicsLayer);
- fixedNode.updateConstraints((const FixedPositionViewportConstraints&)constraints);
- break;
- }
- case ViewportConstraints::StickyPositionConstraint: {
- ScrollingStateStickyNode& stickyNode = downcast<ScrollingStateStickyNode>(*node);
- stickyNode.setLayer(graphicsLayer);
- stickyNode.updateConstraints((const StickyPositionViewportConstraints&)constraints);
- break;
- }
- }
-}
-
-void AsyncScrollingCoordinator::setSynchronousScrollingReasons(SynchronousScrollingReasons reasons)
-{
- if (!m_scrollingStateTree->rootStateNode())
- return;
-
- // The FrameView's GraphicsLayer is likely to be out-of-synch with the PlatformLayer
- // at this point. So we'll update it before we switch back to main thread scrolling
- // in order to avoid layer positioning bugs.
- if (reasons)
- updateMainFrameScrollLayerPosition();
- m_scrollingStateTree->rootStateNode()->setSynchronousScrollingReasons(reasons);
-}
-
-void AsyncScrollingCoordinator::updateMainFrameScrollLayerPosition()
-{
- ASSERT(isMainThread());
-
- if (!m_page)
- return;
-
- FrameView* frameView = m_page->mainFrame().view();
- if (!frameView)
- return;
-
- if (GraphicsLayer* scrollLayer = scrollLayerForFrameView(*frameView))
- scrollLayer->setPosition(-frameView->scrollPosition());
-}
-
-bool AsyncScrollingCoordinator::isRubberBandInProgress() const
-{
- return scrollingTree()->isRubberBandInProgress();
-}
-
-void AsyncScrollingCoordinator::setScrollPinningBehavior(ScrollPinningBehavior pinning)
-{
- scrollingTree()->setScrollPinningBehavior(pinning);
-}
-
-String AsyncScrollingCoordinator::scrollingStateTreeAsText() const
-{
- if (m_scrollingStateTree->rootStateNode()) {
- if (m_nonFastScrollableRegionDirty)
- m_scrollingStateTree->rootStateNode()->setNonFastScrollableRegion(absoluteNonFastScrollableRegion());
- return m_scrollingStateTree->rootStateNode()->scrollingStateTreeAsText();
- }
-
- return String();
-}
-
-#if PLATFORM(COCOA)
-void AsyncScrollingCoordinator::setActiveScrollSnapIndices(ScrollingNodeID scrollingNodeID, unsigned horizontalIndex, unsigned verticalIndex)
-{
- ASSERT(isMainThread());
-
- if (!m_page)
- return;
-
- FrameView* frameView = frameViewForScrollingNode(scrollingNodeID);
- if (!frameView)
- return;
-
- if (scrollingNodeID == frameView->scrollLayerID()) {
- frameView->setCurrentHorizontalSnapPointIndex(horizontalIndex);
- frameView->setCurrentVerticalSnapPointIndex(verticalIndex);
- return;
- }
-
- // Overflow-scroll area.
- if (ScrollableArea* scrollableArea = frameView->scrollableAreaForScrollLayerID(scrollingNodeID)) {
- scrollableArea->setCurrentHorizontalSnapPointIndex(horizontalIndex);
- scrollableArea->setCurrentVerticalSnapPointIndex(verticalIndex);
- }
-}
-
-void AsyncScrollingCoordinator::deferTestsForReason(WheelEventTestTrigger::ScrollableAreaIdentifier identifier, WheelEventTestTrigger::DeferTestTriggerReason reason) const
-{
- ASSERT(isMainThread());
- if (!m_page || !m_page->expectsWheelEventTriggers())
- return;
-
- if (const auto& trigger = m_page->testTrigger()) {
- LOG(WheelEventTestTriggers, " (!) AsyncScrollingCoordinator::deferTestsForReason: Deferring %p for reason %d.", identifier, reason);
- trigger->deferTestsForReason(identifier, reason);
- }
-}
-
-void AsyncScrollingCoordinator::removeTestDeferralForReason(WheelEventTestTrigger::ScrollableAreaIdentifier identifier, WheelEventTestTrigger::DeferTestTriggerReason reason) const
-{
- ASSERT(isMainThread());
- if (!m_page || !m_page->expectsWheelEventTriggers())
- return;
-
- if (const auto& trigger = m_page->testTrigger()) {
- LOG(WheelEventTestTriggers, " (!) AsyncScrollingCoordinator::removeTestDeferralForReason: Deferring %p for reason %d.", identifier, reason);
- trigger->removeTestDeferralForReason(identifier, reason);
- }
-}
-#endif
-
-#if ENABLE(CSS_SCROLL_SNAP)
-bool AsyncScrollingCoordinator::isScrollSnapInProgress() const
-{
- return scrollingTree()->isScrollSnapInProgress();
-}
-
-void AsyncScrollingCoordinator::updateScrollSnapPropertiesWithFrameView(const FrameView& frameView)
-{
- if (auto node = downcast<ScrollingStateFrameScrollingNode>(m_scrollingStateTree->stateNodeForID(frameView.scrollLayerID()))) {
- setStateScrollingNodeSnapOffsetsAsFloat(*node, ScrollEventAxis::Horizontal, frameView.horizontalSnapOffsets(), m_page->deviceScaleFactor());
- setStateScrollingNodeSnapOffsetsAsFloat(*node, ScrollEventAxis::Vertical, frameView.verticalSnapOffsets(), m_page->deviceScaleFactor());
- node->setCurrentHorizontalSnapPointIndex(frameView.currentHorizontalSnapPointIndex());
- node->setCurrentVerticalSnapPointIndex(frameView.currentVerticalSnapPointIndex());
- }
-}
-#endif
-
-} // namespace WebCore
-
-#endif // ENABLE(ASYNC_SCROLLING)
diff --git a/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.h b/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.h
deleted file mode 100644
index db933d28f..000000000
--- a/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.h
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * Copyright (C) 2014-2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef AsyncScrollingCoordinator_h
-#define AsyncScrollingCoordinator_h
-
-#if ENABLE(ASYNC_SCROLLING)
-
-#include "ScrollingCoordinator.h"
-
-#include "ScrollingTree.h"
-#include "Timer.h"
-#include <wtf/PassRefPtr.h>
-#include <wtf/RefPtr.h>
-
-namespace WebCore {
-
-class Page;
-class Scrollbar;
-class ScrollingStateNode;
-class ScrollingStateScrollingNode;
-class ScrollingStateTree;
-
-// ScrollingCoordinator subclass that maintains a ScrollingStateTree and a ScrollingTree,
-// allowing asynchronous scrolling (in another thread or process).
-class AsyncScrollingCoordinator : public ScrollingCoordinator {
-public:
- static Ref<AsyncScrollingCoordinator> create(Page*);
- WEBCORE_EXPORT virtual ~AsyncScrollingCoordinator();
-
- ScrollingTree* scrollingTree() const { return m_scrollingTree.get(); }
-
- void scrollingStateTreePropertiesChanged();
-
- WEBCORE_EXPORT void scheduleUpdateScrollPositionAfterAsyncScroll(ScrollingNodeID, const FloatPoint&, bool programmaticScroll, SetOrSyncScrollingLayerPosition);
-
-#if PLATFORM(COCOA)
- WEBCORE_EXPORT void setActiveScrollSnapIndices(ScrollingNodeID, unsigned horizontalIndex, unsigned verticalIndex);
- void deferTestsForReason(WheelEventTestTrigger::ScrollableAreaIdentifier, WheelEventTestTrigger::DeferTestTriggerReason) const;
- void removeTestDeferralForReason(WheelEventTestTrigger::ScrollableAreaIdentifier, WheelEventTestTrigger::DeferTestTriggerReason) const;
-#endif
-
-#if ENABLE(CSS_SCROLL_SNAP)
- WEBCORE_EXPORT void updateScrollSnapPropertiesWithFrameView(const FrameView&) override;
-#endif
-
-protected:
- WEBCORE_EXPORT AsyncScrollingCoordinator(Page*);
-
- void setScrollingTree(PassRefPtr<ScrollingTree> scrollingTree) { m_scrollingTree = scrollingTree; }
-
- ScrollingStateTree* scrollingStateTree() { return m_scrollingStateTree.get(); }
-
- PassRefPtr<ScrollingTree> releaseScrollingTree() { return m_scrollingTree.release(); }
-
- void updateScrollPositionAfterAsyncScroll(ScrollingNodeID, const FloatPoint&, bool programmaticScroll, SetOrSyncScrollingLayerPosition);
-
- WEBCORE_EXPORT virtual String scrollingStateTreeAsText() const override;
- WEBCORE_EXPORT virtual void willCommitTree() override;
-
- bool nonFastScrollableRegionDirty() const { return m_nonFastScrollableRegionDirty; }
-
-private:
- virtual bool isAsyncScrollingCoordinator() const override { return true; }
-
- virtual bool supportsFixedPositionLayers() const override { return true; }
- virtual bool hasVisibleSlowRepaintViewportConstrainedObjects(const FrameView&) const override { return false; }
-
- WEBCORE_EXPORT virtual void frameViewLayoutUpdated(FrameView&) override;
- WEBCORE_EXPORT virtual void frameViewRootLayerDidChange(FrameView&) override;
- WEBCORE_EXPORT virtual void frameViewNonFastScrollableRegionChanged(FrameView&) override;
-
- WEBCORE_EXPORT virtual bool requestScrollPositionUpdate(FrameView&, const IntPoint&) override;
-
- WEBCORE_EXPORT virtual ScrollingNodeID attachToStateTree(ScrollingNodeType, ScrollingNodeID newNodeID, ScrollingNodeID parentID) override;
- WEBCORE_EXPORT virtual void detachFromStateTree(ScrollingNodeID) override;
- WEBCORE_EXPORT virtual void clearStateTree() override;
-
- WEBCORE_EXPORT virtual void updateViewportConstrainedNode(ScrollingNodeID, const ViewportConstraints&, GraphicsLayer*) override;
-
- WEBCORE_EXPORT virtual void updateFrameScrollingNode(ScrollingNodeID, GraphicsLayer* scrollLayer, GraphicsLayer* scrolledContentsLayer, GraphicsLayer* counterScrollingLayer, GraphicsLayer* insetClipLayer, const ScrollingGeometry* = nullptr) override;
- WEBCORE_EXPORT virtual void updateOverflowScrollingNode(ScrollingNodeID, GraphicsLayer* scrollLayer, GraphicsLayer* scrolledContentsLayer, const ScrollingGeometry* = nullptr) override;
-
- virtual bool isRubberBandInProgress() const override;
- virtual void setScrollPinningBehavior(ScrollPinningBehavior) override;
-
-#if ENABLE(CSS_SCROLL_SNAP)
- bool isScrollSnapInProgress() const override;
-#endif
-
- WEBCORE_EXPORT virtual void syncChildPositions(const LayoutRect& viewportRect) override;
- WEBCORE_EXPORT virtual void scrollableAreaScrollbarLayerDidChange(ScrollableArea&, ScrollbarOrientation) override;
-
- WEBCORE_EXPORT virtual void setSynchronousScrollingReasons(SynchronousScrollingReasons) override;
-
- virtual void scheduleTreeStateCommit() = 0;
-
- void ensureRootStateNodeForFrameView(FrameView&);
- void updateMainFrameScrollLayerPosition();
-
- void updateScrollPositionAfterAsyncScrollTimerFired();
- void setNonFastScrollableRegionDirty();
- void updateNonFastScrollableRegion();
-
- FrameView* frameViewForScrollingNode(ScrollingNodeID) const;
-
- Timer m_updateNodeScrollPositionTimer;
-
- struct ScheduledScrollUpdate {
- ScheduledScrollUpdate()
- : nodeID(0)
- , isProgrammaticScroll(false)
- , updateLayerPositionAction(SyncScrollingLayerPosition)
- { }
-
- ScheduledScrollUpdate(ScrollingNodeID scrollingNodeID, FloatPoint point, bool isProgrammatic, SetOrSyncScrollingLayerPosition udpateAction)
- : nodeID(scrollingNodeID)
- , scrollPosition(point)
- , isProgrammaticScroll(isProgrammatic)
- , updateLayerPositionAction(udpateAction)
- { }
-
- ScrollingNodeID nodeID;
- FloatPoint scrollPosition;
- bool isProgrammaticScroll;
- SetOrSyncScrollingLayerPosition updateLayerPositionAction;
-
- bool matchesUpdateType(const ScheduledScrollUpdate& other) const
- {
- return nodeID == other.nodeID
- && isProgrammaticScroll == other.isProgrammaticScroll
- && updateLayerPositionAction == other.updateLayerPositionAction;
- }
- };
-
- ScheduledScrollUpdate m_scheduledScrollUpdate;
-
- std::unique_ptr<ScrollingStateTree> m_scrollingStateTree;
- RefPtr<ScrollingTree> m_scrollingTree;
-
- bool m_nonFastScrollableRegionDirty { false };
-};
-
-} // namespace WebCore
-
-SPECIALIZE_TYPE_TRAITS_SCROLLING_COORDINATOR(WebCore::AsyncScrollingCoordinator, isAsyncScrollingCoordinator());
-
-#endif // ENABLE(ASYNC_SCROLLING)
-
-#endif // AsyncScrollingCoordinator_h
diff --git a/Source/WebCore/page/scrolling/AxisScrollSnapOffsets.cpp b/Source/WebCore/page/scrolling/AxisScrollSnapOffsets.cpp
deleted file mode 100644
index 12f06b2b9..000000000
--- a/Source/WebCore/page/scrolling/AxisScrollSnapOffsets.cpp
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * Copyright (C) 2014-2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "AxisScrollSnapOffsets.h"
-
-#include "ElementChildIterator.h"
-#include "HTMLCollection.h"
-#include "HTMLElement.h"
-#include "Length.h"
-#include "RenderBox.h"
-#include "RenderView.h"
-#include "ScrollableArea.h"
-#include "StyleScrollSnapPoints.h"
-
-#if ENABLE(CSS_SCROLL_SNAP)
-
-namespace WebCore {
-
-static void appendChildSnapOffsets(HTMLElement& parent, bool shouldAddHorizontalChildOffsets, Vector<LayoutUnit>& horizontalSnapOffsetSubsequence, bool shouldAddVerticalChildOffsets, Vector<LayoutUnit>& verticalSnapOffsetSubsequence)
-{
- RenderElement* scrollContainer = parent.renderer();
- ASSERT(scrollContainer);
-
- RenderView& renderView = scrollContainer->view();
-
- Vector<const RenderBox*> elements;
- for (auto& element : renderView.boxesWithScrollSnapCoordinates()) {
- if (element->findEnclosingScrollableContainer() != scrollContainer)
- continue;
-
- elements.append(element);
- }
-
- for (auto& box : elements) {
- auto& scrollSnapCoordinates = box->style().scrollSnapCoordinates();
- if (scrollSnapCoordinates.isEmpty())
- continue;
-
- LayoutRect viewSize = box->contentBoxRect();
- FloatPoint position = box->localToContainerPoint(FloatPoint(parent.renderBox()->scrollLeft(), parent.renderBox()->scrollTop()), parent.renderBox());
- for (auto& coordinate : scrollSnapCoordinates) {
- LayoutUnit lastPotentialSnapPositionX = position.x() + valueForLength(coordinate.width(), viewSize.width());
- if (shouldAddHorizontalChildOffsets && lastPotentialSnapPositionX > 0)
- horizontalSnapOffsetSubsequence.append(lastPotentialSnapPositionX);
-
- LayoutUnit lastPotentialSnapPositionY = position.y() + valueForLength(coordinate.height(), viewSize.height());
- if (shouldAddVerticalChildOffsets && lastPotentialSnapPositionY > 0)
- verticalSnapOffsetSubsequence.append(lastPotentialSnapPositionY);
- }
- }
-}
-
-static LayoutUnit destinationOffsetForViewSize(ScrollEventAxis axis, const LengthSize& destination, LayoutUnit viewSize)
-{
- const Length& dimension = (axis == ScrollEventAxis::Horizontal) ? destination.width() : destination.height();
- return valueForLength(dimension, viewSize);
-}
-
-static void updateFromStyle(Vector<LayoutUnit>& snapOffsets, const RenderStyle& style, ScrollEventAxis axis, LayoutUnit viewSize, LayoutUnit scrollSize, Vector<LayoutUnit>& snapOffsetSubsequence)
-{
- std::sort(snapOffsetSubsequence.begin(), snapOffsetSubsequence.end());
- if (snapOffsetSubsequence.isEmpty())
- snapOffsetSubsequence.append(0);
-
- auto* points = (axis == ScrollEventAxis::Horizontal) ? style.scrollSnapPointsX() : style.scrollSnapPointsY();
- bool hasRepeat = points ? points->hasRepeat : false;
- LayoutUnit repeatOffset = points ? valueForLength(points->repeatOffset, viewSize) : LayoutUnit::fromPixel(1);
- repeatOffset = std::max<LayoutUnit>(repeatOffset, LayoutUnit::fromPixel(1));
-
- LayoutUnit destinationOffset = destinationOffsetForViewSize(axis, style.scrollSnapDestination(), viewSize);
- LayoutUnit curSnapPositionShift = 0;
- LayoutUnit maxScrollOffset = scrollSize - viewSize;
- LayoutUnit lastSnapPosition = curSnapPositionShift;
- do {
- for (auto& snapPosition : snapOffsetSubsequence) {
- LayoutUnit potentialSnapPosition = curSnapPositionShift + snapPosition - destinationOffset;
- if (potentialSnapPosition < 0)
- continue;
-
- if (potentialSnapPosition >= maxScrollOffset)
- break;
-
- // Don't add another zero offset value.
- if (potentialSnapPosition)
- snapOffsets.append(potentialSnapPosition);
-
- lastSnapPosition = potentialSnapPosition + destinationOffset;
- }
- curSnapPositionShift = lastSnapPosition + repeatOffset;
- } while (hasRepeat && curSnapPositionShift < maxScrollOffset);
-
- if (snapOffsets.isEmpty())
- return;
-
- // Always put a snap point on the zero offset.
- if (snapOffsets.first())
- snapOffsets.insert(0, 0);
-
- // Always put a snap point on the maximum scroll offset.
- // Not a part of the spec, but necessary to prevent unreachable content when snapping.
- if (snapOffsets.last() != maxScrollOffset)
- snapOffsets.append(maxScrollOffset);
-}
-
-static bool styleUsesElements(ScrollEventAxis axis, const RenderStyle& style)
-{
- const ScrollSnapPoints* scrollSnapPoints = (axis == ScrollEventAxis::Horizontal) ? style.scrollSnapPointsX() : style.scrollSnapPointsY();
- if (scrollSnapPoints)
- return scrollSnapPoints->usesElements;
-
- const Length& destination = (axis == ScrollEventAxis::Horizontal) ? style.scrollSnapDestination().width() : style.scrollSnapDestination().height();
-
- return !destination.isUndefined();
-}
-
-void updateSnapOffsetsForScrollableArea(ScrollableArea& scrollableArea, HTMLElement& scrollingElement, const RenderBox& scrollingElementBox, const RenderStyle& scrollingElementStyle)
-{
- if (scrollingElementStyle.scrollSnapType() == ScrollSnapType::None) {
- scrollableArea.clearHorizontalSnapOffsets();
- scrollableArea.clearVerticalSnapOffsets();
- return;
- }
-
- LayoutRect viewSize = scrollingElementBox.contentBoxRect();
- LayoutUnit viewWidth = viewSize.width();
- LayoutUnit viewHeight = viewSize.height();
- LayoutUnit scrollWidth = scrollingElementBox.scrollWidth();
- LayoutUnit scrollHeight = scrollingElementBox.scrollHeight();
- bool canComputeHorizontalOffsets = scrollWidth > 0 && viewWidth > 0 && viewWidth < scrollWidth;
- bool canComputeVerticalOffsets = scrollHeight > 0 && viewHeight > 0 && viewHeight < scrollHeight;
-
- if (!canComputeHorizontalOffsets)
- scrollableArea.clearHorizontalSnapOffsets();
- if (!canComputeVerticalOffsets)
- scrollableArea.clearVerticalSnapOffsets();
-
- if (!canComputeHorizontalOffsets && !canComputeVerticalOffsets)
- return;
-
- Vector<LayoutUnit> horizontalSnapOffsetSubsequence;
- Vector<LayoutUnit> verticalSnapOffsetSubsequence;
-
- bool scrollSnapPointsXUsesElements = styleUsesElements(ScrollEventAxis::Horizontal, scrollingElementStyle);
- bool scrollSnapPointsYUsesElements = styleUsesElements(ScrollEventAxis::Vertical, scrollingElementStyle);
-
- if (scrollSnapPointsXUsesElements || scrollSnapPointsYUsesElements) {
- bool shouldAddHorizontalChildOffsets = scrollSnapPointsXUsesElements && canComputeHorizontalOffsets;
- bool shouldAddVerticalChildOffsets = scrollSnapPointsYUsesElements && canComputeVerticalOffsets;
- appendChildSnapOffsets(scrollingElement, shouldAddHorizontalChildOffsets, horizontalSnapOffsetSubsequence, shouldAddVerticalChildOffsets, verticalSnapOffsetSubsequence);
- }
-
- if (scrollingElementStyle.scrollSnapPointsX() && !scrollSnapPointsXUsesElements && canComputeHorizontalOffsets) {
- for (auto& snapLength : scrollingElementStyle.scrollSnapPointsX()->offsets)
- horizontalSnapOffsetSubsequence.append(valueForLength(snapLength, viewWidth));
- }
-
- if (scrollingElementStyle.scrollSnapPointsY() && !scrollSnapPointsYUsesElements && canComputeVerticalOffsets) {
- for (auto& snapLength : scrollingElementStyle.scrollSnapPointsY()->offsets)
- verticalSnapOffsetSubsequence.append(valueForLength(snapLength, viewHeight));
- }
-
- if (canComputeHorizontalOffsets) {
- auto horizontalSnapOffsets = std::make_unique<Vector<LayoutUnit>>();
- updateFromStyle(*horizontalSnapOffsets, scrollingElementStyle, ScrollEventAxis::Horizontal, viewWidth, scrollWidth, horizontalSnapOffsetSubsequence);
- if (horizontalSnapOffsets->isEmpty())
- scrollableArea.clearHorizontalSnapOffsets();
- else
- scrollableArea.setHorizontalSnapOffsets(WTFMove(horizontalSnapOffsets));
- }
- if (canComputeVerticalOffsets) {
- auto verticalSnapOffsets = std::make_unique<Vector<LayoutUnit>>();
- updateFromStyle(*verticalSnapOffsets, scrollingElementStyle, ScrollEventAxis::Vertical, viewHeight, scrollHeight, verticalSnapOffsetSubsequence);
- if (verticalSnapOffsets->isEmpty())
- scrollableArea.clearVerticalSnapOffsets();
- else
- scrollableArea.setVerticalSnapOffsets(WTFMove(verticalSnapOffsets));
- }
-}
-
-} // namespace WebCore
-
-#endif // CSS_SCROLL_SNAP
diff --git a/Source/WebCore/page/scrolling/AxisScrollSnapOffsets.h b/Source/WebCore/page/scrolling/AxisScrollSnapOffsets.h
deleted file mode 100644
index 8353cb509..000000000
--- a/Source/WebCore/page/scrolling/AxisScrollSnapOffsets.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2014-2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef AxisScrollSnapOffsets_h
-#define AxisScrollSnapOffsets_h
-
-#if ENABLE(CSS_SCROLL_SNAP)
-
-#include "ScrollTypes.h"
-#include <wtf/Vector.h>
-
-namespace WebCore {
-
-class HTMLElement;
-class RenderBox;
-class RenderStyle;
-class ScrollableArea;
-
-void updateSnapOffsetsForScrollableArea(ScrollableArea&, HTMLElement& scrollingElement, const RenderBox& scrollingElementBox, const RenderStyle& scrollingElementStyle);
-
-// closestSnapOffset is a templated function that takes in a Vector representing snap offsets as LayoutTypes (e.g. LayoutUnit or float) and
-// as well as a VelocityType indicating the velocity (e.g. float, CGFloat, etc.) This function is templated because the UI process will now
-// use pixel snapped floats to represent snap offsets rather than LayoutUnits.
-template <typename LayoutType, typename VelocityType>
-LayoutType closestSnapOffset(const Vector<LayoutType>& snapOffsets, LayoutType scrollDestination, VelocityType velocity, unsigned& activeSnapIndex)
-{
- ASSERT(snapOffsets.size());
- activeSnapIndex = 0;
- if (scrollDestination <= snapOffsets.first())
- return snapOffsets.first();
-
- activeSnapIndex = snapOffsets.size() - 1;
- if (scrollDestination >= snapOffsets.last())
- return snapOffsets.last();
-
- size_t lowerIndex = 0;
- size_t upperIndex = snapOffsets.size() - 1;
- while (lowerIndex < upperIndex - 1) {
- size_t middleIndex = (lowerIndex + upperIndex) / 2;
- if (scrollDestination < snapOffsets[middleIndex])
- upperIndex = middleIndex;
- else if (scrollDestination > snapOffsets[middleIndex])
- lowerIndex = middleIndex;
- else {
- upperIndex = middleIndex;
- lowerIndex = middleIndex;
- break;
- }
- }
- LayoutType lowerSnapPosition = snapOffsets[lowerIndex];
- LayoutType upperSnapPosition = snapOffsets[upperIndex];
- // Nonzero velocity indicates a flick gesture. Even if another snap point is closer, snap to the one in the direction of the flick gesture.
- if (velocity) {
- activeSnapIndex = (velocity < 0) ? lowerIndex : upperIndex;
- return velocity < 0 ? lowerSnapPosition : upperSnapPosition;
- }
-
- bool isCloserToLowerSnapPosition = scrollDestination - lowerSnapPosition <= upperSnapPosition - scrollDestination;
- activeSnapIndex = isCloserToLowerSnapPosition ? lowerIndex : upperIndex;
- return isCloserToLowerSnapPosition ? lowerSnapPosition : upperSnapPosition;
-}
-
-} // namespace WebCore
-
-#endif // CSS_SCROLL_SNAP
-
-#endif // AxisScrollSnapOffsets_h
diff --git a/Source/WebCore/page/scrolling/ScrollLatchingState.cpp b/Source/WebCore/page/scrolling/ScrollLatchingState.cpp
deleted file mode 100644
index e39d99efb..000000000
--- a/Source/WebCore/page/scrolling/ScrollLatchingState.cpp
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "ScrollLatchingState.h"
-
-#include "Element.h"
-
-namespace WebCore {
-
-ScrollLatchingState::ScrollLatchingState()
- : m_frame(nullptr)
- , m_widgetIsLatched(false)
- , m_startedGestureAtScrollLimit(false)
-{
-}
-
-ScrollLatchingState::~ScrollLatchingState()
-{
-}
-
-void ScrollLatchingState::clear()
-{
- m_wheelEventElement = nullptr;
- m_frame = nullptr;
- m_scrollableContainer = nullptr;
- m_widgetIsLatched = false;
- m_previousWheelScrolledElement = nullptr;
-}
-
-void ScrollLatchingState::setWheelEventElement(PassRefPtr<Element> element)
-{
- m_wheelEventElement = element;
-}
-
-void ScrollLatchingState::setWidgetIsLatched(bool isOverWidget)
-{
- m_widgetIsLatched = isOverWidget;
-}
-
-void ScrollLatchingState::setPreviousWheelScrolledElement(RefPtr<Element>&& element)
-{
- m_previousWheelScrolledElement = element;
-}
-
-void ScrollLatchingState::setScrollableContainer(PassRefPtr<ContainerNode> node)
-{
- m_scrollableContainer = node;
-}
-
-}
diff --git a/Source/WebCore/page/scrolling/ScrollLatchingState.h b/Source/WebCore/page/scrolling/ScrollLatchingState.h
deleted file mode 100644
index b1ddde5d7..000000000
--- a/Source/WebCore/page/scrolling/ScrollLatchingState.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef ScrollLatchingState_h
-#define ScrollLatchingState_h
-
-#include <wtf/RefPtr.h>
-
-namespace WebCore {
-
-class ContainerNode;
-class Element;
-class Frame;
-
-class ScrollLatchingState final {
-public:
- ScrollLatchingState();
- ~ScrollLatchingState();
-
- void clear();
-
- Element* wheelEventElement() { return m_wheelEventElement.get(); }
- void setWheelEventElement(PassRefPtr<Element>);
- Frame* frame() { return m_frame; }
- void setFrame(Frame* frame) { m_frame = frame; }
-
- bool widgetIsLatched() const { return m_widgetIsLatched; }
- void setWidgetIsLatched(bool isOverWidget);
-
- Element* previousWheelScrolledElement() { return m_previousWheelScrolledElement.get(); }
- void setPreviousWheelScrolledElement(RefPtr<Element>&&);
-
- ContainerNode* scrollableContainer() { return m_scrollableContainer.get(); }
- void setScrollableContainer(PassRefPtr<ContainerNode>);
- bool startedGestureAtScrollLimit() const { return m_startedGestureAtScrollLimit; }
- void setStartedGestureAtScrollLimit(bool startedAtLimit) { m_startedGestureAtScrollLimit = startedAtLimit; }
-
-private:
- RefPtr<Element> m_wheelEventElement;
- RefPtr<Element> m_previousWheelScrolledElement;
- RefPtr<ContainerNode> m_scrollableContainer;
-
- Frame* m_frame;
-
- bool m_widgetIsLatched;
- bool m_startedGestureAtScrollLimit;
-};
-
-}
-
-#endif
diff --git a/Source/WebCore/page/scrolling/ScrollingConstraints.cpp b/Source/WebCore/page/scrolling/ScrollingConstraints.cpp
index 00f101a34..4b3f4d68c 100644
--- a/Source/WebCore/page/scrolling/ScrollingConstraints.cpp
+++ b/Source/WebCore/page/scrolling/ScrollingConstraints.cpp
@@ -26,8 +26,6 @@
#include "config.h"
#include "ScrollingConstraints.h"
-#include "TextStream.h"
-
namespace WebCore {
FloatPoint FixedPositionViewportConstraints::layerPositionForViewportRect(const FloatRect& viewportRect) const
@@ -100,20 +98,4 @@ FloatPoint StickyPositionViewportConstraints::layerPositionForConstrainingRect(c
return m_layerPositionAtLastLayout + offset - m_stickyOffsetAtLastLayout;
}
-TextStream& operator<<(TextStream& ts, const FixedPositionViewportConstraints& constraints)
-{
- ts.dumpProperty("viewport-rect-at-last-layout", constraints.viewportRectAtLastLayout());
- ts.dumpProperty("layer-position-at-last-layout", constraints.layerPositionAtLastLayout());
-
- return ts;
-}
-
-TextStream& operator<<(TextStream& ts, const StickyPositionViewportConstraints& constraints)
-{
- ts.dumpProperty("sticky-position-at-last-layout", constraints.stickyOffsetAtLastLayout());
- ts.dumpProperty("layer-position-at-last-layout", constraints.layerPositionAtLastLayout());
-
- return ts;
-}
-
} // namespace WebCore
diff --git a/Source/WebCore/page/scrolling/ScrollingConstraints.h b/Source/WebCore/page/scrolling/ScrollingConstraints.h
index 23b05b8ab..d4c1dd461 100644
--- a/Source/WebCore/page/scrolling/ScrollingConstraints.h
+++ b/Source/WebCore/page/scrolling/ScrollingConstraints.h
@@ -33,7 +33,6 @@ namespace WebCore {
// ViewportConstraints classes encapsulate data and logic required to reposition elements whose layout
// depends on the viewport rect (positions fixed and sticky), when scrolling and zooming.
class ViewportConstraints {
- WTF_MAKE_FAST_ALLOCATED;
public:
enum ConstraintType {
FixedPositionConstraint,
@@ -86,7 +85,7 @@ public:
, m_layerPositionAtLastLayout(other.m_layerPositionAtLastLayout)
{ }
- WEBCORE_EXPORT FloatPoint layerPositionForViewportRect(const FloatRect& viewportRect) const;
+ FloatPoint layerPositionForViewportRect(const FloatRect& viewportRect) const;
const FloatRect& viewportRectAtLastLayout() const { return m_viewportRectAtLastLayout; }
void setViewportRectAtLastLayout(const FloatRect& rect) { m_viewportRectAtLastLayout = rect; }
@@ -138,7 +137,7 @@ public:
const FloatSize stickyOffsetAtLastLayout() const { return m_stickyOffsetAtLastLayout; }
void setStickyOffsetAtLastLayout(const FloatSize& offset) { m_stickyOffsetAtLastLayout = offset; }
- WEBCORE_EXPORT FloatPoint layerPositionForConstrainingRect(const FloatRect& constrainingRect) const;
+ FloatPoint layerPositionForConstrainingRect(const FloatRect& constrainingRect) const;
const FloatPoint& layerPositionAtLastLayout() const { return m_layerPositionAtLastLayout; }
void setLayerPositionAtLastLayout(const FloatPoint& point) { m_layerPositionAtLastLayout = point; }
@@ -168,9 +167,7 @@ public:
bool operator==(const StickyPositionViewportConstraints& other) const
{
- return m_alignmentOffset == other.m_alignmentOffset
- && m_anchorEdges == other.m_anchorEdges
- && m_leftOffset == other.m_leftOffset
+ return m_leftOffset == other.m_leftOffset
&& m_rightOffset == other.m_rightOffset
&& m_topOffset == other.m_topOffset
&& m_bottomOffset == other.m_bottomOffset
@@ -196,9 +193,6 @@ private:
FloatPoint m_layerPositionAtLastLayout;
};
-WEBCORE_EXPORT TextStream& operator<<(TextStream&, const FixedPositionViewportConstraints&);
-WEBCORE_EXPORT TextStream& operator<<(TextStream&, const StickyPositionViewportConstraints&);
-
} // namespace WebCore
#endif // ScrollingConstraints_h
diff --git a/Source/WebCore/page/scrolling/ScrollingCoordinator.cpp b/Source/WebCore/page/scrolling/ScrollingCoordinator.cpp
index 53b98c145..93dfb0cec 100644
--- a/Source/WebCore/page/scrolling/ScrollingCoordinator.cpp
+++ b/Source/WebCore/page/scrolling/ScrollingCoordinator.cpp
@@ -36,38 +36,35 @@
#include "PlatformWheelEvent.h"
#include "PluginViewBase.h"
#include "Region.h"
-#include "RenderLayerCompositor.h"
#include "RenderView.h"
#include "ScrollAnimator.h"
-#include "Settings.h"
-#include "TextStream.h"
#include <wtf/MainThread.h>
#include <wtf/text/StringBuilder.h>
-#if USE(COORDINATED_GRAPHICS)
-#include "ScrollingCoordinatorCoordinatedGraphics.h"
+#if USE(ACCELERATED_COMPOSITING)
+#include "RenderLayerCompositor.h"
#endif
-#if ENABLE(WEB_REPLAY)
-#include "ReplayController.h"
-#include <replay/InputCursor.h>
+#if USE(COORDINATED_GRAPHICS)
+#include "ScrollingCoordinatorCoordinatedGraphics.h"
#endif
namespace WebCore {
-#if !PLATFORM(COCOA)
-Ref<ScrollingCoordinator> ScrollingCoordinator::create(Page* page)
+#if !PLATFORM(MAC)
+PassRefPtr<ScrollingCoordinator> ScrollingCoordinator::create(Page* page)
{
#if USE(COORDINATED_GRAPHICS)
- return adoptRef(*new ScrollingCoordinatorCoordinatedGraphics(page));
+ return adoptRef(new ScrollingCoordinatorCoordinatedGraphics(page));
#endif
- return adoptRef(*new ScrollingCoordinator(page));
+ return adoptRef(new ScrollingCoordinator(page));
}
#endif
ScrollingCoordinator::ScrollingCoordinator(Page* page)
: m_page(page)
+ , m_forceSynchronousScrollLayerPositionUpdates(false)
{
}
@@ -79,115 +76,88 @@ ScrollingCoordinator::~ScrollingCoordinator()
void ScrollingCoordinator::pageDestroyed()
{
ASSERT(m_page);
- m_page = nullptr;
+ m_page = 0;
}
-bool ScrollingCoordinator::coordinatesScrollingForFrameView(const FrameView& frameView) const
+bool ScrollingCoordinator::coordinatesScrollingForFrameView(FrameView* frameView) const
{
ASSERT(isMainThread());
ASSERT(m_page);
- if (!frameView.frame().isMainFrame() && !m_page->settings().scrollingTreeIncludesFrames())
+ // We currently only handle the main frame.
+ if (!frameView->frame().isMainFrame())
return false;
+ // We currently only support composited mode.
+#if USE(ACCELERATED_COMPOSITING)
RenderView* renderView = m_page->mainFrame().contentRenderer();
if (!renderView)
return false;
return renderView->usesCompositing();
+#else
+ return false;
+#endif
}
-Region ScrollingCoordinator::absoluteNonFastScrollableRegionForFrame(const Frame& frame) const
+Region ScrollingCoordinator::computeNonFastScrollableRegion(const Frame* frame, const IntPoint& frameLocation) const
{
- RenderView* renderView = frame.contentRenderer();
- if (!renderView || renderView->documentBeingDestroyed())
- return Region();
-
-#if ENABLE(IOS_TOUCH_EVENTS)
- // On iOS, we use nonFastScrollableRegion to represent the region covered by elements with touch event handlers.
- ASSERT(frame.isMainFrame());
-
- Document* document = frame.document();
- if (!document)
- return Region();
-
- Vector<IntRect> touchRects;
- document->getTouchRects(touchRects);
-
- Region touchRegion;
- for (const auto& rect : touchRects)
- touchRegion.unite(rect);
-
- // FIXME: use absoluteRegionForEventTargets().
- return touchRegion;
-#else
Region nonFastScrollableRegion;
- FrameView* frameView = frame.view();
+ FrameView* frameView = frame->view();
if (!frameView)
return nonFastScrollableRegion;
- // FIXME: should ASSERT(!frameView->needsLayout()) here, but need to fix DebugPageOverlays
- // to not ask for regions at bad times.
+ IntPoint offset = frameLocation;
+ offset.moveBy(frameView->frameRect().location());
if (const FrameView::ScrollableAreaSet* scrollableAreas = frameView->scrollableAreas()) {
- for (auto& scrollableArea : *scrollableAreas) {
+ for (FrameView::ScrollableAreaSet::const_iterator it = scrollableAreas->begin(), end = scrollableAreas->end(); it != end; ++it) {
+ ScrollableArea* scrollableArea = *it;
+#if USE(ACCELERATED_COMPOSITING)
// Composited scrollable areas can be scrolled off the main thread.
- if (scrollableArea->usesAsyncScrolling())
+ if (scrollableArea->usesCompositedScrolling())
continue;
-
- bool isInsideFixed;
- IntRect box = scrollableArea->scrollableAreaBoundingBox(&isInsideFixed);
- if (isInsideFixed)
- box = IntRect(frameView->fixedScrollableAreaBoundsInflatedForScrolling(LayoutRect(box)));
-
+#endif
+ IntRect box = scrollableArea->scrollableAreaBoundingBox();
+ box.moveBy(offset);
nonFastScrollableRegion.unite(box);
}
}
- for (auto& widget : frameView->widgetsInRenderTree()) {
- RenderWidget* renderWidget = RenderWidget::find(widget);
- if (!renderWidget || !is<PluginViewBase>(*widget))
+ for (auto it = frameView->children().begin(), end = frameView->children().end(); it != end; ++it) {
+ if (!(*it)->isPluginViewBase())
continue;
-
- if (downcast<PluginViewBase>(*widget).wantsWheelEvents())
- nonFastScrollableRegion.unite(renderWidget->absoluteBoundingBoxRect());
+ PluginViewBase* pluginViewBase = toPluginViewBase((*it).get());
+ if (pluginViewBase->wantsWheelEvents())
+ nonFastScrollableRegion.unite(pluginViewBase->frameRect());
}
-
- // FIXME: if we've already accounted for this subframe as a scrollable area, we can avoid recursing into it here.
- for (Frame* subframe = frame.tree().firstChild(); subframe; subframe = subframe->tree().nextSibling()) {
- FrameView* subframeView = subframe->view();
- if (!subframeView)
- continue;
- Region subframeRegion = absoluteNonFastScrollableRegionForFrame(*subframe);
- // Map from the frame document to our document.
- IntPoint offset = subframeView->contentsToContainingViewContents(IntPoint());
+ for (Frame* subframe = frame->tree().firstChild(); subframe; subframe = subframe->tree().nextSibling())
+ nonFastScrollableRegion.unite(computeNonFastScrollableRegion(subframe, offset));
- // FIXME: this translation ignores non-trival transforms on the frame.
- subframeRegion.translate(toIntSize(offset));
- nonFastScrollableRegion.unite(subframeRegion);
- }
+ return nonFastScrollableRegion;
+}
- Document::RegionFixedPair wheelHandlerRegion = frame.document()->absoluteRegionForEventTargets(frame.document()->wheelEventTargets());
- bool wheelHandlerInFixedContent = wheelHandlerRegion.second;
- if (wheelHandlerInFixedContent) {
- // FIXME: need to handle position:sticky here too.
- LayoutRect inflatedWheelHandlerBounds = frameView->fixedScrollableAreaBoundsInflatedForScrolling(LayoutRect(wheelHandlerRegion.first.bounds()));
- wheelHandlerRegion.first.unite(enclosingIntRect(inflatedWheelHandlerBounds));
+unsigned ScrollingCoordinator::computeCurrentWheelEventHandlerCount()
+{
+ unsigned wheelEventHandlerCount = 0;
+
+ for (Frame* frame = &m_page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
+ if (frame->document())
+ wheelEventHandlerCount += frame->document()->wheelEventHandlerCount();
}
-
- nonFastScrollableRegion.unite(wheelHandlerRegion.first);
- // FIXME: If this is not the main frame, we could clip the region to the frame's bounds.
- return nonFastScrollableRegion;
-#endif
+ return wheelEventHandlerCount;
}
-Region ScrollingCoordinator::absoluteNonFastScrollableRegion() const
+void ScrollingCoordinator::frameViewWheelEventHandlerCountChanged(FrameView* frameView)
{
- return absoluteNonFastScrollableRegionForFrame(m_page->mainFrame());
+ ASSERT(isMainThread());
+ ASSERT(m_page);
+
+ recomputeWheelEventHandlerCountForFrameView(frameView);
}
-void ScrollingCoordinator::frameViewHasSlowRepaintObjectsDidChange(FrameView& frameView)
+void ScrollingCoordinator::frameViewHasSlowRepaintObjectsDidChange(FrameView* frameView)
{
ASSERT(isMainThread());
ASSERT(m_page);
@@ -195,10 +165,10 @@ void ScrollingCoordinator::frameViewHasSlowRepaintObjectsDidChange(FrameView& fr
if (!coordinatesScrollingForFrameView(frameView))
return;
- updateSynchronousScrollingReasons(frameView);
+ updateSynchronousScrollingReasons();
}
-void ScrollingCoordinator::frameViewFixedObjectsDidChange(FrameView& frameView)
+void ScrollingCoordinator::frameViewFixedObjectsDidChange(FrameView* frameView)
{
ASSERT(isMainThread());
ASSERT(m_page);
@@ -206,80 +176,75 @@ void ScrollingCoordinator::frameViewFixedObjectsDidChange(FrameView& frameView)
if (!coordinatesScrollingForFrameView(frameView))
return;
- updateSynchronousScrollingReasons(frameView);
+ updateSynchronousScrollingReasons();
}
-GraphicsLayer* ScrollingCoordinator::scrollLayerForScrollableArea(ScrollableArea& scrollableArea)
+#if USE(ACCELERATED_COMPOSITING)
+GraphicsLayer* ScrollingCoordinator::scrollLayerForScrollableArea(ScrollableArea* scrollableArea)
{
- return scrollableArea.layerForScrolling();
+ return scrollableArea->layerForScrolling();
}
-GraphicsLayer* ScrollingCoordinator::scrollLayerForFrameView(FrameView& frameView)
+GraphicsLayer* ScrollingCoordinator::horizontalScrollbarLayerForScrollableArea(ScrollableArea* scrollableArea)
{
- if (RenderView* renderView = frameView.frame().contentRenderer())
- return renderView->compositor().scrollLayer();
- return nullptr;
+ return scrollableArea->layerForHorizontalScrollbar();
}
-GraphicsLayer* ScrollingCoordinator::headerLayerForFrameView(FrameView& frameView)
+GraphicsLayer* ScrollingCoordinator::verticalScrollbarLayerForScrollableArea(ScrollableArea* scrollableArea)
{
-#if ENABLE(RUBBER_BANDING)
- if (RenderView* renderView = frameView.frame().contentRenderer())
- return renderView->compositor().headerLayer();
- return nullptr;
-#else
- UNUSED_PARAM(frameView);
- return nullptr;
-#endif
+ return scrollableArea->layerForVerticalScrollbar();
}
+#endif
-GraphicsLayer* ScrollingCoordinator::footerLayerForFrameView(FrameView& frameView)
+GraphicsLayer* ScrollingCoordinator::scrollLayerForFrameView(FrameView* frameView)
{
-#if ENABLE(RUBBER_BANDING)
- if (RenderView* renderView = frameView.frame().contentRenderer())
- return renderView->compositor().footerLayer();
- return nullptr;
+#if USE(ACCELERATED_COMPOSITING)
+ if (RenderView* renderView = frameView->frame().contentRenderer())
+ return renderView->compositor().scrollLayer();
+ return 0;
#else
UNUSED_PARAM(frameView);
- return nullptr;
+ return 0;
#endif
}
-GraphicsLayer* ScrollingCoordinator::counterScrollingLayerForFrameView(FrameView& frameView)
+GraphicsLayer* ScrollingCoordinator::headerLayerForFrameView(FrameView* frameView)
{
- if (RenderView* renderView = frameView.frame().contentRenderer())
- return renderView->compositor().fixedRootBackgroundLayer();
- return nullptr;
-}
-
-GraphicsLayer* ScrollingCoordinator::insetClipLayerForFrameView(FrameView& frameView)
-{
- if (RenderView* renderView = frameView.frame().contentRenderer())
- return renderView->compositor().clipLayer();
- return nullptr;
+#if USE(ACCELERATED_COMPOSITING) && ENABLE(RUBBER_BANDING)
+ if (RenderView* renderView = frameView->frame().contentRenderer())
+ renderView->compositor().headerLayer();
+ return 0;
+#else
+ UNUSED_PARAM(frameView);
+ return 0;
+#endif
}
-GraphicsLayer* ScrollingCoordinator::contentShadowLayerForFrameView(FrameView& frameView)
+GraphicsLayer* ScrollingCoordinator::footerLayerForFrameView(FrameView* frameView)
{
-#if ENABLE(RUBBER_BANDING)
- if (RenderView* renderView = frameView.frame().contentRenderer())
- return renderView->compositor().layerForContentShadow();
-
- return nullptr;
+#if USE(ACCELERATED_COMPOSITING) && ENABLE(RUBBER_BANDING)
+ if (RenderView* renderView = frameView->frame().contentRenderer())
+ return renderView->compositor().footerLayer();
+ return 0;
#else
UNUSED_PARAM(frameView);
- return nullptr;
+ return 0;
#endif
}
-GraphicsLayer* ScrollingCoordinator::rootContentLayerForFrameView(FrameView& frameView)
+GraphicsLayer* ScrollingCoordinator::counterScrollingLayerForFrameView(FrameView* frameView)
{
- if (RenderView* renderView = frameView.frame().contentRenderer())
- return renderView->compositor().rootContentLayer();
- return nullptr;
+#if USE(ACCELERATED_COMPOSITING)
+ if (RenderView* renderView = frameView->frame().contentRenderer())
+ return renderView->compositor().fixedRootBackgroundLayer();
+ return 0;
+#else
+ UNUSED_PARAM(frameView);
+ return 0;
+#endif
}
-void ScrollingCoordinator::frameViewRootLayerDidChange(FrameView& frameView)
+void ScrollingCoordinator::frameViewRootLayerDidChange(FrameView* frameView)
{
ASSERT(isMainThread());
ASSERT(m_page);
@@ -288,10 +253,11 @@ void ScrollingCoordinator::frameViewRootLayerDidChange(FrameView& frameView)
return;
frameViewLayoutUpdated(frameView);
- updateSynchronousScrollingReasons(frameView);
+ recomputeWheelEventHandlerCountForFrameView(frameView);
+ updateSynchronousScrollingReasons();
}
-#if PLATFORM(COCOA)
+#if PLATFORM(MAC)
void ScrollingCoordinator::handleWheelEventPhase(PlatformWheelEventPhase phase)
{
ASSERT(isMainThread());
@@ -303,58 +269,57 @@ void ScrollingCoordinator::handleWheelEventPhase(PlatformWheelEventPhase phase)
if (!frameView)
return;
- frameView->scrollAnimator().handleWheelEventPhase(phase);
+ frameView->scrollAnimator()->handleWheelEventPhase(phase);
}
#endif
-bool ScrollingCoordinator::hasVisibleSlowRepaintViewportConstrainedObjects(const FrameView& frameView) const
+bool ScrollingCoordinator::hasVisibleSlowRepaintViewportConstrainedObjects(FrameView* frameView) const
{
- const FrameView::ViewportConstrainedObjectSet* viewportConstrainedObjects = frameView.viewportConstrainedObjects();
+ const FrameView::ViewportConstrainedObjectSet* viewportConstrainedObjects = frameView->viewportConstrainedObjects();
if (!viewportConstrainedObjects)
return false;
- for (auto& viewportConstrainedObject : *viewportConstrainedObjects) {
- if (!is<RenderBoxModelObject>(*viewportConstrainedObject) || !viewportConstrainedObject->hasLayer())
+#if USE(ACCELERATED_COMPOSITING)
+ for (FrameView::ViewportConstrainedObjectSet::const_iterator it = viewportConstrainedObjects->begin(), end = viewportConstrainedObjects->end(); it != end; ++it) {
+ RenderObject* viewportConstrainedObject = *it;
+ if (!viewportConstrainedObject->isBoxModelObject() || !viewportConstrainedObject->hasLayer())
return true;
- RenderLayer& layer = *downcast<RenderBoxModelObject>(*viewportConstrainedObject).layer();
+ RenderLayer* layer = toRenderBoxModelObject(viewportConstrainedObject)->layer();
// Any explicit reason that a fixed position element is not composited shouldn't cause slow scrolling.
- if (!layer.isComposited() && layer.viewportConstrainedNotCompositedReason() == RenderLayer::NoNotCompositedReason)
+ if (!layer->isComposited() && layer->viewportConstrainedNotCompositedReason() == RenderLayer::NoNotCompositedReason)
return true;
}
return false;
+#else
+ return viewportConstrainedObjects->size();
+#endif
}
-SynchronousScrollingReasons ScrollingCoordinator::synchronousScrollingReasons(const FrameView& frameView) const
+SynchronousScrollingReasons ScrollingCoordinator::synchronousScrollingReasons() const
{
+ FrameView* frameView = m_page->mainFrame().view();
+ if (!frameView)
+ return static_cast<SynchronousScrollingReasons>(0);
+
SynchronousScrollingReasons synchronousScrollingReasons = (SynchronousScrollingReasons)0;
if (m_forceSynchronousScrollLayerPositionUpdates)
synchronousScrollingReasons |= ForcedOnMainThread;
-#if ENABLE(WEB_REPLAY)
- InputCursor& cursor = m_page->replayController().activeInputCursor();
- if (cursor.isCapturing() || cursor.isReplaying())
- synchronousScrollingReasons |= ForcedOnMainThread;
-#endif
- if (frameView.hasSlowRepaintObjects())
+ if (frameView->hasSlowRepaintObjects())
synchronousScrollingReasons |= HasSlowRepaintObjects;
- if (!supportsFixedPositionLayers() && frameView.hasViewportConstrainedObjects())
+ if (!supportsFixedPositionLayers() && frameView->hasViewportConstrainedObjects())
synchronousScrollingReasons |= HasViewportConstrainedObjectsWithoutSupportingFixedLayers;
if (supportsFixedPositionLayers() && hasVisibleSlowRepaintViewportConstrainedObjects(frameView))
synchronousScrollingReasons |= HasNonLayerViewportConstrainedObjects;
- if (frameView.frame().mainFrame().document() && frameView.frame().document()->isImageDocument())
+ if (m_page->mainFrame().document() && m_page->mainFrame().document()->isImageDocument())
synchronousScrollingReasons |= IsImageDocument;
return synchronousScrollingReasons;
}
-void ScrollingCoordinator::updateSynchronousScrollingReasons(FrameView& frameView)
+void ScrollingCoordinator::updateSynchronousScrollingReasons()
{
- // FIXME: Once we support async scrolling of iframes, we'll have to track the synchronous scrolling
- // reasons per frame (maybe on scrolling tree nodes).
- if (!frameView.frame().isMainFrame())
- return;
-
- setSynchronousScrollingReasons(synchronousScrollingReasons(frameView));
+ setSynchronousScrollingReasons(synchronousScrollingReasons());
}
void ScrollingCoordinator::setForceSynchronousScrollLayerPositionUpdates(bool forceSynchronousScrollLayerPositionUpdates)
@@ -363,25 +328,8 @@ void ScrollingCoordinator::setForceSynchronousScrollLayerPositionUpdates(bool fo
return;
m_forceSynchronousScrollLayerPositionUpdates = forceSynchronousScrollLayerPositionUpdates;
- if (FrameView* frameView = m_page->mainFrame().view())
- updateSynchronousScrollingReasons(*frameView);
-}
-
-bool ScrollingCoordinator::shouldUpdateScrollLayerPositionSynchronously() const
-{
- if (FrameView* frameView = m_page->mainFrame().view())
- return synchronousScrollingReasons(*frameView);
- return true;
-}
-
-#if ENABLE(WEB_REPLAY)
-void ScrollingCoordinator::replaySessionStateDidChange()
-{
- // FIXME: Once we support async scrolling of iframes, this should go through all subframes.
- if (FrameView* frameView = m_page->mainFrame().view())
- updateSynchronousScrollingReasons(*frameView);
+ updateSynchronousScrollingReasons();
}
-#endif
ScrollingNodeID ScrollingCoordinator::uniqueScrollLayerID()
{
@@ -399,15 +347,15 @@ String ScrollingCoordinator::synchronousScrollingReasonsAsText(SynchronousScroll
StringBuilder stringBuilder;
if (reasons & ScrollingCoordinator::ForcedOnMainThread)
- stringBuilder.appendLiteral("Forced on main thread, ");
+ stringBuilder.append("Forced on main thread, ");
if (reasons & ScrollingCoordinator::HasSlowRepaintObjects)
- stringBuilder.appendLiteral("Has slow repaint objects, ");
+ stringBuilder.append("Has slow repaint objects, ");
if (reasons & ScrollingCoordinator::HasViewportConstrainedObjectsWithoutSupportingFixedLayers)
- stringBuilder.appendLiteral("Has viewport constrained objects without supporting fixed layers, ");
+ stringBuilder.append("Has viewport constrained objects without supporting fixed layers, ");
if (reasons & ScrollingCoordinator::HasNonLayerViewportConstrainedObjects)
- stringBuilder.appendLiteral("Has non-layer viewport-constrained objects, ");
+ stringBuilder.append("Has non-layer viewport-constrained objects, ");
if (reasons & ScrollingCoordinator::IsImageDocument)
- stringBuilder.appendLiteral("Is image document, ");
+ stringBuilder.append("Is image document, ");
if (stringBuilder.length())
stringBuilder.resize(stringBuilder.length() - 2);
@@ -416,29 +364,7 @@ String ScrollingCoordinator::synchronousScrollingReasonsAsText(SynchronousScroll
String ScrollingCoordinator::synchronousScrollingReasonsAsText() const
{
- if (FrameView* frameView = m_page->mainFrame().view())
- return synchronousScrollingReasonsAsText(synchronousScrollingReasons(*frameView));
-
- return String();
-}
-
-TextStream& operator<<(TextStream& ts, ScrollingNodeType nodeType)
-{
- switch (nodeType) {
- case FrameScrollingNode:
- ts << "frame-scrolling";
- break;
- case OverflowScrollingNode:
- ts << "overflow-scrolling";
- break;
- case FixedNode:
- ts << "fixed";
- break;
- case StickyNode:
- ts << "sticky";
- break;
- }
- return ts;
+ return synchronousScrollingReasonsAsText(synchronousScrollingReasons());
}
} // namespace WebCore
diff --git a/Source/WebCore/page/scrolling/ScrollingCoordinator.h b/Source/WebCore/page/scrolling/ScrollingCoordinator.h
index c91c32cd2..0e05d69fd 100644
--- a/Source/WebCore/page/scrolling/ScrollingCoordinator.h
+++ b/Source/WebCore/page/scrolling/ScrollingCoordinator.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011, 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -32,7 +32,6 @@
#include "RenderObject.h"
#include "ScrollTypes.h"
#include <wtf/Forward.h>
-#include <wtf/TypeCasts.h>
#if ENABLE(ASYNC_SCROLLING)
#include <wtf/HashMap.h>
@@ -40,20 +39,16 @@
#include <wtf/Threading.h>
#endif
-#if PLATFORM(COCOA)
+#if PLATFORM(MAC)
#include <wtf/RetainPtr.h>
#endif
-#if ENABLE(CSS_SCROLL_SNAP)
-#include "AxisScrollSnapOffsets.h"
-#endif
-
namespace WebCore {
typedef unsigned SynchronousScrollingReasons;
typedef uint64_t ScrollingNodeID;
-enum ScrollingNodeType { FrameScrollingNode, OverflowScrollingNode, FixedNode, StickyNode };
+enum ScrollingNodeType { ScrollingNode, FixedNode, StickyNode };
class Document;
class Frame;
@@ -62,7 +57,6 @@ class GraphicsLayer;
class Page;
class Region;
class ScrollableArea;
-class TextStream;
class ViewportConstraints;
#if ENABLE(ASYNC_SCROLLING)
@@ -107,140 +101,114 @@ struct ScrollableAreaParameters {
class ScrollingCoordinator : public ThreadSafeRefCounted<ScrollingCoordinator> {
public:
- static Ref<ScrollingCoordinator> create(Page*);
+ static PassRefPtr<ScrollingCoordinator> create(Page*);
virtual ~ScrollingCoordinator();
- WEBCORE_EXPORT virtual void pageDestroyed();
+ virtual void pageDestroyed();
virtual bool isAsyncScrollingCoordinator() const { return false; }
virtual bool isRemoteScrollingCoordinator() const { return false; }
// Return whether this scrolling coordinator handles scrolling for the given frame view.
- virtual bool coordinatesScrollingForFrameView(const FrameView&) const;
+ bool coordinatesScrollingForFrameView(FrameView*) const;
// Should be called whenever the given frame view has been laid out.
- virtual void frameViewLayoutUpdated(FrameView&) { }
+ virtual void frameViewLayoutUpdated(FrameView*) { }
+
+ // Should be called whenever a wheel event handler is added or removed in the
+ // frame view's underlying document.
+ void frameViewWheelEventHandlerCountChanged(FrameView*);
// Should be called whenever the slow repaint objects counter changes between zero and one.
- void frameViewHasSlowRepaintObjectsDidChange(FrameView&);
+ void frameViewHasSlowRepaintObjectsDidChange(FrameView*);
// Should be called whenever the set of fixed objects changes.
- void frameViewFixedObjectsDidChange(FrameView&);
-
- // Called whenever the non-fast scrollable region changes for reasons other than layout.
- virtual void frameViewNonFastScrollableRegionChanged(FrameView&) { }
+ void frameViewFixedObjectsDidChange(FrameView*);
// Should be called whenever the root layer for the given frame view changes.
- virtual void frameViewRootLayerDidChange(FrameView&);
+ virtual void frameViewRootLayerDidChange(FrameView*);
// Return whether this scrolling coordinator can keep fixed position layers fixed to their
// containers while scrolling.
virtual bool supportsFixedPositionLayers() const { return false; }
-#if PLATFORM(COCOA)
+#if PLATFORM(MAC)
// Dispatched by the scrolling tree during handleWheelEvent. This is required as long as scrollbars are painted on the main thread.
void handleWheelEventPhase(PlatformWheelEventPhase);
#endif
-#if ENABLE(WEB_REPLAY)
- // Called when the page transitions between executing normally and deterministically.
- void replaySessionStateDidChange();
-#endif
-
// Force all scroll layer position updates to happen on the main thread.
- WEBCORE_EXPORT void setForceSynchronousScrollLayerPositionUpdates(bool);
+ void setForceSynchronousScrollLayerPositionUpdates(bool);
// These virtual functions are currently unique to the threaded scrolling architecture.
// Their meaningful implementations are in ScrollingCoordinatorMac.
virtual void commitTreeStateIfNeeded() { }
- virtual bool requestScrollPositionUpdate(FrameView&, const IntPoint&) { return false; }
- virtual bool handleWheelEvent(FrameView&, const PlatformWheelEvent&) { return true; }
+ virtual bool requestScrollPositionUpdate(FrameView*, const IntPoint&) { return false; }
+ virtual bool handleWheelEvent(FrameView*, const PlatformWheelEvent&) { return true; }
virtual ScrollingNodeID attachToStateTree(ScrollingNodeType, ScrollingNodeID newNodeID, ScrollingNodeID /*parentID*/) { return newNodeID; }
virtual void detachFromStateTree(ScrollingNodeID) { }
virtual void clearStateTree() { }
virtual void updateViewportConstrainedNode(ScrollingNodeID, const ViewportConstraints&, GraphicsLayer*) { }
-
- struct ScrollingGeometry {
- FloatSize scrollableAreaSize;
- FloatSize contentSize;
- FloatSize reachableContentSize; // Smaller than contentSize when overflow is hidden on one axis.
- FloatPoint scrollPosition;
- IntPoint scrollOrigin;
-#if ENABLE(CSS_SCROLL_SNAP)
- Vector<LayoutUnit> horizontalSnapOffsets;
- Vector<LayoutUnit> verticalSnapOffsets;
- unsigned currentHorizontalSnapPointIndex;
- unsigned currentVerticalSnapPointIndex;
-#endif
- };
-
- virtual void updateFrameScrollingNode(ScrollingNodeID, GraphicsLayer* /*scrollLayer*/, GraphicsLayer* /*scrolledContentsLayer*/, GraphicsLayer* /*counterScrollingLayer*/, GraphicsLayer* /*insetClipLayer*/, const ScrollingGeometry* = nullptr) { }
- virtual void updateOverflowScrollingNode(ScrollingNodeID, GraphicsLayer* /*scrollLayer*/, GraphicsLayer* /*scrolledContentsLayer*/, const ScrollingGeometry* = nullptr) { }
+ virtual void updateScrollingNode(ScrollingNodeID, GraphicsLayer* /*scrollLayer*/, GraphicsLayer* /*counterScrollingLayer*/) { }
virtual void syncChildPositions(const LayoutRect&) { }
virtual String scrollingStateTreeAsText() const;
virtual bool isRubberBandInProgress() const { return false; }
- virtual bool isScrollSnapInProgress() const { return false; }
- virtual void updateScrollSnapPropertiesWithFrameView(const FrameView&) { }
virtual void setScrollPinningBehavior(ScrollPinningBehavior) { }
// Generated a unique id for scroll layers.
ScrollingNodeID uniqueScrollLayerID();
enum MainThreadScrollingReasonFlags {
- ForcedOnMainThread = 1 << 0,
- HasSlowRepaintObjects = 1 << 1,
- HasViewportConstrainedObjectsWithoutSupportingFixedLayers = 1 << 2,
- HasNonLayerViewportConstrainedObjects = 1 << 3,
- IsImageDocument = 1 << 4
+ ForcedOnMainThread = 1 << 0,
+ HasSlowRepaintObjects = 1 << 1,
+ HasViewportConstrainedObjectsWithoutSupportingFixedLayers = 1 << 2,
+ HasNonLayerViewportConstrainedObjects = 1 << 3,
+ IsImageDocument = 1 << 4
};
- SynchronousScrollingReasons synchronousScrollingReasons(const FrameView&) const;
- bool shouldUpdateScrollLayerPositionSynchronously() const;
+ SynchronousScrollingReasons synchronousScrollingReasons() const;
+ bool shouldUpdateScrollLayerPositionSynchronously() const { return synchronousScrollingReasons(); }
- virtual void willDestroyScrollableArea(ScrollableArea&) { }
- virtual void scrollableAreaScrollLayerDidChange(ScrollableArea&) { }
- virtual void scrollableAreaScrollbarLayerDidChange(ScrollableArea&, ScrollbarOrientation) { }
+ virtual void willDestroyScrollableArea(ScrollableArea*) { }
+ virtual void scrollableAreaScrollLayerDidChange(ScrollableArea*) { }
+ virtual void scrollableAreaScrollbarLayerDidChange(ScrollableArea*, ScrollbarOrientation) { }
+ virtual void setLayerIsContainerForFixedPositionLayers(GraphicsLayer*, bool) { }
static String synchronousScrollingReasonsAsText(SynchronousScrollingReasons);
String synchronousScrollingReasonsAsText() const;
- Region absoluteNonFastScrollableRegion() const;
+ Region computeNonFastScrollableRegion(const Frame*, const IntPoint& frameLocation) const;
protected:
explicit ScrollingCoordinator(Page*);
- static GraphicsLayer* scrollLayerForScrollableArea(ScrollableArea&);
-
- GraphicsLayer* scrollLayerForFrameView(FrameView&);
- GraphicsLayer* counterScrollingLayerForFrameView(FrameView&);
- GraphicsLayer* insetClipLayerForFrameView(FrameView&);
- GraphicsLayer* rootContentLayerForFrameView(FrameView&);
- GraphicsLayer* contentShadowLayerForFrameView(FrameView&);
- GraphicsLayer* headerLayerForFrameView(FrameView&);
- GraphicsLayer* footerLayerForFrameView(FrameView&);
+#if USE(ACCELERATED_COMPOSITING)
+ static GraphicsLayer* scrollLayerForScrollableArea(ScrollableArea*);
+ static GraphicsLayer* horizontalScrollbarLayerForScrollableArea(ScrollableArea*);
+ static GraphicsLayer* verticalScrollbarLayerForScrollableArea(ScrollableArea*);
+#endif
- virtual void willCommitTree() { }
+ unsigned computeCurrentWheelEventHandlerCount();
+ GraphicsLayer* scrollLayerForFrameView(FrameView*);
+ GraphicsLayer* counterScrollingLayerForFrameView(FrameView*);
+ GraphicsLayer* headerLayerForFrameView(FrameView*);
+ GraphicsLayer* footerLayerForFrameView(FrameView*);
Page* m_page; // FIXME: ideally this would be a reference but it gets nulled on async teardown.
private:
+ virtual void recomputeWheelEventHandlerCountForFrameView(FrameView*) { }
virtual void setSynchronousScrollingReasons(SynchronousScrollingReasons) { }
- virtual bool hasVisibleSlowRepaintViewportConstrainedObjects(const FrameView&) const;
- void updateSynchronousScrollingReasons(FrameView&);
-
- Region absoluteNonFastScrollableRegionForFrame(const Frame&) const;
+ virtual bool hasVisibleSlowRepaintViewportConstrainedObjects(FrameView*) const;
+ void updateSynchronousScrollingReasons();
- bool m_forceSynchronousScrollLayerPositionUpdates { false };
+ bool m_forceSynchronousScrollLayerPositionUpdates;
};
-WEBCORE_EXPORT TextStream& operator<<(TextStream&, ScrollingNodeType);
+#define SCROLLING_COORDINATOR_TYPE_CASTS(ToValueTypeName, predicate) \
+ TYPE_CASTS_BASE(ToValueTypeName, WebCore::ScrollingCoordinator, value, value->predicate, value.predicate)
} // namespace WebCore
-#define SPECIALIZE_TYPE_TRAITS_SCROLLING_COORDINATOR(ToValueTypeName, predicate) \
-SPECIALIZE_TYPE_TRAITS_BEGIN(ToValueTypeName) \
- static bool isType(const WebCore::ScrollingCoordinator& value) { return value.predicate; } \
-SPECIALIZE_TYPE_TRAITS_END()
-
#endif // ScrollingCoordinator_h
diff --git a/Source/WebCore/page/scrolling/ScrollingStateFixedNode.cpp b/Source/WebCore/page/scrolling/ScrollingStateFixedNode.cpp
index ccdc832a0..cce42eb7e 100644
--- a/Source/WebCore/page/scrolling/ScrollingStateFixedNode.cpp
+++ b/Source/WebCore/page/scrolling/ScrollingStateFixedNode.cpp
@@ -29,14 +29,15 @@
#include "GraphicsLayer.h"
#include "ScrollingStateTree.h"
#include "TextStream.h"
+#include <wtf/OwnPtr.h>
#if ENABLE(ASYNC_SCROLLING) || USE(COORDINATED_GRAPHICS)
namespace WebCore {
-Ref<ScrollingStateFixedNode> ScrollingStateFixedNode::create(ScrollingStateTree& stateTree, ScrollingNodeID nodeID)
+PassOwnPtr<ScrollingStateFixedNode> ScrollingStateFixedNode::create(ScrollingStateTree& stateTree, ScrollingNodeID nodeID)
{
- return adoptRef(*new ScrollingStateFixedNode(stateTree, nodeID));
+ return adoptPtr(new ScrollingStateFixedNode(stateTree, nodeID));
}
ScrollingStateFixedNode::ScrollingStateFixedNode(ScrollingStateTree& tree, ScrollingNodeID nodeID)
@@ -54,9 +55,9 @@ ScrollingStateFixedNode::~ScrollingStateFixedNode()
{
}
-Ref<ScrollingStateNode> ScrollingStateFixedNode::clone(ScrollingStateTree& adoptiveTree)
+PassOwnPtr<ScrollingStateNode> ScrollingStateFixedNode::clone(ScrollingStateTree& adoptiveTree)
{
- return adoptRef(*new ScrollingStateFixedNode(*this, adoptiveTree));
+ return adoptPtr(new ScrollingStateFixedNode(*this, adoptiveTree));
}
void ScrollingStateFixedNode::updateConstraints(const FixedPositionViewportConstraints& constraints)
diff --git a/Source/WebCore/page/scrolling/ScrollingStateFixedNode.h b/Source/WebCore/page/scrolling/ScrollingStateFixedNode.h
index 98cb0ca10..a52d7b6d0 100644
--- a/Source/WebCore/page/scrolling/ScrollingStateFixedNode.h
+++ b/Source/WebCore/page/scrolling/ScrollingStateFixedNode.h
@@ -39,9 +39,9 @@ class FixedPositionViewportConstraints;
class ScrollingStateFixedNode final : public ScrollingStateNode {
public:
- static Ref<ScrollingStateFixedNode> create(ScrollingStateTree&, ScrollingNodeID);
+ static PassOwnPtr<ScrollingStateFixedNode> create(ScrollingStateTree&, ScrollingNodeID);
- virtual Ref<ScrollingStateNode> clone(ScrollingStateTree&) override;
+ virtual PassOwnPtr<ScrollingStateNode> clone(ScrollingStateTree&);
virtual ~ScrollingStateFixedNode();
@@ -49,7 +49,7 @@ public:
ViewportConstraints = NumStateNodeBits
};
- WEBCORE_EXPORT void updateConstraints(const FixedPositionViewportConstraints&);
+ void updateConstraints(const FixedPositionViewportConstraints&);
const FixedPositionViewportConstraints& viewportConstraints() const { return m_constraints; }
private:
@@ -63,9 +63,9 @@ private:
FixedPositionViewportConstraints m_constraints;
};
-} // namespace WebCore
+SCROLLING_STATE_NODE_TYPE_CASTS(ScrollingStateFixedNode, nodeType() == FixedNode);
-SPECIALIZE_TYPE_TRAITS_SCROLLING_STATE_NODE(ScrollingStateFixedNode, isFixedNode())
+} // namespace WebCore
#endif // ENABLE(ASYNC_SCROLLING) || USE(COORDINATED_GRAPHICS)
diff --git a/Source/WebCore/page/scrolling/ScrollingStateFrameScrollingNode.cpp b/Source/WebCore/page/scrolling/ScrollingStateFrameScrollingNode.cpp
deleted file mode 100644
index 8503936a1..000000000
--- a/Source/WebCore/page/scrolling/ScrollingStateFrameScrollingNode.cpp
+++ /dev/null
@@ -1,259 +0,0 @@
-/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "ScrollingStateFrameScrollingNode.h"
-
-#if ENABLE(ASYNC_SCROLLING) || USE(COORDINATED_GRAPHICS)
-
-#include "ScrollingStateTree.h"
-#include "TextStream.h"
-
-namespace WebCore {
-
-Ref<ScrollingStateFrameScrollingNode> ScrollingStateFrameScrollingNode::create(ScrollingStateTree& stateTree, ScrollingNodeID nodeID)
-{
- return adoptRef(*new ScrollingStateFrameScrollingNode(stateTree, nodeID));
-}
-
-ScrollingStateFrameScrollingNode::ScrollingStateFrameScrollingNode(ScrollingStateTree& stateTree, ScrollingNodeID nodeID)
- : ScrollingStateScrollingNode(stateTree, FrameScrollingNode, nodeID)
-{
-}
-
-ScrollingStateFrameScrollingNode::ScrollingStateFrameScrollingNode(const ScrollingStateFrameScrollingNode& stateNode, ScrollingStateTree& adoptiveTree)
- : ScrollingStateScrollingNode(stateNode, adoptiveTree)
-#if PLATFORM(MAC)
- , m_verticalScrollbarPainter(stateNode.verticalScrollbarPainter())
- , m_horizontalScrollbarPainter(stateNode.horizontalScrollbarPainter())
-#endif
- , m_nonFastScrollableRegion(stateNode.nonFastScrollableRegion())
- , m_requestedScrollPosition(stateNode.requestedScrollPosition())
- , m_frameScaleFactor(stateNode.frameScaleFactor())
- , m_topContentInset(stateNode.topContentInset())
- , m_headerHeight(stateNode.headerHeight())
- , m_footerHeight(stateNode.footerHeight())
- , m_synchronousScrollingReasons(stateNode.synchronousScrollingReasons())
- , m_behaviorForFixed(stateNode.scrollBehaviorForFixedElements())
- , m_requestedScrollPositionRepresentsProgrammaticScroll(stateNode.requestedScrollPositionRepresentsProgrammaticScroll())
- , m_fixedElementsLayoutRelativeToFrame(stateNode.fixedElementsLayoutRelativeToFrame())
-{
- if (hasChangedProperty(ScrolledContentsLayer))
- setScrolledContentsLayer(stateNode.scrolledContentsLayer().toRepresentation(adoptiveTree.preferredLayerRepresentation()));
-
- if (hasChangedProperty(CounterScrollingLayer))
- setCounterScrollingLayer(stateNode.counterScrollingLayer().toRepresentation(adoptiveTree.preferredLayerRepresentation()));
-
- if (hasChangedProperty(InsetClipLayer))
- setInsetClipLayer(stateNode.insetClipLayer().toRepresentation(adoptiveTree.preferredLayerRepresentation()));
-
- if (hasChangedProperty(ContentShadowLayer))
- setContentShadowLayer(stateNode.contentShadowLayer().toRepresentation(adoptiveTree.preferredLayerRepresentation()));
-
- if (hasChangedProperty(HeaderLayer))
- setHeaderLayer(stateNode.headerLayer().toRepresentation(adoptiveTree.preferredLayerRepresentation()));
-
- if (hasChangedProperty(FooterLayer))
- setFooterLayer(stateNode.footerLayer().toRepresentation(adoptiveTree.preferredLayerRepresentation()));
-}
-
-ScrollingStateFrameScrollingNode::~ScrollingStateFrameScrollingNode()
-{
-}
-
-Ref<ScrollingStateNode> ScrollingStateFrameScrollingNode::clone(ScrollingStateTree& adoptiveTree)
-{
- return adoptRef(*new ScrollingStateFrameScrollingNode(*this, adoptiveTree));
-}
-
-void ScrollingStateFrameScrollingNode::setFrameScaleFactor(float scaleFactor)
-{
- if (m_frameScaleFactor == scaleFactor)
- return;
-
- m_frameScaleFactor = scaleFactor;
-
- setPropertyChanged(FrameScaleFactor);
-}
-
-void ScrollingStateFrameScrollingNode::setNonFastScrollableRegion(const Region& nonFastScrollableRegion)
-{
- if (m_nonFastScrollableRegion == nonFastScrollableRegion)
- return;
-
- m_nonFastScrollableRegion = nonFastScrollableRegion;
- setPropertyChanged(NonFastScrollableRegion);
-}
-
-void ScrollingStateFrameScrollingNode::setSynchronousScrollingReasons(SynchronousScrollingReasons reasons)
-{
- if (m_synchronousScrollingReasons == reasons)
- return;
-
- m_synchronousScrollingReasons = reasons;
- setPropertyChanged(ReasonsForSynchronousScrolling);
-}
-
-void ScrollingStateFrameScrollingNode::setScrollBehaviorForFixedElements(ScrollBehaviorForFixedElements behaviorForFixed)
-{
- if (m_behaviorForFixed == behaviorForFixed)
- return;
-
- m_behaviorForFixed = behaviorForFixed;
- setPropertyChanged(BehaviorForFixedElements);
-}
-
-void ScrollingStateFrameScrollingNode::setHeaderHeight(int headerHeight)
-{
- if (m_headerHeight == headerHeight)
- return;
-
- m_headerHeight = headerHeight;
- setPropertyChanged(HeaderHeight);
-}
-
-void ScrollingStateFrameScrollingNode::setFooterHeight(int footerHeight)
-{
- if (m_footerHeight == footerHeight)
- return;
-
- m_footerHeight = footerHeight;
- setPropertyChanged(FooterHeight);
-}
-
-void ScrollingStateFrameScrollingNode::setTopContentInset(float topContentInset)
-{
- if (m_topContentInset == topContentInset)
- return;
-
- m_topContentInset = topContentInset;
- setPropertyChanged(TopContentInset);
-}
-
-void ScrollingStateFrameScrollingNode::setScrolledContentsLayer(const LayerRepresentation& layerRepresentation)
-{
- if (layerRepresentation == m_scrolledContentsLayer)
- return;
-
- m_scrolledContentsLayer = layerRepresentation;
- setPropertyChanged(ScrolledContentsLayer);
-}
-
-void ScrollingStateFrameScrollingNode::setCounterScrollingLayer(const LayerRepresentation& layerRepresentation)
-{
- if (layerRepresentation == m_counterScrollingLayer)
- return;
-
- m_counterScrollingLayer = layerRepresentation;
- setPropertyChanged(CounterScrollingLayer);
-}
-
-void ScrollingStateFrameScrollingNode::setInsetClipLayer(const LayerRepresentation& layerRepresentation)
-{
- if (layerRepresentation == m_insetClipLayer)
- return;
-
- m_insetClipLayer = layerRepresentation;
- setPropertyChanged(InsetClipLayer);
-}
-
-void ScrollingStateFrameScrollingNode::setContentShadowLayer(const LayerRepresentation& layerRepresentation)
-{
- if (layerRepresentation == m_contentShadowLayer)
- return;
-
- m_contentShadowLayer = layerRepresentation;
- setPropertyChanged(ContentShadowLayer);
-}
-
-void ScrollingStateFrameScrollingNode::setHeaderLayer(const LayerRepresentation& layerRepresentation)
-{
- if (layerRepresentation == m_headerLayer)
- return;
-
- m_headerLayer = layerRepresentation;
- setPropertyChanged(HeaderLayer);
-}
-
-void ScrollingStateFrameScrollingNode::setFooterLayer(const LayerRepresentation& layerRepresentation)
-{
- if (layerRepresentation == m_footerLayer)
- return;
-
- m_footerLayer = layerRepresentation;
- setPropertyChanged(FooterLayer);
-}
-
-void ScrollingStateFrameScrollingNode::setFixedElementsLayoutRelativeToFrame(bool fixedElementsLayoutRelativeToFrame)
-{
- if (fixedElementsLayoutRelativeToFrame == m_fixedElementsLayoutRelativeToFrame)
- return;
-
- m_fixedElementsLayoutRelativeToFrame = fixedElementsLayoutRelativeToFrame;
- setPropertyChanged(FixedElementsLayoutRelativeToFrame);
-}
-
-#if !PLATFORM(MAC)
-void ScrollingStateFrameScrollingNode::setScrollbarPaintersFromScrollbars(Scrollbar*, Scrollbar*)
-{
-}
-#endif
-
-void ScrollingStateFrameScrollingNode::dumpProperties(TextStream& ts, int indent) const
-{
- ts << "(Frame scrolling node" << "\n";
-
- ScrollingStateScrollingNode::dumpProperties(ts, indent);
-
- if (m_frameScaleFactor != 1) {
- writeIndent(ts, indent + 1);
- ts << "(frame scale factor " << m_frameScaleFactor << ")\n";
- }
-
- if (!m_nonFastScrollableRegion.isEmpty()) {
- ++indent;
- writeIndent(ts, indent);
- ts << "(non-fast-scrollable region";
- ++indent;
- for (auto rect : m_nonFastScrollableRegion.rects()) {
- ts << "\n";
- writeIndent(ts, indent);
- ts << rect;
- }
- ts << ")\n";
- indent -= 2;
- }
-
- if (m_synchronousScrollingReasons) {
- writeIndent(ts, indent + 1);
- ts << "(Scrolling on main thread because: " << ScrollingCoordinator::synchronousScrollingReasonsAsText(m_synchronousScrollingReasons) << ")\n";
- }
-
- // FIXME: dump more properties.
-}
-
-} // namespace WebCore
-
-#endif // ENABLE(ASYNC_SCROLLING) || USE(COORDINATED_GRAPHICS)
diff --git a/Source/WebCore/page/scrolling/ScrollingStateFrameScrollingNode.h b/Source/WebCore/page/scrolling/ScrollingStateFrameScrollingNode.h
deleted file mode 100644
index d57d1fd9f..000000000
--- a/Source/WebCore/page/scrolling/ScrollingStateFrameScrollingNode.h
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef ScrollingStateFrameScrollingNode_h
-#define ScrollingStateFrameScrollingNode_h
-
-#if ENABLE(ASYNC_SCROLLING) || USE(COORDINATED_GRAPHICS)
-
-#include "Region.h"
-#include "ScrollTypes.h"
-#include "ScrollbarThemeComposite.h"
-#include "ScrollingCoordinator.h"
-#include "ScrollingStateScrollingNode.h"
-
-namespace WebCore {
-
-class Scrollbar;
-
-class ScrollingStateFrameScrollingNode final : public ScrollingStateScrollingNode {
-public:
- static Ref<ScrollingStateFrameScrollingNode> create(ScrollingStateTree&, ScrollingNodeID);
-
- virtual Ref<ScrollingStateNode> clone(ScrollingStateTree&) override;
-
- virtual ~ScrollingStateFrameScrollingNode();
-
- enum ChangedProperty {
- FrameScaleFactor = NumScrollingStateNodeBits,
- NonFastScrollableRegion,
- ReasonsForSynchronousScrolling,
- ScrolledContentsLayer,
- CounterScrollingLayer,
- InsetClipLayer,
- ContentShadowLayer,
- HeaderHeight,
- FooterHeight,
- HeaderLayer,
- FooterLayer,
- PainterForScrollbar,
- BehaviorForFixedElements,
- TopContentInset,
- FixedElementsLayoutRelativeToFrame,
- };
-
- float frameScaleFactor() const { return m_frameScaleFactor; }
- WEBCORE_EXPORT void setFrameScaleFactor(float);
-
- const Region& nonFastScrollableRegion() const { return m_nonFastScrollableRegion; }
- WEBCORE_EXPORT void setNonFastScrollableRegion(const Region&);
-
- SynchronousScrollingReasons synchronousScrollingReasons() const { return m_synchronousScrollingReasons; }
- WEBCORE_EXPORT void setSynchronousScrollingReasons(SynchronousScrollingReasons);
-
- ScrollBehaviorForFixedElements scrollBehaviorForFixedElements() const { return m_behaviorForFixed; }
- WEBCORE_EXPORT void setScrollBehaviorForFixedElements(ScrollBehaviorForFixedElements);
-
- int headerHeight() const { return m_headerHeight; }
- WEBCORE_EXPORT void setHeaderHeight(int);
-
- int footerHeight() const { return m_footerHeight; }
- WEBCORE_EXPORT void setFooterHeight(int);
-
- float topContentInset() const { return m_topContentInset; }
- WEBCORE_EXPORT void setTopContentInset(float);
-
- const LayerRepresentation& scrolledContentsLayer() const { return m_scrolledContentsLayer; }
- WEBCORE_EXPORT void setScrolledContentsLayer(const LayerRepresentation&);
-
- // This is a layer moved in the opposite direction to scrolling, for example for background-attachment:fixed
- const LayerRepresentation& counterScrollingLayer() const { return m_counterScrollingLayer; }
- WEBCORE_EXPORT void setCounterScrollingLayer(const LayerRepresentation&);
-
- // This is a clipping layer that will scroll with the page for all y-delta scroll values between 0
- // and topContentInset(). Once the y-deltas get beyond the content inset point, this layer no longer
- // needs to move. If the topContentInset() is 0, this layer does not need to move at all. This is
- // only used on the Mac.
- const LayerRepresentation& insetClipLayer() const { return m_insetClipLayer; }
- WEBCORE_EXPORT void setInsetClipLayer(const LayerRepresentation&);
-
- const LayerRepresentation& contentShadowLayer() const { return m_contentShadowLayer; }
- WEBCORE_EXPORT void setContentShadowLayer(const LayerRepresentation&);
-
- // The header and footer layers scroll vertically with the page, they should remain fixed when scrolling horizontally.
- const LayerRepresentation& headerLayer() const { return m_headerLayer; }
- WEBCORE_EXPORT void setHeaderLayer(const LayerRepresentation&);
-
- // The header and footer layers scroll vertically with the page, they should remain fixed when scrolling horizontally.
- const LayerRepresentation& footerLayer() const { return m_footerLayer; }
- WEBCORE_EXPORT void setFooterLayer(const LayerRepresentation&);
-
- bool fixedElementsLayoutRelativeToFrame() const { return m_fixedElementsLayoutRelativeToFrame; }
- WEBCORE_EXPORT void setFixedElementsLayoutRelativeToFrame(bool);
-
-#if PLATFORM(MAC)
- ScrollbarPainter verticalScrollbarPainter() const { return m_verticalScrollbarPainter.get(); }
- ScrollbarPainter horizontalScrollbarPainter() const { return m_horizontalScrollbarPainter.get(); }
-#endif
- void setScrollbarPaintersFromScrollbars(Scrollbar* verticalScrollbar, Scrollbar* horizontalScrollbar);
-
- virtual void dumpProperties(TextStream&, int indent) const override;
-
-private:
- ScrollingStateFrameScrollingNode(ScrollingStateTree&, ScrollingNodeID);
- ScrollingStateFrameScrollingNode(const ScrollingStateFrameScrollingNode&, ScrollingStateTree&);
-
- LayerRepresentation m_counterScrollingLayer;
- LayerRepresentation m_insetClipLayer;
- LayerRepresentation m_scrolledContentsLayer;
- LayerRepresentation m_contentShadowLayer;
- LayerRepresentation m_headerLayer;
- LayerRepresentation m_footerLayer;
-
-#if PLATFORM(MAC)
- RetainPtr<ScrollbarPainter> m_verticalScrollbarPainter;
- RetainPtr<ScrollbarPainter> m_horizontalScrollbarPainter;
-#endif
-
- Region m_nonFastScrollableRegion;
- FloatPoint m_requestedScrollPosition;
- float m_frameScaleFactor { 1 };
- float m_topContentInset { 0 };
- int m_headerHeight { 0 };
- int m_footerHeight { 0 };
- SynchronousScrollingReasons m_synchronousScrollingReasons { 0 };
- ScrollBehaviorForFixedElements m_behaviorForFixed { StickToDocumentBounds };
- bool m_requestedScrollPositionRepresentsProgrammaticScroll { false };
- bool m_fixedElementsLayoutRelativeToFrame { false };
-};
-
-} // namespace WebCore
-
-SPECIALIZE_TYPE_TRAITS_SCROLLING_STATE_NODE(ScrollingStateFrameScrollingNode, isFrameScrollingNode())
-
-#endif // ENABLE(ASYNC_SCROLLING) || USE(COORDINATED_GRAPHICS)
-
-#endif // ScrollingStateFrameScrollingNode_h
diff --git a/Source/WebCore/page/scrolling/ScrollingStateNode.cpp b/Source/WebCore/page/scrolling/ScrollingStateNode.cpp
index d3e4f76fc..0b60c5acb 100644
--- a/Source/WebCore/page/scrolling/ScrollingStateNode.cpp
+++ b/Source/WebCore/page/scrolling/ScrollingStateNode.cpp
@@ -41,7 +41,7 @@ ScrollingStateNode::ScrollingStateNode(ScrollingNodeType nodeType, ScrollingStat
, m_nodeID(nodeID)
, m_changedProperties(0)
, m_scrollingStateTree(scrollingStateTree)
- , m_parent(nullptr)
+ , m_parent(0)
{
}
@@ -52,7 +52,7 @@ ScrollingStateNode::ScrollingStateNode(const ScrollingStateNode& stateNode, Scro
, m_nodeID(stateNode.scrollingNodeID())
, m_changedProperties(stateNode.changedProperties())
, m_scrollingStateTree(adoptiveTree)
- , m_parent(nullptr)
+ , m_parent(0)
{
if (hasChangedProperty(ScrollLayer))
setLayer(stateNode.layer().toRepresentation(adoptiveTree.preferredLayerRepresentation()));
@@ -72,9 +72,9 @@ void ScrollingStateNode::setPropertyChanged(unsigned propertyBit)
m_scrollingStateTree.setHasChangedProperties();
}
-PassRefPtr<ScrollingStateNode> ScrollingStateNode::cloneAndReset(ScrollingStateTree& adoptiveTree)
+PassOwnPtr<ScrollingStateNode> ScrollingStateNode::cloneAndReset(ScrollingStateTree& adoptiveTree)
{
- RefPtr<ScrollingStateNode> clone = this->clone(adoptiveTree);
+ OwnPtr<ScrollingStateNode> clone = this->clone(adoptiveTree);
// Now that this node is cloned, reset our change properties.
resetChangedProperties();
@@ -88,20 +88,53 @@ void ScrollingStateNode::cloneAndResetChildren(ScrollingStateNode& clone, Scroll
if (!m_children)
return;
- for (auto& child : *m_children)
- clone.appendChild(child->cloneAndReset(adoptiveTree));
+ size_t size = m_children->size();
+ for (size_t i = 0; i < size; ++i)
+ clone.appendChild(m_children->at(i)->cloneAndReset(adoptiveTree));
}
-void ScrollingStateNode::appendChild(PassRefPtr<ScrollingStateNode> childNode)
+void ScrollingStateNode::appendChild(PassOwnPtr<ScrollingStateNode> childNode)
{
childNode->setParent(this);
if (!m_children)
- m_children = std::make_unique<Vector<RefPtr<ScrollingStateNode>>>();
+ m_children = adoptPtr(new Vector<OwnPtr<ScrollingStateNode>>);
m_children->append(childNode);
}
+void ScrollingStateNode::removeChild(ScrollingStateNode* node)
+{
+ if (!m_children)
+ return;
+
+ size_t index = m_children->find(node);
+
+ // The index will be notFound if the node to remove is a deeper-than-1-level descendant or
+ // if node is the root state node.
+ if (index != notFound) {
+ node->willBeRemovedFromStateTree();
+ m_children->remove(index);
+ return;
+ }
+
+ size_t size = m_children->size();
+ for (size_t i = 0; i < size; ++i)
+ m_children->at(i)->removeChild(node);
+}
+
+void ScrollingStateNode::willBeRemovedFromStateTree()
+{
+ scrollingStateTree().didRemoveNode(scrollingNodeID());
+
+ if (!m_children)
+ return;
+
+ size_t size = m_children->size();
+ for (size_t i = 0; i < size; ++i)
+ m_children->at(i)->willBeRemovedFromStateTree();
+}
+
void ScrollingStateNode::setLayer(const LayerRepresentation& layerRepresentation)
{
if (layerRepresentation == m_layer)
@@ -119,10 +152,11 @@ void ScrollingStateNode::dump(TextStream& ts, int indent) const
if (m_children) {
writeIndent(ts, indent + 1);
- ts << "(children " << children()->size() << "\n";
+ size_t size = children()->size();
+ ts << "(children " << size << "\n";
- for (auto& child : *m_children)
- child->dump(ts, indent + 2);
+ for (size_t i = 0; i < size; i++)
+ m_children->at(i)->dump(ts, indent + 2);
writeIndent(ts, indent + 1);
ts << ")\n";
}
diff --git a/Source/WebCore/page/scrolling/ScrollingStateNode.h b/Source/WebCore/page/scrolling/ScrollingStateNode.h
index acb601c9e..ca705f3e2 100644
--- a/Source/WebCore/page/scrolling/ScrollingStateNode.h
+++ b/Source/WebCore/page/scrolling/ScrollingStateNode.h
@@ -30,10 +30,14 @@
#include "GraphicsLayer.h"
#include "ScrollingCoordinator.h"
-#include <wtf/RefCounted.h>
-#include <wtf/TypeCasts.h>
+#include <wtf/OwnPtr.h>
+#include <wtf/PassOwnPtr.h>
#include <wtf/Vector.h>
+#if PLATFORM(MAC)
+#include <wtf/RetainPtr.h>
+#endif
+
namespace WebCore {
class GraphicsLayer;
@@ -71,32 +75,14 @@ public:
: m_platformLayer(platformLayer)
, m_layerID(0)
, m_representation(PlatformLayerRepresentation)
- {
- retainPlatformLayer(platformLayer);
- }
+ { }
LayerRepresentation(GraphicsLayer::PlatformLayerID layerID)
: m_graphicsLayer(nullptr)
, m_layerID(layerID)
, m_representation(PlatformLayerIDRepresentation)
- {
- }
-
- LayerRepresentation(const LayerRepresentation& other)
- : m_platformLayer(other.m_platformLayer)
- , m_layerID(other.m_layerID)
- , m_representation(other.m_representation)
- {
- if (m_representation == PlatformLayerRepresentation)
- retainPlatformLayer(m_platformLayer);
- }
-
- ~LayerRepresentation()
- {
- if (m_representation == PlatformLayerRepresentation)
- releasePlatformLayer(m_platformLayer);
- }
-
+ { }
+
operator GraphicsLayer*() const
{
ASSERT(m_representation == GraphicsLayerRepresentation);
@@ -108,31 +94,14 @@ public:
ASSERT(m_representation == PlatformLayerRepresentation);
return m_platformLayer;
}
-
- GraphicsLayer::PlatformLayerID layerID() const
- {
- return m_layerID;
- }
operator GraphicsLayer::PlatformLayerID() const
{
ASSERT(m_representation != PlatformLayerRepresentation);
return m_layerID;
}
-
- LayerRepresentation& operator=(const LayerRepresentation& other)
- {
- m_platformLayer = other.m_platformLayer;
- m_layerID = other.m_layerID;
- m_representation = other.m_representation;
-
- if (m_representation == PlatformLayerRepresentation)
- retainPlatformLayer(m_platformLayer);
-
- return *this;
- }
-
- bool operator==(const LayerRepresentation& other) const
+
+ bool operator ==(const LayerRepresentation& other) const
{
if (m_representation != other.m_representation)
return false;
@@ -171,9 +140,6 @@ public:
bool representsPlatformLayerID() const { return m_representation == PlatformLayerIDRepresentation; }
private:
- WEBCORE_EXPORT void retainPlatformLayer(PlatformLayer*);
- WEBCORE_EXPORT void releasePlatformLayer(PlatformLayer*);
-
union {
GraphicsLayer* m_graphicsLayer;
PlatformLayer *m_platformLayer;
@@ -183,22 +149,15 @@ private:
Type m_representation;
};
-class ScrollingStateNode : public RefCounted<ScrollingStateNode> {
- WTF_MAKE_FAST_ALLOCATED;
+class ScrollingStateNode {
public:
ScrollingStateNode(ScrollingNodeType, ScrollingStateTree&, ScrollingNodeID);
virtual ~ScrollingStateNode();
ScrollingNodeType nodeType() const { return m_nodeType; }
- bool isFixedNode() const { return m_nodeType == FixedNode; }
- bool isStickyNode() const { return m_nodeType == StickyNode; }
- bool isScrollingNode() const { return m_nodeType == FrameScrollingNode || m_nodeType == OverflowScrollingNode; }
- bool isFrameScrollingNode() const { return m_nodeType == FrameScrollingNode; }
- bool isOverflowScrollingNode() const { return m_nodeType == OverflowScrollingNode; }
-
- virtual Ref<ScrollingStateNode> clone(ScrollingStateTree& adoptiveTree) = 0;
- PassRefPtr<ScrollingStateNode> cloneAndReset(ScrollingStateTree& adoptiveTree);
+ virtual PassOwnPtr<ScrollingStateNode> clone(ScrollingStateTree& adoptiveTree) = 0;
+ PassOwnPtr<ScrollingStateNode> cloneAndReset(ScrollingStateTree& adoptiveTree);
void cloneAndResetChildren(ScrollingStateNode&, ScrollingStateTree& adoptiveTree);
enum {
@@ -218,7 +177,7 @@ public:
virtual void syncLayerPositionForViewportRect(const LayoutRect& /*viewportRect*/) { }
const LayerRepresentation& layer() const { return m_layer; }
- WEBCORE_EXPORT void setLayer(const LayerRepresentation&);
+ void setLayer(const LayerRepresentation&);
ScrollingStateTree& scrollingStateTree() const { return m_scrollingStateTree; }
@@ -228,9 +187,10 @@ public:
void setParent(ScrollingStateNode* parent) { m_parent = parent; }
ScrollingNodeID parentNodeID() const { return m_parent ? m_parent->scrollingNodeID() : 0; }
- Vector<RefPtr<ScrollingStateNode>>* children() const { return m_children.get(); }
+ Vector<OwnPtr<ScrollingStateNode>>* children() const { return m_children.get(); }
- void appendChild(PassRefPtr<ScrollingStateNode>);
+ void appendChild(PassOwnPtr<ScrollingStateNode>);
+ void removeChild(ScrollingStateNode*);
String scrollingStateTreeAsText() const;
@@ -241,6 +201,7 @@ private:
void dump(TextStream&, int indent) const;
virtual void dumpProperties(TextStream&, int indent) const = 0;
+ void willBeRemovedFromStateTree();
const ScrollingNodeType m_nodeType;
ScrollingNodeID m_nodeID;
@@ -249,17 +210,15 @@ private:
ScrollingStateTree& m_scrollingStateTree;
ScrollingStateNode* m_parent;
- std::unique_ptr<Vector<RefPtr<ScrollingStateNode>>> m_children;
+ OwnPtr<Vector<OwnPtr<ScrollingStateNode>>> m_children;
LayerRepresentation m_layer;
};
-} // namespace WebCore
+#define SCROLLING_STATE_NODE_TYPE_CASTS(ToValueTypeName, predicate) \
+ TYPE_CASTS_BASE(ToValueTypeName, ScrollingStateNode, value, value->predicate, value.predicate)
-#define SPECIALIZE_TYPE_TRAITS_SCROLLING_STATE_NODE(ToValueTypeName, predicate) \
-SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::ToValueTypeName) \
- static bool isType(const WebCore::ScrollingStateNode& node) { return node.predicate; } \
-SPECIALIZE_TYPE_TRAITS_END()
+} // namespace WebCore
#endif // ENABLE(ASYNC_SCROLLING) || USE(COORDINATED_GRAPHICS)
diff --git a/Source/WebCore/page/scrolling/ScrollingStateOverflowScrollingNode.cpp b/Source/WebCore/page/scrolling/ScrollingStateOverflowScrollingNode.cpp
deleted file mode 100644
index 84d25ef0b..000000000
--- a/Source/WebCore/page/scrolling/ScrollingStateOverflowScrollingNode.cpp
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "ScrollingStateOverflowScrollingNode.h"
-
-#if ENABLE(ASYNC_SCROLLING) || USE(COORDINATED_GRAPHICS)
-
-#include "ScrollingStateTree.h"
-#include "TextStream.h"
-
-namespace WebCore {
-
-Ref<ScrollingStateOverflowScrollingNode> ScrollingStateOverflowScrollingNode::create(ScrollingStateTree& stateTree, ScrollingNodeID nodeID)
-{
- return adoptRef(*new ScrollingStateOverflowScrollingNode(stateTree, nodeID));
-}
-
-ScrollingStateOverflowScrollingNode::ScrollingStateOverflowScrollingNode(ScrollingStateTree& stateTree, ScrollingNodeID nodeID)
- : ScrollingStateScrollingNode(stateTree, OverflowScrollingNode, nodeID)
-{
-}
-
-ScrollingStateOverflowScrollingNode::ScrollingStateOverflowScrollingNode(const ScrollingStateOverflowScrollingNode& stateNode, ScrollingStateTree& adoptiveTree)
- : ScrollingStateScrollingNode(stateNode, adoptiveTree)
-{
- if (hasChangedProperty(ScrolledContentsLayer))
- setScrolledContentsLayer(stateNode.scrolledContentsLayer().toRepresentation(adoptiveTree.preferredLayerRepresentation()));
-}
-
-ScrollingStateOverflowScrollingNode::~ScrollingStateOverflowScrollingNode()
-{
-}
-
-Ref<ScrollingStateNode> ScrollingStateOverflowScrollingNode::clone(ScrollingStateTree& adoptiveTree)
-{
- return adoptRef(*new ScrollingStateOverflowScrollingNode(*this, adoptiveTree));
-}
-
-void ScrollingStateOverflowScrollingNode::setScrolledContentsLayer(const LayerRepresentation& layerRepresentation)
-{
- if (layerRepresentation == m_scrolledContentsLayer)
- return;
-
- m_scrolledContentsLayer = layerRepresentation;
- setPropertyChanged(ScrolledContentsLayer);
-}
-
-void ScrollingStateOverflowScrollingNode::dumpProperties(TextStream& ts, int indent) const
-{
- ts << "(" << "Overflow scrolling node" << "\n";
-
- ScrollingStateScrollingNode::dumpProperties(ts, indent);
-
- if (m_scrolledContentsLayer.layerID()) {
- writeIndent(ts, indent + 1);
- ts << "(scrolled contents layer " << m_scrolledContentsLayer.layerID() << ")\n";
- }
-}
-
-} // namespace WebCore
-
-#endif // ENABLE(ASYNC_SCROLLING) || USE(COORDINATED_GRAPHICS)
diff --git a/Source/WebCore/page/scrolling/ScrollingStateOverflowScrollingNode.h b/Source/WebCore/page/scrolling/ScrollingStateOverflowScrollingNode.h
deleted file mode 100644
index 73aaa3952..000000000
--- a/Source/WebCore/page/scrolling/ScrollingStateOverflowScrollingNode.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef ScrollingStateOverflowScrollingNode_h
-#define ScrollingStateOverflowScrollingNode_h
-
-#if ENABLE(ASYNC_SCROLLING) || USE(COORDINATED_GRAPHICS)
-
-#include "ScrollingStateScrollingNode.h"
-
-namespace WebCore {
-
-class ScrollingStateOverflowScrollingNode : public ScrollingStateScrollingNode {
-public:
- static Ref<ScrollingStateOverflowScrollingNode> create(ScrollingStateTree&, ScrollingNodeID);
-
- virtual Ref<ScrollingStateNode> clone(ScrollingStateTree&) override;
-
- virtual ~ScrollingStateOverflowScrollingNode();
-
- enum ChangedProperty {
- ScrolledContentsLayer = NumScrollingStateNodeBits
- };
-
- // This is a layer with the contents that move.
- const LayerRepresentation& scrolledContentsLayer() const { return m_scrolledContentsLayer; }
- WEBCORE_EXPORT void setScrolledContentsLayer(const LayerRepresentation&);
-
- virtual void dumpProperties(TextStream&, int indent) const override;
-
-private:
- ScrollingStateOverflowScrollingNode(ScrollingStateTree&, ScrollingNodeID);
- ScrollingStateOverflowScrollingNode(const ScrollingStateOverflowScrollingNode&, ScrollingStateTree&);
-
- LayerRepresentation m_scrolledContentsLayer;
-};
-
-} // namespace WebCore
-
-SPECIALIZE_TYPE_TRAITS_SCROLLING_STATE_NODE(ScrollingStateOverflowScrollingNode, isOverflowScrollingNode())
-
-#endif // ENABLE(ASYNC_SCROLLING) || USE(COORDINATED_GRAPHICS)
-
-#endif // ScrollingStateScrollingNode_h
diff --git a/Source/WebCore/page/scrolling/ScrollingStateScrollingNode.cpp b/Source/WebCore/page/scrolling/ScrollingStateScrollingNode.cpp
index c53b9b5ec..8ef8ff6a5 100644
--- a/Source/WebCore/page/scrolling/ScrollingStateScrollingNode.cpp
+++ b/Source/WebCore/page/scrolling/ScrollingStateScrollingNode.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012, 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -30,46 +30,80 @@
#include "ScrollingStateTree.h"
#include "TextStream.h"
+#include <wtf/OwnPtr.h>
namespace WebCore {
-ScrollingStateScrollingNode::ScrollingStateScrollingNode(ScrollingStateTree& stateTree, ScrollingNodeType nodeType, ScrollingNodeID nodeID)
- : ScrollingStateNode(nodeType, stateTree, nodeID)
+PassOwnPtr<ScrollingStateScrollingNode> ScrollingStateScrollingNode::create(ScrollingStateTree& stateTree, ScrollingNodeID nodeID)
+{
+ return adoptPtr(new ScrollingStateScrollingNode(stateTree, nodeID));
+}
+
+ScrollingStateScrollingNode::ScrollingStateScrollingNode(ScrollingStateTree& stateTree, ScrollingNodeID nodeID)
+ : ScrollingStateNode(ScrollingNode, stateTree, nodeID)
+#if PLATFORM(MAC) && !PLATFORM(IOS)
+ , m_verticalScrollbarPainter(0)
+ , m_horizontalScrollbarPainter(0)
+#endif
+ , m_frameScaleFactor(1)
+ , m_wheelEventHandlerCount(0)
+ , m_synchronousScrollingReasons(0)
+ , m_behaviorForFixed(StickToDocumentBounds)
+ , m_headerHeight(0)
+ , m_footerHeight(0)
+ , m_requestedScrollPositionRepresentsProgrammaticScroll(false)
{
}
ScrollingStateScrollingNode::ScrollingStateScrollingNode(const ScrollingStateScrollingNode& stateNode, ScrollingStateTree& adoptiveTree)
: ScrollingStateNode(stateNode, adoptiveTree)
- , m_scrollableAreaSize(stateNode.scrollableAreaSize())
+#if PLATFORM(MAC) && !PLATFORM(IOS)
+ , m_verticalScrollbarPainter(stateNode.verticalScrollbarPainter())
+ , m_horizontalScrollbarPainter(stateNode.horizontalScrollbarPainter())
+#endif
+ , m_viewportRect(stateNode.viewportRect())
, m_totalContentsSize(stateNode.totalContentsSize())
- , m_reachableContentsSize(stateNode.reachableContentsSize())
- , m_scrollPosition(stateNode.scrollPosition())
- , m_requestedScrollPosition(stateNode.requestedScrollPosition())
, m_scrollOrigin(stateNode.scrollOrigin())
-#if ENABLE(CSS_SCROLL_SNAP)
- , m_horizontalSnapOffsets(stateNode.horizontalSnapOffsets())
- , m_verticalSnapOffsets(stateNode.verticalSnapOffsets())
-#endif
, m_scrollableAreaParameters(stateNode.scrollableAreaParameters())
+ , m_nonFastScrollableRegion(stateNode.nonFastScrollableRegion())
+ , m_frameScaleFactor(stateNode.frameScaleFactor())
+ , m_wheelEventHandlerCount(stateNode.wheelEventHandlerCount())
+ , m_synchronousScrollingReasons(stateNode.synchronousScrollingReasons())
+ , m_behaviorForFixed(stateNode.scrollBehaviorForFixedElements())
+ , m_headerHeight(stateNode.headerHeight())
+ , m_footerHeight(stateNode.footerHeight())
+ , m_requestedScrollPosition(stateNode.requestedScrollPosition())
, m_requestedScrollPositionRepresentsProgrammaticScroll(stateNode.requestedScrollPositionRepresentsProgrammaticScroll())
- , m_expectsWheelEventTestTrigger(stateNode.expectsWheelEventTestTrigger())
{
+ if (hasChangedProperty(CounterScrollingLayer))
+ setCounterScrollingLayer(stateNode.counterScrollingLayer().toRepresentation(adoptiveTree.preferredLayerRepresentation()));
+
+ if (hasChangedProperty(HeaderLayer))
+ setHeaderLayer(stateNode.headerLayer().toRepresentation(adoptiveTree.preferredLayerRepresentation()));
+
+ if (hasChangedProperty(FooterLayer))
+ setFooterLayer(stateNode.footerLayer().toRepresentation(adoptiveTree.preferredLayerRepresentation()));
}
ScrollingStateScrollingNode::~ScrollingStateScrollingNode()
{
}
-void ScrollingStateScrollingNode::setScrollableAreaSize(const FloatSize& size)
+PassOwnPtr<ScrollingStateNode> ScrollingStateScrollingNode::clone(ScrollingStateTree& adoptiveTree)
{
- if (m_scrollableAreaSize == size)
+ return adoptPtr(new ScrollingStateScrollingNode(*this, adoptiveTree));
+}
+
+void ScrollingStateScrollingNode::setViewportRect(const IntRect& viewportRect)
+{
+ if (m_viewportRect == viewportRect)
return;
- m_scrollableAreaSize = size;
- setPropertyChanged(ScrollableAreaSize);
+ m_viewportRect = viewportRect;
+ setPropertyChanged(ViewportRect);
}
-void ScrollingStateScrollingNode::setTotalContentsSize(const FloatSize& totalContentsSize)
+void ScrollingStateScrollingNode::setTotalContentsSize(const IntSize& totalContentsSize)
{
if (m_totalContentsSize == totalContentsSize)
return;
@@ -78,124 +112,159 @@ void ScrollingStateScrollingNode::setTotalContentsSize(const FloatSize& totalCon
setPropertyChanged(TotalContentsSize);
}
-void ScrollingStateScrollingNode::setReachableContentsSize(const FloatSize& reachableContentsSize)
+void ScrollingStateScrollingNode::setScrollOrigin(const IntPoint& scrollOrigin)
{
- if (m_reachableContentsSize == reachableContentsSize)
+ if (m_scrollOrigin == scrollOrigin)
return;
- m_reachableContentsSize = reachableContentsSize;
- setPropertyChanged(ReachableContentsSize);
+ m_scrollOrigin = scrollOrigin;
+ setPropertyChanged(ScrollOrigin);
}
-void ScrollingStateScrollingNode::setScrollPosition(const FloatPoint& scrollPosition)
+void ScrollingStateScrollingNode::setScrollableAreaParameters(const ScrollableAreaParameters& parameters)
{
- if (m_scrollPosition == scrollPosition)
+ if (m_scrollableAreaParameters == parameters)
return;
- m_scrollPosition = scrollPosition;
- setPropertyChanged(ScrollPosition);
+ m_scrollableAreaParameters = parameters;
+ setPropertyChanged(ScrollableAreaParams);
}
-void ScrollingStateScrollingNode::setScrollOrigin(const IntPoint& scrollOrigin)
+void ScrollingStateScrollingNode::setFrameScaleFactor(float scaleFactor)
{
- if (m_scrollOrigin == scrollOrigin)
+ if (m_frameScaleFactor == scaleFactor)
return;
- m_scrollOrigin = scrollOrigin;
- setPropertyChanged(ScrollOrigin);
+ m_frameScaleFactor = scaleFactor;
+
+ setPropertyChanged(FrameScaleFactor);
}
-#if ENABLE(CSS_SCROLL_SNAP)
-void ScrollingStateScrollingNode::setHorizontalSnapOffsets(const Vector<float>& snapOffsets)
+void ScrollingStateScrollingNode::setNonFastScrollableRegion(const Region& nonFastScrollableRegion)
{
- if (m_horizontalSnapOffsets == snapOffsets)
+ if (m_nonFastScrollableRegion == nonFastScrollableRegion)
return;
- m_horizontalSnapOffsets = snapOffsets;
- setPropertyChanged(HorizontalSnapOffsets);
+ m_nonFastScrollableRegion = nonFastScrollableRegion;
+ setPropertyChanged(NonFastScrollableRegion);
}
-void ScrollingStateScrollingNode::setVerticalSnapOffsets(const Vector<float>& snapOffsets)
+void ScrollingStateScrollingNode::setWheelEventHandlerCount(unsigned wheelEventHandlerCount)
{
- if (m_verticalSnapOffsets == snapOffsets)
+ if (m_wheelEventHandlerCount == wheelEventHandlerCount)
return;
- m_verticalSnapOffsets = snapOffsets;
- setPropertyChanged(VerticalSnapOffsets);
+ m_wheelEventHandlerCount = wheelEventHandlerCount;
+ setPropertyChanged(WheelEventHandlerCount);
}
-void ScrollingStateScrollingNode::setCurrentHorizontalSnapPointIndex(unsigned index)
+void ScrollingStateScrollingNode::setSynchronousScrollingReasons(SynchronousScrollingReasons reasons)
{
- if (m_currentHorizontalSnapPointIndex == index)
+ if (m_synchronousScrollingReasons == reasons)
return;
-
- m_currentHorizontalSnapPointIndex = index;
- setPropertyChanged(CurrentHorizontalSnapOffsetIndex);
-}
-void ScrollingStateScrollingNode::setCurrentVerticalSnapPointIndex(unsigned index)
-{
- if (m_currentVerticalSnapPointIndex == index)
- return;
-
- m_currentVerticalSnapPointIndex = index;
- setPropertyChanged(CurrentVerticalSnapOffsetIndex);
+ m_synchronousScrollingReasons = reasons;
+ setPropertyChanged(ReasonsForSynchronousScrolling);
}
-#endif
-void ScrollingStateScrollingNode::setScrollableAreaParameters(const ScrollableAreaParameters& parameters)
+void ScrollingStateScrollingNode::setScrollBehaviorForFixedElements(ScrollBehaviorForFixedElements behaviorForFixed)
{
- if (m_scrollableAreaParameters == parameters)
+ if (m_behaviorForFixed == behaviorForFixed)
return;
- m_scrollableAreaParameters = parameters;
- setPropertyChanged(ScrollableAreaParams);
+ m_behaviorForFixed = behaviorForFixed;
+ setPropertyChanged(BehaviorForFixedElements);
}
-void ScrollingStateScrollingNode::setRequestedScrollPosition(const FloatPoint& requestedScrollPosition, bool representsProgrammaticScroll)
+void ScrollingStateScrollingNode::setRequestedScrollPosition(const IntPoint& requestedScrollPosition, bool representsProgrammaticScroll)
{
m_requestedScrollPosition = requestedScrollPosition;
m_requestedScrollPositionRepresentsProgrammaticScroll = representsProgrammaticScroll;
setPropertyChanged(RequestedScrollPosition);
}
-void ScrollingStateScrollingNode::setExpectsWheelEventTestTrigger(bool expectsTestTrigger)
+void ScrollingStateScrollingNode::setHeaderHeight(int headerHeight)
+{
+ if (m_headerHeight == headerHeight)
+ return;
+
+ m_headerHeight = headerHeight;
+ setPropertyChanged(HeaderHeight);
+}
+
+void ScrollingStateScrollingNode::setFooterHeight(int footerHeight)
+{
+ if (m_footerHeight == footerHeight)
+ return;
+
+ m_footerHeight = footerHeight;
+ setPropertyChanged(FooterHeight);
+}
+
+void ScrollingStateScrollingNode::setCounterScrollingLayer(const LayerRepresentation& layerRepresentation)
{
- if (expectsTestTrigger == m_expectsWheelEventTestTrigger)
+ if (layerRepresentation == m_counterScrollingLayer)
return;
+
+ m_counterScrollingLayer = layerRepresentation;
+
+ setPropertyChanged(CounterScrollingLayer);
+}
+
+void ScrollingStateScrollingNode::setHeaderLayer(const LayerRepresentation& layerRepresentation)
+{
+ if (layerRepresentation == m_headerLayer)
+ return;
+
+ m_headerLayer = layerRepresentation;
- m_expectsWheelEventTestTrigger = expectsTestTrigger;
- setPropertyChanged(ExpectsWheelEventTestTrigger);
+ setPropertyChanged(HeaderLayer);
}
+
+void ScrollingStateScrollingNode::setFooterLayer(const LayerRepresentation& layerRepresentation)
+{
+ if (layerRepresentation == m_footerLayer)
+ return;
+
+ m_footerLayer = layerRepresentation;
+
+ setPropertyChanged(FooterLayer);
+}
+
+#if !(PLATFORM(MAC) && !PLATFORM(IOS))
+void ScrollingStateScrollingNode::setScrollbarPaintersFromScrollbars(Scrollbar*, Scrollbar*)
+{
+}
+#endif
+
void ScrollingStateScrollingNode::dumpProperties(TextStream& ts, int indent) const
{
- if (m_scrollPosition != FloatPoint()) {
+ ts << "(" << "Scrolling node" << "\n";
+
+ if (!m_viewportRect.isEmpty()) {
+ writeIndent(ts, indent + 1);
+ ts << "(viewport rect " << m_viewportRect.x() << " " << m_viewportRect.y() << " " << m_viewportRect.width() << " " << m_viewportRect.height() << ")\n";
+ }
+
+ if (!m_totalContentsSize.isEmpty()) {
writeIndent(ts, indent + 1);
- ts << "(scroll position "
- << TextStream::FormatNumberRespectingIntegers(m_scrollPosition.x()) << " "
- << TextStream::FormatNumberRespectingIntegers(m_scrollPosition.y()) << ")\n";
+ ts << "(contents size " << m_totalContentsSize.width() << " " << m_totalContentsSize.height() << ")\n";
}
- if (!m_scrollableAreaSize.isEmpty()) {
+ if (m_frameScaleFactor != 1) {
writeIndent(ts, indent + 1);
- ts << "(scrollable area size "
- << TextStream::FormatNumberRespectingIntegers(m_scrollableAreaSize.width()) << " "
- << TextStream::FormatNumberRespectingIntegers(m_scrollableAreaSize.height()) << ")\n";
+ ts << "(frame scale factor " << m_frameScaleFactor << ")\n";
}
- if (!m_totalContentsSize.isEmpty()) {
+ if (m_synchronousScrollingReasons) {
writeIndent(ts, indent + 1);
- ts << "(contents size "
- << TextStream::FormatNumberRespectingIntegers(m_totalContentsSize.width()) << " "
- << TextStream::FormatNumberRespectingIntegers(m_totalContentsSize.height()) << ")\n";
+ ts << "(Scrolling on main thread because: " << ScrollingCoordinator::synchronousScrollingReasonsAsText(m_synchronousScrollingReasons) << ")\n";
}
if (m_requestedScrollPosition != IntPoint()) {
writeIndent(ts, indent + 1);
- ts << "(requested scroll position "
- << TextStream::FormatNumberRespectingIntegers(m_requestedScrollPosition.x()) << " "
- << TextStream::FormatNumberRespectingIntegers(m_requestedScrollPosition.y()) << ")\n";
+ ts << "(requested scroll position " << m_requestedScrollPosition.x() << " " << m_requestedScrollPosition.y() << ")\n";
}
if (m_scrollOrigin != IntPoint()) {
diff --git a/Source/WebCore/page/scrolling/ScrollingStateScrollingNode.h b/Source/WebCore/page/scrolling/ScrollingStateScrollingNode.h
index 091efd1fa..14be04b97 100644
--- a/Source/WebCore/page/scrolling/ScrollingStateScrollingNode.h
+++ b/Source/WebCore/page/scrolling/ScrollingStateScrollingNode.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012, 2014-2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -28,100 +28,136 @@
#if ENABLE(ASYNC_SCROLLING) || USE(COORDINATED_GRAPHICS)
+#include "GraphicsLayer.h"
+#include "IntRect.h"
+#include "Region.h"
#include "ScrollTypes.h"
+#include "ScrollbarThemeComposite.h"
#include "ScrollingCoordinator.h"
#include "ScrollingStateNode.h"
+#include <wtf/PassOwnPtr.h>
namespace WebCore {
-class ScrollingStateScrollingNode : public ScrollingStateNode {
+class Scrollbar;
+
+class ScrollingStateScrollingNode final : public ScrollingStateNode {
public:
+ static PassOwnPtr<ScrollingStateScrollingNode> create(ScrollingStateTree&, ScrollingNodeID);
+
+ virtual PassOwnPtr<ScrollingStateNode> clone(ScrollingStateTree&);
+
virtual ~ScrollingStateScrollingNode();
enum ChangedProperty {
- ScrollableAreaSize = NumStateNodeBits,
+ ViewportRect = NumStateNodeBits,
TotalContentsSize,
- ReachableContentsSize,
- ScrollPosition,
ScrollOrigin,
ScrollableAreaParams,
+ FrameScaleFactor,
+ NonFastScrollableRegion,
+ WheelEventHandlerCount,
+ ReasonsForSynchronousScrolling,
RequestedScrollPosition,
- NumScrollingStateNodeBits,
-#if ENABLE(CSS_SCROLL_SNAP)
- HorizontalSnapOffsets,
- VerticalSnapOffsets,
- CurrentHorizontalSnapOffsetIndex,
- CurrentVerticalSnapOffsetIndex,
-#endif
- ExpectsWheelEventTestTrigger,
+ CounterScrollingLayer,
+ HeaderHeight,
+ FooterHeight,
+ HeaderLayer,
+ FooterLayer,
+ PainterForScrollbar,
+ BehaviorForFixedElements
};
- const FloatSize& scrollableAreaSize() const { return m_scrollableAreaSize; }
- WEBCORE_EXPORT void setScrollableAreaSize(const FloatSize&);
+ const IntRect& viewportRect() const { return m_viewportRect; }
+ void setViewportRect(const IntRect&);
- const FloatSize& totalContentsSize() const { return m_totalContentsSize; }
- WEBCORE_EXPORT void setTotalContentsSize(const FloatSize&);
-
- const FloatSize& reachableContentsSize() const { return m_reachableContentsSize; }
- WEBCORE_EXPORT void setReachableContentsSize(const FloatSize&);
-
- const FloatPoint& scrollPosition() const { return m_scrollPosition; }
- WEBCORE_EXPORT void setScrollPosition(const FloatPoint&);
+ const IntSize& totalContentsSize() const { return m_totalContentsSize; }
+ void setTotalContentsSize(const IntSize&);
const IntPoint& scrollOrigin() const { return m_scrollOrigin; }
- WEBCORE_EXPORT void setScrollOrigin(const IntPoint&);
+ void setScrollOrigin(const IntPoint&);
-#if ENABLE(CSS_SCROLL_SNAP)
- const Vector<float>& horizontalSnapOffsets() const { return m_horizontalSnapOffsets; }
- WEBCORE_EXPORT void setHorizontalSnapOffsets(const Vector<float>&);
+ float frameScaleFactor() const { return m_frameScaleFactor; }
+ void setFrameScaleFactor(float);
- const Vector<float>& verticalSnapOffsets() const { return m_verticalSnapOffsets; }
- WEBCORE_EXPORT void setVerticalSnapOffsets(const Vector<float>&);
+ const Region& nonFastScrollableRegion() const { return m_nonFastScrollableRegion; }
+ void setNonFastScrollableRegion(const Region&);
- unsigned currentHorizontalSnapPointIndex() const { return m_currentHorizontalSnapPointIndex; }
- WEBCORE_EXPORT void setCurrentHorizontalSnapPointIndex(unsigned);
+ unsigned wheelEventHandlerCount() const { return m_wheelEventHandlerCount; }
+ void setWheelEventHandlerCount(unsigned);
- unsigned currentVerticalSnapPointIndex() const { return m_currentVerticalSnapPointIndex; }
- WEBCORE_EXPORT void setCurrentVerticalSnapPointIndex(unsigned);
-#endif
+ SynchronousScrollingReasons synchronousScrollingReasons() const { return m_synchronousScrollingReasons; }
+ void setSynchronousScrollingReasons(SynchronousScrollingReasons);
const ScrollableAreaParameters& scrollableAreaParameters() const { return m_scrollableAreaParameters; }
- WEBCORE_EXPORT void setScrollableAreaParameters(const ScrollableAreaParameters& params);
+ void setScrollableAreaParameters(const ScrollableAreaParameters& params);
- const FloatPoint& requestedScrollPosition() const { return m_requestedScrollPosition; }
- bool requestedScrollPositionRepresentsProgrammaticScroll() const { return m_requestedScrollPositionRepresentsProgrammaticScroll; }
- WEBCORE_EXPORT void setRequestedScrollPosition(const FloatPoint&, bool representsProgrammaticScroll);
+ ScrollBehaviorForFixedElements scrollBehaviorForFixedElements() const { return m_behaviorForFixed; }
+ void setScrollBehaviorForFixedElements(ScrollBehaviorForFixedElements);
+
+ const IntPoint& requestedScrollPosition() const { return m_requestedScrollPosition; }
+ void setRequestedScrollPosition(const IntPoint&, bool representsProgrammaticScroll);
+
+ int headerHeight() const { return m_headerHeight; }
+ void setHeaderHeight(int);
+
+ int footerHeight() const { return m_footerHeight; }
+ void setFooterHeight(int);
+
+ // This is a layer moved in the opposite direction to scrolling, for example for background-attachment:fixed
+ const LayerRepresentation& counterScrollingLayer() const { return m_counterScrollingLayer; }
+ void setCounterScrollingLayer(const LayerRepresentation&);
+
+ // The header and footer layers scroll vertically with the page, they should remain fixed when scrolling horizontally.
+ const LayerRepresentation& headerLayer() const { return m_headerLayer; }
+ void setHeaderLayer(const LayerRepresentation&);
+
+ // The header and footer layers scroll vertically with the page, they should remain fixed when scrolling horizontally.
+ const LayerRepresentation& footerLayer() const { return m_footerLayer; }
+ void setFooterLayer(const LayerRepresentation&);
+
+#if PLATFORM(MAC) && !PLATFORM(IOS)
+ ScrollbarPainter verticalScrollbarPainter() const { return m_verticalScrollbarPainter.get(); }
+ ScrollbarPainter horizontalScrollbarPainter() const { return m_horizontalScrollbarPainter.get(); }
+#endif
+ void setScrollbarPaintersFromScrollbars(Scrollbar* verticalScrollbar, Scrollbar* horizontalScrollbar);
- bool expectsWheelEventTestTrigger() const { return m_expectsWheelEventTestTrigger; }
- WEBCORE_EXPORT void setExpectsWheelEventTestTrigger(bool);
+ bool requestedScrollPositionRepresentsProgrammaticScroll() const { return m_requestedScrollPositionRepresentsProgrammaticScroll; }
virtual void dumpProperties(TextStream&, int indent) const override;
-
-protected:
- ScrollingStateScrollingNode(ScrollingStateTree&, ScrollingNodeType, ScrollingNodeID);
- ScrollingStateScrollingNode(const ScrollingStateScrollingNode&, ScrollingStateTree&);
-
+
private:
- FloatSize m_scrollableAreaSize;
- FloatSize m_totalContentsSize;
- FloatSize m_reachableContentsSize;
- FloatPoint m_scrollPosition;
- FloatPoint m_requestedScrollPosition;
- IntPoint m_scrollOrigin;
-#if ENABLE(CSS_SCROLL_SNAP)
- Vector<float> m_horizontalSnapOffsets;
- Vector<float> m_verticalSnapOffsets;
- unsigned m_currentHorizontalSnapPointIndex { 0 };
- unsigned m_currentVerticalSnapPointIndex { 0 };
+ ScrollingStateScrollingNode(ScrollingStateTree&, ScrollingNodeID);
+ ScrollingStateScrollingNode(const ScrollingStateScrollingNode&, ScrollingStateTree&);
+
+ LayerRepresentation m_counterScrollingLayer;
+ LayerRepresentation m_headerLayer;
+ LayerRepresentation m_footerLayer;
+
+#if PLATFORM(MAC) && !PLATFORM(IOS)
+ RetainPtr<ScrollbarPainter> m_verticalScrollbarPainter;
+ RetainPtr<ScrollbarPainter> m_horizontalScrollbarPainter;
#endif
+
+ IntRect m_viewportRect;
+ IntSize m_totalContentsSize;
+ IntPoint m_scrollOrigin;
+
ScrollableAreaParameters m_scrollableAreaParameters;
- bool m_requestedScrollPositionRepresentsProgrammaticScroll { false };
- bool m_expectsWheelEventTestTrigger { false };
+ Region m_nonFastScrollableRegion;
+ float m_frameScaleFactor;
+ unsigned m_wheelEventHandlerCount;
+ SynchronousScrollingReasons m_synchronousScrollingReasons;
+ ScrollBehaviorForFixedElements m_behaviorForFixed;
+ int m_headerHeight;
+ int m_footerHeight;
+ IntPoint m_requestedScrollPosition;
+ bool m_requestedScrollPositionRepresentsProgrammaticScroll;
};
-} // namespace WebCore
+SCROLLING_STATE_NODE_TYPE_CASTS(ScrollingStateScrollingNode, nodeType() == ScrollingNode);
-SPECIALIZE_TYPE_TRAITS_SCROLLING_STATE_NODE(ScrollingStateScrollingNode, isScrollingNode())
+} // namespace WebCore
#endif // ENABLE(ASYNC_SCROLLING) || USE(COORDINATED_GRAPHICS)
diff --git a/Source/WebCore/page/scrolling/ScrollingStateStickyNode.cpp b/Source/WebCore/page/scrolling/ScrollingStateStickyNode.cpp
deleted file mode 100644
index cee476e4a..000000000
--- a/Source/WebCore/page/scrolling/ScrollingStateStickyNode.cpp
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "ScrollingStateStickyNode.h"
-
-#if ENABLE(ASYNC_SCROLLING) || USE(COORDINATED_GRAPHICS)
-
-#include "GraphicsLayer.h"
-#include "ScrollingStateTree.h"
-#include "TextStream.h"
-
-namespace WebCore {
-
-Ref<ScrollingStateStickyNode> ScrollingStateStickyNode::create(ScrollingStateTree& stateTree, ScrollingNodeID nodeID)
-{
- return adoptRef(*new ScrollingStateStickyNode(stateTree, nodeID));
-}
-
-ScrollingStateStickyNode::ScrollingStateStickyNode(ScrollingStateTree& tree, ScrollingNodeID nodeID)
- : ScrollingStateNode(StickyNode, tree, nodeID)
-{
-}
-
-ScrollingStateStickyNode::ScrollingStateStickyNode(const ScrollingStateStickyNode& node, ScrollingStateTree& adoptiveTree)
- : ScrollingStateNode(node, adoptiveTree)
- , m_constraints(StickyPositionViewportConstraints(node.viewportConstraints()))
-{
-}
-
-ScrollingStateStickyNode::~ScrollingStateStickyNode()
-{
-}
-
-Ref<ScrollingStateNode> ScrollingStateStickyNode::clone(ScrollingStateTree& adoptiveTree)
-{
- return adoptRef(*new ScrollingStateStickyNode(*this, adoptiveTree));
-}
-
-void ScrollingStateStickyNode::updateConstraints(const StickyPositionViewportConstraints& constraints)
-{
- if (m_constraints == constraints)
- return;
-
- m_constraints = constraints;
- setPropertyChanged(ViewportConstraints);
-}
-
-void ScrollingStateStickyNode::syncLayerPositionForViewportRect(const LayoutRect& viewportRect)
-{
- FloatPoint position = m_constraints.layerPositionForConstrainingRect(viewportRect);
- if (layer().representsGraphicsLayer())
- static_cast<GraphicsLayer*>(layer())->syncPosition(position);
-}
-
-void ScrollingStateStickyNode::dumpProperties(TextStream& ts, int indent) const
-{
- ts << "(" << "Sticky node" << "\n";
-
- if (m_constraints.anchorEdges()) {
- writeIndent(ts, indent + 1);
- ts << "(anchor edges: ";
- if (m_constraints.hasAnchorEdge(ViewportConstraints::AnchorEdgeLeft))
- ts << "AnchorEdgeLeft ";
- if (m_constraints.hasAnchorEdge(ViewportConstraints::AnchorEdgeRight))
- ts << "AnchorEdgeRight ";
- if (m_constraints.hasAnchorEdge(ViewportConstraints::AnchorEdgeTop))
- ts << "AnchorEdgeTop ";
- if (m_constraints.hasAnchorEdge(ViewportConstraints::AnchorEdgeBottom))
- ts << "AnchorEdgeBottom";
- ts << ")\n";
- }
-
- if (m_constraints.hasAnchorEdge(ViewportConstraints::AnchorEdgeLeft)) {
- writeIndent(ts, indent + 1);
- ts << "(left offset " << m_constraints.leftOffset() << ")\n";
- }
- if (m_constraints.hasAnchorEdge(ViewportConstraints::AnchorEdgeRight)) {
- writeIndent(ts, indent + 1);
- ts << "(right offset " << m_constraints.rightOffset() << ")\n";
- }
- if (m_constraints.hasAnchorEdge(ViewportConstraints::AnchorEdgeTop)) {
- writeIndent(ts, indent + 1);
- ts << "(top offset " << m_constraints.topOffset() << ")\n";
- }
- if (m_constraints.hasAnchorEdge(ViewportConstraints::AnchorEdgeBottom)) {
- writeIndent(ts, indent + 1);
- ts << "(bottom offset " << m_constraints.bottomOffset() << ")\n";
- }
-
- writeIndent(ts, indent + 1);
- FloatRect r = m_constraints.containingBlockRect();
- ts << "(containing block rect " << r.x() << ", " << r.y() << " " << r.width() << " x " << r.height() << ")\n";
-
- writeIndent(ts, indent + 1);
- r = m_constraints.stickyBoxRect();
- ts << "(sticky box rect " << r.x() << " " << r.y() << " " << r.width() << " " << r.height() << ")\n";
-
- writeIndent(ts, indent + 1);
- r = m_constraints.constrainingRectAtLastLayout();
- ts << "(constraining rect " << r.x() << " " << r.y() << " " << r.width() << " " << r.height() << ")\n";
-
- writeIndent(ts, indent + 1);
- ts << "(sticky offset at last layout " << m_constraints.stickyOffsetAtLastLayout().width() << " " << m_constraints.stickyOffsetAtLastLayout().height() << ")\n";
-
- writeIndent(ts, indent + 1);
- ts << "(layer position at last layout " << m_constraints.layerPositionAtLastLayout().x() << " " << m_constraints.layerPositionAtLastLayout().y() << ")\n";
-}
-
-} // namespace WebCore
-
-#endif // ENABLE(ASYNC_SCROLLING) || USE(COORDINATED_GRAPHICS)
diff --git a/Source/WebCore/page/scrolling/ScrollingStateStickyNode.h b/Source/WebCore/page/scrolling/ScrollingStateStickyNode.h
deleted file mode 100644
index c9e7935a4..000000000
--- a/Source/WebCore/page/scrolling/ScrollingStateStickyNode.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef ScrollingStateStickyNode_h
-#define ScrollingStateStickyNode_h
-
-#if ENABLE(ASYNC_SCROLLING) || USE(COORDINATED_GRAPHICS)
-
-#include "ScrollingConstraints.h"
-#include "ScrollingStateNode.h"
-
-#include <wtf/Forward.h>
-
-namespace WebCore {
-
-class StickyPositionViewportConstraints;
-
-class ScrollingStateStickyNode final : public ScrollingStateNode {
-public:
- static Ref<ScrollingStateStickyNode> create(ScrollingStateTree&, ScrollingNodeID);
-
- virtual Ref<ScrollingStateNode> clone(ScrollingStateTree&) override;
-
- virtual ~ScrollingStateStickyNode();
-
- enum {
- ViewportConstraints = NumStateNodeBits
- };
-
- WEBCORE_EXPORT void updateConstraints(const StickyPositionViewportConstraints&);
- const StickyPositionViewportConstraints& viewportConstraints() const { return m_constraints; }
-
-private:
- ScrollingStateStickyNode(ScrollingStateTree&, ScrollingNodeID);
- ScrollingStateStickyNode(const ScrollingStateStickyNode&, ScrollingStateTree&);
-
- virtual void syncLayerPositionForViewportRect(const LayoutRect& viewportRect) override;
-
- virtual void dumpProperties(TextStream&, int indent) const override;
-
- StickyPositionViewportConstraints m_constraints;
-};
-
-} // namespace WebCore
-
-SPECIALIZE_TYPE_TRAITS_SCROLLING_STATE_NODE(ScrollingStateStickyNode, isStickyNode())
-
-#endif // ENABLE(ASYNC_SCROLLING) || USE(COORDINATED_GRAPHICS)
-
-#endif // ScrollingStateStickyNode_h
diff --git a/Source/WebCore/page/scrolling/ScrollingStateTree.cpp b/Source/WebCore/page/scrolling/ScrollingStateTree.cpp
index 3bec4360c..e06f22168 100644
--- a/Source/WebCore/page/scrolling/ScrollingStateTree.cpp
+++ b/Source/WebCore/page/scrolling/ScrollingStateTree.cpp
@@ -30,17 +30,16 @@
#include "AsyncScrollingCoordinator.h"
#include "ScrollingStateFixedNode.h"
-#include "ScrollingStateFrameScrollingNode.h"
-#include "ScrollingStateOverflowScrollingNode.h"
+#include "ScrollingStateScrollingNode.h"
#include "ScrollingStateStickyNode.h"
-#include <wtf/text/CString.h>
-
-#ifndef NDEBUG
-#include <stdio.h>
-#endif
namespace WebCore {
+PassOwnPtr<ScrollingStateTree> ScrollingStateTree::create(AsyncScrollingCoordinator* scrollingCoordinator)
+{
+ return adoptPtr(new ScrollingStateTree(scrollingCoordinator));
+}
+
ScrollingStateTree::ScrollingStateTree(AsyncScrollingCoordinator* scrollingCoordinator)
: m_scrollingCoordinator(scrollingCoordinator)
, m_hasChangedProperties(false)
@@ -67,46 +66,27 @@ void ScrollingStateTree::setHasChangedProperties(bool changedProperties)
#endif
}
-PassRefPtr<ScrollingStateNode> ScrollingStateTree::createNode(ScrollingNodeType nodeType, ScrollingNodeID nodeID)
-{
- switch (nodeType) {
- case FixedNode:
- return ScrollingStateFixedNode::create(*this, nodeID);
- case StickyNode:
- return ScrollingStateStickyNode::create(*this, nodeID);
- case FrameScrollingNode:
- return ScrollingStateFrameScrollingNode::create(*this, nodeID);
- case OverflowScrollingNode:
- return ScrollingStateOverflowScrollingNode::create(*this, nodeID);
- }
- ASSERT_NOT_REACHED();
- return nullptr;
-}
-
ScrollingNodeID ScrollingStateTree::attachNode(ScrollingNodeType nodeType, ScrollingNodeID newNodeID, ScrollingNodeID parentID)
{
ASSERT(newNodeID);
- if (ScrollingStateNode* node = stateNodeForID(newNodeID)) {
- if (!parentID)
- return newNodeID;
+ if (ScrollingStateNode* node = stateNodeForID(newNodeID)) {
ScrollingStateNode* parent = stateNodeForID(parentID);
if (!parent)
return newNodeID;
-
if (node->parent() == parent)
return newNodeID;
// The node is being re-parented. To do that, we'll remove it, and then re-create a new node.
- removeNodeAndAllDescendants(node, SubframeNodeRemoval::Orphan);
+ removeNode(node);
}
- ScrollingStateNode* newNode = nullptr;
+ ScrollingStateNode* newNode = 0;
if (!parentID) {
// If we're resetting the root node, we should clear the HashMap and destroy the current children.
clear();
- setRootStateNode(ScrollingStateFrameScrollingNode::create(*this, newNodeID));
+ setRootStateNode(ScrollingStateScrollingNode::create(*this, newNodeID));
newNode = rootStateNode();
m_hasNewRootStateNode = true;
} else {
@@ -114,22 +94,31 @@ ScrollingNodeID ScrollingStateTree::attachNode(ScrollingNodeType nodeType, Scrol
if (!parent)
return 0;
- if (nodeType == FrameScrollingNode && parentID) {
- if (RefPtr<ScrollingStateNode> orphanedNode = m_orphanedSubframeNodes.take(newNodeID)) {
- newNode = orphanedNode.get();
- parent->appendChild(orphanedNode.release());
- }
+ switch (nodeType) {
+ case FixedNode: {
+ OwnPtr<ScrollingStateFixedNode> fixedNode = ScrollingStateFixedNode::create(*this, newNodeID);
+ newNode = fixedNode.get();
+ parent->appendChild(fixedNode.release());
+ break;
+ }
+ case StickyNode: {
+ OwnPtr<ScrollingStateStickyNode> stickyNode = ScrollingStateStickyNode::create(*this, newNodeID);
+ newNode = stickyNode.get();
+ parent->appendChild(stickyNode.release());
+ break;
+ }
+ case ScrollingNode: {
+ // FIXME: We currently only support child nodes that are fixed.
+ ASSERT_NOT_REACHED();
+ OwnPtr<ScrollingStateScrollingNode> scrollingNode = ScrollingStateScrollingNode::create(*this, newNodeID);
+ newNode = scrollingNode.get();
+ parent->appendChild(scrollingNode.release());
+ break;
}
-
- if (!newNode) {
- RefPtr<ScrollingStateNode> stateNode = createNode(nodeType, newNodeID);
- newNode = stateNode.get();
- parent->appendChild(stateNode.release());
}
}
m_stateNodeMap.set(newNodeID, newNode);
- m_nodesRemovedSinceLastCommit.remove(newNodeID);
return newNodeID;
}
@@ -143,46 +132,35 @@ void ScrollingStateTree::detachNode(ScrollingNodeID nodeID)
if (!node)
return;
- removeNodeAndAllDescendants(node, SubframeNodeRemoval::Orphan);
+ removeNode(node);
}
void ScrollingStateTree::clear()
{
- if (rootStateNode())
- removeNodeAndAllDescendants(rootStateNode());
-
+ removeNode(rootStateNode());
m_stateNodeMap.clear();
- m_orphanedSubframeNodes.clear();
}
-std::unique_ptr<ScrollingStateTree> ScrollingStateTree::commit(LayerRepresentation::Type preferredLayerRepresentation)
+PassOwnPtr<ScrollingStateTree> ScrollingStateTree::commit(LayerRepresentation::Type preferredLayerRepresentation)
{
- if (!m_orphanedSubframeNodes.isEmpty()) {
- // If we still have orphaned subtrees, remove them from m_stateNodeMap since they will be deleted
- // when clearing m_orphanedSubframeNodes.
- for (auto& orphanNode : m_orphanedSubframeNodes.values())
- recursiveNodeWillBeRemoved(orphanNode.get(), SubframeNodeRemoval::Delete);
- m_orphanedSubframeNodes.clear();
- }
-
// This function clones and resets the current state tree, but leaves the tree structure intact.
- std::unique_ptr<ScrollingStateTree> treeStateClone = std::make_unique<ScrollingStateTree>();
+ OwnPtr<ScrollingStateTree> treeStateClone = ScrollingStateTree::create();
treeStateClone->setPreferredLayerRepresentation(preferredLayerRepresentation);
if (m_rootStateNode)
- treeStateClone->setRootStateNode(static_pointer_cast<ScrollingStateFrameScrollingNode>(m_rootStateNode->cloneAndReset(*treeStateClone)));
+ treeStateClone->setRootStateNode(static_pointer_cast<ScrollingStateScrollingNode>(m_rootStateNode->cloneAndReset(*treeStateClone)));
// Copy the IDs of the nodes that have been removed since the last commit into the clone.
treeStateClone->m_nodesRemovedSinceLastCommit.swap(m_nodesRemovedSinceLastCommit);
// Now the clone tree has changed properties, and the original tree does not.
- treeStateClone->m_hasChangedProperties = m_hasChangedProperties;
+ treeStateClone->m_hasChangedProperties = true;
m_hasChangedProperties = false;
treeStateClone->m_hasNewRootStateNode = m_hasNewRootStateNode;
m_hasNewRootStateNode = false;
- return treeStateClone;
+ return treeStateClone.release();
}
void ScrollingStateTree::addNode(ScrollingStateNode* node)
@@ -190,50 +168,36 @@ void ScrollingStateTree::addNode(ScrollingStateNode* node)
m_stateNodeMap.add(node->scrollingNodeID(), node);
}
-void ScrollingStateTree::removeNodeAndAllDescendants(ScrollingStateNode* node, SubframeNodeRemoval subframeNodeRemoval)
+void ScrollingStateTree::removeNode(ScrollingStateNode* node)
{
- ScrollingStateNode* parent = node->parent();
-
- recursiveNodeWillBeRemoved(node, subframeNodeRemoval);
+ if (!node)
+ return;
- if (node == m_rootStateNode)
+ if (node == m_rootStateNode) {
+ didRemoveNode(node->scrollingNodeID());
m_rootStateNode = nullptr;
- else if (parent) {
- ASSERT(parent->children() && parent->children()->find(node) != notFound);
- if (auto children = parent->children()) {
- size_t index = children->find(node);
- if (index != notFound)
- children->remove(index);
- }
- }
-}
-
-void ScrollingStateTree::recursiveNodeWillBeRemoved(ScrollingStateNode* currNode, SubframeNodeRemoval subframeNodeRemoval)
-{
- currNode->setParent(nullptr);
- if (subframeNodeRemoval == SubframeNodeRemoval::Orphan && currNode != m_rootStateNode && currNode->isFrameScrollingNode()) {
- m_orphanedSubframeNodes.add(currNode->scrollingNodeID(), currNode);
return;
}
- willRemoveNode(currNode);
+ ASSERT(m_rootStateNode);
+ m_rootStateNode->removeChild(node);
- if (auto children = currNode->children()) {
- for (auto& child : *children)
- recursiveNodeWillBeRemoved(child.get(), subframeNodeRemoval);
- }
+ // ScrollingStateTree::removeNode() will destroy children, so we have to make sure we remove those children
+ // from the HashMap.
+ size_t size = m_nodesRemovedSinceLastCommit.size();
+ for (size_t i = 0; i < size; ++i)
+ m_stateNodeMap.remove(m_nodesRemovedSinceLastCommit[i]);
}
-void ScrollingStateTree::willRemoveNode(ScrollingStateNode* node)
+void ScrollingStateTree::didRemoveNode(ScrollingNodeID nodeID)
{
- m_nodesRemovedSinceLastCommit.add(node->scrollingNodeID());
- m_stateNodeMap.remove(node->scrollingNodeID());
+ m_nodesRemovedSinceLastCommit.append(nodeID);
setHasChangedProperties();
}
-void ScrollingStateTree::setRemovedNodes(HashSet<ScrollingNodeID> nodes)
+void ScrollingStateTree::setRemovedNodes(Vector<ScrollingNodeID> nodes)
{
- m_nodesRemovedSinceLastCommit = WTFMove(nodes);
+ m_nodesRemovedSinceLastCommit = std::move(nodes);
}
ScrollingStateNode* ScrollingStateTree::stateNodeForID(ScrollingNodeID scrollLayerID)
@@ -251,30 +215,4 @@ ScrollingStateNode* ScrollingStateTree::stateNodeForID(ScrollingNodeID scrollLay
} // namespace WebCore
-#ifndef NDEBUG
-void showScrollingStateTree(const WebCore::ScrollingStateTree* tree)
-{
- if (!tree)
- return;
-
- auto rootNode = tree->rootStateNode();
- if (!rootNode) {
- fprintf(stderr, "Scrolling state tree %p with no root node\n", tree);
- return;
- }
-
- String output = rootNode->scrollingStateTreeAsText();
- fprintf(stderr, "%s\n", output.utf8().data());
-}
-
-void showScrollingStateTree(const WebCore::ScrollingStateNode* node)
-{
- if (!node)
- return;
-
- showScrollingStateTree(&node->scrollingStateTree());
-}
-
-#endif
-
#endif // ENABLE(ASYNC_SCROLLING) || USE(COORDINATED_GRAPHICS)
diff --git a/Source/WebCore/page/scrolling/ScrollingStateTree.h b/Source/WebCore/page/scrolling/ScrollingStateTree.h
index 79a65a5f4..59659e534 100644
--- a/Source/WebCore/page/scrolling/ScrollingStateTree.h
+++ b/Source/WebCore/page/scrolling/ScrollingStateTree.h
@@ -28,7 +28,9 @@
#if ENABLE(ASYNC_SCROLLING) || USE(COORDINATED_GRAPHICS)
-#include "ScrollingStateFrameScrollingNode.h"
+#include "ScrollingStateScrollingNode.h"
+#include <wtf/OwnPtr.h>
+#include <wtf/PassOwnPtr.h>
#include <wtf/RefPtr.h>
namespace WebCore {
@@ -41,30 +43,29 @@ class AsyncScrollingCoordinator;
// the scrolling thread, avoiding locking.
class ScrollingStateTree {
- WTF_MAKE_FAST_ALLOCATED;
friend class ScrollingStateNode;
public:
- WEBCORE_EXPORT ScrollingStateTree(AsyncScrollingCoordinator* = nullptr);
- WEBCORE_EXPORT ~ScrollingStateTree();
+
+ static PassOwnPtr<ScrollingStateTree> create(AsyncScrollingCoordinator* = 0);
+ ~ScrollingStateTree();
- ScrollingStateFrameScrollingNode* rootStateNode() const { return m_rootStateNode.get(); }
- WEBCORE_EXPORT ScrollingStateNode* stateNodeForID(ScrollingNodeID);
+ ScrollingStateScrollingNode* rootStateNode() const { return m_rootStateNode.get(); }
+ ScrollingStateNode* stateNodeForID(ScrollingNodeID);
- WEBCORE_EXPORT ScrollingNodeID attachNode(ScrollingNodeType, ScrollingNodeID, ScrollingNodeID parentID);
+ ScrollingNodeID attachNode(ScrollingNodeType, ScrollingNodeID, ScrollingNodeID parentID);
void detachNode(ScrollingNodeID);
void clear();
- const HashSet<ScrollingNodeID>& removedNodes() const { return m_nodesRemovedSinceLastCommit; }
- WEBCORE_EXPORT void setRemovedNodes(HashSet<ScrollingNodeID>);
+ const Vector<ScrollingNodeID>& removedNodes() const { return m_nodesRemovedSinceLastCommit; }
+ void setRemovedNodes(Vector<ScrollingNodeID>);
// Copies the current tree state and clears the changed properties mask in the original.
- WEBCORE_EXPORT std::unique_ptr<ScrollingStateTree> commit(LayerRepresentation::Type preferredLayerRepresentation);
+ PassOwnPtr<ScrollingStateTree> commit(LayerRepresentation::Type preferredLayerRepresentation);
- WEBCORE_EXPORT void setHasChangedProperties(bool = true);
+ void setHasChangedProperties(bool = true);
bool hasChangedProperties() const { return m_hasChangedProperties; }
bool hasNewRootStateNode() const { return m_hasNewRootStateNode; }
- void setHasNewRootStateNode(bool hasNewRoot) { m_hasNewRootStateNode = hasNewRoot; }
int nodeCount() const { return m_stateNodeMap.size(); }
@@ -75,25 +76,17 @@ public:
void setPreferredLayerRepresentation(LayerRepresentation::Type representation) { m_preferredLayerRepresentation = representation; }
private:
- void setRootStateNode(PassRefPtr<ScrollingStateFrameScrollingNode> rootStateNode) { m_rootStateNode = rootStateNode; }
- void addNode(ScrollingStateNode*);
-
- PassRefPtr<ScrollingStateNode> createNode(ScrollingNodeType, ScrollingNodeID);
-
- enum class SubframeNodeRemoval {
- Delete,
- Orphan
- };
- void removeNodeAndAllDescendants(ScrollingStateNode*, SubframeNodeRemoval = SubframeNodeRemoval::Delete);
+ ScrollingStateTree(AsyncScrollingCoordinator*);
- void recursiveNodeWillBeRemoved(ScrollingStateNode* currNode, SubframeNodeRemoval);
- void willRemoveNode(ScrollingStateNode*);
+ void setRootStateNode(PassOwnPtr<ScrollingStateScrollingNode> rootStateNode) { m_rootStateNode = rootStateNode; }
+ void addNode(ScrollingStateNode*);
+ void removeNode(ScrollingStateNode*);
+ void didRemoveNode(ScrollingNodeID);
AsyncScrollingCoordinator* m_scrollingCoordinator;
StateNodeMap m_stateNodeMap;
- RefPtr<ScrollingStateFrameScrollingNode> m_rootStateNode;
- HashSet<ScrollingNodeID> m_nodesRemovedSinceLastCommit;
- HashMap<ScrollingNodeID, RefPtr<ScrollingStateNode>> m_orphanedSubframeNodes;
+ OwnPtr<ScrollingStateScrollingNode> m_rootStateNode;
+ Vector<ScrollingNodeID> m_nodesRemovedSinceLastCommit;
bool m_hasChangedProperties;
bool m_hasNewRootStateNode;
LayerRepresentation::Type m_preferredLayerRepresentation;
@@ -101,11 +94,6 @@ private:
} // namespace WebCore
-#ifndef NDEBUG
-void showScrollingStateTree(const WebCore::ScrollingStateTree*);
-void showScrollingStateTree(const WebCore::ScrollingStateNode*);
-#endif
-
#endif // ENABLE(ASYNC_SCROLLING) || USE(COORDINATED_GRAPHICS)
#endif // ScrollingStateTree_h
diff --git a/Source/WebCore/page/scrolling/ScrollingThread.cpp b/Source/WebCore/page/scrolling/ScrollingThread.cpp
deleted file mode 100644
index 4669a1992..000000000
--- a/Source/WebCore/page/scrolling/ScrollingThread.cpp
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (C) 2012, 2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "ScrollingThread.h"
-
-#if ENABLE(ASYNC_SCROLLING)
-
-#include <mutex>
-#include <wtf/MainThread.h>
-#include <wtf/NeverDestroyed.h>
-
-namespace WebCore {
-
-ScrollingThread::ScrollingThread()
- : m_threadIdentifier(0)
-{
-}
-
-bool ScrollingThread::isCurrentThread()
-{
- auto threadIdentifier = ScrollingThread::singleton().m_threadIdentifier;
- return threadIdentifier && currentThread() == threadIdentifier;
-}
-
-void ScrollingThread::dispatch(std::function<void ()> function)
-{
- auto& scrollingThread = ScrollingThread::singleton();
- scrollingThread.createThreadIfNeeded();
-
- {
- std::lock_guard<Lock> lock(scrollingThread.m_functionsMutex);
- scrollingThread.m_functions.append(function);
- }
-
- scrollingThread.wakeUpRunLoop();
-}
-
-void ScrollingThread::dispatchBarrier(std::function<void ()> function)
-{
- dispatch([function]() mutable {
- callOnMainThread(WTFMove(function));
- });
-}
-
-ScrollingThread& ScrollingThread::singleton()
-{
- static NeverDestroyed<ScrollingThread> scrollingThread;
-
- return scrollingThread;
-}
-
-void ScrollingThread::createThreadIfNeeded()
-{
- if (m_threadIdentifier)
- return;
-
- // Wait for the thread to initialize the run loop.
- {
- std::unique_lock<Lock> lock(m_initializeRunLoopMutex);
-
- m_threadIdentifier = createThread(threadCallback, this, "WebCore: Scrolling");
-
-#if PLATFORM(COCOA)
- m_initializeRunLoopConditionVariable.wait(lock, [this]{ return m_threadRunLoop; });
-#endif
- }
-}
-
-void ScrollingThread::threadCallback(void* scrollingThread)
-{
- WTF::setCurrentThreadIsUserInteractive();
- static_cast<ScrollingThread*>(scrollingThread)->threadBody();
-}
-
-void ScrollingThread::threadBody()
-{
- initializeRunLoop();
-}
-
-void ScrollingThread::dispatchFunctionsFromScrollingThread()
-{
- ASSERT(isCurrentThread());
-
- Vector<std::function<void ()>> functions;
-
- {
- std::lock_guard<Lock> lock(m_functionsMutex);
- functions = WTFMove(m_functions);
- }
-
- for (auto& function : functions)
- function();
-}
-
-} // namespace WebCore
-
-#endif // ENABLE(ASYNC_SCROLLING)
diff --git a/Source/WebCore/page/scrolling/ScrollingThread.h b/Source/WebCore/page/scrolling/ScrollingThread.h
deleted file mode 100644
index a709ccd8e..000000000
--- a/Source/WebCore/page/scrolling/ScrollingThread.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2012, 2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef ScrollingThread_h
-#define ScrollingThread_h
-
-#if ENABLE(ASYNC_SCROLLING)
-
-#include <functional>
-#include <wtf/Condition.h>
-#include <wtf/Forward.h>
-#include <wtf/Lock.h>
-#include <wtf/Noncopyable.h>
-#include <wtf/Threading.h>
-#include <wtf/Vector.h>
-
-#if PLATFORM(COCOA)
-#include <wtf/RetainPtr.h>
-#endif
-
-namespace WebCore {
-
-class ScrollingThread {
- WTF_MAKE_NONCOPYABLE(ScrollingThread);
-
-public:
- static bool isCurrentThread();
- WEBCORE_EXPORT static void dispatch(std::function<void ()>);
-
- // Will dispatch the given function on the main thread once all pending functions
- // on the scrolling thread have finished executing. Used for synchronization purposes.
- WEBCORE_EXPORT static void dispatchBarrier(std::function<void ()>);
-
-private:
- friend NeverDestroyed<ScrollingThread>;
-
- ScrollingThread();
-
- static ScrollingThread& singleton();
-
- void createThreadIfNeeded();
- static void threadCallback(void* scrollingThread);
- void threadBody();
- void dispatchFunctionsFromScrollingThread();
-
- void initializeRunLoop();
- void wakeUpRunLoop();
-
-#if PLATFORM(COCOA)
- static void threadRunLoopSourceCallback(void* scrollingThread);
- void threadRunLoopSourceCallback();
-#endif
-
- ThreadIdentifier m_threadIdentifier;
-
- Condition m_initializeRunLoopConditionVariable;
- Lock m_initializeRunLoopMutex;
-
- Lock m_functionsMutex;
- Vector<std::function<void ()>> m_functions;
-
-#if PLATFORM(COCOA)
- // FIXME: We should use WebCore::RunLoop here.
- RetainPtr<CFRunLoopRef> m_threadRunLoop;
- RetainPtr<CFRunLoopSourceRef> m_threadRunLoopSource;
-#endif
-};
-
-} // namespace WebCore
-
-#endif // ENABLE(ASYNC_SCROLLING)
-
-#endif // ScrollingThread_h
diff --git a/Source/WebCore/page/scrolling/ScrollingTree.cpp b/Source/WebCore/page/scrolling/ScrollingTree.cpp
deleted file mode 100644
index 476b4c271..000000000
--- a/Source/WebCore/page/scrolling/ScrollingTree.cpp
+++ /dev/null
@@ -1,376 +0,0 @@
-/*
- * Copyright (C) 2012-2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "ScrollingTree.h"
-
-#if ENABLE(ASYNC_SCROLLING)
-
-#include "Logging.h"
-#include "PlatformWheelEvent.h"
-#include "ScrollingStateTree.h"
-#include "ScrollingTreeFrameScrollingNode.h"
-#include "ScrollingTreeNode.h"
-#include "ScrollingTreeOverflowScrollingNode.h"
-#include "ScrollingTreeScrollingNode.h"
-#include "TextStream.h"
-#include <wtf/TemporaryChange.h>
-
-namespace WebCore {
-
-ScrollingTree::ScrollingTree()
-{
-}
-
-ScrollingTree::~ScrollingTree()
-{
-}
-
-bool ScrollingTree::shouldHandleWheelEventSynchronously(const PlatformWheelEvent& wheelEvent)
-{
- // This method is invoked by the event handling thread
- LockHolder lock(m_mutex);
-
- bool shouldSetLatch = wheelEvent.shouldConsiderLatching();
-
- if (hasLatchedNode() && !shouldSetLatch)
- return false;
-
- if (shouldSetLatch)
- m_latchedNode = 0;
-
- if (!m_nonFastScrollableRegion.isEmpty() && m_rootNode) {
- ScrollingTreeFrameScrollingNode& frameScrollingNode = downcast<ScrollingTreeFrameScrollingNode>(*m_rootNode);
- FloatPoint position = wheelEvent.position();
- position.move(frameScrollingNode.viewToContentsOffset(m_mainFrameScrollPosition));
-
- LOG_WITH_STREAM(Scrolling, stream << "ScrollingTree::shouldHandleWheelEventSynchronously: wheelEvent at " << wheelEvent.position() << " mapped to content point " << position << ", in non-fast region " << m_nonFastScrollableRegion.contains(roundedIntPoint(position)));
-
- if (m_nonFastScrollableRegion.contains(roundedIntPoint(position)))
- return true;
- }
- return false;
-}
-
-void ScrollingTree::setOrClearLatchedNode(const PlatformWheelEvent& wheelEvent, ScrollingNodeID nodeID)
-{
- if (wheelEvent.shouldConsiderLatching())
- setLatchedNode(nodeID);
- else if (wheelEvent.shouldResetLatching())
- clearLatchedNode();
-}
-
-void ScrollingTree::handleWheelEvent(const PlatformWheelEvent& wheelEvent)
-{
- if (m_rootNode)
- downcast<ScrollingTreeScrollingNode>(*m_rootNode).handleWheelEvent(wheelEvent);
-}
-
-void ScrollingTree::viewportChangedViaDelegatedScrolling(ScrollingNodeID nodeID, const WebCore::FloatRect& fixedPositionRect, double scale)
-{
- ScrollingTreeNode* node = nodeForID(nodeID);
- if (!is<ScrollingTreeScrollingNode>(node))
- return;
-
- downcast<ScrollingTreeScrollingNode>(*node).updateLayersAfterViewportChange(fixedPositionRect, scale);
-}
-
-void ScrollingTree::scrollPositionChangedViaDelegatedScrolling(ScrollingNodeID nodeID, const WebCore::FloatPoint& scrollPosition, bool inUserInteration)
-{
- ScrollingTreeNode* node = nodeForID(nodeID);
- if (!is<ScrollingTreeOverflowScrollingNode>(node))
- return;
-
- // Update descendant nodes
- downcast<ScrollingTreeOverflowScrollingNode>(*node).updateLayersAfterDelegatedScroll(scrollPosition);
-
- // Update GraphicsLayers and scroll state.
- scrollingTreeNodeDidScroll(nodeID, scrollPosition, inUserInteration ? SyncScrollingLayerPosition : SetScrollingLayerPosition);
-}
-
-void ScrollingTree::commitNewTreeState(std::unique_ptr<ScrollingStateTree> scrollingStateTree)
-{
- bool rootStateNodeChanged = scrollingStateTree->hasNewRootStateNode();
-
- ScrollingStateScrollingNode* rootNode = scrollingStateTree->rootStateNode();
- if (rootNode
- && (rootStateNodeChanged
- || rootNode->hasChangedProperty(ScrollingStateFrameScrollingNode::NonFastScrollableRegion)
- || rootNode->hasChangedProperty(ScrollingStateNode::ScrollLayer))) {
- LockHolder lock(m_mutex);
-
- if (rootStateNodeChanged || rootNode->hasChangedProperty(ScrollingStateNode::ScrollLayer))
- m_mainFrameScrollPosition = FloatPoint();
- if (rootStateNodeChanged || rootNode->hasChangedProperty(ScrollingStateFrameScrollingNode::NonFastScrollableRegion))
- m_nonFastScrollableRegion = scrollingStateTree->rootStateNode()->nonFastScrollableRegion();
- }
-
- bool scrollRequestIsProgammatic = rootNode ? rootNode->requestedScrollPositionRepresentsProgrammaticScroll() : false;
- TemporaryChange<bool> changeHandlingProgrammaticScroll(m_isHandlingProgrammaticScroll, scrollRequestIsProgammatic);
-
- removeDestroyedNodes(*scrollingStateTree);
-
- OrphanScrollingNodeMap orphanNodes;
- updateTreeFromStateNode(rootNode, orphanNodes);
-}
-
-void ScrollingTree::updateTreeFromStateNode(const ScrollingStateNode* stateNode, OrphanScrollingNodeMap& orphanNodes)
-{
- if (!stateNode) {
- m_nodeMap.clear();
- m_rootNode = nullptr;
- return;
- }
-
- ScrollingNodeID nodeID = stateNode->scrollingNodeID();
- ScrollingNodeID parentNodeID = stateNode->parentNodeID();
-
- auto it = m_nodeMap.find(nodeID);
-
- RefPtr<ScrollingTreeNode> node;
- if (it != m_nodeMap.end())
- node = it->value;
- else {
- node = createScrollingTreeNode(stateNode->nodeType(), nodeID);
- if (!parentNodeID) {
- // This is the root node. Clear the node map.
- ASSERT(stateNode->nodeType() == FrameScrollingNode);
- m_rootNode = node;
- m_nodeMap.clear();
- }
- m_nodeMap.set(nodeID, node.get());
- }
-
- if (parentNodeID) {
- auto parentIt = m_nodeMap.find(parentNodeID);
- ASSERT_WITH_SECURITY_IMPLICATION(parentIt != m_nodeMap.end());
- if (parentIt != m_nodeMap.end()) {
- ScrollingTreeNode* parent = parentIt->value;
- node->setParent(parent);
- parent->appendChild(node);
- }
- }
-
- node->updateBeforeChildren(*stateNode);
-
- // Move all children into the orphanNodes map. Live ones will get added back as we recurse over children.
- if (auto nodeChildren = node->children()) {
- for (auto& childScrollingNode : *nodeChildren) {
- childScrollingNode->setParent(nullptr);
- orphanNodes.add(childScrollingNode->scrollingNodeID(), childScrollingNode);
- }
- nodeChildren->clear();
- }
-
- // Now update the children if we have any.
- if (auto children = stateNode->children()) {
- for (auto& child : *children)
- updateTreeFromStateNode(child.get(), orphanNodes);
- }
-
- node->updateAfterChildren(*stateNode);
-}
-
-void ScrollingTree::removeDestroyedNodes(const ScrollingStateTree& stateTree)
-{
- for (const auto& removedNodeID : stateTree.removedNodes()) {
- m_nodeMap.remove(removedNodeID);
- if (removedNodeID == m_latchedNode)
- clearLatchedNode();
- }
-}
-
-ScrollingTreeNode* ScrollingTree::nodeForID(ScrollingNodeID nodeID) const
-{
- if (!nodeID)
- return nullptr;
-
- return m_nodeMap.get(nodeID);
-}
-
-void ScrollingTree::setMainFramePinState(bool pinnedToTheLeft, bool pinnedToTheRight, bool pinnedToTheTop, bool pinnedToTheBottom)
-{
- LockHolder locker(m_swipeStateMutex);
-
- m_mainFramePinnedToTheLeft = pinnedToTheLeft;
- m_mainFramePinnedToTheRight = pinnedToTheRight;
- m_mainFramePinnedToTheTop = pinnedToTheTop;
- m_mainFramePinnedToTheBottom = pinnedToTheBottom;
-}
-
-FloatPoint ScrollingTree::mainFrameScrollPosition()
-{
- LockHolder lock(m_mutex);
- return m_mainFrameScrollPosition;
-}
-
-void ScrollingTree::setMainFrameScrollPosition(FloatPoint position)
-{
- LockHolder lock(m_mutex);
- m_mainFrameScrollPosition = position;
-}
-
-bool ScrollingTree::isPointInNonFastScrollableRegion(IntPoint p)
-{
- LockHolder lock(m_mutex);
-
- return m_nonFastScrollableRegion.contains(p);
-}
-
-bool ScrollingTree::isRubberBandInProgress()
-{
- LockHolder lock(m_mutex);
-
- return m_mainFrameIsRubberBanding;
-}
-
-void ScrollingTree::setMainFrameIsRubberBanding(bool isRubberBanding)
-{
- LockHolder locker(m_mutex);
-
- m_mainFrameIsRubberBanding = isRubberBanding;
-}
-
-bool ScrollingTree::isScrollSnapInProgress()
-{
- LockHolder lock(m_mutex);
-
- return m_mainFrameIsScrollSnapping;
-}
-
-void ScrollingTree::setMainFrameIsScrollSnapping(bool isScrollSnapping)
-{
- LockHolder locker(m_mutex);
-
- m_mainFrameIsScrollSnapping = isScrollSnapping;
-}
-
-void ScrollingTree::setCanRubberBandState(bool canRubberBandAtLeft, bool canRubberBandAtRight, bool canRubberBandAtTop, bool canRubberBandAtBottom)
-{
- LockHolder locker(m_swipeStateMutex);
-
- m_rubberBandsAtLeft = canRubberBandAtLeft;
- m_rubberBandsAtRight = canRubberBandAtRight;
- m_rubberBandsAtTop = canRubberBandAtTop;
- m_rubberBandsAtBottom = canRubberBandAtBottom;
-}
-
-bool ScrollingTree::rubberBandsAtLeft()
-{
- LockHolder lock(m_swipeStateMutex);
-
- return m_rubberBandsAtLeft;
-}
-
-bool ScrollingTree::rubberBandsAtRight()
-{
- LockHolder lock(m_swipeStateMutex);
-
- return m_rubberBandsAtRight;
-}
-
-bool ScrollingTree::rubberBandsAtBottom()
-{
- LockHolder lock(m_swipeStateMutex);
-
- return m_rubberBandsAtBottom;
-}
-
-bool ScrollingTree::rubberBandsAtTop()
-{
- LockHolder lock(m_swipeStateMutex);
-
- return m_rubberBandsAtTop;
-}
-
-bool ScrollingTree::isHandlingProgrammaticScroll()
-{
- return m_isHandlingProgrammaticScroll;
-}
-
-void ScrollingTree::setScrollPinningBehavior(ScrollPinningBehavior pinning)
-{
- LockHolder locker(m_swipeStateMutex);
-
- m_scrollPinningBehavior = pinning;
-}
-
-ScrollPinningBehavior ScrollingTree::scrollPinningBehavior()
-{
- LockHolder lock(m_swipeStateMutex);
-
- return m_scrollPinningBehavior;
-}
-
-bool ScrollingTree::willWheelEventStartSwipeGesture(const PlatformWheelEvent& wheelEvent)
-{
- if (wheelEvent.phase() != PlatformWheelEventPhaseBegan)
- return false;
-
- LockHolder lock(m_swipeStateMutex);
-
- if (wheelEvent.deltaX() > 0 && m_mainFramePinnedToTheLeft && !m_rubberBandsAtLeft)
- return true;
- if (wheelEvent.deltaX() < 0 && m_mainFramePinnedToTheRight && !m_rubberBandsAtRight)
- return true;
- if (wheelEvent.deltaY() > 0 && m_mainFramePinnedToTheTop && !m_rubberBandsAtTop)
- return true;
- if (wheelEvent.deltaY() < 0 && m_mainFramePinnedToTheBottom && !m_rubberBandsAtBottom)
- return true;
-
- return false;
-}
-
-void ScrollingTree::setScrollingPerformanceLoggingEnabled(bool flag)
-{
- m_scrollingPerformanceLoggingEnabled = flag;
-}
-
-bool ScrollingTree::scrollingPerformanceLoggingEnabled()
-{
- return m_scrollingPerformanceLoggingEnabled;
-}
-
-ScrollingNodeID ScrollingTree::latchedNode()
-{
- LockHolder locker(m_mutex);
- return m_latchedNode;
-}
-
-void ScrollingTree::setLatchedNode(ScrollingNodeID node)
-{
- LockHolder locker(m_mutex);
- m_latchedNode = node;
-}
-
-void ScrollingTree::clearLatchedNode()
-{
- LockHolder locker(m_mutex);
- m_latchedNode = 0;
-}
-
-} // namespace WebCore
-
-#endif // ENABLE(ASYNC_SCROLLING)
diff --git a/Source/WebCore/page/scrolling/ScrollingTree.h b/Source/WebCore/page/scrolling/ScrollingTree.h
deleted file mode 100644
index b97765b5c..000000000
--- a/Source/WebCore/page/scrolling/ScrollingTree.h
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * Copyright (C) 2012-2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef ScrollingTree_h
-#define ScrollingTree_h
-
-#if ENABLE(ASYNC_SCROLLING)
-
-#include "PlatformWheelEvent.h"
-#include "Region.h"
-#include "ScrollingCoordinator.h"
-#include "WheelEventTestTrigger.h"
-#include <wtf/HashMap.h>
-#include <wtf/Lock.h>
-#include <wtf/ThreadSafeRefCounted.h>
-#include <wtf/TypeCasts.h>
-
-namespace WebCore {
-
-class IntPoint;
-class ScrollingStateTree;
-class ScrollingStateNode;
-class ScrollingTreeNode;
-class ScrollingTreeScrollingNode;
-
-class ScrollingTree : public ThreadSafeRefCounted<ScrollingTree> {
-public:
- WEBCORE_EXPORT ScrollingTree();
- WEBCORE_EXPORT virtual ~ScrollingTree();
-
- enum EventResult {
- DidNotHandleEvent,
- DidHandleEvent,
- SendToMainThread
- };
-
- virtual bool isThreadedScrollingTree() const { return false; }
- virtual bool isRemoteScrollingTree() const { return false; }
- virtual bool isScrollingTreeIOS() const { return false; }
-
- virtual EventResult tryToHandleWheelEvent(const PlatformWheelEvent&) = 0;
- WEBCORE_EXPORT bool shouldHandleWheelEventSynchronously(const PlatformWheelEvent&);
-
- void setMainFrameIsRubberBanding(bool);
- bool isRubberBandInProgress();
- void setMainFrameIsScrollSnapping(bool);
- bool isScrollSnapInProgress();
-
- virtual void invalidate() { }
- WEBCORE_EXPORT virtual void commitNewTreeState(std::unique_ptr<ScrollingStateTree>);
-
- void setMainFramePinState(bool pinnedToTheLeft, bool pinnedToTheRight, bool pinnedToTheTop, bool pinnedToTheBottom);
-
- virtual PassRefPtr<ScrollingTreeNode> createScrollingTreeNode(ScrollingNodeType, ScrollingNodeID) = 0;
-
- // Called after a scrolling tree node has handled a scroll and updated its layers.
- // Updates FrameView/RenderLayer scrolling state and GraphicsLayers.
- virtual void scrollingTreeNodeDidScroll(ScrollingNodeID, const FloatPoint& scrollPosition, SetOrSyncScrollingLayerPosition = SyncScrollingLayerPosition) = 0;
-
- // Called for requested scroll position updates.
- virtual void scrollingTreeNodeRequestsScroll(ScrollingNodeID, const FloatPoint& /*scrollPosition*/, bool /*representsProgrammaticScroll*/) { }
-
- // Delegated scrolling/zooming has caused the viewport to change, so update viewport-constrained layers
- // (but don't cause scroll events to be fired).
- WEBCORE_EXPORT virtual void viewportChangedViaDelegatedScrolling(ScrollingNodeID, const WebCore::FloatRect& fixedPositionRect, double scale);
-
- // Delegated scrolling has scrolled a node. Update layer positions on descendant tree nodes,
- // and call scrollingTreeNodeDidScroll().
- WEBCORE_EXPORT virtual void scrollPositionChangedViaDelegatedScrolling(ScrollingNodeID, const WebCore::FloatPoint& scrollPosition, bool inUserInteration);
-
- WEBCORE_EXPORT virtual void currentSnapPointIndicesDidChange(ScrollingNodeID, unsigned horizontal, unsigned vertical) = 0;
-
- FloatPoint mainFrameScrollPosition();
-
-#if PLATFORM(IOS)
- virtual FloatRect fixedPositionRect() = 0;
- virtual void scrollingTreeNodeWillStartPanGesture() { }
- virtual void scrollingTreeNodeWillStartScroll() { }
- virtual void scrollingTreeNodeDidEndScroll() { }
-#endif
-
- WEBCORE_EXPORT bool isPointInNonFastScrollableRegion(IntPoint);
-
-#if PLATFORM(MAC)
- virtual void handleWheelEventPhase(PlatformWheelEventPhase) = 0;
- virtual void setActiveScrollSnapIndices(ScrollingNodeID, unsigned /*horizontalIndex*/, unsigned /*verticalIndex*/) { }
- virtual void deferTestsForReason(WheelEventTestTrigger::ScrollableAreaIdentifier, WheelEventTestTrigger::DeferTestTriggerReason) { }
- virtual void removeTestDeferralForReason(WheelEventTestTrigger::ScrollableAreaIdentifier, WheelEventTestTrigger::DeferTestTriggerReason) { }
-#endif
-
- // Can be called from any thread. Will update what edges allow rubber-banding.
- WEBCORE_EXPORT void setCanRubberBandState(bool canRubberBandAtLeft, bool canRubberBandAtRight, bool canRubberBandAtTop, bool canRubberBandAtBottom);
-
- bool rubberBandsAtLeft();
- bool rubberBandsAtRight();
- bool rubberBandsAtTop();
- bool rubberBandsAtBottom();
- bool isHandlingProgrammaticScroll();
-
- void setScrollPinningBehavior(ScrollPinningBehavior);
- ScrollPinningBehavior scrollPinningBehavior();
-
- WEBCORE_EXPORT bool willWheelEventStartSwipeGesture(const PlatformWheelEvent&);
-
- WEBCORE_EXPORT void setScrollingPerformanceLoggingEnabled(bool flag);
- bool scrollingPerformanceLoggingEnabled();
-
- ScrollingTreeNode* rootNode() const { return m_rootNode.get(); }
-
- ScrollingNodeID latchedNode();
- void setLatchedNode(ScrollingNodeID);
- void clearLatchedNode();
-
- bool hasLatchedNode() const { return m_latchedNode; }
- void setOrClearLatchedNode(const PlatformWheelEvent&, ScrollingNodeID);
-
- bool hasFixedOrSticky() const { return !!m_fixedOrStickyNodeCount; }
- void fixedOrStickyNodeAdded() { ++m_fixedOrStickyNodeCount; }
- void fixedOrStickyNodeRemoved()
- {
- ASSERT(m_fixedOrStickyNodeCount);
- --m_fixedOrStickyNodeCount;
- }
-
-protected:
- void setMainFrameScrollPosition(FloatPoint);
- WEBCORE_EXPORT virtual void handleWheelEvent(const PlatformWheelEvent&);
-
-private:
- void removeDestroyedNodes(const ScrollingStateTree&);
-
- typedef HashMap<ScrollingNodeID, RefPtr<ScrollingTreeNode>> OrphanScrollingNodeMap;
- void updateTreeFromStateNode(const ScrollingStateNode*, OrphanScrollingNodeMap&);
-
- ScrollingTreeNode* nodeForID(ScrollingNodeID) const;
-
- RefPtr<ScrollingTreeNode> m_rootNode;
-
- typedef HashMap<ScrollingNodeID, ScrollingTreeNode*> ScrollingTreeNodeMap;
- ScrollingTreeNodeMap m_nodeMap;
-
- Lock m_mutex;
- Region m_nonFastScrollableRegion;
- FloatPoint m_mainFrameScrollPosition;
-
- Lock m_swipeStateMutex;
- ScrollPinningBehavior m_scrollPinningBehavior { DoNotPin };
- ScrollingNodeID m_latchedNode { 0 };
-
- unsigned m_fixedOrStickyNodeCount { 0 };
-
- bool m_rubberBandsAtLeft { true };
- bool m_rubberBandsAtRight { true };
- bool m_rubberBandsAtTop { true };
- bool m_rubberBandsAtBottom { true };
- bool m_mainFramePinnedToTheLeft { true };
- bool m_mainFramePinnedToTheRight { true };
- bool m_mainFramePinnedToTheTop { true };
- bool m_mainFramePinnedToTheBottom { true };
- bool m_mainFrameIsRubberBanding { false };
- bool m_mainFrameIsScrollSnapping { false };
- bool m_scrollingPerformanceLoggingEnabled { false };
- bool m_isHandlingProgrammaticScroll { false };
-};
-
-} // namespace WebCore
-
-#define SPECIALIZE_TYPE_TRAITS_SCROLLING_TREE(ToValueTypeName, predicate) \
-SPECIALIZE_TYPE_TRAITS_BEGIN(ToValueTypeName) \
- static bool isType(const WebCore::ScrollingTree& tree) { return tree.predicate; } \
-SPECIALIZE_TYPE_TRAITS_END()
-#endif // ENABLE(ASYNC_SCROLLING)
-
-#endif // ScrollingTree_h
diff --git a/Source/WebCore/page/scrolling/ScrollingTreeFrameScrollingNode.cpp b/Source/WebCore/page/scrolling/ScrollingTreeFrameScrollingNode.cpp
deleted file mode 100644
index ac3dba059..000000000
--- a/Source/WebCore/page/scrolling/ScrollingTreeFrameScrollingNode.cpp
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "ScrollingTreeFrameScrollingNode.h"
-
-#if ENABLE(ASYNC_SCROLLING)
-
-#include "ScrollingStateTree.h"
-#include "ScrollingTree.h"
-
-namespace WebCore {
-
-ScrollingTreeFrameScrollingNode::ScrollingTreeFrameScrollingNode(ScrollingTree& scrollingTree, ScrollingNodeID nodeID)
- : ScrollingTreeScrollingNode(scrollingTree, FrameScrollingNode, nodeID)
-{
-}
-
-ScrollingTreeFrameScrollingNode::~ScrollingTreeFrameScrollingNode()
-{
-}
-
-void ScrollingTreeFrameScrollingNode::updateBeforeChildren(const ScrollingStateNode& stateNode)
-{
- ScrollingTreeScrollingNode::updateBeforeChildren(stateNode);
-
- const ScrollingStateFrameScrollingNode& state = downcast<ScrollingStateFrameScrollingNode>(stateNode);
-
- if (state.hasChangedProperty(ScrollingStateFrameScrollingNode::FrameScaleFactor))
- m_frameScaleFactor = state.frameScaleFactor();
-
- if (state.hasChangedProperty(ScrollingStateFrameScrollingNode::ReasonsForSynchronousScrolling))
- m_synchronousScrollingReasons = state.synchronousScrollingReasons();
-
- if (state.hasChangedProperty(ScrollingStateFrameScrollingNode::HeaderHeight))
- m_headerHeight = state.headerHeight();
-
- if (state.hasChangedProperty(ScrollingStateFrameScrollingNode::FooterHeight))
- m_footerHeight = state.footerHeight();
-
- if (state.hasChangedProperty(ScrollingStateFrameScrollingNode::BehaviorForFixedElements))
- m_behaviorForFixed = state.scrollBehaviorForFixedElements();
-
- if (state.hasChangedProperty(ScrollingStateFrameScrollingNode::TopContentInset))
- m_topContentInset = state.topContentInset();
-
- if (state.hasChangedProperty(ScrollingStateFrameScrollingNode::FixedElementsLayoutRelativeToFrame))
- m_fixedElementsLayoutRelativeToFrame = state.fixedElementsLayoutRelativeToFrame();
-}
-
-void ScrollingTreeFrameScrollingNode::scrollBy(const FloatSize& delta)
-{
- setScrollPosition(scrollPosition() + delta);
-}
-
-void ScrollingTreeFrameScrollingNode::scrollByWithoutContentEdgeConstraints(const FloatSize& offset)
-{
- setScrollPositionWithoutContentEdgeConstraints(scrollPosition() + offset);
-}
-
-void ScrollingTreeFrameScrollingNode::setScrollPosition(const FloatPoint& scrollPosition)
-{
- FloatPoint newScrollPosition = scrollPosition.constrainedBetween(minimumScrollPosition(), maximumScrollPosition());
- setScrollPositionWithoutContentEdgeConstraints(newScrollPosition);
-}
-
-FloatSize ScrollingTreeFrameScrollingNode::viewToContentsOffset(const FloatPoint& scrollPosition) const
-{
- return toFloatSize(scrollPosition) - FloatSize(0, headerHeight() + topContentInset());
-}
-
-} // namespace WebCore
-
-#endif // ENABLE(ASYNC_SCROLLING)
diff --git a/Source/WebCore/page/scrolling/ScrollingTreeFrameScrollingNode.h b/Source/WebCore/page/scrolling/ScrollingTreeFrameScrollingNode.h
deleted file mode 100644
index 92b01f017..000000000
--- a/Source/WebCore/page/scrolling/ScrollingTreeFrameScrollingNode.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef ScrollingTreeFrameScrollingNode_h
-#define ScrollingTreeFrameScrollingNode_h
-
-#if ENABLE(ASYNC_SCROLLING)
-
-#include "ScrollingTreeScrollingNode.h"
-
-namespace WebCore {
-
-class PlatformWheelEvent;
-class ScrollingTree;
-class ScrollingStateScrollingNode;
-
-class ScrollingTreeFrameScrollingNode : public ScrollingTreeScrollingNode {
-public:
- virtual ~ScrollingTreeFrameScrollingNode();
-
- virtual void updateBeforeChildren(const ScrollingStateNode&) override;
-
- // FIXME: We should implement this when we support ScrollingTreeScrollingNodes as children.
- virtual void updateLayersAfterAncestorChange(const ScrollingTreeNode& /*changedNode*/, const FloatRect& /*fixedPositionRect*/, const FloatSize& /*cumulativeDelta*/) override { }
-
- virtual void handleWheelEvent(const PlatformWheelEvent&) override = 0;
- virtual void setScrollPosition(const FloatPoint&) override;
- virtual void setScrollPositionWithoutContentEdgeConstraints(const FloatPoint&) override = 0;
-
- virtual void updateLayersAfterViewportChange(const FloatRect& fixedPositionRect, double scale) override = 0;
- virtual void updateLayersAfterDelegatedScroll(const FloatPoint&) override { }
-
- SynchronousScrollingReasons synchronousScrollingReasons() const { return m_synchronousScrollingReasons; }
- bool shouldUpdateScrollLayerPositionSynchronously() const { return m_synchronousScrollingReasons; }
- bool fixedElementsLayoutRelativeToFrame() const { return m_fixedElementsLayoutRelativeToFrame; }
-
- FloatSize viewToContentsOffset(const FloatPoint& scrollPosition) const;
-
-protected:
- ScrollingTreeFrameScrollingNode(ScrollingTree&, ScrollingNodeID);
-
- void scrollBy(const FloatSize&);
- void scrollByWithoutContentEdgeConstraints(const FloatSize&);
-
- float frameScaleFactor() const { return m_frameScaleFactor; }
- int headerHeight() const { return m_headerHeight; }
- int footerHeight() const { return m_footerHeight; }
- float topContentInset() const { return m_topContentInset; }
-
- ScrollBehaviorForFixedElements scrollBehaviorForFixedElements() const { return m_behaviorForFixed; }
-
-private:
- float m_frameScaleFactor { 1 };
- float m_topContentInset { 0 };
-
- int m_headerHeight { 0 };
- int m_footerHeight { 0 };
-
- SynchronousScrollingReasons m_synchronousScrollingReasons { 0 };
- ScrollBehaviorForFixedElements m_behaviorForFixed { StickToDocumentBounds };
-
- bool m_fixedElementsLayoutRelativeToFrame { false };
-};
-
-} // namespace WebCore
-
-SPECIALIZE_TYPE_TRAITS_SCROLLING_NODE(ScrollingTreeFrameScrollingNode, isFrameScrollingNode())
-
-#endif // ENABLE(ASYNC_SCROLLING)
-
-#endif // ScrollingTreeScrollingNode_h
diff --git a/Source/WebCore/page/scrolling/ScrollingTreeNode.cpp b/Source/WebCore/page/scrolling/ScrollingTreeNode.cpp
deleted file mode 100644
index 8c4111822..000000000
--- a/Source/WebCore/page/scrolling/ScrollingTreeNode.cpp
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "ScrollingTreeNode.h"
-
-#if ENABLE(ASYNC_SCROLLING)
-
-#include "ScrollingStateTree.h"
-
-namespace WebCore {
-
-ScrollingTreeNode::ScrollingTreeNode(ScrollingTree& scrollingTree, ScrollingNodeType nodeType, ScrollingNodeID nodeID)
- : m_scrollingTree(scrollingTree)
- , m_nodeType(nodeType)
- , m_nodeID(nodeID)
- , m_parent(nullptr)
-{
-}
-
-ScrollingTreeNode::~ScrollingTreeNode()
-{
-}
-
-void ScrollingTreeNode::appendChild(PassRefPtr<ScrollingTreeNode> childNode)
-{
- childNode->setParent(this);
-
- if (!m_children)
- m_children = std::make_unique<ScrollingTreeChildrenVector>();
-
- m_children->append(childNode);
-}
-
-void ScrollingTreeNode::removeChild(ScrollingTreeNode* node)
-{
- if (!m_children)
- return;
-
- size_t index = m_children->find(node);
-
- // The index will be notFound if the node to remove is a deeper-than-1-level descendant or
- // if node is the root state node.
- if (index != notFound) {
- m_children->remove(index);
- return;
- }
-
- for (auto& child : *m_children)
- child->removeChild(node);
-}
-
-} // namespace WebCore
-
-#endif // ENABLE(ASYNC_SCROLLING)
diff --git a/Source/WebCore/page/scrolling/ScrollingTreeNode.h b/Source/WebCore/page/scrolling/ScrollingTreeNode.h
deleted file mode 100644
index dad214f22..000000000
--- a/Source/WebCore/page/scrolling/ScrollingTreeNode.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef ScrollingTreeNode_h
-#define ScrollingTreeNode_h
-
-#if ENABLE(ASYNC_SCROLLING)
-
-#include "IntRect.h"
-#include "ScrollTypes.h"
-#include "ScrollingCoordinator.h"
-#include <wtf/RefCounted.h>
-#include <wtf/TypeCasts.h>
-
-namespace WebCore {
-
-class ScrollingStateFixedNode;
-class ScrollingStateNode;
-class ScrollingStateScrollingNode;
-
-class ScrollingTreeNode : public RefCounted<ScrollingTreeNode> {
-public:
- virtual ~ScrollingTreeNode();
-
- ScrollingNodeType nodeType() const { return m_nodeType; }
- ScrollingNodeID scrollingNodeID() const { return m_nodeID; }
-
- bool isFixedNode() const { return nodeType() == FixedNode; }
- bool isStickyNode() const { return nodeType() == StickyNode; }
- bool isScrollingNode() const { return nodeType() == FrameScrollingNode || nodeType() == OverflowScrollingNode; }
- bool isFrameScrollingNode() const { return nodeType() == FrameScrollingNode; }
- bool isOverflowScrollingNode() const { return nodeType() == OverflowScrollingNode; }
-
- virtual void updateBeforeChildren(const ScrollingStateNode&) = 0;
- virtual void updateAfterChildren(const ScrollingStateNode&) { }
-
- virtual void updateLayersAfterAncestorChange(const ScrollingTreeNode& changedNode, const FloatRect& fixedPositionRect, const FloatSize& cumulativeDelta) = 0;
-
- ScrollingTreeNode* parent() const { return m_parent; }
- void setParent(ScrollingTreeNode* parent) { m_parent = parent; }
-
- typedef Vector<RefPtr<ScrollingTreeNode>> ScrollingTreeChildrenVector;
- ScrollingTreeChildrenVector* children() { return m_children.get(); }
-
- void appendChild(PassRefPtr<ScrollingTreeNode>);
- void removeChild(ScrollingTreeNode*);
-
-protected:
- ScrollingTreeNode(ScrollingTree&, ScrollingNodeType, ScrollingNodeID);
- ScrollingTree& scrollingTree() const { return m_scrollingTree; }
-
- std::unique_ptr<ScrollingTreeChildrenVector> m_children;
-
-private:
- ScrollingTree& m_scrollingTree;
-
- const ScrollingNodeType m_nodeType;
- const ScrollingNodeID m_nodeID;
-
- ScrollingTreeNode* m_parent;
-};
-
-} // namespace WebCore
-
-#define SPECIALIZE_TYPE_TRAITS_SCROLLING_NODE(ToValueTypeName, predicate) \
-SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::ToValueTypeName) \
- static bool isType(const WebCore::ScrollingTreeNode& node) { return node.predicate; } \
-SPECIALIZE_TYPE_TRAITS_END()
-
-#endif // ENABLE(ASYNC_SCROLLING)
-
-#endif // ScrollingTreeNode_h
diff --git a/Source/WebCore/page/scrolling/ScrollingTreeOverflowScrollingNode.cpp b/Source/WebCore/page/scrolling/ScrollingTreeOverflowScrollingNode.cpp
deleted file mode 100644
index 013e350e6..000000000
--- a/Source/WebCore/page/scrolling/ScrollingTreeOverflowScrollingNode.cpp
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "ScrollingTreeOverflowScrollingNode.h"
-
-#if ENABLE(ASYNC_SCROLLING)
-
-#include "ScrollingStateTree.h"
-#include "ScrollingTree.h"
-
-namespace WebCore {
-
-ScrollingTreeOverflowScrollingNode::ScrollingTreeOverflowScrollingNode(ScrollingTree& scrollingTree, ScrollingNodeID nodeID)
- : ScrollingTreeScrollingNode(scrollingTree, OverflowScrollingNode, nodeID)
-{
-}
-
-ScrollingTreeOverflowScrollingNode::~ScrollingTreeOverflowScrollingNode()
-{
-}
-
-} // namespace WebCore
-
-#endif // ENABLE(ASYNC_SCROLLING)
diff --git a/Source/WebCore/page/scrolling/ScrollingTreeOverflowScrollingNode.h b/Source/WebCore/page/scrolling/ScrollingTreeOverflowScrollingNode.h
deleted file mode 100644
index 42a4f4bbb..000000000
--- a/Source/WebCore/page/scrolling/ScrollingTreeOverflowScrollingNode.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef ScrollingTreeOverflowScrollingNode_h
-#define ScrollingTreeOverflowScrollingNode_h
-
-#if ENABLE(ASYNC_SCROLLING)
-
-#include "ScrollingTreeScrollingNode.h"
-
-namespace WebCore {
-
-class ScrollingTreeOverflowScrollingNode : public ScrollingTreeScrollingNode {
-public:
- WEBCORE_EXPORT virtual ~ScrollingTreeOverflowScrollingNode();
-
-
-protected:
- WEBCORE_EXPORT ScrollingTreeOverflowScrollingNode(ScrollingTree&, ScrollingNodeID);
-};
-
-} // namespace WebCore
-
-SPECIALIZE_TYPE_TRAITS_SCROLLING_NODE(ScrollingTreeOverflowScrollingNode, isOverflowScrollingNode())
-
-#endif // ENABLE(ASYNC_SCROLLING)
-
-#endif // ScrollingTreeOverflowScrollingNode_h
diff --git a/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.cpp b/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.cpp
deleted file mode 100644
index 8457e19c0..000000000
--- a/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.cpp
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "ScrollingTreeScrollingNode.h"
-
-#if ENABLE(ASYNC_SCROLLING)
-
-#include "ScrollingStateTree.h"
-#include "ScrollingTree.h"
-
-namespace WebCore {
-
-ScrollingTreeScrollingNode::ScrollingTreeScrollingNode(ScrollingTree& scrollingTree, ScrollingNodeType nodeType, ScrollingNodeID nodeID)
- : ScrollingTreeNode(scrollingTree, nodeType, nodeID)
-{
-}
-
-ScrollingTreeScrollingNode::~ScrollingTreeScrollingNode()
-{
-}
-
-void ScrollingTreeScrollingNode::updateBeforeChildren(const ScrollingStateNode& stateNode)
-{
- const ScrollingStateScrollingNode& state = downcast<ScrollingStateScrollingNode>(stateNode);
-
- if (state.hasChangedProperty(ScrollingStateScrollingNode::ScrollableAreaSize))
- m_scrollableAreaSize = state.scrollableAreaSize();
-
- if (state.hasChangedProperty(ScrollingStateScrollingNode::TotalContentsSize)) {
- if (scrollingTree().isRubberBandInProgress())
- m_totalContentsSizeForRubberBand = m_totalContentsSize;
- else
- m_totalContentsSizeForRubberBand = state.totalContentsSize();
-
- m_totalContentsSize = state.totalContentsSize();
- }
-
- if (state.hasChangedProperty(ScrollingStateScrollingNode::ReachableContentsSize))
- m_reachableContentsSize = state.reachableContentsSize();
-
- if (state.hasChangedProperty(ScrollingStateScrollingNode::ScrollPosition))
- m_lastCommittedScrollPosition = state.scrollPosition();
-
- if (state.hasChangedProperty(ScrollingStateScrollingNode::ScrollOrigin))
- m_scrollOrigin = state.scrollOrigin();
-
-#if ENABLE(CSS_SCROLL_SNAP)
- if (state.hasChangedProperty(ScrollingStateScrollingNode::HorizontalSnapOffsets))
- m_horizontalSnapOffsets = state.horizontalSnapOffsets();
-
- if (state.hasChangedProperty(ScrollingStateScrollingNode::VerticalSnapOffsets))
- m_verticalSnapOffsets = state.verticalSnapOffsets();
-
- if (state.hasChangedProperty(ScrollingStateScrollingNode::CurrentHorizontalSnapOffsetIndex))
- m_currentHorizontalSnapPointIndex = state.currentHorizontalSnapPointIndex();
-
- if (state.hasChangedProperty(ScrollingStateScrollingNode::CurrentVerticalSnapOffsetIndex))
- m_currentVerticalSnapPointIndex = state.currentVerticalSnapPointIndex();
-#endif
-
- if (state.hasChangedProperty(ScrollingStateScrollingNode::ScrollableAreaParams))
- m_scrollableAreaParameters = state.scrollableAreaParameters();
-}
-
-void ScrollingTreeScrollingNode::updateAfterChildren(const ScrollingStateNode& stateNode)
-{
- const ScrollingStateScrollingNode& scrollingStateNode = downcast<ScrollingStateScrollingNode>(stateNode);
- if (scrollingStateNode.hasChangedProperty(ScrollingStateScrollingNode::RequestedScrollPosition))
- scrollingTree().scrollingTreeNodeRequestsScroll(scrollingNodeID(), scrollingStateNode.requestedScrollPosition(), scrollingStateNode.requestedScrollPositionRepresentsProgrammaticScroll());
-}
-
-void ScrollingTreeScrollingNode::updateLayersAfterAncestorChange(const ScrollingTreeNode& changedNode, const FloatRect& fixedPositionRect, const FloatSize& cumulativeDelta)
-{
- if (!m_children)
- return;
-
- for (auto& child : *m_children)
- child->updateLayersAfterAncestorChange(changedNode, fixedPositionRect, cumulativeDelta);
-}
-
-void ScrollingTreeScrollingNode::setScrollPosition(const FloatPoint& scrollPosition)
-{
- FloatPoint newScrollPosition = scrollPosition.constrainedBetween(minimumScrollPosition(), maximumScrollPosition());
- setScrollPositionWithoutContentEdgeConstraints(newScrollPosition);
-}
-
-void ScrollingTreeScrollingNode::setScrollPositionWithoutContentEdgeConstraints(const FloatPoint& scrollPosition)
-{
- setScrollLayerPosition(scrollPosition);
- scrollingTree().scrollingTreeNodeDidScroll(scrollingNodeID(), scrollPosition);
-}
-
-FloatPoint ScrollingTreeScrollingNode::minimumScrollPosition() const
-{
- return FloatPoint();
-}
-
-FloatPoint ScrollingTreeScrollingNode::maximumScrollPosition() const
-{
- FloatPoint contentSizePoint(totalContentsSize());
- return FloatPoint(contentSizePoint - scrollableAreaSize()).expandedTo(FloatPoint());
-}
-
-
-} // namespace WebCore
-
-#endif // ENABLE(ASYNC_SCROLLING)
diff --git a/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.h b/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.h
deleted file mode 100644
index 07c896c80..000000000
--- a/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef ScrollingTreeScrollingNode_h
-#define ScrollingTreeScrollingNode_h
-
-#if ENABLE(ASYNC_SCROLLING)
-
-#include "IntRect.h"
-#include "ScrollTypes.h"
-#include "ScrollingCoordinator.h"
-#include "ScrollingTreeNode.h"
-
-namespace WebCore {
-
-class ScrollingTree;
-class ScrollingStateScrollingNode;
-
-class ScrollingTreeScrollingNode : public ScrollingTreeNode {
-public:
- virtual ~ScrollingTreeScrollingNode();
-
- WEBCORE_EXPORT virtual void updateBeforeChildren(const ScrollingStateNode&) override;
- WEBCORE_EXPORT virtual void updateAfterChildren(const ScrollingStateNode&) override;
-
- WEBCORE_EXPORT virtual void updateLayersAfterAncestorChange(const ScrollingTreeNode& changedNode, const FloatRect& fixedPositionRect, const FloatSize& cumulativeDelta) override;
-
- virtual void handleWheelEvent(const PlatformWheelEvent&) = 0;
- WEBCORE_EXPORT virtual void setScrollPosition(const FloatPoint&);
- WEBCORE_EXPORT virtual void setScrollPositionWithoutContentEdgeConstraints(const FloatPoint&);
-
- virtual void updateLayersAfterViewportChange(const FloatRect& fixedPositionRect, double scale) = 0;
- virtual void updateLayersAfterDelegatedScroll(const FloatPoint&) { }
-
- virtual FloatPoint scrollPosition() const = 0;
-
-#if ENABLE(CSS_SCROLL_SNAP)
- const Vector<float>& horizontalSnapOffsets() const { return m_horizontalSnapOffsets; }
- const Vector<float>& verticalSnapOffsets() const { return m_verticalSnapOffsets; }
- unsigned currentHorizontalSnapPointIndex() const { return m_currentHorizontalSnapPointIndex; }
- unsigned currentVerticalSnapPointIndex() const { return m_currentVerticalSnapPointIndex; }
- void setCurrentHorizontalSnapPointIndex(unsigned index) { m_currentHorizontalSnapPointIndex = index; }
- void setCurrentVerticalSnapPointIndex(unsigned index) { m_currentVerticalSnapPointIndex = index; }
-#endif
-
-protected:
- ScrollingTreeScrollingNode(ScrollingTree&, ScrollingNodeType, ScrollingNodeID);
-
- WEBCORE_EXPORT virtual FloatPoint minimumScrollPosition() const;
- WEBCORE_EXPORT virtual FloatPoint maximumScrollPosition() const;
-
- virtual void setScrollLayerPosition(const FloatPoint&) = 0;
-
- FloatPoint lastCommittedScrollPosition() const { return m_lastCommittedScrollPosition; }
- const FloatSize& scrollableAreaSize() const { return m_scrollableAreaSize; }
- const FloatSize& totalContentsSize() const { return m_totalContentsSize; }
- const FloatSize& reachableContentsSize() const { return m_reachableContentsSize; }
- const IntPoint& scrollOrigin() const { return m_scrollOrigin; }
-
- // If the totalContentsSize changes in the middle of a rubber-band, we still want to use the old totalContentsSize for the sake of
- // computing the stretchAmount(). Using the old value will keep the animation smooth. When there is no rubber-band in progress at
- // all, m_totalContentsSizeForRubberBand should be equivalent to m_totalContentsSize.
- const FloatSize& totalContentsSizeForRubberBand() const { return m_totalContentsSizeForRubberBand; }
- void setTotalContentsSizeForRubberBand(const FloatSize& totalContentsSizeForRubberBand) { m_totalContentsSizeForRubberBand = totalContentsSizeForRubberBand; }
-
- ScrollElasticity horizontalScrollElasticity() const { return m_scrollableAreaParameters.horizontalScrollElasticity; }
- ScrollElasticity verticalScrollElasticity() const { return m_scrollableAreaParameters.verticalScrollElasticity; }
-
- bool hasEnabledHorizontalScrollbar() const { return m_scrollableAreaParameters.hasEnabledHorizontalScrollbar; }
- bool hasEnabledVerticalScrollbar() const { return m_scrollableAreaParameters.hasEnabledVerticalScrollbar; }
-
- bool canHaveScrollbars() const { return m_scrollableAreaParameters.horizontalScrollbarMode != ScrollbarAlwaysOff || m_scrollableAreaParameters.verticalScrollbarMode != ScrollbarAlwaysOff; }
-
-private:
- FloatSize m_scrollableAreaSize;
- FloatSize m_totalContentsSize;
- FloatSize m_totalContentsSizeForRubberBand;
- FloatSize m_reachableContentsSize;
- FloatPoint m_lastCommittedScrollPosition;
- IntPoint m_scrollOrigin;
-#if ENABLE(CSS_SCROLL_SNAP)
- Vector<float> m_horizontalSnapOffsets;
- Vector<float> m_verticalSnapOffsets;
- unsigned m_currentHorizontalSnapPointIndex { 0 };
- unsigned m_currentVerticalSnapPointIndex { 0 };
-#endif
- ScrollableAreaParameters m_scrollableAreaParameters;
-};
-
-} // namespace WebCore
-
-SPECIALIZE_TYPE_TRAITS_SCROLLING_NODE(ScrollingTreeScrollingNode, isScrollingNode())
-
-#endif // ENABLE(ASYNC_SCROLLING)
-
-#endif // ScrollingTreeScrollingNode_h
diff --git a/Source/WebCore/page/scrolling/ThreadedScrollingTree.cpp b/Source/WebCore/page/scrolling/ThreadedScrollingTree.cpp
deleted file mode 100644
index 483986af5..000000000
--- a/Source/WebCore/page/scrolling/ThreadedScrollingTree.cpp
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * Copyright (C) 2014-2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "ThreadedScrollingTree.h"
-
-#if ENABLE(ASYNC_SCROLLING)
-
-#include "AsyncScrollingCoordinator.h"
-#include "PlatformWheelEvent.h"
-#include "ScrollingThread.h"
-#include "ScrollingTreeFixedNode.h"
-#include "ScrollingTreeNode.h"
-#include "ScrollingTreeScrollingNode.h"
-#include "ScrollingTreeStickyNode.h"
-#include <wtf/RunLoop.h>
-#include <wtf/TemporaryChange.h>
-
-namespace WebCore {
-
-ThreadedScrollingTree::ThreadedScrollingTree(AsyncScrollingCoordinator* scrollingCoordinator)
- : m_scrollingCoordinator(scrollingCoordinator)
-{
-}
-
-ThreadedScrollingTree::~ThreadedScrollingTree()
-{
- // invalidate() should have cleared m_scrollingCoordinator.
- ASSERT(!m_scrollingCoordinator);
-}
-
-ScrollingTree::EventResult ThreadedScrollingTree::tryToHandleWheelEvent(const PlatformWheelEvent& wheelEvent)
-{
- if (shouldHandleWheelEventSynchronously(wheelEvent))
- return SendToMainThread;
-
- if (willWheelEventStartSwipeGesture(wheelEvent))
- return DidNotHandleEvent;
-
- RefPtr<ThreadedScrollingTree> threadedScrollingTree(this);
- ScrollingThread::dispatch([threadedScrollingTree, wheelEvent] {
- threadedScrollingTree->handleWheelEvent(wheelEvent);
- });
-
- return DidHandleEvent;
-}
-
-void ThreadedScrollingTree::handleWheelEvent(const PlatformWheelEvent& wheelEvent)
-{
- ASSERT(ScrollingThread::isCurrentThread());
- ScrollingTree::handleWheelEvent(wheelEvent);
-}
-
-void ThreadedScrollingTree::invalidate()
-{
- // Invalidate is dispatched by the ScrollingCoordinator class on the ScrollingThread
- // to break the reference cycle between ScrollingTree and ScrollingCoordinator when the
- // ScrollingCoordinator's page is destroyed.
- ASSERT(ScrollingThread::isCurrentThread());
-
- // Since this can potentially be the last reference to the scrolling coordinator,
- // we need to release it on the main thread since it has member variables (such as timers)
- // that expect to be destroyed from the main thread.
- ScrollingCoordinator* scrollingCoordinator = m_scrollingCoordinator.release().leakRef();
- RunLoop::main().dispatch([scrollingCoordinator] {
- scrollingCoordinator->deref();
- });
-}
-
-void ThreadedScrollingTree::commitNewTreeState(std::unique_ptr<ScrollingStateTree> scrollingStateTree)
-{
- ASSERT(ScrollingThread::isCurrentThread());
- ScrollingTree::commitNewTreeState(WTFMove(scrollingStateTree));
-}
-
-void ThreadedScrollingTree::scrollingTreeNodeDidScroll(ScrollingNodeID nodeID, const FloatPoint& scrollPosition, SetOrSyncScrollingLayerPosition scrollingLayerPositionAction)
-{
- if (!m_scrollingCoordinator)
- return;
-
- if (nodeID == rootNode()->scrollingNodeID())
- setMainFrameScrollPosition(scrollPosition);
-
- RefPtr<AsyncScrollingCoordinator> scrollingCoordinator = m_scrollingCoordinator;
- bool localIsHandlingProgrammaticScroll = isHandlingProgrammaticScroll();
-
- RunLoop::main().dispatch([scrollingCoordinator, nodeID, scrollPosition, localIsHandlingProgrammaticScroll, scrollingLayerPositionAction] {
- scrollingCoordinator->scheduleUpdateScrollPositionAfterAsyncScroll(nodeID, scrollPosition, localIsHandlingProgrammaticScroll, scrollingLayerPositionAction);
- });
-}
-
-void ThreadedScrollingTree::currentSnapPointIndicesDidChange(ScrollingNodeID nodeID, unsigned horizontal, unsigned vertical)
-{
- if (!m_scrollingCoordinator)
- return;
-
- RefPtr<AsyncScrollingCoordinator> scrollingCoordinator = m_scrollingCoordinator;
- RunLoop::main().dispatch([scrollingCoordinator, nodeID, horizontal, vertical] {
- scrollingCoordinator->setActiveScrollSnapIndices(nodeID, horizontal, vertical);
- });
-}
-
-#if PLATFORM(MAC)
-void ThreadedScrollingTree::handleWheelEventPhase(PlatformWheelEventPhase phase)
-{
- if (!m_scrollingCoordinator)
- return;
-
- RefPtr<AsyncScrollingCoordinator> scrollingCoordinator = m_scrollingCoordinator;
- RunLoop::main().dispatch([scrollingCoordinator, phase] {
- scrollingCoordinator->handleWheelEventPhase(phase);
- });
-}
-
-void ThreadedScrollingTree::setActiveScrollSnapIndices(ScrollingNodeID nodeID, unsigned horizontalIndex, unsigned verticalIndex)
-{
- if (!m_scrollingCoordinator)
- return;
-
- RefPtr<AsyncScrollingCoordinator> scrollingCoordinator = m_scrollingCoordinator;
- RunLoop::main().dispatch([scrollingCoordinator, nodeID, horizontalIndex, verticalIndex] {
- scrollingCoordinator->setActiveScrollSnapIndices(nodeID, horizontalIndex, verticalIndex);
- });
-}
-
-void ThreadedScrollingTree::deferTestsForReason(WheelEventTestTrigger::ScrollableAreaIdentifier identifier, WheelEventTestTrigger::DeferTestTriggerReason reason)
-{
- if (!m_scrollingCoordinator)
- return;
-
- RefPtr<AsyncScrollingCoordinator> scrollingCoordinator = m_scrollingCoordinator;
- RunLoop::main().dispatch([scrollingCoordinator, identifier, reason] {
- scrollingCoordinator->deferTestsForReason(identifier, reason);
- });
-}
-
-void ThreadedScrollingTree::removeTestDeferralForReason(WheelEventTestTrigger::ScrollableAreaIdentifier identifier, WheelEventTestTrigger::DeferTestTriggerReason reason)
-{
- if (!m_scrollingCoordinator)
- return;
-
- RefPtr<AsyncScrollingCoordinator> scrollingCoordinator = m_scrollingCoordinator;
- RunLoop::main().dispatch([scrollingCoordinator, identifier, reason] {
- scrollingCoordinator->removeTestDeferralForReason(identifier, reason);
- });
-}
-
-#endif
-
-} // namespace WebCore
-
-#endif // ENABLE(ASYNC_SCROLLING)
diff --git a/Source/WebCore/page/scrolling/ThreadedScrollingTree.h b/Source/WebCore/page/scrolling/ThreadedScrollingTree.h
deleted file mode 100644
index 6bc801b70..000000000
--- a/Source/WebCore/page/scrolling/ThreadedScrollingTree.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2014-2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef ThreadedScrollingTree_h
-#define ThreadedScrollingTree_h
-
-#if ENABLE(ASYNC_SCROLLING)
-
-#include "ScrollingStateTree.h"
-#include "ScrollingTree.h"
-#include <wtf/PassRefPtr.h>
-#include <wtf/RefPtr.h>
-
-namespace WebCore {
-
-class AsyncScrollingCoordinator;
-
-// The ThreadedScrollingTree class lives almost exclusively on the scrolling thread and manages the
-// hierarchy of scrollable regions on the page. It's also responsible for dispatching events
-// to the correct scrolling tree nodes or dispatching events back to the ScrollingCoordinator
-// object on the main thread if they can't be handled on the scrolling thread for various reasons.
-class ThreadedScrollingTree : public ScrollingTree {
-public:
- virtual ~ThreadedScrollingTree();
-
- virtual void commitNewTreeState(std::unique_ptr<ScrollingStateTree>) override;
-
- virtual void handleWheelEvent(const PlatformWheelEvent&) override;
-
- // Can be called from any thread. Will try to handle the wheel event on the scrolling thread.
- // Returns true if the wheel event can be handled on the scrolling thread and false if the
- // event must be sent again to the WebCore event handler.
- virtual EventResult tryToHandleWheelEvent(const PlatformWheelEvent&) override;
-
- virtual void invalidate() override;
-
-protected:
- explicit ThreadedScrollingTree(AsyncScrollingCoordinator*);
-
- virtual void scrollingTreeNodeDidScroll(ScrollingNodeID, const FloatPoint& scrollPosition, SetOrSyncScrollingLayerPosition = SyncScrollingLayerPosition) override;
- void currentSnapPointIndicesDidChange(ScrollingNodeID, unsigned horizontal, unsigned vertical) override;
-#if PLATFORM(MAC)
- void handleWheelEventPhase(PlatformWheelEventPhase) override;
- void setActiveScrollSnapIndices(ScrollingNodeID, unsigned horizontalIndex, unsigned verticalIndex) override;
- void deferTestsForReason(WheelEventTestTrigger::ScrollableAreaIdentifier, WheelEventTestTrigger::DeferTestTriggerReason) override;
- void removeTestDeferralForReason(WheelEventTestTrigger::ScrollableAreaIdentifier, WheelEventTestTrigger::DeferTestTriggerReason) override;
-#endif
-
-private:
- virtual bool isThreadedScrollingTree() const override { return true; }
-
- RefPtr<AsyncScrollingCoordinator> m_scrollingCoordinator;
-};
-
-} // namespace WebCore
-
-SPECIALIZE_TYPE_TRAITS_SCROLLING_TREE(WebCore::ThreadedScrollingTree, isThreadedScrollingTree())
-
-#endif // ENABLE(ASYNC_SCROLLING)
-
-#endif // ThreadedScrollingTree_h
diff --git a/Source/WebCore/page/scrolling/coordinatedgraphics/ScrollingCoordinatorCoordinatedGraphics.cpp b/Source/WebCore/page/scrolling/coordinatedgraphics/ScrollingCoordinatorCoordinatedGraphics.cpp
deleted file mode 100644
index 09d3fa5ee..000000000
--- a/Source/WebCore/page/scrolling/coordinatedgraphics/ScrollingCoordinatorCoordinatedGraphics.cpp
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies).
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#if USE(COORDINATED_GRAPHICS)
-
-#include "ScrollingCoordinatorCoordinatedGraphics.h"
-
-#include "CoordinatedGraphicsLayer.h"
-#include "FrameView.h"
-#include "HostWindow.h"
-#include "Page.h"
-#include "RenderLayer.h"
-#include "RenderLayerBacking.h"
-#include "ScrollingConstraints.h"
-#include "ScrollingStateFixedNode.h"
-#include "ScrollingStateScrollingNode.h"
-#include "ScrollingStateStickyNode.h"
-#include "ScrollingStateTree.h"
-#include "Settings.h"
-
-namespace WebCore {
-
-ScrollingCoordinatorCoordinatedGraphics::ScrollingCoordinatorCoordinatedGraphics(Page* page)
- : ScrollingCoordinator(page)
- , m_scrollingStateTree(std::make_unique<ScrollingStateTree>())
-{
-}
-
-ScrollingCoordinatorCoordinatedGraphics::~ScrollingCoordinatorCoordinatedGraphics()
-{
-}
-
-ScrollingNodeID ScrollingCoordinatorCoordinatedGraphics::attachToStateTree(ScrollingNodeType nodeType, ScrollingNodeID newNodeID, ScrollingNodeID parentID)
-{
- return m_scrollingStateTree->attachNode(nodeType, newNodeID, parentID);
-}
-
-void ScrollingCoordinatorCoordinatedGraphics::detachFromStateTree(ScrollingNodeID nodeID)
-{
- ScrollingStateNode* node = m_scrollingStateTree->stateNodeForID(nodeID);
- if (node && node->nodeType() == FixedNode)
- toCoordinatedGraphicsLayer(node->layer())->setFixedToViewport(false);
-
- m_scrollingStateTree->detachNode(nodeID);
-}
-
-void ScrollingCoordinatorCoordinatedGraphics::clearStateTree()
-{
- m_scrollingStateTree->clear();
-}
-
-void ScrollingCoordinatorCoordinatedGraphics::updateViewportConstrainedNode(ScrollingNodeID nodeID, const ViewportConstraints& constraints, GraphicsLayer* graphicsLayer)
-{
- ASSERT(supportsFixedPositionLayers());
-
- ScrollingStateNode* node = m_scrollingStateTree->stateNodeForID(nodeID);
- if (!node)
- return;
-
- switch (constraints.constraintType()) {
- case ViewportConstraints::FixedPositionConstraint: {
- toCoordinatedGraphicsLayer(graphicsLayer)->setFixedToViewport(true); // FIXME : Use constraints!
- downcast<ScrollingStateFixedNode>(*node).setLayer(graphicsLayer);
- break;
- }
- case ViewportConstraints::StickyPositionConstraint:
- break; // FIXME : Support sticky elements.
- default:
- ASSERT_NOT_REACHED();
- }
-}
-
-void ScrollingCoordinatorCoordinatedGraphics::scrollableAreaScrollLayerDidChange(ScrollableArea& scrollableArea)
-{
- CoordinatedGraphicsLayer* layer = toCoordinatedGraphicsLayer(scrollLayerForScrollableArea(scrollableArea));
- if (!layer)
- return;
-
- layer->setScrollableArea(&scrollableArea);
-}
-
-void ScrollingCoordinatorCoordinatedGraphics::willDestroyScrollableArea(ScrollableArea& scrollableArea)
-{
- CoordinatedGraphicsLayer* layer = toCoordinatedGraphicsLayer(scrollLayerForScrollableArea(scrollableArea));
- if (!layer)
- return;
-
- layer->setScrollableArea(nullptr);
-}
-
-bool ScrollingCoordinatorCoordinatedGraphics::requestScrollPositionUpdate(FrameView& frameView, const IntPoint& scrollPosition)
-{
- if (!frameView.delegatesScrolling())
- return false;
-
- frameView.hostWindow()->delegatedScrollRequested(scrollPosition);
- return true;
-}
-
-} // namespace WebCore
-
-#endif // USE(COORDINATED_GRAPHICS)
diff --git a/Source/WebCore/page/scrolling/coordinatedgraphics/ScrollingCoordinatorCoordinatedGraphics.h b/Source/WebCore/page/scrolling/coordinatedgraphics/ScrollingCoordinatorCoordinatedGraphics.h
deleted file mode 100644
index a1200725e..000000000
--- a/Source/WebCore/page/scrolling/coordinatedgraphics/ScrollingCoordinatorCoordinatedGraphics.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies).
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef ScrollingCoordinatorCoordinatedGraphics_h
-#define ScrollingCoordinatorCoordinatedGraphics_h
-
-#if USE(COORDINATED_GRAPHICS)
-
-#include "ScrollingCoordinator.h"
-
-namespace WebCore {
-
-class ScrollingStateTree;
-
-class ScrollingCoordinatorCoordinatedGraphics : public ScrollingCoordinator {
-public:
- explicit ScrollingCoordinatorCoordinatedGraphics(Page*);
- virtual ~ScrollingCoordinatorCoordinatedGraphics();
-
- virtual bool supportsFixedPositionLayers() const override { return true; }
-
- virtual ScrollingNodeID attachToStateTree(ScrollingNodeType, ScrollingNodeID newNodeID, ScrollingNodeID parentID) override;
- virtual void detachFromStateTree(ScrollingNodeID) override;
- virtual void clearStateTree() override;
-
- virtual void updateViewportConstrainedNode(ScrollingNodeID, const ViewportConstraints&, GraphicsLayer*) override;
-
- virtual void scrollableAreaScrollLayerDidChange(ScrollableArea&) override;
- virtual void willDestroyScrollableArea(ScrollableArea&) override;
-
- virtual bool requestScrollPositionUpdate(FrameView&, const IntPoint&) override;
-
-private:
- std::unique_ptr<ScrollingStateTree> m_scrollingStateTree;
-};
-
-} // namespace WebCore
-
-#endif // USE(COORDINATED_GRAPHICS)
-
-#endif // ScrollingCoordinatorCoordinatedGraphics_h