Changeset 235860 in webkit


Ignore:
Timestamp:
Sep 10, 2018 2:02:50 PM (6 years ago)
Author:
dbates@webkit.org
Message:

[iOS] Arrow keys do not dispatch DOM events to non-editable elements
https://bugs.webkit.org/show_bug.cgi?id=189389

Reviewed by Simon Fraser.

Source/WebCore:

On iOS the arrow keys are identified by special multi character key strings: UIKeyInput{Up,
Down, Left, Right}Arrow as opposed to special key codes as on Mac. When converting the iOS-
specific WebEvent we need to take care to recognize when the key string for the event is
one of these special key strings when computing key code, character code, and key identifier
properties for the WebCore platform-specific event. These details will be included in
the corresponding DOM keyboard events that are dispatched when the arrow keys are pressed.

  • SourcesCocoa.txt:
  • WebCore.xcodeproj/project.pbxproj:

Mark file PlatformEventFactoryIOS as @no-unify as it is not compatible with the unified sources
build strategy given its use of wtf/cocoa/SoftLinking.h macros.

  • platform/ios/PlatformEventFactoryIOS.h:
  • platform/ios/PlatformEventFactoryIOS.mm:

(WebCore::convertSpecialKeyToCharCode): Manufacture the appropriate character code for an
event that represents an arrow key. Otherwise, return std::nullopt to indicate that the
event is not for an arrow key.
(WebCore::keyCodeForEvent): Manufacture the appropriate Windows virtual key code for an
event that represents an arrow key. Otherwise, do what we do now and return the key code
associated with the WebEvent.
(WebCore::keyIdentifierForKeyEvent): Modified to test if the event is for an arrow key
and return the appropriate key identifier.
(WebCore::keyForKeyEvent): Modified to test if the event is for an arrow key
and return the appropriate character code.
(WebCore::codeForKeyEvent): Modified to call keyCodeForEvent(), which knows how to account
for events that represent arrow keys.
(WebCore::PlatformKeyboardEventBuilder::PlatformKeyboardEventBuilder):

Source/WebKit:

Use WebCore::keyCodeForEvent() to retrieve the key code for a WebEvent instead of querying
the key code from the WebEvent directly. The function WebCore::keyCodeForEvent() knows how
to compute the key code for an event that represents an arrow key.

  • Shared/ios/WebIOSEventFactory.mm:

(WebIOSEventFactory::createWebKeyboardEvent):

LayoutTests:

Update expected result now that we compute the correct keyIdentifier, keycode, and which properties
for DOM keyboard events dispatched when the arrow keys are pressed.

  • fast/events/ios/keydown-keyup-in-non-editable-content-expected.txt:
Location:
trunk
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r235858 r235860  
     12018-09-10  Daniel Bates  <dabates@apple.com>
     2
     3        [iOS] Arrow keys do not dispatch DOM events to non-editable elements
     4        https://bugs.webkit.org/show_bug.cgi?id=189389
     5
     6        Reviewed by Simon Fraser.
     7
     8        Update expected result now that we compute the correct keyIdentifier, keycode, and which properties
     9        for DOM keyboard events dispatched when the arrow keys are pressed.
     10
     11        * fast/events/ios/keydown-keyup-in-non-editable-content-expected.txt:
     12
    1132018-09-10  Daniel Bates  <dabates@apple.com>
    214
  • trunk/LayoutTests/fast/events/ios/keydown-keyup-in-non-editable-content-expected.txt

    r235858 r235860  
    9595type: keydown, key: Enter, code: Enter, keyIdentifier: Enter, keyCode: 13, charCode: 0, keyCode: 13, which: 13
    9696type: keyup, key: Dead, code: Unidentified, keyIdentifier: Unidentified, keyCode: 0, charCode: 0, keyCode: 0, which: 0
    97 type: keydown, key: UIKeyInputUpArrow, code: Unidentified, keyIdentifier: Unidentified, keyCode: 0, charCode: 0, keyCode: 0, which: 0
    98 type: keyup, key: UIKeyInputUpArrow, code: Unidentified, keyIdentifier: Unidentified, keyCode: 0, charCode: 0, keyCode: 0, which: 0
    99 type: keyup, key: UIKeyInputDownArrow, code: Unidentified, keyIdentifier: Unidentified, keyCode: 0, charCode: 0, keyCode: 0, which: 0
    100 type: keydown, key: UIKeyInputLeftArrow, code: Unidentified, keyIdentifier: Unidentified, keyCode: 0, charCode: 0, keyCode: 0, which: 0
    101 type: keyup, key: UIKeyInputLeftArrow, code: Unidentified, keyIdentifier: Unidentified, keyCode: 0, charCode: 0, keyCode: 0, which: 0
    102 type: keyup, key: UIKeyInputRightArrow, code: Unidentified, keyIdentifier: Unidentified, keyCode: 0, charCode: 0, keyCode: 0, which: 0
     97type: keydown, key: ArrowUp, code: ArrowUp, keyIdentifier: Up, keyCode: 38, charCode: 0, keyCode: 38, which: 38
     98type: keyup, key: ArrowUp, code: ArrowUp, keyIdentifier: Up, keyCode: 38, charCode: 0, keyCode: 38, which: 38
     99type: keyup, key: ArrowDown, code: ArrowDown, keyIdentifier: Down, keyCode: 40, charCode: 0, keyCode: 40, which: 40
     100type: keydown, key: ArrowLeft, code: ArrowLeft, keyIdentifier: Left, keyCode: 37, charCode: 0, keyCode: 37, which: 37
     101type: keyup, key: ArrowLeft, code: ArrowLeft, keyIdentifier: Left, keyCode: 37, charCode: 0, keyCode: 37, which: 37
     102type: keyup, key: ArrowRight, code: ArrowRight, keyIdentifier: Right, keyCode: 39, charCode: 0, keyCode: 39, which: 39
    103103
  • trunk/Source/WebCore/ChangeLog

    r235857 r235860  
     12018-09-10  Daniel Bates  <dabates@apple.com>
     2
     3        [iOS] Arrow keys do not dispatch DOM events to non-editable elements
     4        https://bugs.webkit.org/show_bug.cgi?id=189389
     5
     6        Reviewed by Simon Fraser.
     7
     8        On iOS the arrow keys are identified by special multi character key strings: UIKeyInput{Up,
     9        Down, Left, Right}Arrow as opposed to special key codes as on Mac. When converting the iOS-
     10        specific WebEvent we need to take care to recognize when the key string for the event is
     11        one of these special key strings when computing key code, character code, and key identifier
     12        properties for the WebCore platform-specific event. These details will be included in
     13        the corresponding DOM keyboard events that are dispatched when the arrow keys are pressed.
     14
     15        * SourcesCocoa.txt:
     16        * WebCore.xcodeproj/project.pbxproj:
     17        Mark file PlatformEventFactoryIOS as @no-unify as it is not compatible with the unified sources
     18        build strategy given its use of wtf/cocoa/SoftLinking.h macros.
     19
     20        * platform/ios/PlatformEventFactoryIOS.h:
     21        * platform/ios/PlatformEventFactoryIOS.mm:
     22        (WebCore::convertSpecialKeyToCharCode): Manufacture the appropriate character code for an
     23        event that represents an arrow key. Otherwise, return std::nullopt to indicate that the
     24        event is not for an arrow key.
     25        (WebCore::keyCodeForEvent): Manufacture the appropriate Windows virtual key code for an
     26        event that represents an arrow key. Otherwise, do what we do now and return the key code
     27        associated with the WebEvent.
     28        (WebCore::keyIdentifierForKeyEvent): Modified to test if the event is for an arrow key
     29        and return the appropriate key identifier.
     30        (WebCore::keyForKeyEvent): Modified to test if the event is for an arrow key
     31        and return the appropriate character code.
     32        (WebCore::codeForKeyEvent): Modified to call keyCodeForEvent(), which knows how to account
     33        for events that represent arrow keys.
     34        (WebCore::PlatformKeyboardEventBuilder::PlatformKeyboardEventBuilder):
     35
    1362018-09-10  Dan Bernstein  <mitz@apple.com>
    237
  • trunk/Source/WebCore/SourcesCocoa.txt

    r235748 r235860  
    386386platform/ios/LowPowerModeNotifierIOS.mm
    387387platform/ios/PasteboardIOS.mm
    388 platform/ios/PlatformEventFactoryIOS.mm
     388platform/ios/PlatformEventFactoryIOS.mm @no-unify
    389389platform/ios/PlatformPasteboardIOS.mm
    390390platform/ios/PlatformScreenIOS.mm
  • trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r235856 r235860  
    41254125                CE7B2DB51586ABAD0098B3FA /* TextAlternativeWithRange.h in Headers */ = {isa = PBXBuildFile; fileRef = CE7B2DB11586ABAD0098B3FA /* TextAlternativeWithRange.h */; settings = {ATTRIBUTES = (Private, ); }; };
    41264126                CE7E17831C83A49100AD06AF /* ContentSecurityPolicyHash.h in Headers */ = {isa = PBXBuildFile; fileRef = CE7E17821C83A49100AD06AF /* ContentSecurityPolicyHash.h */; settings = {ATTRIBUTES = (Private, ); }; };
     4127                CEA284662141E84900E407E8 /* PlatformEventFactoryIOS.mm in Sources */ = {isa = PBXBuildFile; fileRef = 26601EBE14B3B9AD0012C0FE /* PlatformEventFactoryIOS.mm */; };
    41274128                CEBB8C3320786DCB00039547 /* FetchIdioms.h in Headers */ = {isa = PBXBuildFile; fileRef = CEBB8C3120786DCB00039547 /* FetchIdioms.h */; };
    41284129                CECADFC7153778FF00E37068 /* DictationAlternative.h in Headers */ = {isa = PBXBuildFile; fileRef = CECADFC3153778FF00E37068 /* DictationAlternative.h */; settings = {ATTRIBUTES = (Private, ); }; };
     
    3156331564                                77A17A7112F28182004E02F6 /* OESVertexArrayObject.cpp in Sources */,
    3156431565                                DE5F86101FA238D9006DB63A /* PaymentMerchantSessionCocoa.mm in Sources */,
     31566                                CEA284662141E84900E407E8 /* PlatformEventFactoryIOS.mm in Sources */,
    3156531567                                AA12DF491743DF83004DAFDF /* PlatformSpeechSynthesizerIOS.mm in Sources */,
    3156631568                                CDA29A301CBF74D400901CCF /* PlaybackSessionInterfaceAVKit.mm in Sources */,
  • trunk/Source/WebCore/platform/ios/PlatformEventFactoryIOS.h

    r228531 r235860  
    5454WEBCORE_EXPORT String codeForKeyEvent(WebEvent *);
    5555WEBCORE_EXPORT String keyIdentifierForKeyEvent(WebEvent *);
     56WEBCORE_EXPORT int keyCodeForEvent(WebEvent *);
    5657
    5758} // namespace WebCore
  • trunk/Source/WebCore/platform/ios/PlatformEventFactoryIOS.mm

    r235560 r235860  
    3131#import "IntPoint.h"
    3232#import "KeyEventCocoa.h"
     33#import "KeyEventCodesIOS.h"
    3334#import "Logging.h"
    3435#import "WAKAppKitStubs.h"
    3536#import "WebEvent.h"
    3637#import "WindowsKeyboardCodes.h"
     38#import <UIKit/UIKit.h>
     39#import <wtf/Optional.h>
     40#import <wtf/SoftLinking.h>
    3741#import <wtf/WallTime.h>
     42
     43SOFT_LINK_FRAMEWORK(UIKit)
     44SOFT_LINK_CONSTANT(UIKit, UIKeyInputUpArrow, NSString *)
     45SOFT_LINK_CONSTANT(UIKit, UIKeyInputDownArrow, NSString *)
     46SOFT_LINK_CONSTANT(UIKit, UIKeyInputLeftArrow, NSString *)
     47SOFT_LINK_CONSTANT(UIKit, UIKeyInputRightArrow, NSString *)
     48
     49#define UIKeyInputUpArrow getUIKeyInputUpArrow()
     50#define UIKeyInputDownArrow getUIKeyInputDownArrow()
     51#define UIKeyInputLeftArrow getUIKeyInputLeftArrow()
     52#define UIKeyInputRightArrow getUIKeyInputRightArrow()
    3853
    3954namespace WebCore {
     
    8398}
    8499
     100static std::optional<int> convertSpecialKeyToCharCode(NSString *keyString)
     101{
     102    if ([keyString isEqualToString:UIKeyInputUpArrow])
     103        return NSUpArrowFunctionKey;
     104    if ([keyString isEqualToString:UIKeyInputDownArrow])
     105        return NSDownArrowFunctionKey;
     106    if ([keyString isEqualToString:UIKeyInputLeftArrow])
     107        return NSLeftArrowFunctionKey;
     108    if ([keyString isEqualToString:UIKeyInputRightArrow])
     109        return NSRightArrowFunctionKey;
     110    return std::nullopt;
     111}
     112
     113int keyCodeForEvent(WebEvent *event)
     114{
     115    if ([event.characters isEqualToString:UIKeyInputUpArrow])
     116        return VK_UP;
     117    if ([event.characters isEqualToString:UIKeyInputDownArrow])
     118        return VK_DOWN;
     119    if ([event.characters isEqualToString:UIKeyInputLeftArrow])
     120        return VK_LEFT;
     121    if ([event.characters isEqualToString:UIKeyInputRightArrow])
     122        return VK_RIGHT;
     123    return event.keyCode;
     124}
     125
    85126class PlatformMouseEventBuilder : public PlatformMouseEvent {
    86127public:
     
    126167String keyIdentifierForKeyEvent(WebEvent *event)
    127168{
    128     NSString *s = event.charactersIgnoringModifiers;
    129     if ([s length] != 1) {
    130         LOG(Events, "received an unexpected number of characters in key event: %u", [s length]);
    131         return "Unidentified";
    132     }
    133 
    134     return keyIdentifierForCharCode(CFStringGetCharacterAtIndex((CFStringRef)s, 0));
     169    NSString *characters = event.charactersIgnoringModifiers;
     170    if (auto specialKeyCharCode = convertSpecialKeyToCharCode(characters))
     171        return keyIdentifierForCharCode(*specialKeyCharCode);
     172    if ([characters length] != 1) {
     173        LOG(Events, "received an unexpected number of characters in key event: %u", [characters length]);
     174        return "Unidentified"_s;
     175    }
     176    return keyIdentifierForCharCode([characters characterAtIndex:0]);
    135177}
    136178
     
    139181    NSString *characters = event.characters;
    140182    auto length = [characters length];
    141 
    142183    // characters return an empty string for dead keys.
    143184    // https://developer.apple.com/reference/appkit/nsevent/1534183-characters
     
    145186    if (!length)
    146187        return "Dead"_s;
    147 
     188    if (auto specialKeyCharCode = convertSpecialKeyToCharCode(characters))
     189        return keyForCharCode(*specialKeyCharCode);
    148190    if (length > 1)
    149191        return characters;
    150 
    151192    return keyForCharCode([characters characterAtIndex:0]);
    152193}
     
    155196String codeForKeyEvent(WebEvent *event)
    156197{
    157     switch (event.keyCode) {
     198    switch (keyCodeForEvent(event)) {
    158199    // Keys in the alphanumeric section.
    159200    case VK_OEM_3: return "Backquote"_s;
     
    379420        m_code = codeForKeyEvent(event);
    380421        m_keyIdentifier = keyIdentifierForKeyEvent(event);
    381         m_windowsVirtualKeyCode = event.keyCode;
     422        m_windowsVirtualKeyCode = keyCodeForEvent(event);
    382423        m_autoRepeat = event.isKeyRepeating;
    383424        m_isKeypad = false; // iOS does not distinguish the numpad. See <rdar://problem/7190835>.
  • trunk/Source/WebKit/ChangeLog

    r235859 r235860  
     12018-09-10  Daniel Bates  <dabates@apple.com>
     2
     3        [iOS] Arrow keys do not dispatch DOM events to non-editable elements
     4        https://bugs.webkit.org/show_bug.cgi?id=189389
     5
     6        Reviewed by Simon Fraser.
     7
     8        Use WebCore::keyCodeForEvent() to retrieve the key code for a WebEvent instead of querying
     9        the key code from the WebEvent directly. The function WebCore::keyCodeForEvent() knows how
     10        to compute the key code for an event that represents an arrow key.
     11
     12        * Shared/ios/WebIOSEventFactory.mm:
     13        (WebIOSEventFactory::createWebKeyboardEvent):
     14
    1152018-09-10  Tim Horton  <timothy_horton@apple.com>
    216
  • trunk/Source/WebKit/Shared/ios/WebIOSEventFactory.mm

    r233122 r235860  
    5959    String code = WebCore::codeForKeyEvent(event);
    6060    String keyIdentifier = WebCore::keyIdentifierForKeyEvent(event);
    61     int windowsVirtualKeyCode = event.keyCode;
    62     int nativeVirtualKeyCode = event.keyCode;
     61    int windowsVirtualKeyCode = WebCore::keyCodeForEvent(event);
     62    int nativeVirtualKeyCode = WebCore::keyCodeForEvent(event);
    6363    int macCharCode = 0;
    6464    bool autoRepeat = event.isKeyRepeating;
Note: See TracChangeset for help on using the changeset viewer.