Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings
This repository was archived by the owner on Nov 11, 2024. It is now read-only.

Commit26b036d

Browse files
committed
feat: rework the RCTKeyCommands api
BREAKING CHANGE
1 parent873b3a6 commit26b036d

File tree

8 files changed

+198
-177
lines changed

8 files changed

+198
-177
lines changed

‎React/Base/RCTKeyCommands.h‎

Lines changed: 48 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,56 @@
1-
/**
2-
* Copyright (c) 2015-present, Facebook, Inc.
3-
*
4-
* This source code is licensed under the MIT license found in the
5-
* LICENSE file in the root directory of this source tree.
6-
*/
7-
81
#import<AppKit/AppKit.h>
92

3+
#pragma mark - RCTKeyCommand
4+
5+
typedefunsignedshort RCTKeyCode;
6+
7+
@interfaceRCTKeyCommand :NSObject
8+
9+
/// The upper or lower cased characters being pressed.
10+
@property (nonatomic,readonly)NSString *input;
11+
12+
/// The device-independent key code.
13+
@property (nonatomic,readonly) RCTKeyCode keyCode;
14+
15+
/// True for keydown events. False for keyup events.
16+
@property (nonatomic,readonly)BOOL isDown;
17+
18+
/// The modifiers being pressed. (eg: command, control, etc)
19+
@property (nonatomic,readonly)NSEventModifierFlags flags;
20+
21+
/// The window that received the original NSEvent.
22+
@property (nonatomic,readonly)NSWindow *window;
23+
24+
/// The original NSEvent that triggered this command.
25+
@property (nonatomic,readonly)NSEvent *event;
26+
27+
- (BOOL)matchesInput:(NSString *)input;
28+
- (BOOL)matchesInput:(NSString *)inputflags:(NSEventModifierFlags)flags;
29+
30+
- (BOOL)matchesKeyCode:(RCTKeyCode)keyCode;
31+
- (BOOL)matchesKeyCode:(RCTKeyCode)keyCodeflags:(NSEventModifierFlags)flags;
32+
33+
- (void)preventDefault;
34+
- (BOOL)isDefaultPrevented;
35+
36+
@end
37+
38+
#pragma mark - RCTKeyCommandObserver
39+
40+
@protocolRCTKeyCommandObserver <NSObject>
41+
42+
- (void)observeKeyCommand:(RCTKeyCommand *)command;
43+
44+
@end
45+
46+
#pragma mark - RCTKeyCommands
47+
1048
@interfaceRCTKeyCommands :NSObject
1149

1250
+ (instancetype)sharedInstance;
1351

14-
/**
15-
* Register a single-press keyboard command.
16-
*/
17-
- (void)registerKeyCommandWithInput:(NSString *)input
18-
modifierFlags:(NSEventModifierFlags)flags
19-
action:(void (^)(NSEvent *command))block;
20-
21-
/**
22-
* Unregister a single-press keyboard command.
23-
*/
24-
- (void)unregisterKeyCommandWithInput:(NSString *)input
25-
modifierFlags:(NSEventModifierFlags)flags;
26-
27-
/**
28-
* Check if a single-press command is registered.
29-
*/
30-
- (BOOL)isKeyCommandRegisteredForInput:(NSString *)input
31-
modifierFlags:(NSEventModifierFlags)flags;
52+
- (void)addObserver:(NSObject<RCTKeyCommandObserver> *)observer;
53+
54+
- (void)removeObserver:(NSObject<RCTKeyCommandObserver> *)observer;
3255

3356
@end

‎React/Base/RCTKeyCommands.m‎

Lines changed: 74 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1,101 +1,89 @@
1-
/**
2-
* Copyright (c) 2015-present, Facebook, Inc.
3-
*
4-
* This source code is licensed under the MIT license found in the
5-
* LICENSE file in the root directory of this source tree.
6-
*/
7-
81
#import"RCTKeyCommands.h"
9-
10-
#import<AppKit/AppKit.h>
11-
122
#import"RCTDefines.h"
133
#import"RCTUtils.h"
144

15-
@interfaceRCTKeyCommand :NSObject <NSCopying>
16-
17-
@property (nonatomic,strong)NSString *keyCommand;
18-
@property (nonatomic)NSEventModifierFlags modifierFlags;
19-
@property (nonatomic,copy)void (^block)(NSEvent *);
20-
21-
@end
22-
235
@implementationRCTKeyCommand
6+
{
7+
BOOL _preventDefault;
8+
}
249

25-
- (instancetype)initWithKeyCommand:(NSString *)keyCommand
26-
modifierFlags:(NSEventModifierFlags)modifierFlags
27-
block:(void (^)(NSEvent *))block
10+
- (instancetype)initWithEvent:(NSEvent *)event
2811
{
2912
if ((self = [superinit])) {
30-
_keyCommand = keyCommand;
31-
_modifierFlags = modifierFlags;
32-
_block = block;
13+
_event = event;
3314
}
3415
return self;
3516
}
3617

3718
RCT_NOT_IMPLEMENTED(- (instancetype)init)
3819

39-
- (id)copyWithZone:(__unusedNSZone *)zone
20+
- (NSString *)input
4021
{
41-
returnself;
22+
return_event.characters;
4223
}
4324

44-
- (NSUInteger)hash
25+
- (unsignedshort)keyCode
4526
{
46-
return_keyCommand.hash ^ _modifierFlags;
27+
return_event.keyCode;
4728
}
4829

49-
- (BOOL)isEqual:(RCTKeyCommand *)object
30+
- (BOOL)isDown
5031
{
51-
if (![objectisKindOfClass:[RCTKeyCommandclass]]) {
52-
returnNO;
53-
}
54-
return [selfmatchesInput:object.keyCommand
55-
flags:object.modifierFlags];
32+
return _event.type == NSEventTypeKeyDown;
5633
}
5734

58-
- (BOOL)matchesInput:(NSString*)keyCommandflags:(int)flags
35+
- (NSEventModifierFlags)flags
5936
{
60-
return[_keyCommandisEqual:keyCommand] && _modifierFlags == flags;
37+
return_event.modifierFlags & NSEventModifierFlagDeviceIndependentFlagsMask;
6138
}
6239

63-
- (NSString *)description
40+
- (NSWindow *)window
6441
{
65-
return [NSStringstringWithFormat:@"<%@:%p input=\"%@\" flags=%zd hasBlock=%@>",
66-
[selfclass],self, _keyCommand, _modifierFlags,
67-
_block ?@"YES" :@"NO"];
42+
return _event.window;
6843
}
6944

70-
@end
71-
72-
@interfaceRCTKeyCommands ()
45+
- (NSString *)description
46+
{
47+
return [NSStringstringWithFormat:@"<%@:%p input=\"%@\" flags=%zd isDown=%@>",
48+
[selfclass],self,self.input,self.flags,self.isDown ?@"YES" :@"NO"];
49+
}
7350

74-
@property (nonatomic,strong)NSMutableSet<RCTKeyCommand *> *commands;
51+
- (BOOL)matchesInput:(NSString *)input
52+
{
53+
return [selfmatchesInput:inputflags:0];
54+
}
7555

76-
@end
56+
- (BOOL)matchesInput:(NSString *)inputflags:(NSEventModifierFlags)flags
57+
{
58+
return [self.inputisEqualToString:input] && self.flags == flags;
59+
}
7760

61+
- (BOOL)matchesKeyCode:(RCTKeyCode)keyCode
62+
{
63+
return [selfmatchesKeyCode:keyCodeflags:0];
64+
}
7865

79-
@implementationNSWindow (RCTKeyCommands)
66+
- (BOOL)matchesKeyCode:(RCTKeyCode)keyCodeflags:(NSEventModifierFlags)flags
67+
{
68+
return self.keyCode == keyCode && self.flags == flags;
69+
}
8070

81-
- (void)keyDown:(NSEvent *)theEvent
71+
- (void)preventDefault
8272
{
83-
for (RCTKeyCommand *command in [RCTKeyCommandssharedInstance].commands) {
84-
if ([command.keyCommandisEqualToString:theEvent.characters] &&
85-
command.modifierFlags == (theEvent.modifierFlags &NSDeviceIndependentModifierFlagsMask)) {
86-
if (command.block) {
87-
command.block(theEvent);
88-
}
89-
return;
90-
}
91-
}
73+
_preventDefault =YES;
74+
}
9275

93-
[superkeyDown:theEvent];
76+
- (BOOL)isDefaultPrevented
77+
{
78+
return _preventDefault;
9479
}
9580

9681
@end
9782

9883
@implementationRCTKeyCommands
84+
{
85+
NSHashTable<id<RCTKeyCommandObserver>> *_observers;
86+
}
9987

10088
+ (instancetype)sharedInstance
10189
{
@@ -111,46 +99,52 @@ + (instancetype)sharedInstance
11199
- (instancetype)init
112100
{
113101
if ((self = [superinit])) {
114-
_commands = [NSMutableSetnew];
102+
_observers = [NSHashTableweakObjectsHashTable];
115103
}
116104
return self;
117105
}
118106

119-
- (void)registerKeyCommandWithInput:(NSString *)input
120-
modifierFlags:(NSEventModifierFlags)flags
121-
action:(void (^)(NSEvent *))block
107+
- (void)addObserver:(NSObject<RCTKeyCommandObserver> *)observer
122108
{
123109
RCTAssertMainQueue();
124-
125-
RCTKeyCommand *keyCommand = [[RCTKeyCommandalloc]initWithKeyCommand:inputmodifierFlags:flagsblock:block];
126-
[_commandsremoveObject:keyCommand];
127-
[_commandsaddObject:keyCommand];
110+
[_observersaddObject:observer];
128111
}
129112

130-
- (void)unregisterKeyCommandWithInput:(NSString *)input
131-
modifierFlags:(NSEventModifierFlags)flags
113+
- (void)removeObserver:(NSObject<RCTKeyCommandObserver> *)observer
132114
{
133115
RCTAssertMainQueue();
116+
[_observersremoveObject:observer];
117+
}
134118

135-
for (RCTKeyCommand *command in _commands.allObjects) {
136-
if ([commandmatchesInput:inputflags:flags]) {
137-
[_commandsremoveObject:command];
138-
break;
139-
}
119+
- (BOOL)observeEvent:(NSEvent *)event
120+
{
121+
RCTAssertMainQueue();
122+
RCTKeyCommand *command = [[RCTKeyCommandalloc]initWithEvent:event];
123+
for (id<RCTKeyCommandObserver> observer in _observers) {
124+
[observerobserveKeyCommand:command];
140125
}
126+
return command.isDefaultPrevented;
141127
}
142128

143-
- (BOOL)isKeyCommandRegisteredForInput:(NSString *)input
144-
modifierFlags:(NSEventModifierFlags)flags
129+
@end
130+
131+
@implementationNSWindow (RCTKeyCommands)
132+
133+
- (void)keyDown:(NSEvent *)event
145134
{
146-
RCTAssertMainQueue();
135+
BOOL isDefaultPrevented = [[RCTKeyCommandssharedInstance]observeEvent:event];
136+
if (!isDefaultPrevented) {
137+
[superkeyDown:event];
138+
}
139+
}
147140

148-
for (RCTKeyCommand *command in _commands) {
149-
if ([commandmatchesInput:inputflags:flags]) {
150-
returnYES;
151-
}
141+
- (void)keyUp:(NSEvent *)event
142+
{
143+
BOOL isDefaultPrevented = [[RCTKeyCommandssharedInstance]observeEvent:event];
144+
if (!isDefaultPrevented) {
145+
[superkeyUp:event];
152146
}
153-
returnNO;
154147
}
155148

156149
@end
150+

‎React/Base/RCTReloadCommand.h‎

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,3 @@
1515

1616
/** Registers a weakly-held observer of the Command+R reload key command.*/
1717
RCT_EXTERNvoidRCTRegisterReloadCommandListener(id<RCTReloadListener> listener);
18-
19-
/** Triggers a reload for all current listeners. You shouldn't need to use this directly in most cases.*/
20-
RCT_EXTERNvoidRCTTriggerReloadCommandListeners(void);

‎React/Base/RCTReloadCommand.m‎

Lines changed: 34 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -10,32 +10,44 @@
1010
#import"RCTAssert.h"
1111
#import"RCTKeyCommands.h"
1212

13-
/** main queue only*/
14-
staticNSHashTable<id<RCTReloadListener>> *listeners;
13+
@interfaceRCTReloadCommand :NSObject <RCTKeyCommandObserver>
1514

16-
voidRCTRegisterReloadCommandListener(id<RCTReloadListener> listener)
15+
@property (nonatomic,strong)NSHashTable<id<RCTReloadListener>> *listeners;
16+
17+
@end
18+
19+
@implementationRCTReloadCommand
20+
21+
- (instancetype)init
1722
{
18-
RCTAssertMainQueue();// because registerKeyCommandWithInput: must be called on the main thread
19-
staticdispatch_once_t onceToken;
20-
dispatch_once(&onceToken, ^{
21-
listeners = [NSHashTableweakObjectsHashTable];
22-
[[RCTKeyCommandssharedInstance]registerKeyCommandWithInput:@"r"
23-
modifierFlags:NSEventModifierFlagCommand
24-
action:
25-
^(__unusedNSEvent *command) {
26-
RCTTriggerReloadCommandListeners();
27-
}];
28-
});
29-
[listenersaddObject:listener];
23+
if (self = [superinit]) {
24+
_listeners = [NSHashTableweakObjectsHashTable];
25+
26+
[RCTKeyCommands.sharedInstanceaddObserver:self];
27+
}
28+
return self;
3029
}
3130

32-
voidRCTTriggerReloadCommandListeners(void)
31+
-(void)observeKeyCommand:(RCTKeyCommand *)command
3332
{
34-
RCTAssertMainQueue();
35-
// Copy to protect against mutation-during-enumeration.
36-
// If listeners hasn't been initialized yet we get nil, which works just fine.
37-
NSArray<id<RCTReloadListener>> *copiedListeners = [listenersallObjects];
38-
for (id<RCTReloadListener> l in copiedListeners) {
39-
[ldidReceiveReloadCommand];
33+
if (command.isDown && [commandmatchesInput:@"r"flags:NSEventModifierFlagCommand]) {
34+
for (id<RCTReloadListener> listener in _listeners.allObjects) {
35+
[listenerdidReceiveReloadCommand];
36+
}
4037
}
4138
}
39+
40+
@end
41+
42+
voidRCTRegisterReloadCommandListener(id<RCTReloadListener> listener)
43+
{
44+
RCTAssertMainQueue();
45+
46+
static RCTReloadCommand *command;
47+
staticdispatch_once_t onceToken;
48+
dispatch_once(&onceToken, ^{
49+
command = [RCTReloadCommandnew];
50+
});
51+
52+
[command.listenersaddObject:listener];
53+
}

‎React/Base/RCTRootView.m‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
#import"RCTBridge.h"
1616
#import"RCTBridge+Private.h"
1717
#import"RCTEventDispatcher.h"
18-
#import"RCTKeyCommands.h"
1918
#import"RCTLog.h"
2019
#import"RCTPerformanceLogger.h"
2120
#import"RCTProfile.h"

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp