summaryrefslogtreecommitdiff
path: root/Source/WebCore/page
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/page')
-rw-r--r--Source/WebCore/page/BarInfo.idl2
-rw-r--r--Source/WebCore/page/Console.idl8
-rw-r--r--Source/WebCore/page/DOMSelection.idl4
-rw-r--r--Source/WebCore/page/DOMWindow.cpp21
-rw-r--r--Source/WebCore/page/DOMWindow.h4
-rw-r--r--Source/WebCore/page/DOMWindow.idl109
-rw-r--r--Source/WebCore/page/DragController.cpp8
-rw-r--r--Source/WebCore/page/EventHandler.cpp138
-rw-r--r--Source/WebCore/page/EventHandler.h4
-rw-r--r--Source/WebCore/page/EventSource.idl2
-rw-r--r--Source/WebCore/page/FocusController.cpp50
-rw-r--r--Source/WebCore/page/FocusController.h4
-rw-r--r--Source/WebCore/page/Frame.cpp17
-rw-r--r--Source/WebCore/page/FrameView.cpp136
-rw-r--r--Source/WebCore/page/FrameView.h17
-rw-r--r--Source/WebCore/page/Geolocation.idl2
-rw-r--r--Source/WebCore/page/History.cpp23
-rw-r--r--Source/WebCore/page/History.h6
-rw-r--r--Source/WebCore/page/History.idl11
-rw-r--r--Source/WebCore/page/Location.idl18
-rw-r--r--Source/WebCore/page/MemoryInfo.idl2
-rw-r--r--Source/WebCore/page/Navigator.idl8
-rw-r--r--Source/WebCore/page/Page.cpp41
-rw-r--r--Source/WebCore/page/Page.h13
-rw-r--r--Source/WebCore/page/PageSerializer.cpp24
-rw-r--r--Source/WebCore/page/PageSerializer.h7
-rw-r--r--Source/WebCore/page/PrintContext.cpp4
-rw-r--r--Source/WebCore/page/Screen.idl2
-rw-r--r--Source/WebCore/page/Settings.cpp9
-rw-r--r--Source/WebCore/page/Settings.h13
-rw-r--r--Source/WebCore/page/SpeechInputResultList.idl2
-rw-r--r--Source/WebCore/page/WebKitAnimation.cpp13
-rw-r--r--Source/WebCore/page/WebKitAnimation.h2
-rw-r--r--Source/WebCore/page/WebKitAnimationList.idl2
-rw-r--r--Source/WebCore/page/WorkerNavigator.idl4
-rw-r--r--Source/WebCore/page/animation/AnimationBase.cpp4
-rw-r--r--Source/WebCore/page/scrolling/ScrollingCoordinator.cpp137
-rw-r--r--Source/WebCore/page/scrolling/ScrollingCoordinator.h57
-rw-r--r--Source/WebCore/page/scrolling/ScrollingThread.cpp111
-rw-r--r--Source/WebCore/page/scrolling/ScrollingThread.h86
-rw-r--r--Source/WebCore/page/scrolling/ScrollingTree.cpp125
-rw-r--r--Source/WebCore/page/scrolling/ScrollingTree.h84
-rw-r--r--Source/WebCore/page/scrolling/ScrollingTreeNode.cpp55
-rw-r--r--Source/WebCore/page/scrolling/ScrollingTreeNode.h66
-rw-r--r--Source/WebCore/page/scrolling/ScrollingTreeState.cpp94
-rw-r--r--Source/WebCore/page/scrolling/ScrollingTreeState.h102
-rw-r--r--Source/WebCore/page/scrolling/mac/ScrollingCoordinatorMac.mm175
-rw-r--r--Source/WebCore/page/scrolling/mac/ScrollingThreadMac.mm69
-rw-r--r--Source/WebCore/page/scrolling/mac/ScrollingTreeNodeMac.h58
-rw-r--r--Source/WebCore/page/scrolling/mac/ScrollingTreeNodeMac.mm81
-rw-r--r--Source/WebCore/page/scrolling/mac/ScrollingTreeStateMac.mm51
-rw-r--r--Source/WebCore/page/win/FrameCGWin.cpp2
52 files changed, 1573 insertions, 514 deletions
diff --git a/Source/WebCore/page/BarInfo.idl b/Source/WebCore/page/BarInfo.idl
index 2f036c11b..11a97c70e 100644
--- a/Source/WebCore/page/BarInfo.idl
+++ b/Source/WebCore/page/BarInfo.idl
@@ -29,7 +29,7 @@
module window {
interface [
- GenerateIsReachable=ImplFrame,
+ JSGenerateIsReachable=ImplFrame,
OmitConstructor
] BarInfo {
readonly attribute boolean visible;
diff --git a/Source/WebCore/page/Console.idl b/Source/WebCore/page/Console.idl
index 3c63a8ace..42cd187f9 100644
--- a/Source/WebCore/page/Console.idl
+++ b/Source/WebCore/page/Console.idl
@@ -29,7 +29,7 @@
module window {
interface [
- GenerateIsReachable=ImplFrame,
+ JSGenerateIsReachable=ImplFrame,
OmitConstructor
] Console {
@@ -41,7 +41,7 @@ module window {
[CustomArgumentHandling] void dir();
[CustomArgumentHandling] void dirxml();
[V8Custom, CustomArgumentHandling] void trace();
- [V8Custom, CustomArgumentHandling, ImplementationFunction=assertCondition] void assert(in boolean condition);
+ [V8Custom, CustomArgumentHandling, ImplementedAs=assertCondition] void assert(in boolean condition);
[CustomArgumentHandling] void count();
[CustomArgumentHandling] void markTimeline();
@@ -51,8 +51,8 @@ module window {
[Custom] void profileEnd(in DOMString title);
#endif
- void time(in [ConvertUndefinedOrNullToNullString,Optional=CallWithDefaultValue] DOMString title);
- [CustomArgumentHandling] void timeEnd(in [ConvertUndefinedOrNullToNullString] DOMString title);
+ void time(in [TreatNullAs=NullString, TreatUndefinedAs=NullString,Optional=CallWithDefaultValue] DOMString title);
+ [CustomArgumentHandling] void timeEnd(in [TreatNullAs=NullString, TreatUndefinedAs=NullString] DOMString title);
[CustomArgumentHandling] void timeStamp();
[CustomArgumentHandling] void group();
[CustomArgumentHandling] void groupCollapsed();
diff --git a/Source/WebCore/page/DOMSelection.idl b/Source/WebCore/page/DOMSelection.idl
index 8a28e6ddb..ccd30e375 100644
--- a/Source/WebCore/page/DOMSelection.idl
+++ b/Source/WebCore/page/DOMSelection.idl
@@ -32,7 +32,7 @@ module window {
// This is based off of Mozilla's Selection interface
// https://developer.mozilla.org/En/DOM/Selection
interface [
- GenerateIsReachable=ImplFrame,
+ JSGenerateIsReachable=ImplFrame,
OmitConstructor
] DOMSelection {
readonly attribute Node anchorNode;
@@ -67,7 +67,7 @@ module window {
void addRange(in [Optional=CallWithDefaultValue] Range range);
#if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT
- [DontEnum] DOMString toString();
+ [NotEnumerable] DOMString toString();
#endif
// WebKit extensions
diff --git a/Source/WebCore/page/DOMWindow.cpp b/Source/WebCore/page/DOMWindow.cpp
index f6fe47b69..2597f864f 100644
--- a/Source/WebCore/page/DOMWindow.cpp
+++ b/Source/WebCore/page/DOMWindow.cpp
@@ -874,7 +874,7 @@ void DOMWindow::postMessageTimerFired(PassOwnPtr<PostMessageTimer> t)
// Give the embedder a chance to intercept this postMessage because this
// DOMWindow might be a proxy for another in browsers that support
// postMessage calls across WebKit instances.
- if (isCurrentlyDisplayedInFrame() && m_frame->loader()->client()->willCheckAndDispatchMessageEvent(timer->targetOrigin(), PassRefPtr<MessageEvent>(event).leakRef()))
+ if (isCurrentlyDisplayedInFrame() && m_frame->loader()->client()->willCheckAndDispatchMessageEvent(timer->targetOrigin(), event.get()))
return;
if (timer->targetOrigin()) {
@@ -1550,8 +1550,11 @@ bool DOMWindow::addEventListener(const AtomicString& eventType, PassRefPtr<Event
if (!EventTarget::addEventListener(eventType, listener, useCapture))
return false;
- if (Document* document = this->document())
+ if (Document* document = this->document()) {
document->addListenerTypeIfNeeded(eventType);
+ if (eventType == eventNames().mousewheelEvent)
+ document->didAddWheelEventHandler();
+ }
if (eventType == eventNames().unloadEvent)
addUnloadEventListener(this);
@@ -1572,6 +1575,11 @@ bool DOMWindow::removeEventListener(const AtomicString& eventType, EventListener
if (!EventTarget::removeEventListener(eventType, listener, useCapture))
return false;
+ if (Document* document = this->document()) {
+ if (eventType == eventNames().mousewheelEvent)
+ document->didRemoveWheelEventHandler();
+ }
+
if (eventType == eventNames().unloadEvent)
removeUnloadEventListener(this);
else if (eventType == eventNames().beforeunloadEvent && allowsBeforeUnloadListeners(this))
@@ -1889,15 +1897,6 @@ void DOMWindow::showModalDialog(const String& urlString, const String& dialogFea
dialogFrame->page()->chrome()->runModal();
}
-#if ENABLE(BLOB)
-DOMURL* DOMWindow::webkitURL() const
-{
- if (!m_domURL && isCurrentlyDisplayedInFrame())
- m_domURL = DOMURL::create(this->scriptExecutionContext());
- return m_domURL.get();
-}
-#endif
-
#if ENABLE(QUOTA)
StorageInfo* DOMWindow::webkitStorageInfo() const
{
diff --git a/Source/WebCore/page/DOMWindow.h b/Source/WebCore/page/DOMWindow.h
index 38e8c5d73..96a58e583 100644
--- a/Source/WebCore/page/DOMWindow.h
+++ b/Source/WebCore/page/DOMWindow.h
@@ -351,10 +351,6 @@ namespace WebCore {
using RefCounted<DOMWindow>::ref;
using RefCounted<DOMWindow>::deref;
-#if ENABLE(BLOB)
- DOMURL* webkitURL() const;
-#endif
-
#if ENABLE(DEVICE_ORIENTATION)
DEFINE_ATTRIBUTE_EVENT_LISTENER(devicemotion);
DEFINE_ATTRIBUTE_EVENT_LISTENER(deviceorientation);
diff --git a/Source/WebCore/page/DOMWindow.idl b/Source/WebCore/page/DOMWindow.idl
index 6eb74773d..41ace04d0 100644
--- a/Source/WebCore/page/DOMWindow.idl
+++ b/Source/WebCore/page/DOMWindow.idl
@@ -28,23 +28,22 @@ module window {
interface [
CheckDomainSecurity,
- CustomDefineGetter,
- CustomDefineSetter,
+ JSCustomDefineOwnProperty,
CustomDeleteProperty,
CustomGetOwnPropertySlot,
CustomGetPropertyNames,
- CustomMarkFunction,
- CustomNativeConverter,
+ JSCustomMarkFunction,
+ JSCustomToNativeObject,
CustomPutFunction,
EventTarget,
ExtendsDOMGlobalObject,
- GenerateNativeConverter,
+ JSGenerateToNativeObject,
ReplaceableConstructor,
- LegacyParent=JSDOMWindowBase
+ JSLegacyParent=JSDOMWindowBase
] DOMWindow {
// DOM Level 0
attribute [Replaceable] Screen screen;
- attribute [Replaceable, DoNotCheckDomainSecurityOnGet, JSCCustomGetter] History history;
+ attribute [Replaceable, DoNotCheckDomainSecurityOnGetter, JSCustomGetter] History history;
attribute [Replaceable] BarInfo locationbar;
attribute [Replaceable] BarInfo menubar;
attribute [Replaceable] BarInfo personalbar;
@@ -54,14 +53,14 @@ module window {
attribute [Replaceable] Navigator navigator;
attribute [Replaceable] Navigator clientInformation;
readonly attribute Crypto crypto;
- attribute [DoNotCheckDomainSecurity, JSCCustom, V8CustomSetter, V8Unforgeable, CPPCustom] Location location;
+ attribute [DoNotCheckDomainSecurity, JSCustom, V8CustomSetter, V8Unforgeable, CPPCustom] Location location;
attribute [Replaceable, CustomGetter, V8CustomSetter] Event event;
DOMSelection getSelection();
- readonly attribute [CheckNodeSecurity] Element frameElement;
+ readonly attribute [CheckAccessToNode] Element frameElement;
[DoNotCheckDomainSecurity] void focus();
[DoNotCheckDomainSecurity] void blur();
@@ -81,7 +80,7 @@ module window {
void alert(in [Optional=CallWithDefaultValue] DOMString message);
boolean confirm(in [Optional=CallWithDefaultValue] DOMString message);
[ConvertNullStringTo=Null] DOMString prompt(in [Optional=CallWithDefaultValue] DOMString message,
- in [ConvertUndefinedOrNullToNullString,Optional=CallWithDefaultValue] DOMString defaultValue);
+ in [TreatNullAs=NullString, TreatUndefinedAs=NullString,Optional=CallWithDefaultValue] DOMString defaultValue);
boolean find(in [Optional=CallWithDefaultValue] DOMString string,
in [Optional=CallWithDefaultValue] boolean caseSensitive,
@@ -116,7 +115,7 @@ module window {
readonly attribute [DoNotCheckDomainSecurity] boolean closed;
- attribute [Replaceable, DoNotCheckDomainSecurityOnGet] unsigned long length;
+ attribute [Replaceable, DoNotCheckDomainSecurityOnGetter] unsigned long length;
attribute DOMString name;
@@ -128,13 +127,13 @@ module window {
#endif
// Self referential attributes
- attribute [Replaceable, DoNotCheckDomainSecurityOnGet] DOMWindow self;
+ attribute [Replaceable, DoNotCheckDomainSecurityOnGetter] DOMWindow self;
readonly attribute [DoNotCheckDomainSecurity, V8Unforgeable] DOMWindow window;
- attribute [Replaceable, DoNotCheckDomainSecurityOnGet] DOMWindow frames;
+ attribute [Replaceable, DoNotCheckDomainSecurityOnGetter] DOMWindow frames;
- attribute [Replaceable, DoNotCheckDomainSecurityOnGet, V8CustomSetter] DOMWindow opener;
- attribute [Replaceable, DoNotCheckDomainSecurityOnGet] DOMWindow parent;
- attribute [Replaceable, DoNotCheckDomainSecurityOnGet, V8Unforgeable, V8ReadOnly] DOMWindow top;
+ attribute [Replaceable, DoNotCheckDomainSecurityOnGetter, V8CustomSetter] DOMWindow opener;
+ attribute [Replaceable, DoNotCheckDomainSecurityOnGetter] DOMWindow parent;
+ attribute [Replaceable, DoNotCheckDomainSecurityOnGetter, V8Unforgeable, V8ReadOnly] DOMWindow top;
// DOM Level 2 AbstractView Interface
readonly attribute Document document;
@@ -147,7 +146,7 @@ module window {
// DOM Level 2 Style Interface
CSSStyleDeclaration getComputedStyle(in [Optional=CallWithDefaultValue] Element element,
- in [ConvertUndefinedOrNullToNullString,Optional=CallWithDefaultValue] DOMString pseudoElement);
+ in [TreatNullAs=NullString, TreatUndefinedAs=NullString,Optional=CallWithDefaultValue] DOMString pseudoElement);
// WebKit extensions
#if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT
@@ -162,21 +161,21 @@ module window {
WebKitPoint webkitConvertPointFromNodeToPage(in [Optional=CallWithDefaultValue] Node node,
in [Optional=CallWithDefaultValue] WebKitPoint p);
- readonly attribute [EnabledAtRuntime] DOMApplicationCache applicationCache;
+ readonly attribute [V8EnabledAtRuntime] DOMApplicationCache applicationCache;
- readonly attribute [EnabledAtRuntime] Storage sessionStorage
+ readonly attribute [V8EnabledAtRuntime] Storage sessionStorage
getter raises(DOMException);
- readonly attribute [EnabledAtRuntime] Storage localStorage
+ readonly attribute [V8EnabledAtRuntime] Storage localStorage
getter raises(DOMException);
#if defined(ENABLE_NOTIFICATIONS) && ENABLE_NOTIFICATIONS
- readonly attribute [EnabledAtRuntime] NotificationCenter webkitNotifications;
+ readonly attribute [V8EnabledAtRuntime] NotificationCenter webkitNotifications;
#endif
#if defined(ENABLE_FILE_SYSTEM) && ENABLE_FILE_SYSTEM
const unsigned short TEMPORARY = 0;
const unsigned short PERSISTENT = 1;
- [EnabledAtRuntime=FileSystem] void webkitRequestFileSystem(in unsigned short type, in long long size, in [Callback] FileSystemCallback successCallback, in [Callback, Optional] ErrorCallback errorCallback);
- [EnabledAtRuntime=FileSystem] void webkitResolveLocalFileSystemURL(in DOMString url, in [Callback, Optional] EntryCallback successCallback, in [Callback, Optional] ErrorCallback errorCallback);
+ [V8EnabledAtRuntime=FileSystem] void webkitRequestFileSystem(in unsigned short type, in long long size, in [Callback] FileSystemCallback successCallback, in [Callback, Optional] ErrorCallback errorCallback);
+ [V8EnabledAtRuntime=FileSystem] void webkitResolveLocalFileSystemURL(in DOMString url, in [Callback, Optional] EntryCallback successCallback, in [Callback, Optional] ErrorCallback errorCallback);
#endif
#if defined(ENABLE_ORIENTATION_EVENTS) && ENABLE_ORIENTATION_EVENTS
@@ -228,9 +227,9 @@ module window {
#endif
// Base64
- DOMString atob(in [TreatNullAs=EmptyString,Optional=CallWithDefaultValue] DOMString string)
+ DOMString atob(in [TreatNullAs=NullString,Optional=CallWithDefaultValue] DOMString string)
raises(DOMException);
- DOMString btoa(in [TreatNullAs=EmptyString,Optional=CallWithDefaultValue] DOMString string)
+ DOMString btoa(in [TreatNullAs=NullString,Optional=CallWithDefaultValue] DOMString string)
raises(DOMException);
// Events
@@ -314,15 +313,15 @@ module window {
#if defined(ENABLE_ORIENTATION_EVENTS) && ENABLE_ORIENTATION_EVENTS
attribute EventListener onorientationchange;
#endif
- attribute [Conditional=TOUCH_EVENTS,EnabledAtRuntime] EventListener ontouchstart;
- attribute [Conditional=TOUCH_EVENTS,EnabledAtRuntime] EventListener ontouchmove;
- attribute [Conditional=TOUCH_EVENTS,EnabledAtRuntime] EventListener ontouchend;
- attribute [Conditional=TOUCH_EVENTS,EnabledAtRuntime] EventListener ontouchcancel;
+ attribute [Conditional=TOUCH_EVENTS,V8EnabledAtRuntime] EventListener ontouchstart;
+ attribute [Conditional=TOUCH_EVENTS,V8EnabledAtRuntime] EventListener ontouchmove;
+ attribute [Conditional=TOUCH_EVENTS,V8EnabledAtRuntime] EventListener ontouchend;
+ attribute [Conditional=TOUCH_EVENTS,V8EnabledAtRuntime] EventListener ontouchcancel;
- attribute [Conditional=DEVICE_ORIENTATION,EnabledAtRuntime] EventListener ondevicemotion;
- attribute [Conditional=DEVICE_ORIENTATION,EnabledAtRuntime] EventListener ondeviceorientation;
+ attribute [Conditional=DEVICE_ORIENTATION,V8EnabledAtRuntime] EventListener ondevicemotion;
+ attribute [Conditional=DEVICE_ORIENTATION,V8EnabledAtRuntime] EventListener ondeviceorientation;
- attribute [Conditional=MEDIA_STREAM,EnabledAtRuntime] PeerConnectionConstructor webkitPeerConnection;
+ attribute [Conditional=MEDIA_STREAM,V8EnabledAtRuntime] PeerConnectionConstructor webkitPeerConnection;
// EventTarget interface
[Custom] void addEventListener(in DOMString type,
@@ -398,7 +397,7 @@ module window {
attribute EntityConstructor Entity;
attribute EntityReferenceConstructor EntityReference;
attribute ProcessingInstructionConstructor ProcessingInstruction;
- attribute [Conditional=SHADOW_DOM, EnabledAtRuntime=shadowDOM] ShadowRootConstructor WebKitShadowRoot;
+ attribute [Conditional=SHADOW_DOM, V8EnabledAtRuntime=shadowDOM] ShadowRootConstructor WebKitShadowRoot;
attribute HTMLDocumentConstructor HTMLDocument;
@@ -472,8 +471,8 @@ module window {
attribute [Conditional=MICRODATA] HTMLPropertiesCollectionConstructor HTMLPropertiesCollection;
attribute HTMLUnknownElementConstructor HTMLUnknownElement;
- attribute [JSCCustomGetter, CustomConstructor] HTMLImageElementConstructorConstructor Image; // Usable with new operator
- attribute [JSCCustomGetter] HTMLOptionElementConstructorConstructor Option; // Usable with new operator
+ attribute [JSCustomGetter, CustomConstructor] HTMLImageElementConstructorConstructor Image; // Usable with new operator
+ attribute [JSCustomGetter] HTMLOptionElementConstructorConstructor Option; // Usable with new operator
attribute CanvasPatternConstructor CanvasPattern;
attribute CanvasGradientConstructor CanvasGradient;
@@ -526,8 +525,8 @@ module window {
attribute WheelEventConstructor WheelEvent;
attribute XMLHttpRequestProgressEventConstructor XMLHttpRequestProgressEvent;
attribute [Conditional=SVG] SVGZoomEventConstructor SVGZoomEvent;
- attribute [Conditional=DEVICE_ORIENTATION, EnabledAtRuntime] DeviceMotionEventConstructor DeviceMotionEvent;
- attribute [Conditional=DEVICE_ORIENTATION, EnabledAtRuntime] DeviceOrientationEventConstructor DeviceOrientationEvent;
+ attribute [Conditional=DEVICE_ORIENTATION, V8EnabledAtRuntime] DeviceMotionEventConstructor DeviceMotionEvent;
+ attribute [Conditional=DEVICE_ORIENTATION, V8EnabledAtRuntime] DeviceOrientationEventConstructor DeviceOrientationEvent;
attribute [Conditional=TOUCH_EVENTS] TouchEventConstructor TouchEvent;
attribute StorageEventConstructor StorageEvent;
attribute [Conditional=INPUT_SPEECH] SpeechInputEventConstructor SpeechInputEvent;
@@ -579,16 +578,16 @@ module window {
#endif
#if defined(ENABLE_SHARED_WORKERS) && ENABLE_SHARED_WORKERS
- attribute [JSCCustomGetter, EnabledAtRuntime] SharedWorkerConstructor SharedWorker; // Usable with the new operator
+ attribute [JSCustomGetter, V8EnabledAtRuntime] SharedWorkerConstructor SharedWorker; // Usable with the new operator
#endif
#if defined(ENABLE_VIDEO_TRACK) && ENABLE_VIDEO_TRACK
- attribute [EnabledAtRuntime=webkitVideoTrack] HTMLTrackElementConstructor HTMLTrackElement;
- attribute [EnabledAtRuntime=webkitVideoTrack] TextTrackConstructor TextTrack;
- attribute [EnabledAtRuntime=webkitVideoTrack] TextTrackCueConstructor TextTrackCue; // Usable with the new operator
- attribute [EnabledAtRuntime=webkitVideoTrack] TextTrackCueListConstructor TextTrackCueList;
- attribute [EnabledAtRuntime=webkitVideoTrack] TextTrackListConstructor TextTrackList;
- attribute [EnabledAtRuntime=webkitVideoTrack] TrackEventConstructor TrackEvent;
+ attribute [V8EnabledAtRuntime=webkitVideoTrack] HTMLTrackElementConstructor HTMLTrackElement;
+ attribute [V8EnabledAtRuntime=webkitVideoTrack] TextTrackConstructor TextTrack;
+ attribute [V8EnabledAtRuntime=webkitVideoTrack] TextTrackCueConstructor TextTrackCue; // Usable with the new operator
+ attribute [V8EnabledAtRuntime=webkitVideoTrack] TextTrackCueListConstructor TextTrackCueList;
+ attribute [V8EnabledAtRuntime=webkitVideoTrack] TextTrackListConstructor TextTrackList;
+ attribute [V8EnabledAtRuntime=webkitVideoTrack] TrackEventConstructor TrackEvent;
#endif
attribute DOMPluginConstructor Plugin;
@@ -602,14 +601,14 @@ module window {
attribute StorageConstructor Storage;
- attribute [JSCCustomGetter, Conditional=VIDEO, EnabledAtRuntime] HTMLAudioElementConstructorConstructor Audio; // Usable with the new operator
- attribute [Conditional=VIDEO, EnabledAtRuntime] HTMLAudioElementConstructor HTMLAudioElement;
- attribute [Conditional=VIDEO, EnabledAtRuntime] HTMLMediaElementConstructor HTMLMediaElement;
- attribute [Conditional=VIDEO, EnabledAtRuntime] HTMLVideoElementConstructor HTMLVideoElement;
- attribute [Conditional=VIDEO, EnabledAtRuntime] MediaErrorConstructor MediaError;
- attribute [Conditional=VIDEO, EnabledAtRuntime] TimeRangesConstructor TimeRanges;
- attribute [Conditional=VIDEO, EnabledAtRuntime] HTMLSourceElementConstructor HTMLSourceElement;
- attribute [Conditional=VIDEO, EnabledAtRuntime] MediaControllerConstructor MediaController;
+ attribute [JSCustomGetter, Conditional=VIDEO, V8EnabledAtRuntime] HTMLAudioElementConstructorConstructor Audio; // Usable with the new operator
+ attribute [Conditional=VIDEO, V8EnabledAtRuntime] HTMLAudioElementConstructor HTMLAudioElement;
+ attribute [Conditional=VIDEO, V8EnabledAtRuntime] HTMLMediaElementConstructor HTMLMediaElement;
+ attribute [Conditional=VIDEO, V8EnabledAtRuntime] HTMLVideoElementConstructor HTMLVideoElement;
+ attribute [Conditional=VIDEO, V8EnabledAtRuntime] MediaErrorConstructor MediaError;
+ attribute [Conditional=VIDEO, V8EnabledAtRuntime] TimeRangesConstructor TimeRanges;
+ attribute [Conditional=VIDEO, V8EnabledAtRuntime] HTMLSourceElementConstructor HTMLSourceElement;
+ attribute [Conditional=VIDEO, V8EnabledAtRuntime] MediaControllerConstructor MediaController;
#if defined(ENABLE_ANIMATION_API) && ENABLE_ANIMATION_API
attribute WebKitAnimationConstructor WebKitAnimation;
@@ -783,10 +782,10 @@ module window {
attribute [Conditional=BLOB] WebKitBlobBuilderConstructor WebKitBlobBuilder;
- readonly attribute [Conditional=BLOB] DOMURL webkitURL;
+ attribute [Conditional=BLOB] DOMURLConstructor webkitURL;
#if defined(ENABLE_QUOTA) && ENABLE_QUOTA
- readonly attribute [EnabledAtRuntime=Quota] StorageInfo webkitStorageInfo;
+ readonly attribute [V8EnabledAtRuntime=Quota] StorageInfo webkitStorageInfo;
#endif
attribute [Conditional=MUTATION_OBSERVERS] WebKitMutationObserverConstructor WebKitMutationObserver;
@@ -795,7 +794,7 @@ module window {
#if defined(V8_BINDING) && V8_BINDING
// window.toString() requires special handling in V8
- [V8DoNotCheckSignature, DoNotCheckDomainSecurity, Custom, DontEnum] DOMString toString();
+ [V8DoNotCheckSignature, DoNotCheckDomainSecurity, Custom, NotEnumerable] DOMString toString();
#endif // defined(V8_BINDING)
};
diff --git a/Source/WebCore/page/DragController.cpp b/Source/WebCore/page/DragController.cpp
index a47b6a4bc..7919d761e 100644
--- a/Source/WebCore/page/DragController.cpp
+++ b/Source/WebCore/page/DragController.cpp
@@ -27,7 +27,6 @@
#include "DragController.h"
#if ENABLE(DRAG_SUPPORT)
-#include "CSSMutableStyleDeclaration.h"
#include "Clipboard.h"
#include "ClipboardAccessPolicy.h"
#include "CachedResourceLoader.h"
@@ -64,6 +63,7 @@
#include "ResourceRequest.h"
#include "SecurityOrigin.h"
#include "Settings.h"
+#include "StylePropertySet.h"
#include "Text.h"
#include "TextEvent.h"
#include "htmlediting.h"
@@ -447,12 +447,12 @@ bool DragController::concludeEditDrag(DragData* dragData)
if (!color.isValid())
return false;
RefPtr<Range> innerRange = innerFrame->selection()->toNormalizedRange();
- RefPtr<CSSMutableStyleDeclaration> style = CSSMutableStyleDeclaration::create();
+ RefPtr<StylePropertySet> style = StylePropertySet::create();
style->setProperty(CSSPropertyColor, color.serialized(), false);
- if (!innerFrame->editor()->shouldApplyStyle(style.get(), innerRange.get()))
+ if (!innerFrame->editor()->shouldApplyStyle(style->ensureCSSStyleDeclaration(), innerRange.get()))
return false;
m_client->willPerformDragDestinationAction(DragDestinationActionEdit, dragData);
- innerFrame->editor()->applyStyle(style.get(), EditActionSetColor);
+ innerFrame->editor()->applyStyle(style->ensureCSSStyleDeclaration(), EditActionSetColor);
return true;
}
diff --git a/Source/WebCore/page/EventHandler.cpp b/Source/WebCore/page/EventHandler.cpp
index a2f322e26..9acfc54d2 100644
--- a/Source/WebCore/page/EventHandler.cpp
+++ b/Source/WebCore/page/EventHandler.cpp
@@ -60,6 +60,7 @@
#include "MouseEvent.h"
#include "MouseEventWithHitTestResults.h"
#include "Page.h"
+#include "PlatformEvent.h"
#include "PlatformKeyboardEvent.h"
#include "PlatformWheelEvent.h"
#include "PluginDocument.h"
@@ -142,6 +143,73 @@ private:
Cursor m_cursor;
};
+#if ENABLE(TOUCH_EVENTS)
+class SyntheticTouchPoint : public PlatformTouchPoint {
+public:
+
+ // The default values are based on http://dvcs.w3.org/hg/webevents/raw-file/tip/touchevents.html
+ explicit SyntheticTouchPoint(const PlatformMouseEvent& event)
+ {
+ const static int idDefaultValue = 0;
+ const static int radiusYDefaultValue = 1;
+ const static int radiusXDefaultValue = 1;
+ const static float rotationAngleDefaultValue = 0.0f;
+ const static float forceDefaultValue = 1.0f;
+
+ m_id = idDefaultValue; // There is only one active TouchPoint.
+ m_screenPos = event.globalPosition();
+ m_pos = event.position();
+ m_radiusY = radiusYDefaultValue;
+ m_radiusX = radiusXDefaultValue;
+ m_rotationAngle = rotationAngleDefaultValue;
+ m_force = forceDefaultValue;
+
+ PlatformEvent::Type type = event.type();
+ ASSERT(type == PlatformEvent::MouseMoved || type == PlatformEvent::MousePressed || type == PlatformEvent::MouseReleased);
+
+ switch (type) {
+ case PlatformEvent::MouseMoved:
+ m_state = TouchMoved;
+ break;
+ case PlatformEvent::MousePressed:
+ m_state = TouchPressed;
+ break;
+ case PlatformEvent::MouseReleased:
+ m_state = TouchReleased;
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ break;
+ }
+ }
+};
+
+class SyntheticSingleTouchEvent : public PlatformTouchEvent {
+public:
+ explicit SyntheticSingleTouchEvent(const PlatformMouseEvent& event)
+ {
+ switch (event.type()) {
+ case PlatformEvent::MouseMoved:
+ m_type = TouchMove;
+ break;
+ case PlatformEvent::MousePressed:
+ m_type = TouchStart;
+ break;
+ case PlatformEvent::MouseReleased:
+ m_type = TouchEnd;
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ m_type = NoType;
+ break;
+ }
+ m_timestamp = event.timestamp();
+ m_modifiers = event.modifiers();
+ m_touchPoints.append(SyntheticTouchPoint(event));
+ }
+};
+#endif
+
static inline bool scrollNode(float delta, WheelEvent::Granularity granularity, ScrollDirection positiveDirection, ScrollDirection negativeDirection, Node* node, Node** stopNode)
{
if (!delta)
@@ -1375,6 +1443,12 @@ bool EventHandler::handleMousePressEvent(const PlatformMouseEvent& mouseEvent)
{
RefPtr<FrameView> protector(m_frame->view());
+#if ENABLE(TOUCH_EVENTS)
+ bool defaultPrevented = dispatchSyntheticTouchEventIfEnabled(mouseEvent);
+ if (defaultPrevented)
+ return true;
+#endif
+
UserGestureIndicator gestureIndicator(DefinitelyProcessingUserGesture);
// FIXME (bug 68185): this call should be made at another abstraction layer
@@ -1401,7 +1475,7 @@ bool EventHandler::handleMousePressEvent(const PlatformMouseEvent& mouseEvent)
HitTestRequest request(HitTestRequest::Active);
// Save the document point we generate in case the window coordinate is invalidated by what happens
// when we dispatch the event.
- IntPoint documentPoint = documentPointForWindowPoint(m_frame, mouseEvent.position());
+ LayoutPoint documentPoint = documentPointForWindowPoint(m_frame, mouseEvent.position());
MouseEventWithHitTestResults mev = m_frame->document()->prepareMouseEvent(request, documentPoint, mouseEvent);
if (!targetNode(mev)) {
@@ -1561,6 +1635,13 @@ bool EventHandler::mouseMoved(const PlatformMouseEvent& event)
{
RefPtr<FrameView> protector(m_frame->view());
+#if ENABLE(TOUCH_EVENTS)
+ // FIXME: this should be moved elsewhere to also be able to dispatch touchcancel events.
+ bool defaultPrevented = dispatchSyntheticTouchEventIfEnabled(event);
+ if (defaultPrevented)
+ return true;
+#endif
+
HitTestResult hoveredNode = HitTestResult(LayoutPoint());
bool result = handleMouseMoveEvent(event, &hoveredNode);
@@ -1569,8 +1650,10 @@ bool EventHandler::mouseMoved(const PlatformMouseEvent& event)
return result;
if (RenderLayer* layer = layerForNode(hoveredNode.innerNode())) {
- if (page->containsScrollableArea(layer))
- layer->mouseMovedInContentArea();
+ if (FrameView* frameView = m_frame->view()) {
+ if (frameView->containsScrollableArea(layer))
+ layer->mouseMovedInContentArea();
+ }
}
if (FrameView* frameView = m_frame->view())
@@ -1698,7 +1781,13 @@ void EventHandler::invalidateClick()
bool EventHandler::handleMouseReleaseEvent(const PlatformMouseEvent& mouseEvent)
{
RefPtr<FrameView> protector(m_frame->view());
-
+
+#if ENABLE(TOUCH_EVENTS)
+ bool defaultPrevented = dispatchSyntheticTouchEventIfEnabled(mouseEvent);
+ if (defaultPrevented)
+ return true;
+#endif
+
UserGestureIndicator gestureIndicator(DefinitelyProcessingUserGesture);
#if ENABLE(PAN_SCROLLING)
@@ -2030,10 +2119,14 @@ void EventHandler::updateMouseEventTargetNode(Node* targetNode, const PlatformMo
}
} else if (page && (layerForLastNode && (!layerForNodeUnderMouse || layerForNodeUnderMouse != layerForLastNode))) {
// The mouse has moved between layers.
- if (page->containsScrollableArea(layerForLastNode))
- layerForLastNode->mouseExitedContentArea();
+ if (Frame* frame = m_lastNodeUnderMouse->document()->frame()) {
+ if (FrameView* frameView = frame->view()) {
+ if (frameView->containsScrollableArea(layerForLastNode))
+ layerForLastNode->mouseExitedContentArea();
+ }
+ }
}
-
+
if (m_nodeUnderMouse && (!m_lastNodeUnderMouse || m_lastNodeUnderMouse->document() != m_frame->document())) {
// The mouse has moved between frames.
if (Frame* frame = m_nodeUnderMouse->document()->frame()) {
@@ -2042,10 +2135,14 @@ void EventHandler::updateMouseEventTargetNode(Node* targetNode, const PlatformMo
}
} else if (page && (layerForNodeUnderMouse && (!layerForLastNode || layerForNodeUnderMouse != layerForLastNode))) {
// The mouse has moved between layers.
- if (page->containsScrollableArea(layerForNodeUnderMouse))
- layerForNodeUnderMouse->mouseEnteredContentArea();
+ if (Frame* frame = m_nodeUnderMouse->document()->frame()) {
+ if (FrameView* frameView = frame->view()) {
+ if (frameView->containsScrollableArea(layerForNodeUnderMouse))
+ layerForNodeUnderMouse->mouseEnteredContentArea();
+ }
+ }
}
-
+
if (m_lastNodeUnderMouse && m_lastNodeUnderMouse->document() != m_frame->document()) {
m_lastNodeUnderMouse = 0;
m_lastScrollbarUnderMouse = 0;
@@ -3194,6 +3291,8 @@ static const AtomicString& eventNameForTouchPointState(PlatformTouchPoint::State
return eventNames().touchstartEvent;
case PlatformTouchPoint::TouchMoved:
return eventNames().touchmoveEvent;
+ case PlatformTouchPoint::TouchStationary:
+ // TouchStationary state is not converted to touch events, so fall through to assert.
default:
ASSERT_NOT_REACHED();
return emptyAtom;
@@ -3249,6 +3348,9 @@ bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event)
case PlatformTouchPoint::TouchCancelled:
hitType |= HitTestRequest::Release;
break;
+ case PlatformTouchPoint::TouchStationary:
+ hitType |= HitTestRequest::Active | HitTestRequest::ReadOnly;
+ break;
default:
ASSERT_NOT_REACHED();
break;
@@ -3281,7 +3383,7 @@ bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event)
// we also remove it from the map.
touchTarget = m_originatingTouchPointTargets.take(touchPointTargetKey);
} else
- // No hittest is performed on move, since the target is not allowed to change anyway.
+ // No hittest is performed on move or stationary, since the target is not allowed to change anyway.
touchTarget = m_originatingTouchPointTargets.get(touchPointTargetKey);
if (!touchTarget.get())
@@ -3362,7 +3464,21 @@ bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event)
return defaultPrevented;
}
+bool EventHandler::dispatchSyntheticTouchEventIfEnabled(const PlatformMouseEvent& event)
+{
+ if (!m_frame || !m_frame->settings() || !m_frame->settings()->isTouchEventEmulationEnabled())
+ return false;
+
+ PlatformEvent::Type eventType = event.type();
+ if (eventType != PlatformEvent::MouseMoved && eventType != PlatformEvent::MousePressed && eventType != PlatformEvent::MouseReleased)
+ return false;
+ if (eventType == PlatformEvent::MouseMoved && !m_touchPressed)
+ return false;
+
+ SyntheticSingleTouchEvent touchEvent(event);
+ return handleTouchEvent(touchEvent);
+}
#endif
diff --git a/Source/WebCore/page/EventHandler.h b/Source/WebCore/page/EventHandler.h
index 547bfe57d..7733a0f65 100644
--- a/Source/WebCore/page/EventHandler.h
+++ b/Source/WebCore/page/EventHandler.h
@@ -264,6 +264,10 @@ private:
void fakeMouseMoveEventTimerFired(Timer<EventHandler>*);
void cancelFakeMouseMoveEvent();
+#if ENABLE(TOUCH_EVENTS)
+ bool dispatchSyntheticTouchEventIfEnabled(const PlatformMouseEvent&);
+#endif
+
void invalidateClick();
Node* nodeUnderMouse() const;
diff --git a/Source/WebCore/page/EventSource.idl b/Source/WebCore/page/EventSource.idl
index 4c4433f7a..9b7fe38dc 100644
--- a/Source/WebCore/page/EventSource.idl
+++ b/Source/WebCore/page/EventSource.idl
@@ -38,7 +38,7 @@ module window {
CallWith=ScriptExecutionContext,
ConstructorRaisesException,
EventTarget,
- NoStaticTables
+ JSNoStaticTables
] EventSource {
readonly attribute DOMString URL; // Lowercased .url is the one in the spec, but leaving .URL for compatibility reasons.
diff --git a/Source/WebCore/page/FocusController.cpp b/Source/WebCore/page/FocusController.cpp
index b0ef2110f..51426a308 100644
--- a/Source/WebCore/page/FocusController.cpp
+++ b/Source/WebCore/page/FocusController.cpp
@@ -88,6 +88,7 @@ FocusController::FocusController(Page* page)
, m_isActive(false)
, m_isFocused(false)
, m_isChangingFocusedFrame(false)
+ , m_containingWindowIsVisible(false)
{
}
@@ -573,16 +574,6 @@ void FocusController::setActive(bool active)
view->updateLayoutAndStyleIfNeededRecursive();
view->updateControlTints();
}
-
- if (const HashSet<ScrollableArea*>* scrollableAreas = m_page->scrollableAreaSet()) {
- HashSet<ScrollableArea*>::const_iterator end = scrollableAreas->end();
- for (HashSet<ScrollableArea*>::const_iterator it = scrollableAreas->begin(); it != end; ++it) {
- if (!active)
- (*it)->contentAreaDidHide();
- else
- (*it)->contentAreaDidShow();
- }
- }
}
focusedOrMainFrame()->selection()->pageActivationChanged();
@@ -591,6 +582,45 @@ void FocusController::setActive(bool active)
dispatchEventsOnWindowAndFocusedNode(m_focusedFrame->document(), active);
}
+static void contentAreaDidShowOrHide(ScrollableArea* scrollableArea, bool didShow)
+{
+ if (didShow)
+ scrollableArea->contentAreaDidShow();
+ else
+ scrollableArea->contentAreaDidHide();
+}
+
+void FocusController::setContainingWindowIsVisible(bool containingWindowIsVisible)
+{
+ if (m_containingWindowIsVisible == containingWindowIsVisible)
+ return;
+
+ m_containingWindowIsVisible = containingWindowIsVisible;
+
+ FrameView* view = m_page->mainFrame()->view();
+ if (!view)
+ return;
+
+ contentAreaDidShowOrHide(view, containingWindowIsVisible);
+
+ for (Frame* frame = m_page->mainFrame(); frame; frame = frame->tree()->traverseNext()) {
+ FrameView* frameView = frame->view();
+ if (!frameView)
+ continue;
+
+ const HashSet<ScrollableArea*>* scrollableAreas = frameView->scrollableAreas();
+ if (!scrollableAreas)
+ continue;
+
+ for (HashSet<ScrollableArea*>::const_iterator it = scrollableAreas->begin(), end = scrollableAreas->end(); it != end; ++it) {
+ ScrollableArea* scrollableArea = *it;
+ ASSERT(scrollableArea->isOnActivePage());
+
+ contentAreaDidShowOrHide(scrollableArea, containingWindowIsVisible);
+ }
+ }
+}
+
static void updateFocusCandidateIfNeeded(FocusDirection direction, const FocusCandidate& current, FocusCandidate& candidate, FocusCandidate& closest)
{
ASSERT(candidate.visibleNode->isElementNode());
diff --git a/Source/WebCore/page/FocusController.h b/Source/WebCore/page/FocusController.h
index 6880a1c45..3b56377bd 100644
--- a/Source/WebCore/page/FocusController.h
+++ b/Source/WebCore/page/FocusController.h
@@ -63,6 +63,9 @@ public:
void setFocused(bool);
bool isFocused() const { return m_isFocused; }
+ void setContainingWindowIsVisible(bool);
+ bool containingWindowIsVisible() const { return m_containingWindowIsVisible; }
+
bool transferFocusToElementInShadowRoot(Element* shadowHost, bool restorePreviousSelection);
private:
@@ -96,6 +99,7 @@ private:
bool m_isActive;
bool m_isFocused;
bool m_isChangingFocusedFrame;
+ bool m_containingWindowIsVisible;
};
diff --git a/Source/WebCore/page/Frame.cpp b/Source/WebCore/page/Frame.cpp
index e1f5bcf99..72ddd62cb 100644
--- a/Source/WebCore/page/Frame.cpp
+++ b/Source/WebCore/page/Frame.cpp
@@ -33,7 +33,6 @@
#include "ApplyStyleCommand.h"
#include "BackForwardController.h"
#include "CSSComputedStyleDeclaration.h"
-#include "CSSMutableStyleDeclaration.h"
#include "CSSProperty.h"
#include "CSSPropertyNames.h"
#include "CachedCSSStyleSheet.h"
@@ -80,6 +79,7 @@
#include "ScriptSourceCode.h"
#include "ScriptValue.h"
#include "Settings.h"
+#include "StylePropertySet.h"
#include "TextIterator.h"
#include "TextResourceDecoder.h"
#include "UserContentURLPattern.h"
@@ -290,11 +290,11 @@ void Frame::setDocument(PassRefPtr<Document> newDoc)
// Update the cached 'document' property, which is now stale.
m_script.updateDocument();
- if (m_page) {
- m_page->updateViewportArguments();
- if (m_page->mainFrame() == this)
- notifyChromeClientWheelEventHandlerCountChanged();
- }
+ if (m_doc)
+ m_doc->updateViewportArguments();
+
+ if (m_page && m_page->mainFrame() == this)
+ notifyChromeClientWheelEventHandlerCountChanged();
}
#if ENABLE(ORIENTATION_EVENTS)
@@ -668,6 +668,9 @@ void Frame::pageDestroyed()
if (m_domWindow) {
m_domWindow->resetGeolocation();
+#if ENABLE(NOTIFICATIONS)
+ m_domWindow->resetNotifications();
+#endif
m_domWindow->pageDestroyed();
}
@@ -1068,7 +1071,7 @@ DragImageRef Frame::nodeImage(Node* node)
m_doc->updateLayout();
m_view->setNodeToDraw(node); // Enable special sub-tree drawing mode.
- IntRect topLevelRect;
+ LayoutRect topLevelRect;
IntRect paintingRect = renderer->paintingRootRect(topLevelRect);
OwnPtr<ImageBuffer> buffer(ImageBuffer::create(paintingRect.size()));
diff --git a/Source/WebCore/page/FrameView.cpp b/Source/WebCore/page/FrameView.cpp
index 9fc1cc605..baba068e4 100644
--- a/Source/WebCore/page/FrameView.cpp
+++ b/Source/WebCore/page/FrameView.cpp
@@ -152,16 +152,17 @@ FrameView::FrameView(Frame* frame)
{
init();
- if (m_frame) {
- if (Page* page = m_frame->page()) {
- m_page = page;
- m_page->addScrollableArea(this);
+ // FIXME: Can m_frame ever be null here?
+ if (!m_frame)
+ return;
- if (m_frame == m_page->mainFrame()) {
- ScrollableArea::setVerticalScrollElasticity(ScrollElasticityAllowed);
- ScrollableArea::setHorizontalScrollElasticity(ScrollElasticityAllowed);
- }
- }
+ Page* page = m_frame->page();
+ if (!page)
+ return;
+
+ if (m_frame == page->mainFrame()) {
+ ScrollableArea::setVerticalScrollElasticity(ScrollElasticityAllowed);
+ ScrollableArea::setHorizontalScrollElasticity(ScrollElasticityAllowed);
}
}
@@ -202,9 +203,6 @@ FrameView::~FrameView()
ASSERT(!m_scrollCorner);
ASSERT(m_actionScheduler->isEmpty());
- if (m_page)
- m_page->removeScrollableArea(this);
-
if (m_frame) {
ASSERT(m_frame->view() != this || !m_frame->contentRenderer());
RenderPart* renderer = m_frame->ownerRenderer();
@@ -323,21 +321,6 @@ void FrameView::detachCustomScrollbars()
}
}
-void FrameView::didAddHorizontalScrollbar(Scrollbar* scrollbar)
-{
- if (m_frame && m_frame->document())
- m_frame->document()->didAddWheelEventHandler();
- ScrollView::didAddHorizontalScrollbar(scrollbar);
-}
-
-void FrameView::willRemoveHorizontalScrollbar(Scrollbar* scrollbar)
-{
- ScrollView::willRemoveHorizontalScrollbar(scrollbar);
- // FIXME: maybe need a separate ScrollableArea::didRemoveHorizontalScrollbar callback?
- if (m_frame && m_frame->document())
- m_frame->document()->didRemoveWheelEventHandler();
-}
-
void FrameView::recalculateScrollbarOverlayStyle()
{
ScrollbarOverlayStyle oldOverlayStyle = scrollbarOverlayStyle();
@@ -1242,8 +1225,8 @@ void FrameView::removeWidgetToUpdate(RenderEmbeddedObject* object)
void FrameView::zoomAnimatorTransformChanged(float scale, float x, float y, ZoomAnimationState state)
{
if (state == ZoomAnimationFinishing) {
- m_page->setPageScaleFactor(m_page->pageScaleFactor() * scale,
- IntPoint(scale * scrollX() - x, scale * scrollY() - y));
+ if (Page* page = m_frame->page())
+ page->setPageScaleFactor(page->pageScaleFactor() * scale, IntPoint(scale * scrollX() - x, scale * scrollY() - y));
scrollAnimator()->resetZoom();
}
@@ -2280,8 +2263,10 @@ void FrameView::performPostLayoutTasks()
if (m_firstLayoutCallbackPending) {
m_firstLayoutCallbackPending = false;
m_frame->loader()->didFirstLayout();
- if (Page* page = m_frame->page())
- page->startCountingRelevantRepaintedObjects();
+ if (Page* page = m_frame->page()) {
+ if (page->mainFrame() == m_frame)
+ page->startCountingRelevantRepaintedObjects();
+ }
}
// Ensure that we always send this eventually.
@@ -2305,6 +2290,13 @@ void FrameView::performPostLayoutTasks()
break;
}
+#if ENABLE(THREADED_SCROLLING)
+ if (Page* page = m_frame->page()) {
+ if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
+ scrollingCoordinator->frameViewLayoutUpdated(this);
+ }
+#endif
+
scrollToAnchor();
m_actionScheduler->resume();
@@ -2542,6 +2534,12 @@ ScrollableArea* FrameView::enclosingScrollableArea() const
return 0;
}
+IntRect FrameView::scrollableAreaBoundingBox() const
+{
+ // FIXME: This isn't correct for transformed frames. We probably need to ask the renderer instead.
+ return frameRect();
+}
+
bool FrameView::shouldSuspendScrollAnimations() const
{
return m_frame->loader()->state() != FrameStateComplete;
@@ -2566,18 +2564,16 @@ void FrameView::setAnimatorsAreActive()
if (!page)
return;
- const HashSet<ScrollableArea*>* scrollableAreas = page->scrollableAreaSet();
- if (!scrollableAreas)
+ scrollAnimator()->setIsActive();
+
+ if (!m_scrollableAreas)
return;
- HashSet<ScrollableArea*>::const_iterator end = scrollableAreas->end();
- for (HashSet<ScrollableArea*>::const_iterator it = scrollableAreas->begin(); it != end; ++it) {
- // FIXME: This extra check to make sure the ScrollableArea is on an active page needs
- // to be here as long as the ScrollableArea HashSet lives on Page. But it should really be
- // moved to the top-level Document or a similar class that really represents a single
- // web page. https://bugs.webkit.org/show_bug.cgi?id=62762
- if ((*it)->isOnActivePage())
- (*it)->scrollAnimator()->setIsActive();
+ for (HashSet<ScrollableArea*>::const_iterator it = m_scrollableAreas->begin(), end = m_scrollableAreas->end(); it != end; ++it) {
+ ScrollableArea* scrollableArea = *it;
+
+ ASSERT(scrollableArea->isOnActivePage());
+ scrollableArea->scrollAnimator()->setIsActive();
}
}
@@ -2587,21 +2583,28 @@ void FrameView::notifyPageThatContentAreaWillPaint() const
if (!page)
return;
- const HashSet<ScrollableArea*>* scrollableAreas = page->scrollableAreaSet();
- if (!scrollableAreas)
+ contentAreaWillPaint();
+
+ if (!m_scrollableAreas)
return;
- HashSet<ScrollableArea*>::const_iterator end = scrollableAreas->end();
- for (HashSet<ScrollableArea*>::const_iterator it = scrollableAreas->begin(); it != end; ++it)
- (*it)->contentAreaWillPaint();
+ for (HashSet<ScrollableArea*>::const_iterator it = m_scrollableAreas->begin(), end = m_scrollableAreas->end(); it != end; ++it) {
+ ScrollableArea* scrollableArea = *it;
+
+ if (!scrollableArea->isOnActivePage())
+ continue;
+
+ scrollableArea->contentAreaWillPaint();
+ }
}
bool FrameView::scrollAnimatorEnabled() const
{
#if ENABLE(SMOOTH_SCROLLING)
- if (m_page && m_page->settings())
- return m_page->settings()->scrollAnimatorEnabled();
+ if (Page* page = m_frame->page())
+ return page->settings()->scrollAnimatorEnabled();
#endif
+
return false;
}
@@ -3253,6 +3256,43 @@ void FrameView::setTracksRepaints(bool trackRepaints)
m_isTrackingRepaints = trackRepaints;
}
+void FrameView::addScrollableArea(ScrollableArea* scrollableArea)
+{
+ if (!m_scrollableAreas)
+ m_scrollableAreas = adoptPtr(new ScrollableAreaSet);
+ m_scrollableAreas->add(scrollableArea);
+}
+
+void FrameView::removeScrollableArea(ScrollableArea* scrollableArea)
+{
+ if (!m_scrollableAreas)
+ return;
+ m_scrollableAreas->remove(scrollableArea);
+}
+
+bool FrameView::containsScrollableArea(ScrollableArea* scrollableArea) const
+{
+ if (!m_scrollableAreas)
+ return false;
+ return m_scrollableAreas->contains(scrollableArea);
+}
+
+void FrameView::addChild(PassRefPtr<Widget> widget)
+{
+ if (widget->isFrameView())
+ addScrollableArea(static_cast<FrameView*>(widget.get()));
+
+ ScrollView::addChild(widget);
+}
+
+void FrameView::removeChild(Widget* widget)
+{
+ if (widget->isFrameView())
+ removeScrollableArea(static_cast<FrameView*>(widget));
+
+ ScrollView::removeChild(widget);
+}
+
bool FrameView::isVerticalDocument() const
{
RenderView* root = rootRenderer(this);
diff --git a/Source/WebCore/page/FrameView.h b/Source/WebCore/page/FrameView.h
index 466a88939..51fe7c370 100644
--- a/Source/WebCore/page/FrameView.h
+++ b/Source/WebCore/page/FrameView.h
@@ -86,8 +86,6 @@ public:
virtual PassRefPtr<Scrollbar> createScrollbar(ScrollbarOrientation);
virtual bool avoidScrollbarCreation() const;
- virtual void didAddHorizontalScrollbar(Scrollbar*);
- virtual void willRemoveHorizontalScrollbar(Scrollbar*);
virtual void setContentsSize(const IntSize&);
@@ -308,6 +306,15 @@ public:
void resetTrackedRepaints() { m_trackedRepaintRects.clear(); }
const Vector<IntRect>& trackedRepaintRects() const { return m_trackedRepaintRects; }
+ typedef HashSet<ScrollableArea*> ScrollableAreaSet;
+ void addScrollableArea(ScrollableArea*);
+ void removeScrollableArea(ScrollableArea*);
+ bool containsScrollableArea(ScrollableArea*) const;
+ const ScrollableAreaSet* scrollableAreas() const { return m_scrollableAreas.get(); }
+
+ virtual void addChild(PassRefPtr<Widget>) OVERRIDE;
+ virtual void removeChild(Widget*) OVERRIDE;
+
protected:
virtual bool scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect);
virtual void scrollContentsSlowPath(const IntRect& updateRect);
@@ -362,6 +369,7 @@ private:
virtual void setVisibleScrollerThumbRect(const IntRect&);
virtual bool isOnActivePage() const;
virtual ScrollableArea* enclosingScrollableArea() const;
+ virtual IntRect scrollableAreaBoundingBox() const OVERRIDE;
#if USE(ACCELERATED_COMPOSITING)
virtual GraphicsLayer* layerForHorizontalScrollbar() const OVERRIDE;
@@ -373,7 +381,6 @@ private:
#endif
virtual void notifyPageThatContentAreaWillPaint() const;
- virtual void disconnectFromPage() { m_page = 0; }
virtual bool scrollAnimatorEnabled() const;
@@ -476,8 +483,6 @@ private:
// Renderer to hold our custom scroll corner.
RenderScrollbarPart* m_scrollCorner;
- Page* m_page;
-
// If true, automatically resize the frame view around its content.
bool m_shouldAutoSize;
bool m_inAutoSize;
@@ -486,6 +491,8 @@ private:
// The upper bound on the size when autosizing.
IntSize m_maxAutoSize;
+ OwnPtr<ScrollableAreaSet> m_scrollableAreas;
+
static double s_deferredRepaintDelay;
static double s_initialDeferredRepaintDelayDuringLoading;
static double s_maxDeferredRepaintDelayDuringLoading;
diff --git a/Source/WebCore/page/Geolocation.idl b/Source/WebCore/page/Geolocation.idl
index d1d534992..4f159bcb1 100644
--- a/Source/WebCore/page/Geolocation.idl
+++ b/Source/WebCore/page/Geolocation.idl
@@ -28,7 +28,7 @@ module core {
// http://www.w3.org/TR/geolocation-API/#geolocation_interface
interface [
Conditional=GEOLOCATION,
- GenerateIsReachable=ImplFrame,
+ JSGenerateIsReachable=ImplFrame,
OmitConstructor
] Geolocation {
[Custom] void getCurrentPosition(in PositionCallback successCallback,
diff --git a/Source/WebCore/page/History.cpp b/Source/WebCore/page/History.cpp
index 1f5a39f28..a1f9a05f6 100644
--- a/Source/WebCore/page/History.cpp
+++ b/Source/WebCore/page/History.cpp
@@ -42,6 +42,7 @@ namespace WebCore {
History::History(Frame* frame)
: DOMWindowProperty(frame)
+ , m_lastStateObjectRequested(0)
{
}
@@ -54,6 +55,28 @@ unsigned History::length() const
return m_frame->page()->backForward()->count();
}
+SerializedScriptValue* History::state()
+{
+ m_lastStateObjectRequested = stateInternal();
+ return m_lastStateObjectRequested;
+}
+
+SerializedScriptValue* History::stateInternal() const
+{
+ if (!m_frame)
+ return 0;
+
+ if (HistoryItem* historyItem = m_frame->loader()->history()->currentItem())
+ return historyItem->stateObject();
+
+ return 0;
+}
+
+bool History::stateChanged() const
+{
+ return m_lastStateObjectRequested != stateInternal();
+}
+
void History::back()
{
go(-1);
diff --git a/Source/WebCore/page/History.h b/Source/WebCore/page/History.h
index bd50fccd2..bd6f6aa21 100644
--- a/Source/WebCore/page/History.h
+++ b/Source/WebCore/page/History.h
@@ -44,6 +44,8 @@ public:
static PassRefPtr<History> create(Frame* frame) { return adoptRef(new History(frame)); }
unsigned length() const;
+ SerializedScriptValue* state();
+ bool stateChanged() const;
void back();
void forward();
void go(int distance);
@@ -62,6 +64,10 @@ private:
explicit History(Frame*);
KURL urlForState(const String& url);
+
+ SerializedScriptValue* stateInternal() const;
+
+ SerializedScriptValue* m_lastStateObjectRequested;
};
} // namespace WebCore
diff --git a/Source/WebCore/page/History.idl b/Source/WebCore/page/History.idl
index ff3701ed2..f7036403a 100644
--- a/Source/WebCore/page/History.idl
+++ b/Source/WebCore/page/History.idl
@@ -29,22 +29,23 @@ module window {
#if defined(V8_BINDING) && V8_BINDING
CheckDomainSecurity,
#endif
- DelegatingGetOwnPropertySlot,
- DelegatingPutFunction,
- GenerateIsReachable=ImplFrame,
+ JSCustomGetOwnPropertySlotDelegate,
+ CustomNamedSetter,
+ JSGenerateIsReachable=ImplFrame,
CustomDeleteProperty,
CustomGetPropertyNames,
OmitConstructor
] History {
readonly attribute unsigned long length;
+ readonly attribute [CachedAttribute, Custom] SerializedScriptValue state;
[DoNotCheckDomainSecurity, CallWith=ScriptExecutionContext] void back();
[DoNotCheckDomainSecurity, CallWith=ScriptExecutionContext] void forward();
[DoNotCheckDomainSecurity, CallWith=ScriptExecutionContext] void go(in [Optional=CallWithDefaultValue] long distance);
- [Custom, EnabledAtRuntime] void pushState(in any data, in DOMString title, in [Optional] DOMString url)
+ [Custom, V8EnabledAtRuntime] void pushState(in any data, in DOMString title, in [Optional] DOMString url)
raises(DOMException);
- [Custom, EnabledAtRuntime] void replaceState(in any data, in DOMString title, in [Optional] DOMString url)
+ [Custom, V8EnabledAtRuntime] void replaceState(in any data, in DOMString title, in [Optional] DOMString url)
raises(DOMException);
};
diff --git a/Source/WebCore/page/Location.idl b/Source/WebCore/page/Location.idl
index d510052c3..d5d27e2c6 100644
--- a/Source/WebCore/page/Location.idl
+++ b/Source/WebCore/page/Location.idl
@@ -32,18 +32,18 @@ module window {
#if defined(V8_BINDING) && V8_BINDING
CheckDomainSecurity,
#endif
- DelegatingGetOwnPropertySlot,
- DelegatingPutFunction,
- GenerateIsReachable=ImplFrame,
+ JSCustomGetOwnPropertySlotDelegate,
+ CustomNamedSetter,
+ JSGenerateIsReachable=ImplFrame,
CustomDeleteProperty,
CustomGetPropertyNames,
- CustomDefineGetter,
- DelegatingPrototypePutFunction,
- CustomPrototypeDefineGetter,
+ JSCustomDefineOwnProperty,
+ JSCustomPrototypePutDelegate,
+ JSCustomPrototypeDefineOwnProperty,
OmitConstructor
] Location {
#if !defined(LANGUAGE_CPP) || !LANGUAGE_CPP
- attribute [DoNotCheckDomainSecurityOnSet, CustomSetter, V8Unforgeable] DOMString href;
+ attribute [DoNotCheckDomainSecurityOnSetter, CustomSetter, V8Unforgeable] DOMString href;
#endif
[Custom, V8OnInstance] void assign(in [Optional=CallWithDefaultValue] DOMString url);
@@ -64,10 +64,10 @@ module window {
#endif
#if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT
- [DontEnum, Custom, V8OnInstance, V8ReadOnly, ImplementationFunction=toStringFunction] DOMString toString();
+ [NotEnumerable, Custom, V8OnInstance, V8ReadOnly, ImplementedAs=toStringFunction] DOMString toString();
#endif
#if defined(V8_BINDING) && V8_BINDING
- [DontEnum, Custom, V8OnInstance, V8ReadOnly] DOMObject valueOf();
+ [NotEnumerable, Custom, V8OnInstance, V8ReadOnly] DOMObject valueOf();
#endif
};
diff --git a/Source/WebCore/page/MemoryInfo.idl b/Source/WebCore/page/MemoryInfo.idl
index f04447479..b9149d54d 100644
--- a/Source/WebCore/page/MemoryInfo.idl
+++ b/Source/WebCore/page/MemoryInfo.idl
@@ -36,7 +36,7 @@ module window {
readonly attribute unsigned long totalJSHeapSize;
readonly attribute unsigned long usedJSHeapSize;
- readonly attribute [JSCCustomGetter] unsigned long jsHeapSizeLimit;
+ readonly attribute [JSCustomGetter] unsigned long jsHeapSizeLimit;
};
diff --git a/Source/WebCore/page/Navigator.idl b/Source/WebCore/page/Navigator.idl
index 6fe43e660..213fab125 100644
--- a/Source/WebCore/page/Navigator.idl
+++ b/Source/WebCore/page/Navigator.idl
@@ -20,7 +20,7 @@
module window {
interface [
- GenerateIsReachable=ImplFrame,
+ JSGenerateIsReachable=ImplFrame,
OmitConstructor
] Navigator {
readonly attribute DOMString appCodeName;
@@ -41,11 +41,11 @@ module window {
readonly attribute boolean onLine;
#if defined(ENABLE_GEOLOCATION) && ENABLE_GEOLOCATION
- readonly attribute [EnabledAtRuntime] Geolocation geolocation;
+ readonly attribute [V8EnabledAtRuntime] Geolocation geolocation;
#endif
#if defined(ENABLE_POINTER_LOCK) && ENABLE_POINTER_LOCK
- readonly attribute [EnabledAtRuntime] PointerLock webkitPointer;
+ readonly attribute [V8EnabledAtRuntime] PointerLock webkitPointer;
#endif
void getStorageUpdates(); // FIXME: Remove this method or rename to yieldForStorageUpdates.
@@ -56,7 +56,7 @@ module window {
#endif
#if defined(ENABLE_MEDIA_STREAM) && ENABLE_MEDIA_STREAM
- [Custom, EnabledAtRuntime] void webkitGetUserMedia(in DOMString options,
+ [Custom, V8EnabledAtRuntime] void webkitGetUserMedia(in DOMString options,
in [Callback=FunctionOnly] NavigatorUserMediaSuccessCallback successCallback,
in [Callback=FunctionOnly, Optional] NavigatorUserMediaErrorCallback errorCallback)
raises(DOMException);
diff --git a/Source/WebCore/page/Page.cpp b/Source/WebCore/page/Page.cpp
index 2442bf7c2..492e949ee 100644
--- a/Source/WebCore/page/Page.cpp
+++ b/Source/WebCore/page/Page.cpp
@@ -211,12 +211,6 @@ Page::~Page()
for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNext())
frame->pageDestroyed();
- if (m_scrollableAreaSet) {
- ScrollableAreaSet::const_iterator end = m_scrollableAreaSet->end();
- for (ScrollableAreaSet::const_iterator it = m_scrollableAreaSet->begin(); it != end; ++it)
- (*it)->disconnectFromPage();
- }
-
m_editorClient->pageDestroyed();
#if ENABLE(INSPECTOR)
@@ -240,6 +234,11 @@ Page::~Page()
#endif
}
+ViewportArguments Page::viewportArguments() const
+{
+ return mainFrame() && mainFrame()->document() ? mainFrame()->document()->viewportArguments() : ViewportArguments();
+}
+
#if ENABLE(THREADED_SCROLLING)
ScrollingCoordinator* Page::scrollingCoordinator()
{
@@ -430,15 +429,6 @@ void Page::setNeedsRecalcStyleInAllFrames()
frame->document()->styleSelectorChanged(DeferRecalcStyle);
}
-void Page::updateViewportArguments()
-{
- if (!mainFrame() || !mainFrame()->document())
- return;
-
- m_viewportArguments = mainFrame()->document()->viewportArguments();
- chrome()->dispatchViewportPropertiesDidChange(m_viewportArguments);
-}
-
void Page::refreshPlugins(bool reload)
{
if (!allPages)
@@ -1030,27 +1020,6 @@ void Page::privateBrowsingStateChanged()
pluginViewBases[i]->privateBrowsingStateChanged(privateBrowsingEnabled);
}
-void Page::addScrollableArea(ScrollableArea* scrollableArea)
-{
- if (!m_scrollableAreaSet)
- m_scrollableAreaSet = adoptPtr(new ScrollableAreaSet);
- m_scrollableAreaSet->add(scrollableArea);
-}
-
-void Page::removeScrollableArea(ScrollableArea* scrollableArea)
-{
- if (!m_scrollableAreaSet)
- return;
- m_scrollableAreaSet->remove(scrollableArea);
-}
-
-bool Page::containsScrollableArea(ScrollableArea* scrollableArea) const
-{
- if (!m_scrollableAreaSet)
- return false;
- return m_scrollableAreaSet->contains(scrollableArea);
-}
-
#if !ASSERT_DISABLED
void Page::checkFrameCountConsistency() const
{
diff --git a/Source/WebCore/page/Page.h b/Source/WebCore/page/Page.h
index 887893f9f..5f6e20649 100644
--- a/Source/WebCore/page/Page.h
+++ b/Source/WebCore/page/Page.h
@@ -133,8 +133,7 @@ namespace WebCore {
RenderTheme* theme() const { return m_theme.get(); };
- ViewportArguments viewportArguments() const { return m_viewportArguments; }
- void updateViewportArguments();
+ ViewportArguments viewportArguments() const;
static void refreshPlugins(bool reload);
PluginData* pluginData() const;
@@ -334,12 +333,6 @@ namespace WebCore {
void setJavaScriptURLsAreAllowed(bool);
bool javaScriptURLsAreAllowed() const;
- typedef HashSet<ScrollableArea*> ScrollableAreaSet;
- void addScrollableArea(ScrollableArea*);
- void removeScrollableArea(ScrollableArea*);
- bool containsScrollableArea(ScrollableArea*) const;
- const ScrollableAreaSet* scrollableAreaSet() const { return m_scrollableAreaSet.get(); }
-
// Don't allow more than a certain number of frames in a page.
// This seems like a reasonable upper bound, and otherwise mutually
// recursive frameset pages can quickly bring the program to its knees
@@ -464,12 +457,8 @@ namespace WebCore {
ViewMode m_viewMode;
- ViewportArguments m_viewportArguments;
-
double m_minimumTimerInterval;
- OwnPtr<ScrollableAreaSet> m_scrollableAreaSet;
-
bool m_isEditable;
#if ENABLE(PAGE_VISIBILITY_API)
diff --git a/Source/WebCore/page/PageSerializer.cpp b/Source/WebCore/page/PageSerializer.cpp
index 2c3778b46..64d901b7a 100644
--- a/Source/WebCore/page/PageSerializer.cpp
+++ b/Source/WebCore/page/PageSerializer.cpp
@@ -69,9 +69,9 @@ static bool isCharsetSpecifyingNode(Node* node)
if (!element->hasTagName(HTMLNames::metaTag))
return false;
HTMLMetaCharsetParser::AttributeList attributes;
- if (const NamedNodeMap* attributesMap = element->updatedAttributes()) {
- for (unsigned i = 0; i < attributesMap->length(); ++i) {
- Attribute* item = attributesMap->attributeItem(i);
+ if (element->hasAttributes()) {
+ for (unsigned i = 0; i < element->attributeCount(); ++i) {
+ Attribute* item = element->attributeItem(i);
// FIXME: We should deal appropriately with the attribute if they have a namespace.
attributes.append(make_pair(item->name().toString(), item->value().string()));
}
@@ -227,7 +227,7 @@ void PageSerializer::serializeFrame(Frame* frame)
Element* element = toElement(node);
// We have to process in-line style as it might contain some resources (typically background images).
if (element->isStyledElement())
- retrieveResourcesForCSSDeclaration(static_cast<StyledElement*>(element)->inlineStyleDecl());
+ retrieveResourcesForCSSDeclaration(static_cast<StyledElement*>(element)->inlineStyleDecl(), document);
if (element->hasTagName(HTMLNames::imgTag)) {
HTMLImageElement* imageElement = static_cast<HTMLImageElement*>(element);
@@ -263,10 +263,10 @@ void PageSerializer::serializeCSSStyleSheet(CSSStyleSheet* styleSheet, const KUR
if (i < styleSheet->length() - 1)
cssText.append("\n\n");
}
+ Document* document = styleSheet->findDocument();
// Some rules have resources associated with them that we need to retrieve.
if (rule->isImportRule()) {
- CSSImportRule* importRule = static_cast<CSSImportRule*>(rule);
- Document* document = styleSheet->findDocument();
+ CSSImportRule* importRule = static_cast<CSSImportRule*>(rule);
KURL importURL = document->completeURL(importRule->href());
if (m_resourceURLs.contains(importURL))
continue;
@@ -275,7 +275,7 @@ void PageSerializer::serializeCSSStyleSheet(CSSStyleSheet* styleSheet, const KUR
// 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 (rule->isStyleRule())
- retrieveResourcesForCSSRule(static_cast<CSSStyleRule*>(rule));
+ retrieveResourcesForCSSRule(static_cast<CSSStyleRule*>(rule), document);
}
if (url.isValid() && !m_resourceURLs.contains(url)) {
@@ -302,19 +302,16 @@ void PageSerializer::addImageToResources(CachedImage* image, RenderObject* image
m_resourceURLs.add(url);
}
-void PageSerializer::retrieveResourcesForCSSRule(CSSStyleRule* rule)
+void PageSerializer::retrieveResourcesForCSSRule(CSSStyleRule* rule, Document* document)
{
- retrieveResourcesForCSSDeclaration(rule->declaration());
+ retrieveResourcesForCSSDeclaration(rule->declaration(), document);
}
-void PageSerializer::retrieveResourcesForCSSDeclaration(CSSMutableStyleDeclaration* styleDeclaration)
+void PageSerializer::retrieveResourcesForCSSDeclaration(StylePropertySet* styleDeclaration, Document* document)
{
if (!styleDeclaration)
return;
- CSSStyleSheet* cssStyleSheet = styleDeclaration->parentStyleSheet();
- ASSERT(cssStyleSheet);
-
// The background-image and list-style-image (for ul or ol) are the CSS properties
// that make use of images. We iterate to make sure we include any other
// image properties there might be.
@@ -332,7 +329,6 @@ void PageSerializer::retrieveResourcesForCSSDeclaration(CSSMutableStyleDeclarati
CachedImage* image = static_cast<StyleCachedImage*>(styleImage)->cachedImage();
- Document* document = cssStyleSheet->findDocument();
KURL url = document->completeURL(image->url());
addImageToResources(image, 0, url);
}
diff --git a/Source/WebCore/page/PageSerializer.h b/Source/WebCore/page/PageSerializer.h
index d92ef20ab..a900f150a 100644
--- a/Source/WebCore/page/PageSerializer.h
+++ b/Source/WebCore/page/PageSerializer.h
@@ -41,12 +41,13 @@
namespace WebCore {
class CachedImage;
-class CSSMutableStyleDeclaration;
class CSSStyleRule;
class CSSStyleSheet;
+class Document;
class Frame;
class Page;
class RenderObject;
+class StylePropertySet;
// This class is used to serialize a page contents back to text (typically HTML).
// It serializes all the page frames and retrieves resources such as images and CSS stylesheets.
@@ -77,8 +78,8 @@ private:
void serializeCSSStyleSheet(CSSStyleSheet*, const KURL&);
void addImageToResources(CachedImage*, RenderObject*, const KURL&);
- void retrieveResourcesForCSSDeclaration(CSSMutableStyleDeclaration*);
- void retrieveResourcesForCSSRule(CSSStyleRule*);
+ void retrieveResourcesForCSSDeclaration(StylePropertySet*, Document*);
+ void retrieveResourcesForCSSRule(CSSStyleRule*, Document*);
Vector<Resource>* m_resources;
ListHashSet<KURL> m_resourceURLs;
diff --git a/Source/WebCore/page/PrintContext.cpp b/Source/WebCore/page/PrintContext.cpp
index abb417128..0af0bb576 100644
--- a/Source/WebCore/page/PrintContext.cpp
+++ b/Source/WebCore/page/PrintContext.cpp
@@ -249,8 +249,8 @@ int PrintContext::pageNumberForElement(Element* element, const FloatSize& pageSi
scaledPageSize.scale(frame->view()->contentsSize().width() / pageRect.width());
printContext.computePageRectsWithPageSize(scaledPageSize, false);
- int top = box->offsetTop();
- int left = 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);
diff --git a/Source/WebCore/page/Screen.idl b/Source/WebCore/page/Screen.idl
index 4471617b1..588060914 100644
--- a/Source/WebCore/page/Screen.idl
+++ b/Source/WebCore/page/Screen.idl
@@ -30,7 +30,7 @@
module window {
interface [
- GenerateIsReachable=ImplFrame,
+ JSGenerateIsReachable=ImplFrame,
OmitConstructor
] Screen {
readonly attribute unsigned long height;
diff --git a/Source/WebCore/page/Settings.cpp b/Source/WebCore/page/Settings.cpp
index 599cb3110..b5cb963bb 100644
--- a/Source/WebCore/page/Settings.cpp
+++ b/Source/WebCore/page/Settings.cpp
@@ -189,6 +189,7 @@ Settings::Settings(Page* page)
, m_showRepaintCounter(false)
, m_experimentalNotificationsEnabled(false)
, m_webGLEnabled(false)
+ , m_webGLErrorsToConsoleEnabled(false)
, m_openGLMultisamplingEnabled(true)
, m_privilegedWebGLExtensionsEnabled(false)
, m_webAudioEnabled(false)
@@ -240,6 +241,9 @@ Settings::Settings(Page* page)
, m_scrollingCoordinatorEnabled(false)
#endif
, m_notificationsEnabled(true)
+#if ENABLE(TOUCH_EVENTS)
+ , m_touchEventEmulationEnabled(false)
+#endif
, m_loadsImagesAutomaticallyTimer(this, &Settings::loadsImagesAutomaticallyTimerFired)
{
// A Frame may not have been created yet, so we initialize the AtomicString
@@ -803,6 +807,11 @@ void Settings::setWebGLEnabled(bool enabled)
m_webGLEnabled = enabled;
}
+void Settings::setWebGLErrorsToConsoleEnabled(bool enabled)
+{
+ m_webGLErrorsToConsoleEnabled = enabled;
+}
+
void Settings::setOpenGLMultisamplingEnabled(bool enabled)
{
m_openGLMultisamplingEnabled = enabled;
diff --git a/Source/WebCore/page/Settings.h b/Source/WebCore/page/Settings.h
index 5ef8eea7f..3a1406601 100644
--- a/Source/WebCore/page/Settings.h
+++ b/Source/WebCore/page/Settings.h
@@ -357,6 +357,9 @@ namespace WebCore {
void setWebGLEnabled(bool);
bool webGLEnabled() const { return m_webGLEnabled; }
+ void setWebGLErrorsToConsoleEnabled(bool);
+ bool webGLErrorsToConsoleEnabled() const { return m_webGLErrorsToConsoleEnabled; }
+
void setOpenGLMultisamplingEnabled(bool);
bool openGLMultisamplingEnabled() const { return m_openGLMultisamplingEnabled; }
@@ -523,6 +526,11 @@ namespace WebCore {
void setNotificationsEnabled(bool enabled) { m_notificationsEnabled = enabled; }
bool notificationsEnabled() const { return m_notificationsEnabled; }
+#if ENABLE(TOUCH_EVENTS)
+ void setTouchEventEmulationEnabled(bool enabled) { m_touchEventEmulationEnabled = enabled; }
+ bool isTouchEventEmulationEnabled() const { return m_touchEventEmulationEnabled; }
+#endif
+
private:
Settings(Page*);
@@ -618,6 +626,7 @@ namespace WebCore {
bool m_showRepaintCounter : 1;
bool m_experimentalNotificationsEnabled : 1;
bool m_webGLEnabled : 1;
+ bool m_webGLErrorsToConsoleEnabled : 1;
bool m_openGLMultisamplingEnabled : 1;
bool m_privilegedWebGLExtensionsEnabled : 1;
bool m_webAudioEnabled : 1;
@@ -669,6 +678,10 @@ namespace WebCore {
bool m_notificationsEnabled : 1;
+#if ENABLE(TOUCH_EVENTS)
+ bool m_touchEventEmulationEnabled : 1;
+#endif
+
Timer<Settings> m_loadsImagesAutomaticallyTimer;
void loadsImagesAutomaticallyTimerFired(Timer<Settings>*);
diff --git a/Source/WebCore/page/SpeechInputResultList.idl b/Source/WebCore/page/SpeechInputResultList.idl
index 5a23d4f02..b9213d002 100644
--- a/Source/WebCore/page/SpeechInputResultList.idl
+++ b/Source/WebCore/page/SpeechInputResultList.idl
@@ -26,7 +26,7 @@
module core {
interface [
- HasIndexGetter,
+ IndexedGetter,
Conditional=INPUT_SPEECH
] SpeechInputResultList {
readonly attribute unsigned long length;
diff --git a/Source/WebCore/page/WebKitAnimation.cpp b/Source/WebCore/page/WebKitAnimation.cpp
index b757d2317..98e77367c 100644
--- a/Source/WebCore/page/WebKitAnimation.cpp
+++ b/Source/WebCore/page/WebKitAnimation.cpp
@@ -84,9 +84,18 @@ bool WebKitAnimation::ended() const
WebKitAnimation::Direction WebKitAnimation::direction() const
{
- if (m_keyframeAnimation->animation()->direction() == Animation::AnimationDirectionNormal)
+ switch (m_keyframeAnimation->animation()->direction()) {
+ case Animation::AnimationDirectionNormal:
return DIRECTION_NORMAL;
- return DIRECTION_ALTERNATE;
+ case Animation::AnimationDirectionAlternate:
+ return DIRECTION_ALTERNATE;
+ case Animation::AnimationDirectionReverse:
+ return DIRECTION_REVERSE;
+ case Animation::AnimationDirectionAlternateReverse:
+ return DIRECTION_ALTERNATE_REVERSE;
+ }
+ ASSERT_NOT_REACHED();
+ return DIRECTION_NORMAL;
}
WebKitAnimation::FillMode WebKitAnimation::fillMode() const
diff --git a/Source/WebCore/page/WebKitAnimation.h b/Source/WebCore/page/WebKitAnimation.h
index 6bea1e5d4..bef74382a 100644
--- a/Source/WebCore/page/WebKitAnimation.h
+++ b/Source/WebCore/page/WebKitAnimation.h
@@ -59,7 +59,7 @@ public:
bool ended() const;
// direction
- enum Direction { DIRECTION_NORMAL, DIRECTION_ALTERNATE };
+ enum Direction { DIRECTION_NORMAL, DIRECTION_ALTERNATE, DIRECTION_REVERSE, DIRECTION_ALTERNATE_REVERSE };
Direction direction() const;
// fill mode
diff --git a/Source/WebCore/page/WebKitAnimationList.idl b/Source/WebCore/page/WebKitAnimationList.idl
index 72172a70a..ed305f792 100644
--- a/Source/WebCore/page/WebKitAnimationList.idl
+++ b/Source/WebCore/page/WebKitAnimationList.idl
@@ -26,7 +26,7 @@
module html {
interface [
- HasIndexGetter
+ IndexedGetter
] WebKitAnimationList {
readonly attribute unsigned long length;
WebKitAnimation item(in unsigned long index);
diff --git a/Source/WebCore/page/WorkerNavigator.idl b/Source/WebCore/page/WorkerNavigator.idl
index 1544f155e..819de09d6 100644
--- a/Source/WebCore/page/WorkerNavigator.idl
+++ b/Source/WebCore/page/WorkerNavigator.idl
@@ -30,8 +30,8 @@ module threads {
interface [
Conditional=WORKERS,
- GenerateIsReachable=Impl,
- NoStaticTables,
+ JSGenerateIsReachable=Impl,
+ JSNoStaticTables,
OmitConstructor
] WorkerNavigator {
readonly attribute DOMString appName;
diff --git a/Source/WebCore/page/animation/AnimationBase.cpp b/Source/WebCore/page/animation/AnimationBase.cpp
index e3ad92fa0..4fd0409ec 100644
--- a/Source/WebCore/page/animation/AnimationBase.cpp
+++ b/Source/WebCore/page/animation/AnimationBase.cpp
@@ -1673,7 +1673,9 @@ double AnimationBase::fractionalTime(double scale, double elapsedTime, double of
integralTime = min(integralTime, m_animation->iterationCount() - 1);
fractionalTime -= integralTime;
- if ((m_animation->direction() == Animation::AnimationDirectionAlternate) && (integralTime & 1))
+ if (((m_animation->direction() == Animation::AnimationDirectionAlternate) && (integralTime & 1))
+ || ((m_animation->direction() == Animation::AnimationDirectionAlternateReverse) && !(integralTime & 1))
+ || m_animation->direction() == Animation::AnimationDirectionReverse)
fractionalTime = 1 - fractionalTime;
if (scale != 1 || offset)
diff --git a/Source/WebCore/page/scrolling/ScrollingCoordinator.cpp b/Source/WebCore/page/scrolling/ScrollingCoordinator.cpp
index c83bcb4aa..e569b2c25 100644
--- a/Source/WebCore/page/scrolling/ScrollingCoordinator.cpp
+++ b/Source/WebCore/page/scrolling/ScrollingCoordinator.cpp
@@ -34,7 +34,11 @@
#include "IntRect.h"
#include "Page.h"
#include "PlatformWheelEvent.h"
+#include "Region.h"
#include "ScrollAnimator.h"
+#include "ScrollingThread.h"
+#include "ScrollingTree.h"
+#include "ScrollingTreeState.h"
#include <wtf/Functional.h>
#include <wtf/MainThread.h>
#include <wtf/PassRefPtr.h>
@@ -48,19 +52,31 @@ PassRefPtr<ScrollingCoordinator> ScrollingCoordinator::create(Page* page)
ScrollingCoordinator::ScrollingCoordinator(Page* page)
: m_page(page)
- , m_didDispatchDidUpdateMainFrameScrollPosition(false)
+ , m_scrollingTree(ScrollingTree::create(this))
+ , m_scrollingTreeState(ScrollingTreeState::create())
+ , m_scrollingTreeStateCommitterTimer(this, &ScrollingCoordinator::scrollingTreeStateCommitterTimerFired)
{
}
ScrollingCoordinator::~ScrollingCoordinator()
{
ASSERT(!m_page);
+ ASSERT(!m_scrollingTree);
}
void ScrollingCoordinator::pageDestroyed()
{
ASSERT(m_page);
m_page = 0;
+
+ // Invalidating the scrolling tree will break the reference cycle between the ScrollingCoordinator and ScrollingTree objects.
+ ScrollingThread::dispatch(bind(&ScrollingTree::invalidate, m_scrollingTree.release()));
+}
+
+ScrollingTree* ScrollingCoordinator::scrollingTree() const
+{
+ ASSERT(m_scrollingTree);
+ return m_scrollingTree.get();
}
bool ScrollingCoordinator::coordinatesScrollingForFrameView(FrameView* frameView) const
@@ -75,78 +91,103 @@ bool ScrollingCoordinator::coordinatesScrollingForFrameView(FrameView* frameView
return true;
}
-void ScrollingCoordinator::syncFrameViewGeometry(FrameView* frameView)
+void ScrollingCoordinator::frameViewLayoutUpdated(FrameView* frameView)
{
ASSERT(isMainThread());
ASSERT(m_page);
- if (frameView->frame() != m_page->mainFrame())
+ if (!coordinatesScrollingForFrameView(frameView))
return;
- IntRect visibleContentRect = frameView->visibleContentRect();
- IntSize contentsSize = frameView->contentsSize();
+ // 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.
+ Region nonScrollableRegion;
+ if (const FrameView::ScrollableAreaSet* scrollableAreas = frameView->scrollableAreas()) {
+ for (FrameView::ScrollableAreaSet::const_iterator it = scrollableAreas->begin(), end = scrollableAreas->end(); it != end; ++it) {
+ ScrollableArea* scrollableArea = *it;
- MutexLocker locker(m_mainFrameGeometryMutex);
- if (m_mainFrameVisibleContentRect == visibleContentRect && m_mainFrameContentsSize == contentsSize)
- return;
+ // Check if this area can be scrolled at all.
+ if ((!scrollableArea->horizontalScrollbar() || !scrollableArea->horizontalScrollbar()->enabled())
+ && (!scrollableArea->verticalScrollbar() || !scrollableArea->verticalScrollbar()->enabled()))
+ continue;
- m_mainFrameVisibleContentRect = visibleContentRect;
- m_mainFrameContentsSize = contentsSize;
+ nonScrollableRegion.unite(scrollableArea->scrollableAreaBoundingBox());
+ }
+ }
- // FIXME: Inform the scrolling thread that the frame geometry has changed.
+ m_scrollingTreeState->setViewportRect(IntRect(IntPoint(), frameView->visibleContentRect().size()));
+ m_scrollingTreeState->setContentsSize(frameView->contentsSize());
+ m_scrollingTreeState->setNonFastScrollableRegion(nonScrollableRegion);
+ scheduleTreeStateCommit();
}
-bool ScrollingCoordinator::handleWheelEvent(const PlatformWheelEvent& wheelEvent)
+void ScrollingCoordinator::frameViewWheelEventHandlerCountChanged(FrameView*)
{
- // FIXME: Check for wheel event handlers.
- // FIXME: Check if we're over a subframe or overflow div.
- // FIXME: As soon as we've determined that we can handle the wheel event, we should do the
- // bulk of the work on the scrolling thread and return from this function.
- // FIXME: Handle rubberbanding.
- float deltaX = wheelEvent.deltaX();
- float deltaY = wheelEvent.deltaY();
-
- // Slightly prefer scrolling vertically by applying the = case to deltaY
- if (fabsf(deltaY) >= fabsf(deltaX))
- deltaX = 0;
- else
- deltaY = 0;
-
- IntSize scrollOffset = IntSize(-deltaX, -deltaY);
- dispatchOnScrollingThread(bind(&ScrollingCoordinator::scrollByOnScrollingThread, this, scrollOffset));
- return true;
-}
+ ASSERT(isMainThread());
+ ASSERT(m_page);
-#if ENABLE(GESTURE_EVENTS)
-bool ScrollingCoordinator::handleGestureEvent(const PlatformGestureEvent&)
-{
- // FIXME: Implement.
- return false;
+ recomputeWheelEventHandlerCount();
}
-#endif
-void ScrollingCoordinator::didUpdateMainFrameScrollPosition()
+void ScrollingCoordinator::updateMainFrameScrollPosition(const IntPoint& scrollPosition)
{
ASSERT(isMainThread());
if (!m_page)
return;
- IntPoint scrollPosition;
+ FrameView* frameView = m_page->mainFrame()->view();
+ if (!frameView)
+ return;
- {
- MutexLocker locker(m_mainFrameGeometryMutex);
- ASSERT(m_didDispatchDidUpdateMainFrameScrollPosition);
+ frameView->setConstrainsScrollingToContentEdge(false);
+ frameView->scrollToOffsetWithoutAnimation(scrollPosition);
+ frameView->setConstrainsScrollingToContentEdge(true);
+}
- scrollPosition = m_mainFrameScrollPosition;
- m_didDispatchDidUpdateMainFrameScrollPosition = false;
+void ScrollingCoordinator::recomputeWheelEventHandlerCount()
+{
+ unsigned wheelEventHandlerCount = 0;
+ for (Frame* frame = m_page->mainFrame(); frame; frame = frame->tree()->traverseNext()) {
+ if (frame->document())
+ wheelEventHandlerCount += frame->document()->wheelEventHandlerCount();
}
- if (FrameView* frameView = m_page->mainFrame()->view()) {
- frameView->setConstrainsScrollingToContentEdge(false);
- frameView->scrollToOffsetWithoutAnimation(scrollPosition);
- frameView->setConstrainsScrollingToContentEdge(true);
- }
+ m_scrollingTreeState->setWheelEventHandlerCount(wheelEventHandlerCount);
+ scheduleTreeStateCommit();
+}
+
+void ScrollingCoordinator::scheduleTreeStateCommit()
+{
+ if (m_scrollingTreeStateCommitterTimer.isActive())
+ return;
+
+ if (!m_scrollingTreeState->hasChangedProperties())
+ return;
+
+ m_scrollingTreeStateCommitterTimer.startOneShot(0);
+}
+
+void ScrollingCoordinator::scrollingTreeStateCommitterTimerFired(Timer<ScrollingCoordinator>*)
+{
+ commitTreeState();
+}
+
+void ScrollingCoordinator::commitTreeStateIfNeeded()
+{
+ if (!m_scrollingTreeState->hasChangedProperties())
+ return;
+
+ commitTreeState();
+ m_scrollingTreeStateCommitterTimer.stop();
+}
+
+void ScrollingCoordinator::commitTreeState()
+{
+ ASSERT(m_scrollingTreeState->hasChangedProperties());
+
+ OwnPtr<ScrollingTreeState> treeState = m_scrollingTreeState->commit();
+ ScrollingThread::dispatch(bind(&ScrollingTree::commitNewTreeState, m_scrollingTree.get(), treeState.release()));
}
} // namespace WebCore
diff --git a/Source/WebCore/page/scrolling/ScrollingCoordinator.h b/Source/WebCore/page/scrolling/ScrollingCoordinator.h
index e295d8031..eb597b8b0 100644
--- a/Source/WebCore/page/scrolling/ScrollingCoordinator.h
+++ b/Source/WebCore/page/scrolling/ScrollingCoordinator.h
@@ -30,6 +30,7 @@
#include "GraphicsLayer.h"
#include "IntRect.h"
+#include "Timer.h"
#include <wtf/Forward.h>
#include <wtf/ThreadSafeRefCounted.h>
#include <wtf/Threading.h>
@@ -44,6 +45,8 @@ class FrameView;
class GraphicsLayer;
class Page;
class PlatformWheelEvent;
+class ScrollingTree;
+class ScrollingTreeState;
#if ENABLE(GESTURE_EVENTS)
class PlatformGestureEvent;
@@ -56,9 +59,18 @@ public:
void pageDestroyed();
+ ScrollingTree* scrollingTree() const;
+
// Return whether this scrolling coordinator handles scrolling for the given frame view.
bool coordinatesScrollingForFrameView(FrameView*) const;
+ // Should be called whenever the given frame view has been laid out.
+ 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 scroll layer for the given frame view changes.
void frameViewScrollLayerDidChange(FrameView*, const GraphicsLayer*);
@@ -68,49 +80,24 @@ public:
// Should be called whenever the horizontal scrollbar layer for the given frame view changes.
void frameViewVerticalScrollbarLayerDidChange(FrameView*, GraphicsLayer* verticalScrollbarLayer);
- // Should be called whenever the geometry of the given frame view changes,
- // including the visible content rect and the content size.
- void syncFrameViewGeometry(FrameView*);
-
- // Can be called from any thread. Will try to handle the wheel event on the scrolling thread,
- // and return false if the event must be sent again to the WebCore event handler.
- bool handleWheelEvent(const PlatformWheelEvent&);
-
-#if ENABLE(GESTURE_EVENTS)
- // Can be called from any thread. Will try to handle the gesture event on the scrolling thread,
- // and return false if the event must be sent again to the WebCore event handler.
- bool handleGestureEvent(const PlatformGestureEvent&);
-#endif
+ // Dispatched by the scrolling tree whenever the main frame scroll position changes.
+ void updateMainFrameScrollPosition(const IntPoint&);
private:
explicit ScrollingCoordinator(Page*);
- // FIXME: Once we have a proper thread/run loop abstraction we should get rid of these
- // functions and just use something like scrollingRunLoop()->dispatch(function);
- static bool isScrollingThread();
- static void dispatchOnScrollingThread(const Function<void()>&);
+ void recomputeWheelEventHandlerCount();
- // The following functions can only be called from the main thread.
- void didUpdateMainFrameScrollPosition();
+ void scheduleTreeStateCommit();
+ void scrollingTreeStateCommitterTimerFired(Timer<ScrollingCoordinator>*);
+ void commitTreeStateIfNeeded();
+ void commitTreeState();
- // The following functions can only be called from the scrolling thread.
- void scrollByOnScrollingThread(const IntSize& offset);
-
- // This function must be called with the main frame geometry mutex held.
- void updateMainFrameScrollLayerPositionOnScrollingThread(const FloatPoint&);
-
-private:
Page* m_page;
+ RefPtr<ScrollingTree> m_scrollingTree;
- Mutex m_mainFrameGeometryMutex;
- IntRect m_mainFrameVisibleContentRect;
- IntSize m_mainFrameContentsSize;
-#if PLATFORM(MAC)
- RetainPtr<PlatformLayer> m_mainFrameScrollLayer;
-#endif
-
- bool m_didDispatchDidUpdateMainFrameScrollPosition;
- IntPoint m_mainFrameScrollPosition;
+ OwnPtr<ScrollingTreeState> m_scrollingTreeState;
+ Timer<ScrollingCoordinator> m_scrollingTreeStateCommitterTimer;
};
} // namespace WebCore
diff --git a/Source/WebCore/page/scrolling/ScrollingThread.cpp b/Source/WebCore/page/scrolling/ScrollingThread.cpp
new file mode 100644
index 000000000..fc5a405da
--- /dev/null
+++ b/Source/WebCore/page/scrolling/ScrollingThread.cpp
@@ -0,0 +1,111 @@
+/*
+ * 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 "ScrollingThread.h"
+
+#if ENABLE(THREADED_SCROLLING)
+
+namespace WebCore {
+
+ScrollingThread::ScrollingThread()
+ : m_threadIdentifier(0)
+{
+}
+
+bool ScrollingThread::isCurrentThread()
+{
+ if (!shared().m_threadIdentifier)
+ return false;
+
+ return currentThread() == shared().m_threadIdentifier;
+}
+
+void ScrollingThread::dispatch(const Function<void()>& function)
+{
+ shared().createThreadIfNeeded();
+
+ {
+ MutexLocker locker(shared().m_functionsMutex);
+ shared().m_functions.append(function);
+ }
+
+ shared().wakeUpRunLoop();
+}
+
+ScrollingThread& ScrollingThread::shared()
+{
+ DEFINE_STATIC_LOCAL(ScrollingThread, scrollingThread, ());
+ return scrollingThread;
+}
+
+void ScrollingThread::createThreadIfNeeded()
+{
+ if (m_threadIdentifier)
+ return;
+
+ m_threadIdentifier = createThread(threadCallback, this, "WebCore: Scrolling");
+
+ // Wait for the thread to initialize the run loop.
+ {
+ MutexLocker locker(m_initializeRunLoopConditionMutex);
+
+ while (!m_threadRunLoop)
+ m_initializeRunLoopCondition.wait(m_initializeRunLoopConditionMutex);
+ }
+}
+
+void* ScrollingThread::threadCallback(void* scrollingThread)
+{
+ static_cast<ScrollingThread*>(scrollingThread)->threadBody();
+
+ return 0;
+}
+
+void ScrollingThread::threadBody()
+{
+ ASSERT(isCurrentThread());
+
+ initializeRunLoop();
+}
+
+void ScrollingThread::dispatchFunctionsFromScrollingThread()
+{
+ ASSERT(isCurrentThread());
+
+ Vector<Function<void()> > functions;
+
+ {
+ MutexLocker locker(m_functionsMutex);
+ m_functions.swap(functions);
+ }
+
+ for (size_t i = 0; i < functions.size(); ++i)
+ functions[i]();
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(THREADED_SCROLLING)
diff --git a/Source/WebCore/page/scrolling/ScrollingThread.h b/Source/WebCore/page/scrolling/ScrollingThread.h
new file mode 100644
index 000000000..22671e4f5
--- /dev/null
+++ b/Source/WebCore/page/scrolling/ScrollingThread.h
@@ -0,0 +1,86 @@
+/*
+ * 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 ScrollingThread_h
+#define ScrollingThread_h
+
+#if ENABLE(THREADED_SCROLLING)
+
+#include <wtf/Functional.h>
+#include <wtf/Noncopyable.h>
+#include <wtf/Threading.h>
+#include <wtf/Vector.h>
+
+#if PLATFORM(MAC)
+#include <wtf/RetainPtr.h>
+#endif
+
+namespace WebCore {
+
+class ScrollingThread {
+ WTF_MAKE_NONCOPYABLE(ScrollingThread);
+
+public:
+ static bool isCurrentThread();
+ static void dispatch(const Function<void()>&);
+
+private:
+ ScrollingThread();
+
+ static ScrollingThread& shared();
+
+ void createThreadIfNeeded();
+ static void* threadCallback(void* scrollingThread);
+ void threadBody();
+ void dispatchFunctionsFromScrollingThread();
+
+ void initializeRunLoop();
+ void wakeUpRunLoop();
+
+#if PLATFORM(MAC)
+ static void threadRunLoopSourceCallback(void* scrollingThread);
+ void threadRunLoopSourceCallback();
+#endif
+
+ ThreadIdentifier m_threadIdentifier;
+
+ ThreadCondition m_initializeRunLoopCondition;
+ Mutex m_initializeRunLoopConditionMutex;
+
+ Mutex m_functionsMutex;
+ Vector<Function<void()> > m_functions;
+
+#if PLATFORM(MAC)
+ // FIXME: We should use WebCore::RunLoop here.
+ RetainPtr<CFRunLoopRef> m_threadRunLoop;
+ RetainPtr<CFRunLoopSourceRef> m_threadRunLoopSource;
+#endif
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(THREADED_SCROLLING)
+
+#endif // ScrollingThread_h
diff --git a/Source/WebCore/page/scrolling/ScrollingTree.cpp b/Source/WebCore/page/scrolling/ScrollingTree.cpp
new file mode 100644
index 000000000..bc1c50d9f
--- /dev/null
+++ b/Source/WebCore/page/scrolling/ScrollingTree.cpp
@@ -0,0 +1,125 @@
+/*
+ * 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 "ScrollingTree.h"
+
+#if ENABLE(THREADED_SCROLLING)
+
+#include "PlatformWheelEvent.h"
+#include "ScrollingCoordinator.h"
+#include "ScrollingThread.h"
+#include "ScrollingTreeNode.h"
+#include "ScrollingTreeState.h"
+#include <wtf/MainThread.h>
+
+namespace WebCore {
+
+PassRefPtr<ScrollingTree> ScrollingTree::create(ScrollingCoordinator* scrollingCoordinator)
+{
+ return adoptRef(new ScrollingTree(scrollingCoordinator));
+}
+
+ScrollingTree::ScrollingTree(ScrollingCoordinator* scrollingCoordinator)
+ : m_scrollingCoordinator(scrollingCoordinator)
+ , m_rootNode(ScrollingTreeNode::create(this))
+ , m_hasWheelEventHandlers(false)
+{
+}
+
+ScrollingTree::~ScrollingTree()
+{
+ ASSERT(!m_scrollingCoordinator);
+}
+
+bool ScrollingTree::tryToHandleWheelEvent(const PlatformWheelEvent& wheelEvent)
+{
+ {
+ MutexLocker lock(m_mutex);
+
+ if (m_hasWheelEventHandlers)
+ return false;
+
+ if (!m_nonFastScrollableRegion.isEmpty()) {
+ // FIXME: This is not correct for non-default scroll origins.
+ IntPoint position = wheelEvent.position();
+ position.moveBy(m_mainFrameScrollPosition);
+ if (m_nonFastScrollableRegion.contains(position))
+ return false;
+ }
+ }
+
+ ScrollingThread::dispatch(bind(&ScrollingTree::handleWheelEvent, this, wheelEvent));
+ return true;
+}
+
+void ScrollingTree::handleWheelEvent(const PlatformWheelEvent& wheelEvent)
+{
+ ASSERT(ScrollingThread::isCurrentThread());
+
+ m_rootNode->handleWheelEvent(wheelEvent);
+}
+
+void ScrollingTree::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());
+ m_scrollingCoordinator = nullptr;
+}
+
+void ScrollingTree::commitNewTreeState(PassOwnPtr<ScrollingTreeState> scrollingTreeState)
+{
+ ASSERT(ScrollingThread::isCurrentThread());
+
+ if (scrollingTreeState->changedProperties() & (ScrollingTreeState::WheelEventHandlerCount | ScrollingTreeState::NonFastScrollableRegion)) {
+ MutexLocker lock(m_mutex);
+
+ if (scrollingTreeState->changedProperties() & ScrollingTreeState::WheelEventHandlerCount)
+ m_hasWheelEventHandlers = scrollingTreeState->wheelEventHandlerCount();
+ if (scrollingTreeState->changedProperties() & ScrollingTreeState::NonFastScrollableRegion)
+ m_nonFastScrollableRegion = scrollingTreeState->nonFastScrollableRegion();
+ }
+
+ m_rootNode->update(scrollingTreeState.get());
+}
+
+void ScrollingTree::updateMainFrameScrollPosition(const IntPoint& scrollPosition)
+{
+ if (!m_scrollingCoordinator)
+ return;
+
+ {
+ MutexLocker lock(m_mutex);
+ m_mainFrameScrollPosition = scrollPosition;
+ }
+
+ callOnMainThread(bind(&ScrollingCoordinator::updateMainFrameScrollPosition, m_scrollingCoordinator.get(), scrollPosition));
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(THREADED_SCROLLING)
diff --git a/Source/WebCore/page/scrolling/ScrollingTree.h b/Source/WebCore/page/scrolling/ScrollingTree.h
new file mode 100644
index 000000000..76cbfda0a
--- /dev/null
+++ b/Source/WebCore/page/scrolling/ScrollingTree.h
@@ -0,0 +1,84 @@
+/*
+ * 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 ScrollingTree_h
+#define ScrollingTree_h
+
+#if ENABLE(THREADED_SCROLLING)
+
+#include "Region.h"
+#include <wtf/OwnPtr.h>
+#include <wtf/PassOwnPtr.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefPtr.h>
+#include <wtf/ThreadSafeRefCounted.h>
+
+namespace WebCore {
+
+class IntPoint;
+class PlatformWheelEvent;
+class ScrollingCoordinator;
+class ScrollingTreeNode;
+class ScrollingTreeState;
+
+// The ScrollingTree 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 ScrollingTree : public ThreadSafeRefCounted<ScrollingTree> {
+public:
+ static PassRefPtr<ScrollingTree> create(ScrollingCoordinator*);
+ ~ScrollingTree();
+
+ // 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.
+ bool tryToHandleWheelEvent(const PlatformWheelEvent&);
+
+ // Must be called from the scrolling thread. Handles the wheel event.
+ void handleWheelEvent(const PlatformWheelEvent&);
+
+ void invalidate();
+ void commitNewTreeState(PassOwnPtr<ScrollingTreeState>);
+
+ void updateMainFrameScrollPosition(const IntPoint& scrollPosition);
+
+private:
+ explicit ScrollingTree(ScrollingCoordinator*);
+
+ RefPtr<ScrollingCoordinator> m_scrollingCoordinator;
+ OwnPtr<ScrollingTreeNode> m_rootNode;
+
+ Mutex m_mutex;
+ Region m_nonFastScrollableRegion;
+ IntPoint m_mainFrameScrollPosition;
+ bool m_hasWheelEventHandlers;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(THREADED_SCROLLING)
+
+#endif // ScrollingTree_h
diff --git a/Source/WebCore/page/scrolling/ScrollingTreeNode.cpp b/Source/WebCore/page/scrolling/ScrollingTreeNode.cpp
new file mode 100644
index 000000000..bd94f00dc
--- /dev/null
+++ b/Source/WebCore/page/scrolling/ScrollingTreeNode.cpp
@@ -0,0 +1,55 @@
+/*
+ * 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(THREADED_SCROLLING)
+
+#include "ScrollingTreeState.h"
+
+namespace WebCore {
+
+ScrollingTreeNode::ScrollingTreeNode(ScrollingTree* scrollingTree)
+ : m_scrollingTree(scrollingTree)
+{
+}
+
+ScrollingTreeNode::~ScrollingTreeNode()
+{
+}
+
+void ScrollingTreeNode::update(ScrollingTreeState* state)
+{
+ if (state->changedProperties() & ScrollingTreeState::ViewportRect)
+ m_viewportRect = state->viewportRect();
+
+ if (state->changedProperties() & ScrollingTreeState::ContentsSize)
+ m_contentsSize = state->contentsSize();
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(THREADED_SCROLLING)
diff --git a/Source/WebCore/page/scrolling/ScrollingTreeNode.h b/Source/WebCore/page/scrolling/ScrollingTreeNode.h
new file mode 100644
index 000000000..d26293a89
--- /dev/null
+++ b/Source/WebCore/page/scrolling/ScrollingTreeNode.h
@@ -0,0 +1,66 @@
+/*
+ * 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(THREADED_SCROLLING)
+
+#include "IntRect.h"
+#include <wtf/PassOwnPtr.h>
+
+namespace WebCore {
+
+class PlatformWheelEvent;
+class ScrollingTree;
+class ScrollingTreeState;
+
+class ScrollingTreeNode {
+public:
+ static PassOwnPtr<ScrollingTreeNode> create(ScrollingTree*);
+ virtual ~ScrollingTreeNode();
+
+ virtual void update(ScrollingTreeState*);
+ virtual void handleWheelEvent(const PlatformWheelEvent&) = 0;
+
+protected:
+ explicit ScrollingTreeNode(ScrollingTree*);
+
+ ScrollingTree* scrollingTree() const { return m_scrollingTree; }
+ const IntRect& viewportRect() const { return m_viewportRect; }
+ const IntSize& contentsSize() const { return m_contentsSize; }
+
+private:
+ ScrollingTree* m_scrollingTree;
+
+ IntRect m_viewportRect;
+ IntSize m_contentsSize;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(THREADED_SCROLLING)
+
+#endif // ScrollingTreeNode_h
diff --git a/Source/WebCore/page/scrolling/ScrollingTreeState.cpp b/Source/WebCore/page/scrolling/ScrollingTreeState.cpp
new file mode 100644
index 000000000..c368152c3
--- /dev/null
+++ b/Source/WebCore/page/scrolling/ScrollingTreeState.cpp
@@ -0,0 +1,94 @@
+/*
+ * 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 "ScrollingTreeState.h"
+
+#if ENABLE(THREADED_SCROLLING)
+
+namespace WebCore {
+
+PassOwnPtr<ScrollingTreeState> ScrollingTreeState::create()
+{
+ return adoptPtr(new ScrollingTreeState);
+}
+
+ScrollingTreeState::ScrollingTreeState()
+ : m_changedProperties(0)
+ , m_wheelEventHandlerCount(0)
+{
+}
+
+ScrollingTreeState::~ScrollingTreeState()
+{
+}
+
+void ScrollingTreeState::setViewportRect(const IntRect& viewportRect)
+{
+ if (m_viewportRect == viewportRect)
+ return;
+
+ m_viewportRect = viewportRect;
+ m_changedProperties |= ViewportRect;
+}
+
+void ScrollingTreeState::setContentsSize(const IntSize& contentsSize)
+{
+ if (m_contentsSize == contentsSize)
+ return;
+
+ m_contentsSize = contentsSize;
+ m_changedProperties |= ContentsSize;
+}
+
+void ScrollingTreeState::setNonFastScrollableRegion(const Region& nonFastScrollableRegion)
+{
+ if (m_nonFastScrollableRegion == nonFastScrollableRegion)
+ return;
+
+ m_nonFastScrollableRegion = nonFastScrollableRegion;
+ m_changedProperties |= NonFastScrollableRegion;
+}
+
+void ScrollingTreeState::setWheelEventHandlerCount(unsigned wheelEventHandlerCount)
+{
+ if (m_wheelEventHandlerCount == wheelEventHandlerCount)
+ return;
+
+ m_wheelEventHandlerCount = wheelEventHandlerCount;
+ m_changedProperties |= WheelEventHandlerCount;
+}
+
+PassOwnPtr<ScrollingTreeState> ScrollingTreeState::commit()
+{
+ OwnPtr<ScrollingTreeState> treeState = adoptPtr(new ScrollingTreeState(*this));
+ m_changedProperties = 0;
+
+ return treeState.release();
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(THREADED_SCROLLING)
diff --git a/Source/WebCore/page/scrolling/ScrollingTreeState.h b/Source/WebCore/page/scrolling/ScrollingTreeState.h
new file mode 100644
index 000000000..fde884922
--- /dev/null
+++ b/Source/WebCore/page/scrolling/ScrollingTreeState.h
@@ -0,0 +1,102 @@
+/*
+ * 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 ScrollingTreeState_h
+#define ScrollingTreeState_h
+
+#if ENABLE(THREADED_SCROLLING)
+
+#include "GraphicsLayer.h"
+#include "IntRect.h"
+#include "Region.h"
+#include <wtf/PassOwnPtr.h>
+
+#if PLATFORM(MAC)
+#include <wtf/RetainPtr.h>
+#endif
+
+namespace WebCore {
+
+// The ScrollingTreeState object keeps track of the current state of scrolling related properties.
+// Whenever any properties change, the scrolling coordinator will be informed and will update the state
+// and schedule a timer that will clone the new state and send it over to the scrolling thread, avoiding locking.
+// FIXME: Once we support fast scrolling in subframes, this will have to become a tree-like structure.
+class ScrollingTreeState {
+public:
+ static PassOwnPtr<ScrollingTreeState> create();
+ ~ScrollingTreeState();
+
+ enum ChangedProperty {
+ ViewportRect = 1 << 0,
+ ContentsSize = 1 << 1,
+ NonFastScrollableRegion = 1 << 2,
+ WheelEventHandlerCount = 1 << 3,
+ ScrollLayer = 1 << 4,
+ };
+
+ bool hasChangedProperties() const { return m_changedProperties; }
+ unsigned changedProperties() const { return m_changedProperties; }
+
+ const IntRect& viewportRect() const { return m_viewportRect; }
+ void setViewportRect(const IntRect&);
+
+ const IntSize& contentsSize() const { return m_contentsSize; }
+ void setContentsSize(const IntSize&);
+
+ const Region& nonFastScrollableRegion() const { return m_nonFastScrollableRegion; }
+ void setNonFastScrollableRegion(const Region&);
+
+ unsigned wheelEventHandlerCount() const { return m_wheelEventHandlerCount; }
+ void setWheelEventHandlerCount(unsigned);
+
+ PlatformLayer* platformScrollLayer() const;
+ void setScrollLayer(const GraphicsLayer*);
+
+ // Copies the current tree state and clears the changed properties mask in the original.
+ PassOwnPtr<ScrollingTreeState> commit();
+
+private:
+ ScrollingTreeState();
+
+ unsigned m_changedProperties;
+
+ IntRect m_viewportRect;
+ IntSize m_contentsSize;
+
+ Region m_nonFastScrollableRegion;
+
+ unsigned m_wheelEventHandlerCount;
+
+#if PLATFORM(MAC)
+ RetainPtr<PlatformLayer> m_platformScrollLayer;
+#endif
+
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(THREADED_SCROLLING)
+
+#endif // ScrollingTreeState_h
diff --git a/Source/WebCore/page/scrolling/mac/ScrollingCoordinatorMac.mm b/Source/WebCore/page/scrolling/mac/ScrollingCoordinatorMac.mm
index 00535d2b9..31fa76683 100644
--- a/Source/WebCore/page/scrolling/mac/ScrollingCoordinatorMac.mm
+++ b/Source/WebCore/page/scrolling/mac/ScrollingCoordinatorMac.mm
@@ -31,6 +31,8 @@
#import "FrameView.h"
#import "Page.h"
+#import "ScrollingThread.h"
+#import "ScrollingTreeState.h"
#import <QuartzCore/QuartzCore.h>
#import <wtf/Functional.h>
#import <wtf/MainThread.h>
@@ -40,127 +42,6 @@
namespace WebCore {
-class ScrollingThread {
-public:
- ScrollingThread()
- : m_threadIdentifier(0)
- {
- }
-
- bool isCurrentThread() const;
- void dispatch(const Function<void()>&);
-
-private:
- void createThreadIfNeeded();
-
- static void* threadCallback(void* scrollingThread);
- void threadBody();
-
- static void threadRunLoopSourceCallback(void* scrollingThread);
- void threadRunLoopSourceCallback();
-
- ThreadIdentifier m_threadIdentifier;
-
- ThreadCondition m_initializeRunLoopCondition;
- Mutex m_initializeRunLoopConditionMutex;
-
- RetainPtr<CFRunLoopRef> m_threadRunLoop;
- RetainPtr<CFRunLoopSourceRef> m_threadRunLoopSource;
-
- Mutex m_functionsMutex;
- Vector<Function<void()> > m_functions;
-};
-
-bool ScrollingThread::isCurrentThread() const
-{
- if (!m_threadIdentifier)
- return false;
-
- return currentThread() == m_threadIdentifier;
-}
-
-void ScrollingThread::createThreadIfNeeded()
-{
- if (m_threadIdentifier)
- return;
-
- m_threadIdentifier = createThread(threadCallback, this, "WebCore: Scrolling");
-
- // Wait for the thread to initialize the run loop.
- {
- MutexLocker locker(m_initializeRunLoopConditionMutex);
-
- while (!m_threadRunLoop)
- m_initializeRunLoopCondition.wait(m_initializeRunLoopConditionMutex);
- }
-}
-
-void* ScrollingThread::threadCallback(void* scrollingThread)
-{
- static_cast<ScrollingThread*>(scrollingThread)->threadBody();
-
- return 0;
-}
-
-void ScrollingThread::threadBody()
-{
- ASSERT(isCurrentThread());
-
- // Initialize the run loop.
- {
- MutexLocker locker(m_initializeRunLoopConditionMutex);
-
- m_threadRunLoop = CFRunLoopGetCurrent();
-
- CFRunLoopSourceContext context = { 0, this, 0, 0, 0, 0, 0, 0, 0, threadRunLoopSourceCallback };
- m_threadRunLoopSource = adoptCF(CFRunLoopSourceCreate(0, 0, &context));
- CFRunLoopAddSource(CFRunLoopGetCurrent(), m_threadRunLoopSource.get(), kCFRunLoopDefaultMode);
-
- m_initializeRunLoopCondition.broadcast();
- }
-
- CFRunLoopRun();
-}
-
-void ScrollingThread::threadRunLoopSourceCallback(void* scrollingThread)
-{
- static_cast<ScrollingThread*>(scrollingThread)->threadRunLoopSourceCallback();
-}
-
-void ScrollingThread::threadRunLoopSourceCallback()
-{
- ASSERT(isCurrentThread());
-
- Vector<Function<void ()> > functions;
-
- {
- MutexLocker locker(m_functionsMutex);
- m_functions.swap(functions);
- }
-
- for (size_t i = 0; i < functions.size(); ++i)
- functions[i]();
-}
-
-void ScrollingThread::dispatch(const Function<void()>& function)
-{
- createThreadIfNeeded();
-
- {
- MutexLocker locker(m_functionsMutex);
- m_functions.append(function);
- }
-
- CFRunLoopSourceSignal(m_threadRunLoopSource.get());
- CFRunLoopWakeUp(m_threadRunLoop.get());
-}
-
-static ScrollingThread& scrollingThread()
-{
- DEFINE_STATIC_LOCAL(ScrollingThread, scrollingThread, ());
- return scrollingThread;
-}
-
void ScrollingCoordinator::frameViewHorizontalScrollbarLayerDidChange(FrameView* frameView, GraphicsLayer*)
{
ASSERT(isMainThread());
@@ -191,56 +72,8 @@ void ScrollingCoordinator::frameViewScrollLayerDidChange(FrameView* frameView, c
if (frameView->frame() != m_page->mainFrame())
return;
- MutexLocker locker(m_mainFrameGeometryMutex);
- m_mainFrameScrollLayer = scrollLayer->platformLayer();
-
- // FIXME: Inform the scrolling thread?
-}
-
-bool ScrollingCoordinator::isScrollingThread()
-{
- return scrollingThread().isCurrentThread();
-}
-
-void ScrollingCoordinator::dispatchOnScrollingThread(const Function<void()>& function)
-{
- return scrollingThread().dispatch(function);
-}
-
-void ScrollingCoordinator::scrollByOnScrollingThread(const IntSize& offset)
-{
- ASSERT(isScrollingThread());
-
- MutexLocker locker(m_mainFrameGeometryMutex);
-
- // FIXME: Should we cache the scroll position as well or always get it from the layer?
- IntPoint scrollPosition = IntPoint([m_mainFrameScrollLayer.get() position]);
- scrollPosition = -scrollPosition;
-
- scrollPosition += offset;
- scrollPosition.clampNegativeToZero();
-
- IntPoint maximumScrollPosition = IntPoint(m_mainFrameContentsSize.width() - m_mainFrameVisibleContentRect.width(), m_mainFrameContentsSize.height() - m_mainFrameVisibleContentRect.height());
- scrollPosition = scrollPosition.shrunkTo(maximumScrollPosition);
-
- updateMainFrameScrollLayerPositionOnScrollingThread(-scrollPosition);
-
- m_mainFrameScrollPosition = scrollPosition;
- if (!m_didDispatchDidUpdateMainFrameScrollPosition) {
- callOnMainThread(bind(&ScrollingCoordinator::didUpdateMainFrameScrollPosition, this));
- m_didDispatchDidUpdateMainFrameScrollPosition = true;
- }
-}
-
-void ScrollingCoordinator::updateMainFrameScrollLayerPositionOnScrollingThread(const FloatPoint& scrollLayerPosition)
-{
- ASSERT(isScrollingThread());
- ASSERT(!m_mainFrameGeometryMutex.tryLock());
-
- [CATransaction begin];
- [CATransaction setDisableActions:YES];
- [m_mainFrameScrollLayer.get() setPosition:scrollLayerPosition];
- [CATransaction commit];
+ m_scrollingTreeState->setScrollLayer(scrollLayer);
+ scheduleTreeStateCommit();
}
} // namespace WebCore
diff --git a/Source/WebCore/page/scrolling/mac/ScrollingThreadMac.mm b/Source/WebCore/page/scrolling/mac/ScrollingThreadMac.mm
new file mode 100644
index 000000000..a6a768113
--- /dev/null
+++ b/Source/WebCore/page/scrolling/mac/ScrollingThreadMac.mm
@@ -0,0 +1,69 @@
+/*
+ * 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 "ScrollingThread.h"
+
+#if ENABLE(THREADED_SCROLLING)
+
+namespace WebCore {
+
+void ScrollingThread::initializeRunLoop()
+{
+ // Initialize the run loop.
+ {
+ MutexLocker locker(m_initializeRunLoopConditionMutex);
+
+ m_threadRunLoop = CFRunLoopGetCurrent();
+
+ CFRunLoopSourceContext context = { 0, this, 0, 0, 0, 0, 0, 0, 0, threadRunLoopSourceCallback };
+ m_threadRunLoopSource = adoptCF(CFRunLoopSourceCreate(0, 0, &context));
+ CFRunLoopAddSource(CFRunLoopGetCurrent(), m_threadRunLoopSource.get(), kCFRunLoopDefaultMode);
+
+ m_initializeRunLoopCondition.broadcast();
+ }
+
+ CFRunLoopRun();
+}
+
+void ScrollingThread::wakeUpRunLoop()
+{
+ CFRunLoopSourceSignal(m_threadRunLoopSource.get());
+ CFRunLoopWakeUp(m_threadRunLoop.get());
+}
+
+void ScrollingThread::threadRunLoopSourceCallback(void* scrollingThread)
+{
+ static_cast<ScrollingThread*>(scrollingThread)->threadRunLoopSourceCallback();
+}
+
+void ScrollingThread::threadRunLoopSourceCallback()
+{
+ dispatchFunctionsFromScrollingThread();
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(THREADED_SCROLLING)
diff --git a/Source/WebCore/page/scrolling/mac/ScrollingTreeNodeMac.h b/Source/WebCore/page/scrolling/mac/ScrollingTreeNodeMac.h
new file mode 100644
index 000000000..b1ae6ee76
--- /dev/null
+++ b/Source/WebCore/page/scrolling/mac/ScrollingTreeNodeMac.h
@@ -0,0 +1,58 @@
+/*
+ * 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 ScrollingTreeNodeMac_h
+#define ScrollingTreeNodeMac_h
+
+#if ENABLE(THREADED_SCROLLING)
+
+#include "ScrollingTreeNode.h"
+#include <wtf/RetainPtr.h>
+
+OBJC_CLASS CALayer;
+
+namespace WebCore {
+
+class ScrollingTreeNodeMac : public ScrollingTreeNode {
+public:
+ explicit ScrollingTreeNodeMac(ScrollingTree*);
+
+private:
+ virtual void update(ScrollingTreeState*) OVERRIDE;
+ virtual void handleWheelEvent(const PlatformWheelEvent&) OVERRIDE;
+
+ IntPoint scrollPosition() const;
+ void setScrollPosition(const IntPoint&);
+
+ void scrollBy(const IntSize&);
+
+ RetainPtr<CALayer> m_scrollLayer;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(THREADED_SCROLLING)
+
+#endif // ScrollingTreeNodeMac_h
diff --git a/Source/WebCore/page/scrolling/mac/ScrollingTreeNodeMac.mm b/Source/WebCore/page/scrolling/mac/ScrollingTreeNodeMac.mm
new file mode 100644
index 000000000..76a8e3eaf
--- /dev/null
+++ b/Source/WebCore/page/scrolling/mac/ScrollingTreeNodeMac.mm
@@ -0,0 +1,81 @@
+/*
+ * 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 "ScrollingTreeNodeMac.h"
+
+#if ENABLE(THREADED_SCROLLING)
+
+#include "PlatformWheelEvent.h"
+#include "ScrollingTree.h"
+#include "ScrollingTreeState.h"
+
+namespace WebCore {
+
+PassOwnPtr<ScrollingTreeNode> ScrollingTreeNode::create(ScrollingTree* scrollingTree)
+{
+ return adoptPtr(new ScrollingTreeNodeMac(scrollingTree));
+}
+
+ScrollingTreeNodeMac::ScrollingTreeNodeMac(ScrollingTree* scrollingTree)
+ : ScrollingTreeNode(scrollingTree)
+{
+}
+
+void ScrollingTreeNodeMac::update(ScrollingTreeState* state)
+{
+ ScrollingTreeNode::update(state);
+
+ if (state->changedProperties() & ScrollingTreeState::ScrollLayer)
+ m_scrollLayer = state->platformScrollLayer();
+}
+
+void ScrollingTreeNodeMac::handleWheelEvent(const PlatformWheelEvent& wheelEvent)
+{
+ // FXIME: This needs to handle rubberbanding.
+ scrollBy(IntSize(-wheelEvent.deltaX(), -wheelEvent.deltaY()));
+}
+
+IntPoint ScrollingTreeNodeMac::scrollPosition() const
+{
+ CGPoint scrollLayerPosition = m_scrollLayer.get().position;
+ return IntPoint(-scrollLayerPosition.x, -scrollLayerPosition.y);
+}
+
+void ScrollingTreeNodeMac::setScrollPosition(const IntPoint& position)
+{
+ m_scrollLayer.get().position = CGPointMake(-position.x(), -position.y());
+}
+
+void ScrollingTreeNodeMac::scrollBy(const IntSize &offset)
+{
+ setScrollPosition(scrollPosition() + offset);
+
+ scrollingTree()->updateMainFrameScrollPosition(scrollPosition());
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(THREADED_SCROLLING)
diff --git a/Source/WebCore/page/scrolling/mac/ScrollingTreeStateMac.mm b/Source/WebCore/page/scrolling/mac/ScrollingTreeStateMac.mm
new file mode 100644
index 000000000..21f0c7253
--- /dev/null
+++ b/Source/WebCore/page/scrolling/mac/ScrollingTreeStateMac.mm
@@ -0,0 +1,51 @@
+/*
+ * 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 "ScrollingTreeState.h"
+
+#if ENABLE(THREADED_SCROLLING)
+
+namespace WebCore {
+
+PlatformLayer* ScrollingTreeState::platformScrollLayer() const
+{
+ return m_platformScrollLayer.get();
+}
+
+void ScrollingTreeState::setScrollLayer(const GraphicsLayer* graphicsLayer)
+{
+ PlatformLayer* platformScrollLayer = graphicsLayer ? graphicsLayer->platformLayer() : nil;
+
+ if (m_platformScrollLayer == platformScrollLayer)
+ return;
+
+ m_platformScrollLayer = platformScrollLayer;
+ m_changedProperties |= ScrollLayer;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(THREADED_SCROLLING)
diff --git a/Source/WebCore/page/win/FrameCGWin.cpp b/Source/WebCore/page/win/FrameCGWin.cpp
index 39f8d0a6b..ea2c391e7 100644
--- a/Source/WebCore/page/win/FrameCGWin.cpp
+++ b/Source/WebCore/page/win/FrameCGWin.cpp
@@ -97,7 +97,7 @@ DragImageRef Frame::nodeImage(Node* node)
if (!renderer)
return 0;
- IntRect topLevelRect;
+ LayoutRect topLevelRect;
IntRect paintingRect = renderer->paintingRootRect(topLevelRect);
document()->updateLayout();