Use PlatformKeyboardEvent in KeyboardScrollingAnimator to fix a layering violation
https://bugs.webkit.org/show_bug.cgi?id=231711
Reviewed by Beth Dakin.
KeyboardScrollingAnimator lives in platform/ so should not know about dom/KeyboardEvent.
Have it use PlatformKeyboardEvent instead.
* page/EventHandler.cpp:
(WebCore::EventHandler::stopKeyboardScrolling):
(WebCore::EventHandler::startKeyboardScrolling): Null check the view. Use the platform event.
* platform/KeyboardScrollingAnimator.cpp:
(WebCore::keyboardScrollingKeyFromEvent):
(WebCore::KeyboardScrollingAnimator::keyboardScrollForKeyboardEvent const):
(WebCore::KeyboardScrollingAnimator::beginKeyboardScrollGesture):
* platform/KeyboardScrollingAnimator.h:
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@284146 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index e39fa05..981ae0b 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,22 @@
+2021-10-13 Simon Fraser <simon.fraser@apple.com>
+
+ Use PlatformKeyboardEvent in KeyboardScrollingAnimator to fix a layering violation
+ https://bugs.webkit.org/show_bug.cgi?id=231711
+
+ Reviewed by Beth Dakin.
+
+ KeyboardScrollingAnimator lives in platform/ so should not know about dom/KeyboardEvent.
+ Have it use PlatformKeyboardEvent instead.
+
+ * page/EventHandler.cpp:
+ (WebCore::EventHandler::stopKeyboardScrolling):
+ (WebCore::EventHandler::startKeyboardScrolling): Null check the view. Use the platform event.
+ * platform/KeyboardScrollingAnimator.cpp:
+ (WebCore::keyboardScrollingKeyFromEvent):
+ (WebCore::KeyboardScrollingAnimator::keyboardScrollForKeyboardEvent const):
+ (WebCore::KeyboardScrollingAnimator::beginKeyboardScrollGesture):
+ * platform/KeyboardScrollingAnimator.h:
+
2021-10-13 Megan Gardner <megan_gardner@apple.com>
Scroll To Text Fragment directive parsing
diff --git a/Source/WebCore/page/EventHandler.cpp b/Source/WebCore/page/EventHandler.cpp
index 46d9ff8..61935b3 100644
--- a/Source/WebCore/page/EventHandler.cpp
+++ b/Source/WebCore/page/EventHandler.cpp
@@ -4321,10 +4321,11 @@
void EventHandler::stopKeyboardScrolling()
{
Ref protectedFrame = m_frame;
- FrameView* view = m_frame.view();
+ auto* view = m_frame.view();
+ if (!view)
+ return;
- KeyboardScrollingAnimator* animator = view->scrollAnimator().keyboardScrollingAnimator();
-
+ auto* animator = view->scrollAnimator().keyboardScrollingAnimator();
if (animator)
animator->handleKeyUpEvent();
}
@@ -4335,12 +4336,14 @@
return false;
Ref protectedFrame = m_frame;
- FrameView* view = m_frame.view();
+ auto* view = m_frame.view();
+ if (!view)
+ return false;
- KeyboardScrollingAnimator* animator = view->scrollAnimator().keyboardScrollingAnimator();
-
- if (animator)
- return animator->beginKeyboardScrollGesture(event);
+ auto* animator = view->scrollAnimator().keyboardScrollingAnimator();
+ auto* platformEvent = event.underlyingPlatformEvent();
+ if (animator && platformEvent)
+ return animator->beginKeyboardScrollGesture(*platformEvent);
return false;
}
diff --git a/Source/WebCore/platform/KeyboardScrollingAnimator.cpp b/Source/WebCore/platform/KeyboardScrollingAnimator.cpp
index fd8f0fc..cacd043 100644
--- a/Source/WebCore/platform/KeyboardScrollingAnimator.cpp
+++ b/Source/WebCore/platform/KeyboardScrollingAnimator.cpp
@@ -27,12 +27,23 @@
#include "KeyboardScrollingAnimator.h"
#include "EventNames.h"
+#include "PlatformKeyboardEvent.h"
#include "ScrollTypes.h"
#include "ScrollableArea.h"
#include "WritingMode.h"
namespace WebCore {
+enum class KeyboardScrollingKey : uint8_t {
+ LeftArrow,
+ RightArrow,
+ UpArrow,
+ DownArrow,
+ Space,
+ PageUp,
+ PageDown
+};
+
KeyboardScrollingAnimator::KeyboardScrollingAnimator(ScrollAnimator& scrollAnimator, ScrollingEffectsController& scrollController)
: m_scrollAnimator(scrollAnimator)
, m_scrollController(scrollController)
@@ -158,63 +169,68 @@
return 0;
}
-std::optional<KeyboardScroll> KeyboardScrollingAnimator::keyboardScrollForKeyboardEvent(KeyboardEvent& event) const
+static std::optional<KeyboardScrollingKey> keyboardScrollingKeyFromEvent(const PlatformKeyboardEvent& event)
{
+ auto identifier = event.keyIdentifier();
+ if (identifier == "Left")
+ return KeyboardScrollingKey::LeftArrow;
+ if (identifier == "Right")
+ return KeyboardScrollingKey::RightArrow;
+ if (identifier == "Up")
+ return KeyboardScrollingKey::UpArrow;
+ if (identifier == "Down")
+ return KeyboardScrollingKey::DownArrow;
+ if (identifier == "PageUp")
+ return KeyboardScrollingKey::PageUp;
+ if (identifier == "PageDown")
+ return KeyboardScrollingKey::PageDown;
+
+ if (event.text().characterStartingAt(0) == ' ')
+ return KeyboardScrollingKey::Space;
+
+ return { };
+}
+
+std::optional<KeyboardScroll> KeyboardScrollingAnimator::keyboardScrollForKeyboardEvent(const PlatformKeyboardEvent& event) const
+{
+ auto key = keyboardScrollingKeyFromEvent(event);
+ if (!key)
+ return { };
+
// FIXME (bug 227459): This logic does not account for writing-mode.
-
- enum class Key : uint8_t { LeftArrow, RightArrow, UpArrow, DownArrow, Space, PageUp, PageDown };
-
- Key key;
- if (event.keyIdentifier() == "Left")
- key = Key::LeftArrow;
- else if (event.keyIdentifier() == "Right")
- key = Key::RightArrow;
- else if (event.keyIdentifier() == "Up")
- key = Key::UpArrow;
- else if (event.keyIdentifier() == "Down")
- key = Key::DownArrow;
- else if (event.charCode() == ' ')
- key = Key::Space;
- else if (event.keyIdentifier() == "PageUp")
- key = Key::PageUp;
- else if (event.keyIdentifier() == "PageDown")
- key = Key::PageDown;
- else
- return std::nullopt;
-
auto granularity = [&] {
- switch (key) {
- case Key::LeftArrow:
- case Key::RightArrow:
+ switch (key.value()) {
+ case KeyboardScrollingKey::LeftArrow:
+ case KeyboardScrollingKey::RightArrow:
return event.altKey() ? ScrollGranularity::ScrollByPage : ScrollGranularity::ScrollByLine;
- case Key::UpArrow:
- case Key::DownArrow:
+ case KeyboardScrollingKey::UpArrow:
+ case KeyboardScrollingKey::DownArrow:
if (event.metaKey())
return ScrollGranularity::ScrollByDocument;
if (event.altKey())
return ScrollGranularity::ScrollByPage;
return ScrollGranularity::ScrollByLine;
- case Key::Space:
- case Key::PageUp:
- case Key::PageDown:
+ case KeyboardScrollingKey::Space:
+ case KeyboardScrollingKey::PageUp:
+ case KeyboardScrollingKey::PageDown:
return ScrollGranularity::ScrollByPage;
};
RELEASE_ASSERT_NOT_REACHED();
}();
auto direction = [&] {
- switch (key) {
- case Key::LeftArrow:
+ switch (key.value()) {
+ case KeyboardScrollingKey::LeftArrow:
return ScrollDirection::ScrollLeft;
- case Key::RightArrow:
+ case KeyboardScrollingKey::RightArrow:
return ScrollDirection::ScrollRight;
- case Key::UpArrow:
- case Key::PageUp:
+ case KeyboardScrollingKey::UpArrow:
+ case KeyboardScrollingKey::PageUp:
return ScrollDirection::ScrollUp;
- case Key::DownArrow:
- case Key::PageDown:
+ case KeyboardScrollingKey::DownArrow:
+ case KeyboardScrollingKey::PageDown:
return ScrollDirection::ScrollDown;
- case Key::Space:
+ case KeyboardScrollingKey::Space:
return event.shiftKey() ? ScrollDirection::ScrollUp : ScrollDirection::ScrollDown;
}
RELEASE_ASSERT_NOT_REACHED();
@@ -236,16 +252,16 @@
return scroll;
}
-bool KeyboardScrollingAnimator::beginKeyboardScrollGesture(KeyboardEvent& event)
+bool KeyboardScrollingAnimator::beginKeyboardScrollGesture(const PlatformKeyboardEvent& event)
{
auto scroll = keyboardScrollForKeyboardEvent(event);
-
if (!scroll)
return false;
m_currentKeyboardScroll = scroll;
- if (!(event.type() == eventNames().keydownEvent || event.type() == eventNames().keypressEvent))
+ // PlatformEvent::Char is a "keypress" event.
+ if (!(event.type() == PlatformEvent::RawKeyDown || event.type() == PlatformEvent::Char))
return false;
if (m_scrollTriggeringKeyIsPressed)
diff --git a/Source/WebCore/platform/KeyboardScrollingAnimator.h b/Source/WebCore/platform/KeyboardScrollingAnimator.h
index 3c9814f..485abb0 100644
--- a/Source/WebCore/platform/KeyboardScrollingAnimator.h
+++ b/Source/WebCore/platform/KeyboardScrollingAnimator.h
@@ -25,27 +25,28 @@
#pragma once
-#include "KeyboardEvent.h" // FIXME: This is a layering violation.
#include "KeyboardScroll.h" // FIXME: This is a layering violation.
#include "RectEdges.h"
#include "ScrollAnimator.h"
namespace WebCore {
+class PlatformKeyboardEvent;
+
class KeyboardScrollingAnimator {
WTF_MAKE_NONCOPYABLE(KeyboardScrollingAnimator);
WTF_MAKE_FAST_ALLOCATED;
public:
KeyboardScrollingAnimator(ScrollAnimator&, ScrollingEffectsController&);
- bool beginKeyboardScrollGesture(KeyboardEvent&);
+ bool beginKeyboardScrollGesture(const PlatformKeyboardEvent&);
void handleKeyUpEvent();
void updateKeyboardScrollPosition(MonotonicTime);
private:
void stopKeyboardScrollAnimation();
RectEdges<bool> scrollableDirectionsFromPosition(FloatPoint) const;
- std::optional<KeyboardScroll> keyboardScrollForKeyboardEvent(KeyboardEvent&) const;
+ std::optional<KeyboardScroll> keyboardScrollForKeyboardEvent(const PlatformKeyboardEvent&) const;
float scrollDistance(ScrollDirection, ScrollGranularity) const;
ScrollAnimator& m_scrollAnimator;