Title: [199331] trunk
Revision
199331
Author
[email protected]
Date
2016-04-11 20:07:18 -0700 (Mon, 11 Apr 2016)

Log Message

Use WeakPtrs to avoid using deallocated Widgets and ScrollableAreas
https://bugs.webkit.org/show_bug.cgi?id=156420
<rdar://problem/25637378>

Reviewed by Darin Adler.

Source/WebCore:

Avoid the risk of using deallocated Widgets and ScrollableAreas by using WeakPtrs instead of
bare pointers. This allows us to remove some explicit calls to get ScrollableArea and Widget
members in the event handling logic. Instead, null checks are sufficient to ensure we never
accidentally dereference a deleted element.

1. Modify the ScrollableArea class to support vending WeakPtrs.
2. Modify the Event Handling code to use WeakPtrs to hold ScrollableArea and RenderWidget
   objects, and to null-check these elements after event handling dispatching is finished
   to handle cases where these objects are destroyed.

Test: fast/events/wheel-event-destroys-frame.html
      fast/events/wheel-event-destroys-overflow.html

* page/EventHandler.cpp:
(WebCore::EventHandler::platformPrepareForWheelEvents): Change signature for WeakPtr.
(WebCore::EventHandler::platformCompleteWheelEvent): Ditto.
(WebCore::EventHandler::platformNotifyIfEndGesture): Ditto.
(WebCore::widgetForElement): Change to return a WeakPtr.
(WebCore::EventHandler::handleWheelEvent): Use WeakPtrs to hold elements that might be destroyed
during event handling.
* page/EventHandler.h:
* page/mac/EventHandlerEfl.cpp: Rename passWheelEventToWidget to widgetDidHandleWheelEvent.
* page/mac/EventHandlerGtk.cpp: Ditto.
* page/mac/EventHandlerIOS.mm: Ditto.
* page/mac/EventHandlerMac.mm:
(WebCore::scrollableAreaForEventTarget): Renamed from scrollViewForEventTarget. Return
a WeakPtr rather than a bare pointer.
(WebCore::scrollableAreaForContainerNode): Return WeakPtr rather than bare pointer.
(WebCore::EventHandler::completeWidgetWheelEvent): Added.
(WebCore::EventHandler::passWheelEventToWidget): Deleted.
(WebCore::EventHandler::platformPrepareForWheelEvents): Convert to WeakPtrs.
(WebCore::EventHandler::platformCompleteWheelEvent): Ditto.
(WebCore::EventHandler::platformCompletePlatformWidgetWheelEvent): Ditto.
(WebCore::EventHandler::platformNotifyIfEndGesture): Ditto.
(WebCore::EventHandler::widgetDidHandleWheelEvent): Renamed from passWheelEventToWidget.
(WebCore::EventHandler::widgetForEventTarget): Converted from static function to static
method so it can be shared with EventHandlerMac.
(WebCore::scrollViewForEventTarget): Deleted.
* page/mac/EventHandlerWin.cpp: Rename passWheelEventToWidget to widgetDidHandleWheelEvent.
* platform/ScrollableArea.cpp:
* platform/ScrollableArea.h:
(WebCore::ScrollableArea::createWeakPtr): Added.
* platform/Widget.h:
(WebCore::ScrollableArea::createWeakPtr): Added.

LayoutTests:

* fast/events/wheel-event-destroys-overflow-expected.txt: Added.
* fast/events/wheel-event-destroys-overflow.html: Added.
* platform/ios-simulator/TestExpectations: Skip wheel-event test on iOS.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (199330 => 199331)


--- trunk/LayoutTests/ChangeLog	2016-04-12 02:57:03 UTC (rev 199330)
+++ trunk/LayoutTests/ChangeLog	2016-04-12 03:07:18 UTC (rev 199331)
@@ -1,3 +1,15 @@
+2016-04-11  Brent Fulgham  <[email protected]>
+
+        Use WeakPtrs to avoid using deallocated Widgets and ScrollableAreas
+        https://bugs.webkit.org/show_bug.cgi?id=156420
+        <rdar://problem/25637378>
+
+        Reviewed by Darin Adler.
+
+        * fast/events/wheel-event-destroys-overflow-expected.txt: Added.
+        * fast/events/wheel-event-destroys-overflow.html: Added.
+        * platform/ios-simulator/TestExpectations: Skip wheel-event test on iOS.
+
 2016-04-11  Dean Jackson  <[email protected]>
 
         putImageData needs to premultiply input

Added: trunk/LayoutTests/fast/events/wheel-event-destroys-overflow-expected.txt (0 => 199331)


--- trunk/LayoutTests/fast/events/wheel-event-destroys-overflow-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/events/wheel-event-destroys-overflow-expected.txt	2016-04-12 03:07:18 UTC (rev 199331)
@@ -0,0 +1,3 @@
+This test should not crash.
+
+

Added: trunk/LayoutTests/fast/events/wheel-event-destroys-overflow.html (0 => 199331)


--- trunk/LayoutTests/fast/events/wheel-event-destroys-overflow.html	                        (rev 0)
+++ trunk/LayoutTests/fast/events/wheel-event-destroys-overflow.html	2016-04-12 03:07:18 UTC (rev 199331)
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <script>
+        if (window.eventSender) {
+            testRunner.dumpAsText();
+            testRunner.waitUntilDone();
+        }
+
+        function onLoad()
+        {
+            var divTarget = document.getElementById('target');
+            var divTargetBounds = divTarget.getBoundingClientRect();
+
+            divTarget.addEventListener('wheel', function() {
+                // Removing the div during event firing causes crash.
+                if (divTarget.parentNode)
+                    divTarget.parentNode.removeChild(divTarget);
+                window.setTimeout(function() {
+                    if (window.testRunner)
+                        testRunner.notifyDone();
+                }, 0);
+            });
+
+            if (!window.eventSender)
+                return;
+
+            eventSender.mouseMoveTo(divTargetBounds.left + 10, divTargetBounds.top + 10);
+            eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'began', 'none');
+            eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'changed', 'none');
+            eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'changed', 'none');
+            eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 0, 'ended', 'none');
+        }
+    </script>
+</head>
+<body _onload_="onLoad();">
+    <p>This test should not crash.<p>
+    <div id="parent" style="height: 2000px; width: 2000px;">
+        <div id="holder" class="scrollable_region"">
+            <div id="target" style='overflow-y: auto; overflow-x: hidden; max-height: 350px;'>
+                <div style='height:1000px'>Wheel Here.</div>
+            </div>
+        </div>
+    </div>
+</body>
+</html>

Modified: trunk/LayoutTests/platform/ios-simulator/TestExpectations (199330 => 199331)


--- trunk/LayoutTests/platform/ios-simulator/TestExpectations	2016-04-12 02:57:03 UTC (rev 199330)
+++ trunk/LayoutTests/platform/ios-simulator/TestExpectations	2016-04-12 03:07:18 UTC (rev 199331)
@@ -58,6 +58,7 @@
 fast/scrolling/iframe-scrollable-after-back.html [ Skip ]
 fast/scrolling/overflow-scrollable-after-back.html [ Skip ]
 fast/events/wheel-event-destroys-frame.html [ Skip ]
+fast/events/wheel-event-destroys-overflow.html [ Skip ]
 
 # Not supported on iOS
 batterystatus

Modified: trunk/Source/WebCore/ChangeLog (199330 => 199331)


--- trunk/Source/WebCore/ChangeLog	2016-04-12 02:57:03 UTC (rev 199330)
+++ trunk/Source/WebCore/ChangeLog	2016-04-12 03:07:18 UTC (rev 199331)
@@ -1,3 +1,56 @@
+2016-04-11  Brent Fulgham  <[email protected]>
+
+        Use WeakPtrs to avoid using deallocated Widgets and ScrollableAreas
+        https://bugs.webkit.org/show_bug.cgi?id=156420
+        <rdar://problem/25637378>
+
+        Reviewed by Darin Adler.
+
+        Avoid the risk of using deallocated Widgets and ScrollableAreas by using WeakPtrs instead of
+        bare pointers. This allows us to remove some explicit calls to get ScrollableArea and Widget
+        members in the event handling logic. Instead, null checks are sufficient to ensure we never
+        accidentally dereference a deleted element.
+
+        1. Modify the ScrollableArea class to support vending WeakPtrs.
+        2. Modify the Event Handling code to use WeakPtrs to hold ScrollableArea and RenderWidget
+           objects, and to null-check these elements after event handling dispatching is finished
+           to handle cases where these objects are destroyed.
+
+        Test: fast/events/wheel-event-destroys-frame.html
+              fast/events/wheel-event-destroys-overflow.html
+
+        * page/EventHandler.cpp:
+        (WebCore::EventHandler::platformPrepareForWheelEvents): Change signature for WeakPtr.
+        (WebCore::EventHandler::platformCompleteWheelEvent): Ditto.
+        (WebCore::EventHandler::platformNotifyIfEndGesture): Ditto.
+        (WebCore::widgetForElement): Change to return a WeakPtr.
+        (WebCore::EventHandler::handleWheelEvent): Use WeakPtrs to hold elements that might be destroyed
+        during event handling.
+        * page/EventHandler.h:
+        * page/mac/EventHandlerEfl.cpp: Rename passWheelEventToWidget to widgetDidHandleWheelEvent.
+        * page/mac/EventHandlerGtk.cpp: Ditto.
+        * page/mac/EventHandlerIOS.mm: Ditto.
+        * page/mac/EventHandlerMac.mm:
+        (WebCore::scrollableAreaForEventTarget): Renamed from scrollViewForEventTarget. Return
+        a WeakPtr rather than a bare pointer.
+        (WebCore::scrollableAreaForContainerNode): Return WeakPtr rather than bare pointer.
+        (WebCore::EventHandler::completeWidgetWheelEvent): Added.
+        (WebCore::EventHandler::passWheelEventToWidget): Deleted.
+        (WebCore::EventHandler::platformPrepareForWheelEvents): Convert to WeakPtrs.
+        (WebCore::EventHandler::platformCompleteWheelEvent): Ditto.
+        (WebCore::EventHandler::platformCompletePlatformWidgetWheelEvent): Ditto.
+        (WebCore::EventHandler::platformNotifyIfEndGesture): Ditto.
+        (WebCore::EventHandler::widgetDidHandleWheelEvent): Renamed from passWheelEventToWidget.
+        (WebCore::EventHandler::widgetForEventTarget): Converted from static function to static
+        method so it can be shared with EventHandlerMac.
+        (WebCore::scrollViewForEventTarget): Deleted.
+        * page/mac/EventHandlerWin.cpp: Rename passWheelEventToWidget to widgetDidHandleWheelEvent.
+        * platform/ScrollableArea.cpp:
+        * platform/ScrollableArea.h:
+        (WebCore::ScrollableArea::createWeakPtr): Added.
+        * platform/Widget.h:
+        (WebCore::ScrollableArea::createWeakPtr): Added.
+
 2016-04-11  Dean Jackson  <[email protected]>
 
         putImageData needs to premultiply input

Modified: trunk/Source/WebCore/page/EventHandler.cpp (199330 => 199331)


--- trunk/Source/WebCore/page/EventHandler.cpp	2016-04-12 02:57:03 UTC (rev 199330)
+++ trunk/Source/WebCore/page/EventHandler.cpp	2016-04-12 03:07:18 UTC (rev 199331)
@@ -2559,7 +2559,7 @@
 
 #if !PLATFORM(MAC)
 
-void EventHandler::platformPrepareForWheelEvents(const PlatformWheelEvent&, const HitTestResult&, RefPtr<Element>&, RefPtr<ContainerNode>&, ScrollableArea*&, bool&)
+void EventHandler::platformPrepareForWheelEvents(const PlatformWheelEvent&, const HitTestResult&, RefPtr<Element>&, RefPtr<ContainerNode>&, WeakPtr<ScrollableArea>&, bool&)
 {
 }
 
@@ -2568,7 +2568,7 @@
     m_frame.mainFrame().wheelEventDeltaFilter()->updateFromDelta(FloatSize(event.deltaX(), event.deltaY()));
 }
 
-bool EventHandler::platformCompleteWheelEvent(const PlatformWheelEvent& event, ContainerNode*, ScrollableArea*)
+bool EventHandler::platformCompleteWheelEvent(const PlatformWheelEvent& event, ContainerNode*, const WeakPtr<ScrollableArea>&)
 {
     // We do another check on the frame view because the event handler can run JS which results in the frame getting destroyed.
     FrameView* view = m_frame.view();
@@ -2583,7 +2583,7 @@
     return true;
 }
 
-void EventHandler::platformNotifyIfEndGesture(const PlatformWheelEvent&, ScrollableArea*)
+void EventHandler::platformNotifyIfEndGesture(const PlatformWheelEvent&, const WeakPtr<ScrollableArea>&)
 {
 }
 
@@ -2598,18 +2598,46 @@
 }
 #endif
 
-static Widget* widgetForElement(const Element& element)
+Widget* EventHandler::widgetForEventTarget(Element* eventTarget)
 {
-    RenderElement* target = element.renderer();
-    if (!target)
+    if (!eventTarget)
         return nullptr;
 
+    auto* target = eventTarget->renderer();
     if (!is<RenderWidget>(target))
         return nullptr;
 
     return downcast<RenderWidget>(*target).widget();
 }
 
+static WeakPtr<Widget> widgetForElement(const Element& element)
+{
+    auto target = element.renderer();
+    if (!is<RenderWidget>(target) || !downcast<RenderWidget>(*target).widget())
+        return { };
+
+    return downcast<RenderWidget>(*target).widget()->createWeakPtr();
+}
+
+bool EventHandler::completeWidgetWheelEvent(const PlatformWheelEvent& event, const WeakPtr<Widget>& widget, const WeakPtr<ScrollableArea>& scrollableArea, ContainerNode* scrollableContainer)
+{
+    m_isHandlingWheelEvent = false;
+    
+    // We do another check on the widget because the event handler can run JS which results in the frame getting destroyed.
+    if (!widget)
+        return false;
+    
+    if (scrollableArea)
+        scrollableArea->setScrolledProgrammatically(false);
+
+    platformNotifyIfEndGesture(event, scrollableArea);
+
+    if (!widget->platformWidget())
+        return true;
+
+    return platformCompletePlatformWidgetWheelEvent(event, *widget.get(), scrollableContainer);
+}
+
 bool EventHandler::handleWheelEvent(const PlatformWheelEvent& event)
 {
     RenderView* renderView = m_frame.contentRenderer();
@@ -2631,7 +2659,7 @@
 
     RefPtr<Element> element = result.innerElement();
     RefPtr<ContainerNode> scrollableContainer;
-    ScrollableArea* scrollableArea = nullptr;
+    WeakPtr<ScrollableArea> scrollableArea;
     bool isOverWidget = result.isOverWidget();
     platformPrepareForWheelEvents(event, result, element, scrollableContainer, scrollableArea, isOverWidget);
 
@@ -2650,21 +2678,9 @@
 
     if (element) {
         if (isOverWidget) {
-            Widget* widget = widgetForElement(*element);
-            if (widget && passWheelEventToWidget(event, *widget)) {
-                m_isHandlingWheelEvent = false;
-
-                // We do another check on the widget because the event handler can run JS which results in the frame getting destroyed.
-                Widget* widget = widgetForElement(*element);
-                if (!widget)
-                    return false;
-
-                if (scrollableArea)
-                    scrollableArea->setScrolledProgrammatically(false);
-                platformNotifyIfEndGesture(adjustedEvent, scrollableArea);
-                if (!widget->platformWidget())
-                    return true;
-                return platformCompletePlatformWidgetWheelEvent(event, *widget, scrollableContainer.get());
+            if (WeakPtr<Widget> widget = widgetForElement(*element)) {
+                if (widgetDidHandleWheelEvent(event, *widget.get()))
+                    return completeWidgetWheelEvent(adjustedEvent, widget, scrollableArea, scrollableContainer.get());
             }
         }
 

Modified: trunk/Source/WebCore/page/EventHandler.h (199330 => 199331)


--- trunk/Source/WebCore/page/EventHandler.h	2016-04-12 02:57:03 UTC (rev 199330)
+++ trunk/Source/WebCore/page/EventHandler.h	2016-04-12 03:07:18 UTC (rev 199331)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006-2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2006-2016 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -204,11 +204,11 @@
     void defaultWheelEventHandler(Node*, WheelEvent*);
     bool handlePasteGlobalSelection(const PlatformMouseEvent&);
 
-    void platformPrepareForWheelEvents(const PlatformWheelEvent&, const HitTestResult&, RefPtr<Element>& eventTarget, RefPtr<ContainerNode>& scrollableContainer, ScrollableArea*&, bool& isOverWidget);
+    void platformPrepareForWheelEvents(const PlatformWheelEvent&, const HitTestResult&, RefPtr<Element>& eventTarget, RefPtr<ContainerNode>& scrollableContainer, WeakPtr<ScrollableArea>&, bool& isOverWidget);
     void platformRecordWheelEvent(const PlatformWheelEvent&);
-    bool platformCompleteWheelEvent(const PlatformWheelEvent&, ContainerNode* scrollableContainer, ScrollableArea*);
+    bool platformCompleteWheelEvent(const PlatformWheelEvent&, ContainerNode* scrollableContainer, const WeakPtr<ScrollableArea>&);
     bool platformCompletePlatformWidgetWheelEvent(const PlatformWheelEvent&, const Widget&, ContainerNode* scrollableContainer);
-    void platformNotifyIfEndGesture(const PlatformWheelEvent&, ScrollableArea*);
+    void platformNotifyIfEndGesture(const PlatformWheelEvent&, const WeakPtr<ScrollableArea>&);
 
 #if ENABLE(IOS_TOUCH_EVENTS) || ENABLE(IOS_GESTURE_EVENTS)
     typedef Vector<RefPtr<Touch>> TouchArray;
@@ -318,6 +318,8 @@
     WEBCORE_EXPORT void setImmediateActionStage(ImmediateActionStage stage);
     ImmediateActionStage immediateActionStage() const { return m_immediateActionStage; }
 
+    static Widget* widgetForEventTarget(Element* eventTarget);
+
 private:
 #if ENABLE(DRAG_SUPPORT)
     static DragState& dragState();
@@ -415,7 +417,8 @@
     bool passWidgetMouseDownEventToWidget(RenderWidget*);
 
     bool passMouseDownEventToWidget(Widget*);
-    bool passWheelEventToWidget(const PlatformWheelEvent&, Widget&);
+    bool widgetDidHandleWheelEvent(const PlatformWheelEvent&, Widget&);
+    bool completeWidgetWheelEvent(const PlatformWheelEvent&, const WeakPtr<Widget>&, const WeakPtr<ScrollableArea>&, ContainerNode*);
 
     void defaultSpaceEventHandler(KeyboardEvent*);
     void defaultBackspaceEventHandler(KeyboardEvent*);

Modified: trunk/Source/WebCore/page/efl/EventHandlerEfl.cpp (199330 => 199331)


--- trunk/Source/WebCore/page/efl/EventHandlerEfl.cpp	2016-04-12 02:57:03 UTC (rev 199330)
+++ trunk/Source/WebCore/page/efl/EventHandlerEfl.cpp	2016-04-12 03:07:18 UTC (rev 199331)
@@ -87,7 +87,7 @@
     return false;
 }
 
-bool EventHandler::passWheelEventToWidget(const PlatformWheelEvent& event, Widget& widget)
+bool EventHandler::widgetDidHandleWheelEvent(const PlatformWheelEvent& event, Widget& widget)
 {
     if (!is<FrameView>(widget))
         return false;

Modified: trunk/Source/WebCore/page/gtk/EventHandlerGtk.cpp (199330 => 199331)


--- trunk/Source/WebCore/page/gtk/EventHandlerGtk.cpp	2016-04-12 02:57:03 UTC (rev 199330)
+++ trunk/Source/WebCore/page/gtk/EventHandlerGtk.cpp	2016-04-12 03:07:18 UTC (rev 199331)
@@ -87,7 +87,7 @@
     return false;
 }
 
-bool EventHandler::passWheelEventToWidget(const PlatformWheelEvent& event, Widget& widget)
+bool EventHandler::widgetDidHandleWheelEvent(const PlatformWheelEvent& event, Widget& widget)
 {
     if (!is<FrameView>(widget))
         return false;

Modified: trunk/Source/WebCore/page/ios/EventHandlerIOS.mm (199330 => 199331)


--- trunk/Source/WebCore/page/ios/EventHandlerIOS.mm	2016-04-12 02:57:03 UTC (rev 199330)
+++ trunk/Source/WebCore/page/ios/EventHandlerIOS.mm	2016-04-12 03:07:18 UTC (rev 199331)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2006-2016 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -406,7 +406,7 @@
     return false;
 }
 
-bool EventHandler::passWheelEventToWidget(const PlatformWheelEvent&, Widget& widget)
+bool EventHandler::widgetDidHandleWheelEvent(const PlatformWheelEvent&, Widget& widget)
 {
     BEGIN_BLOCK_OBJC_EXCEPTIONS;
 

Modified: trunk/Source/WebCore/page/mac/EventHandlerMac.mm (199330 => 199331)


--- trunk/Source/WebCore/page/mac/EventHandlerMac.mm	2016-04-12 02:57:03 UTC (rev 199330)
+++ trunk/Source/WebCore/page/mac/EventHandlerMac.mm	2016-04-12 03:07:18 UTC (rev 199331)
@@ -463,7 +463,7 @@
         [self release];
 }
 
-bool EventHandler::passWheelEventToWidget(const PlatformWheelEvent& wheelEvent, Widget& widget)
+bool EventHandler::widgetDidHandleWheelEvent(const PlatformWheelEvent& wheelEvent, Widget& widget)
 {
     BEGIN_BLOCK_OBJC_EXCEPTIONS;
 
@@ -855,33 +855,18 @@
     return area.scrolledToTop();
 }
 
-static Widget* widgetForEventTarget(Element* eventTarget)
+static WeakPtr<ScrollableArea> scrollableAreaForEventTarget(Element* eventTarget)
 {
-    if (!eventTarget)
-        return nullptr;
-    
-    auto* target = eventTarget->renderer();
-    if (!is<RenderWidget>(target))
-        return nullptr;
-    
-    return downcast<RenderWidget>(*target).widget();
-}
+    auto* widget = EventHandler::widgetForEventTarget(eventTarget);
+    if (!widget || !widget->isScrollView())
+        return { };
 
-static ScrollView* scrollViewForEventTarget(Element* eventTarget)
-{
-    Widget* widget = widgetForEventTarget(eventTarget);
-    if (!widget)
-        return nullptr;
-    
-    if (!widget->isScrollView())
-        return nullptr;
-    
-    return reinterpret_cast<ScrollView*>(widget);
+    return static_cast<ScrollableArea*>(static_cast<ScrollView*>(widget))->createWeakPtr();
 }
     
 static bool eventTargetIsPlatformWidget(Element* eventTarget)
 {
-    Widget* widget = widgetForEventTarget(eventTarget);
+    Widget* widget = EventHandler::widgetForEventTarget(eventTarget);
     if (!widget)
         return false;
     
@@ -917,14 +902,17 @@
     return false;
 }
 
-static ScrollableArea* scrollableAreaForContainerNode(ContainerNode& container)
+static WeakPtr<ScrollableArea> scrollableAreaForContainerNode(ContainerNode& container)
 {
-    ScrollableArea* scrollableArea = nullptr;
+    auto box = container.renderBox();
+    if (!box)
+        return { };
 
-    if (RenderBox* box = container.renderBox())
-        scrollableArea = scrollableAreaForBox(*box);
-
-    return scrollableArea;
+    auto scrollableAreaPtr = scrollableAreaForBox(*box);
+    if (!scrollableAreaPtr)
+        return { };
+    
+    return scrollableAreaPtr->createWeakPtr();
 }
 
 static bool latchedToFrameOrBody(ContainerNode& container)
@@ -957,27 +945,25 @@
     }
 }
 
-void EventHandler::platformPrepareForWheelEvents(const PlatformWheelEvent& wheelEvent, const HitTestResult& result, RefPtr<Element>& wheelEventTarget, RefPtr<ContainerNode>& scrollableContainer, ScrollableArea*& scrollableArea, bool& isOverWidget)
+void EventHandler::platformPrepareForWheelEvents(const PlatformWheelEvent& wheelEvent, const HitTestResult& result, RefPtr<Element>& wheelEventTarget, RefPtr<ContainerNode>& scrollableContainer, WeakPtr<ScrollableArea>& scrollableArea, bool& isOverWidget)
 {
     clearOrScheduleClearingLatchedStateIfNeeded(wheelEvent);
 
     FrameView* view = m_frame.view();
 
-    scrollableContainer = nullptr;
-    scrollableArea = nullptr;
     if (!view)
         scrollableContainer = wheelEventTarget;
     else {
         if (eventTargetIsPlatformWidget(wheelEventTarget.get())) {
             scrollableContainer = wheelEventTarget;
-            scrollableArea = scrollViewForEventTarget(wheelEventTarget.get());
+            scrollableArea = scrollableAreaForEventTarget(wheelEventTarget.get());
         } else {
             scrollableContainer = findEnclosingScrollableContainer(wheelEventTarget.get(), wheelEvent.deltaX(), wheelEvent.deltaY());
             if (scrollableContainer && !is<HTMLIFrameElement>(wheelEventTarget.get()))
                 scrollableArea = scrollableAreaForContainerNode(*scrollableContainer);
             else {
                 scrollableContainer = view->frame().document()->bodyOrFrameset();
-                scrollableArea = view;
+                scrollableArea = static_cast<ScrollableArea*>(view)->createWeakPtr();
             }
         }
     }
@@ -989,7 +975,7 @@
     ScrollLatchingState* latchingState = m_frame.mainFrame().latchingState();
     if (wheelEvent.shouldConsiderLatching()) {
         if (scrollableContainer && scrollableArea) {
-            bool startingAtScrollLimit = scrolledToEdgeInDominantDirection(*scrollableContainer, *scrollableArea, wheelEvent.deltaX(), wheelEvent.deltaY());
+            bool startingAtScrollLimit = scrolledToEdgeInDominantDirection(*scrollableContainer, *scrollableArea.get(), wheelEvent.deltaX(), wheelEvent.deltaY());
             if (!startingAtScrollLimit) {
                 m_frame.mainFrame().pushNewLatchingState();
                 latchingState = m_frame.mainFrame().latchingState();
@@ -1047,7 +1033,7 @@
     return latchingState->frame() ? latchingState->frame()->view() : frame.view();
 }
 
-bool EventHandler::platformCompleteWheelEvent(const PlatformWheelEvent& wheelEvent, ContainerNode* scrollableContainer, ScrollableArea* scrollableArea)
+bool EventHandler::platformCompleteWheelEvent(const PlatformWheelEvent& wheelEvent, ContainerNode* scrollableContainer, const WeakPtr<ScrollableArea>& scrollableArea)
 {
     FrameView* view = m_frame.view();
     // We do another check on the frame view because the event handler can run JS which results in the frame getting destroyed.
@@ -1060,7 +1046,7 @@
         m_isHandlingWheelEvent = false;
 
         // WebKit2 code path
-        if (!frameHasPlatformWidget(m_frame) && !latchingState->startedGestureAtScrollLimit() && scrollableContainer == latchingState->scrollableContainer() && scrollableArea && view != scrollableArea) {
+        if (!frameHasPlatformWidget(m_frame) && !latchingState->startedGestureAtScrollLimit() && scrollableContainer == latchingState->scrollableContainer() && scrollableArea && view != scrollableArea.get()) {
             // If we did not start at the scroll limit, do not pass the event on to be handled by enclosing scrollable regions.
             return true;
         }
@@ -1078,7 +1064,7 @@
         }
 
         // If the platform widget is handling the event, we always want to return false.
-        if (scrollableArea == view && view->platformWidget())
+        if (scrollableArea.get() == view && view->platformWidget())
             didHandleWheelEvent = false;
         
         return didHandleWheelEvent;
@@ -1105,7 +1091,7 @@
     return false;
 }
 
-void EventHandler::platformNotifyIfEndGesture(const PlatformWheelEvent& wheelEvent, ScrollableArea* scrollableArea)
+void EventHandler::platformNotifyIfEndGesture(const PlatformWheelEvent& wheelEvent, const WeakPtr<ScrollableArea>& scrollableArea)
 {
     if (!scrollableArea)
         return;

Modified: trunk/Source/WebCore/page/win/EventHandlerWin.cpp (199330 => 199331)


--- trunk/Source/WebCore/page/win/EventHandlerWin.cpp	2016-04-12 02:57:03 UTC (rev 199330)
+++ trunk/Source/WebCore/page/win/EventHandlerWin.cpp	2016-04-12 03:07:18 UTC (rev 199331)
@@ -73,7 +73,7 @@
     return true;
 }
 
-bool EventHandler::passWheelEventToWidget(const PlatformWheelEvent& wheelEvent, Widget& widget)
+bool EventHandler::widgetDidHandleWheelEvent(const PlatformWheelEvent& wheelEvent, Widget& widget)
 {
     if (!is<FrameView>(widget))
         return false;

Modified: trunk/Source/WebCore/platform/ScrollableArea.cpp (199330 => 199331)


--- trunk/Source/WebCore/platform/ScrollableArea.cpp	2016-04-12 02:57:03 UTC (rev 199330)
+++ trunk/Source/WebCore/platform/ScrollableArea.cpp	2016-04-12 03:07:18 UTC (rev 199331)
@@ -48,10 +48,10 @@
 struct SameSizeAsScrollableArea {
     virtual ~SameSizeAsScrollableArea();
 #if ENABLE(CSS_SCROLL_SNAP)
-    void* pointers[3];
+    void* pointers[4];
     unsigned currentIndices[2];
 #else
-    void* pointer;
+    void* pointer[2];
 #endif
     IntPoint origin;
     unsigned bitfields : 16;

Modified: trunk/Source/WebCore/platform/ScrollableArea.h (199330 => 199331)


--- trunk/Source/WebCore/platform/ScrollableArea.h	2016-04-12 02:57:03 UTC (rev 199330)
+++ trunk/Source/WebCore/platform/ScrollableArea.h	2016-04-12 03:07:18 UTC (rev 199331)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008, 2011, 2014-2015 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2008-2016 Apple Inc. All Rights Reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -28,6 +28,7 @@
 
 #include "Scrollbar.h"
 #include <wtf/Vector.h>
+#include <wtf/WeakPtr.h>
 
 namespace WebCore {
 
@@ -63,6 +64,8 @@
 
     WEBCORE_EXPORT bool handleWheelEvent(const PlatformWheelEvent&);
 
+    WeakPtr<ScrollableArea> createWeakPtr() { return m_weakPtrFactory.createWeakPtr(); }
+
 #if ENABLE(CSS_SCROLL_SNAP)
     const Vector<LayoutUnit>* horizontalSnapOffsets() const { return m_horizontalSnapOffsets.get(); };
     const Vector<LayoutUnit>* verticalSnapOffsets() const { return m_verticalSnapOffsets.get(); };
@@ -349,6 +352,8 @@
 
     mutable std::unique_ptr<ScrollAnimator> m_scrollAnimator;
 
+    WeakPtrFactory<ScrollableArea> m_weakPtrFactory { this };
+
 #if ENABLE(CSS_SCROLL_SNAP)
     std::unique_ptr<Vector<LayoutUnit>> m_horizontalSnapOffsets;
     std::unique_ptr<Vector<LayoutUnit>> m_verticalSnapOffsets;

Modified: trunk/Source/WebCore/platform/Widget.h (199330 => 199331)


--- trunk/Source/WebCore/platform/Widget.h	2016-04-12 02:57:03 UTC (rev 199330)
+++ trunk/Source/WebCore/platform/Widget.h	2016-04-12 03:07:18 UTC (rev 199331)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2004, 2005, 2006 Apple Inc.  All rights reserved.
+ * Copyright (C) 2004-2016 Apple Inc.  All rights reserved.
  * Copyright (C) 2008 Collabora Ltd.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -38,6 +38,7 @@
 #include <wtf/Forward.h>
 #include <wtf/RefCounted.h>
 #include <wtf/TypeCasts.h>
+#include <wtf/WeakPtr.h>
 
 #if PLATFORM(COCOA)
 #include <wtf/RetainPtr.h>
@@ -191,6 +192,8 @@
     WEBCORE_EXPORT virtual IntPoint convertToContainingView(const IntPoint&) const;
     WEBCORE_EXPORT virtual IntPoint convertFromContainingView(const IntPoint&) const;
 
+    WeakPtr<Widget> createWeakPtr() { return m_weakPtrFactory.createWeakPtr(); }
+
 private:
     void init(PlatformWidget); // Must be called by all Widget constructors to initialize cross-platform data.
 
@@ -212,6 +215,7 @@
 #else
     RetainPtr<NSView> m_widget;
 #endif
+    WeakPtrFactory<Widget> m_weakPtrFactory { this };
     bool m_selfVisible;
     bool m_parentVisible;
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to