Skip to content

Commit

Permalink
Merge branch 'main' into text-input-errors
Browse files Browse the repository at this point in the history
  • Loading branch information
fabOnReact committed Apr 11, 2022
2 parents 3a1ef4a + 61b013e commit 994089c
Show file tree
Hide file tree
Showing 42 changed files with 552 additions and 101 deletions.
4 changes: 4 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -727,6 +727,10 @@ jobs:
name: Set USE_HERMES=1
command: echo "export USE_HERMES=1" >> $BASH_ENV

- run:
name: Set BUILD_HERMES_SOURCE=1
command: echo "export BUILD_HERMES_SOURCE=1" >> $BASH_ENV

- with_brew_cache_span:
steps:
- brew_install:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/needs-attention.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ jobs:
name: Apply Needs Attention Label
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Apply Needs Attention Label
uses: hramos/needs-attention@v1
with:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/on-issue-labeled.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ jobs:
name: Respond to Issue Based on Label
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Respond to Issue Based on Label
uses: hramos/respond-to-issue-based-on-label@v2
with:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/stale-bot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ jobs:
issues: write
pull-requests: write
steps:
- uses: actions/stale@v4
- uses: actions/stale@v5
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
days-before-stale: 180
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test-docker-android.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
name: Test Docker
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Free up space by removing unnecessary folders
run: |
sudo rm -rf /usr/share/dotnet
Expand Down
3 changes: 3 additions & 0 deletions Libraries/Image/RCTImageCache.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,7 @@
@end

@interface RCTImageCache : NSObject <RCTImageCache>

RCT_EXTERN void RCTSetImageCacheLimits(NSUInteger maxCachableDecodedImageSizeInBytes, NSUInteger imageCacheTotalCostLimit);

@end
10 changes: 8 additions & 2 deletions Libraries/Image/RCTImageCache.m
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,13 @@

#import <React/RCTImageUtils.h>

static const NSUInteger RCTMaxCachableDecodedImageSizeInBytes = 2097152; // 2 MB
static NSUInteger RCTMaxCachableDecodedImageSizeInBytes = 2*1024*1024;
static NSUInteger RCTImageCacheTotalCostLimit = 20*1024*1024;

void RCTSetImageCacheLimits(NSUInteger maxCachableDecodedImageSizeInBytes, NSUInteger imageCacheTotalCostLimit) {
RCTMaxCachableDecodedImageSizeInBytes = maxCachableDecodedImageSizeInBytes;
RCTImageCacheTotalCostLimit = imageCacheTotalCostLimit;
}

static NSString *RCTCacheKeyForImage(NSString *imageTag, CGSize size, CGFloat scale,
RCTResizeMode resizeMode)
Expand All @@ -38,7 +44,7 @@ - (instancetype)init
{
if (self = [super init]) {
_decodedImageCache = [NSCache new];
_decodedImageCache.totalCostLimit = 20 * 1024 * 1024; // 20 MB
_decodedImageCache.totalCostLimit = RCTImageCacheTotalCostLimit;
_cacheStaleTimes = [NSMutableDictionary new];

[[NSNotificationCenter defaultCenter] addObserver:self
Expand Down
26 changes: 26 additions & 0 deletions Libraries/NativeComponent/PlatformBaseViewConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,32 @@ const PlatformBaseViewConfig: PartialViewConfigWithoutName =
captured: 'onTouchEndCapture',
},
},

// Pointer Events
topPointerCancel: {
phasedRegistrationNames: {
captured: 'onPointerCancelCapture',
bubbled: 'onPointerCancel',
},
},
topPointerDown: {
phasedRegistrationNames: {
captured: 'onPointerDownCapture',
bubbled: 'onPointerDown',
},
},
topPointerMove2: {
phasedRegistrationNames: {
captured: 'onPointerMove2Capture',
bubbled: 'onPointerMove2',
},
},
topPointerUp: {
phasedRegistrationNames: {
captured: 'onPointerUpCapture',
bubbled: 'onPointerUp',
},
},
},
directEventTypes: {
topAccessibilityAction: {
Expand Down
12 changes: 8 additions & 4 deletions Libraries/PushNotificationIOS/RCTPushNotificationManager.mm
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,7 @@ - (void)handleRemoteNotificationRegistrationError:(NSNotification *)notification
RCT_EXPORT_METHOD(checkPermissions:(RCTResponseSenderBlock)callback)
{
if (RCTRunningInAppExtension()) {
callback(@[RCTSettingsDictForUNNotificationSettings(NO, NO, NO)]);
callback(@[RCTSettingsDictForUNNotificationSettings(NO, NO, NO, NO, NO, NO, UNAuthorizationStatusNotDetermined)]);
return;
}

Expand All @@ -343,11 +343,15 @@ - (void)handleRemoteNotificationRegistrationError:(NSNotification *)notification
static inline NSDictionary *RCTPromiseResolveValueForUNNotificationSettings(UNNotificationSettings* _Nonnull settings) {
return RCTSettingsDictForUNNotificationSettings(settings.alertSetting == UNNotificationSettingEnabled,
settings.badgeSetting == UNNotificationSettingEnabled,
settings.soundSetting == UNNotificationSettingEnabled);
settings.soundSetting == UNNotificationSettingEnabled,
settings.criticalAlertSetting == UNNotificationSettingEnabled,
settings.lockScreenSetting == UNNotificationSettingEnabled,
settings.notificationCenterSetting == UNNotificationSettingEnabled,
settings.authorizationStatus);
}

static inline NSDictionary *RCTSettingsDictForUNNotificationSettings(BOOL alert, BOOL badge, BOOL sound) {
return @{@"alert": @(alert), @"badge": @(badge), @"sound": @(sound)};
static inline NSDictionary *RCTSettingsDictForUNNotificationSettings(BOOL alert, BOOL badge, BOOL sound, BOOL critical, BOOL lockScreen, BOOL notificationCenter, UNAuthorizationStatus authorizationStatus) {
return @{@"alert": @(alert), @"badge": @(badge), @"sound": @(sound), @"critical": @(critical), @"lockScreen": @(lockScreen), @"notificationCenter": @(notificationCenter), @"authorizationStatus": @(authorizationStatus)};
}

RCT_EXPORT_METHOD(presentLocalNotification:(JS::NativePushNotificationManagerIOS::Notification &)notification)
Expand Down
6 changes: 6 additions & 0 deletions React/Base/RCTConstants.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,9 @@ RCT_EXTERN NSString *const RCTUserInterfaceStyleDidChangeNotificationTraitCollec
*/
RCT_EXTERN BOOL RCTExperimentGetPreemptiveViewAllocationDisabled(void);
RCT_EXTERN void RCTExperimentSetPreemptiveViewAllocationDisabled(BOOL value);

/*
* W3C Pointer Events
*/
RCT_EXTERN BOOL RCTGetDispatchW3CPointerEvents(void);
RCT_EXTERN void RCTSetDispatchW3CPointerEvents(BOOL value);
15 changes: 15 additions & 0 deletions React/Base/RCTConstants.m
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,18 @@ void RCTExperimentSetPreemptiveViewAllocationDisabled(BOOL value)
{
RCTExperimentPreemptiveViewAllocationDisabled = value;
}

/*
* W3C Pointer Events
*/
static BOOL RCTDispatchW3CPointerEvents = NO;

BOOL RCTGetDispatchW3CPointerEvents()
{
return RCTDispatchW3CPointerEvents;
}

void RCTSetDispatchW3CPointerEvents(BOOL value)
{
RCTDispatchW3CPointerEvents = value;
}
46 changes: 37 additions & 9 deletions React/Fabric/RCTSurfacePresenter.mm
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ @implementation RCTSurfacePresenter {
RuntimeExecutor _runtimeExecutor; // Protected by `_schedulerLifeCycleMutex`.

butter::shared_mutex _observerListMutex;
NSMutableArray<id<RCTSurfacePresenterObserver>> *_observers;
std::vector<__weak id<RCTSurfacePresenterObserver>> _observers; // Protected by `_observerListMutex`.
}

- (instancetype)initWithContextContainer:(ContextContainer::Shared)contextContainer
Expand All @@ -96,8 +96,6 @@ - (instancetype)initWithContextContainer:(ContextContainer::Shared)contextContai
_mountingManager.contextContainer = contextContainer;
_mountingManager.delegate = self;

_observers = [NSMutableArray array];

_scheduler = [self _createScheduler];

auto reactNativeConfig = _contextContainer->at<std::shared_ptr<ReactNativeConfig const>>("ReactNativeConfig");
Expand Down Expand Up @@ -271,6 +269,10 @@ - (RCTScheduler *)_createScheduler
RCTExperimentSetPreemptiveViewAllocationDisabled(YES);
}

if (reactNativeConfig && reactNativeConfig->getBool("rn_convergence:dispatch_pointer_events")) {
RCTSetDispatchW3CPointerEvents(YES);
}

auto componentRegistryFactory =
[factory = wrapManagedObject(_mountingManager.componentViewRegistry.componentViewFactory)](
EventDispatcher::Weak const &eventDispatcher, ContextContainer::Shared const &contextContainer) {
Expand Down Expand Up @@ -386,13 +388,17 @@ - (void)schedulerDidSetIsJSResponder:(BOOL)isJSResponder
- (void)addObserver:(id<RCTSurfacePresenterObserver>)observer
{
std::unique_lock<butter::shared_mutex> lock(_observerListMutex);
[self->_observers addObject:observer];
_observers.push_back(observer);
}

- (void)removeObserver:(id<RCTSurfacePresenterObserver>)observer
{
std::unique_lock<butter::shared_mutex> lock(_observerListMutex);
[self->_observers removeObject:observer];
std::vector<__weak id<RCTSurfacePresenterObserver>>::const_iterator it =
std::find(_observers.begin(), _observers.end(), observer);
if (it != _observers.end()) {
_observers.erase(it);
}
}

#pragma mark - RCTMountingManagerDelegate
Expand All @@ -401,8 +407,13 @@ - (void)mountingManager:(RCTMountingManager *)mountingManager willMountComponent
{
RCTAssertMainQueue();

std::shared_lock<butter::shared_mutex> lock(_observerListMutex);
for (id<RCTSurfacePresenterObserver> observer in _observers) {
NSArray<id<RCTSurfacePresenterObserver>> *observersCopy;
{
std::shared_lock<butter::shared_mutex> lock(_observerListMutex);
observersCopy = [self _getObservers];
}

for (id<RCTSurfacePresenterObserver> observer in observersCopy) {
if ([observer respondsToSelector:@selector(willMountComponentsWithRootTag:)]) {
[observer willMountComponentsWithRootTag:rootTag];
}
Expand All @@ -413,12 +424,29 @@ - (void)mountingManager:(RCTMountingManager *)mountingManager didMountComponents
{
RCTAssertMainQueue();

std::shared_lock<butter::shared_mutex> lock(_observerListMutex);
for (id<RCTSurfacePresenterObserver> observer in _observers) {
NSArray<id<RCTSurfacePresenterObserver>> *observersCopy;
{
std::shared_lock<butter::shared_mutex> lock(_observerListMutex);
observersCopy = [self _getObservers];
}

for (id<RCTSurfacePresenterObserver> observer in observersCopy) {
if ([observer respondsToSelector:@selector(didMountComponentsWithRootTag:)]) {
[observer didMountComponentsWithRootTag:rootTag];
}
}
}

- (NSArray<id<RCTSurfacePresenterObserver>> *)_getObservers
{
NSMutableArray<id<RCTSurfacePresenterObserver>> *observersCopy = [NSMutableArray new];
for (id<RCTSurfacePresenterObserver> observer : _observers) {
if (observer) {
[observersCopy addObject:observer];
}
}

return observersCopy;
}

@end
55 changes: 55 additions & 0 deletions React/Fabric/RCTSurfaceTouchHandler.mm
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ typedef NS_ENUM(NSInteger, RCTTouchEventType) {
Touch touch;
SharedTouchEventEmitter eventEmitter;

/*
* The type of touch received.
*/
UITouchType touchType;

/*
* A component view on which the touch was begun.
*/
Expand Down Expand Up @@ -98,6 +103,8 @@ static void UpdateActiveTouchWithUITouch(
if (RCTForceTouchAvailable()) {
activeTouch.touch.force = RCTZeroIfNaN(uiTouch.force / uiTouch.maximumPossibleForce);
}

activeTouch.touchType = uiTouch.type;
}

static ActiveTouch CreateTouchWithUITouch(UITouch *uiTouch, UIView *rootComponentView, CGPoint rootViewOriginOffset)
Expand All @@ -121,6 +128,35 @@ static ActiveTouch CreateTouchWithUITouch(UITouch *uiTouch, UIView *rootComponen
return activeTouch;
}

static const char *PointerTypeCStringFromUITouchType(UITouchType type)
{
switch (type) {
case UITouchTypeDirect:
return "touch";
case UITouchTypePencil:
return "pen";
case UITouchTypeIndirectPointer:
return "mouse";
case UITouchTypeIndirect:
default:
return "";
}
}

static PointerEvent CreatePointerEventFromActiveTouch(ActiveTouch activeTouch)
{
Touch touch = activeTouch.touch;

PointerEvent event = {};
event.pointerId = touch.identifier;
event.pressure = touch.force;
event.pointerType = PointerTypeCStringFromUITouchType(activeTouch.touchType);
event.clientPoint = touch.pagePoint;
event.target = touch.target;
event.timestamp = touch.timestamp;
return event;
}

static BOOL AllTouchesAreCancelledOrEnded(NSSet<UITouch *> *touches)
{
for (UITouch *touch in touches) {
Expand Down Expand Up @@ -273,6 +309,25 @@ - (void)_dispatchActiveTouches:(std::vector<ActiveTouch>)activeTouches eventType
changedActiveTouches.insert(activeTouch);
event.changedTouches.insert(activeTouch.touch);
uniqueEventEmitters.insert(activeTouch.eventEmitter);

// emit w3c pointer events
if (RCTGetDispatchW3CPointerEvents()) {
PointerEvent pointerEvent = CreatePointerEventFromActiveTouch(activeTouch);
switch (eventType) {
case RCTTouchEventTypeTouchStart:
activeTouch.eventEmitter->onPointerDown(pointerEvent);
break;
case RCTTouchEventTypeTouchMove:
activeTouch.eventEmitter->onPointerMove2(pointerEvent);
break;
case RCTTouchEventTypeTouchEnd:
activeTouch.eventEmitter->onPointerUp(pointerEvent);
break;
case RCTTouchEventTypeTouchCancel:
activeTouch.eventEmitter->onPointerCancel(pointerEvent);
break;
}
}
}

for (const auto &pair : _activeTouches) {
Expand Down
22 changes: 22 additions & 0 deletions React/Modules/RCTUIManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -1523,6 +1523,28 @@ static void RCTMeasureLayout(RCTShadowView *view, RCTShadowView *ancestor, RCTRe
}
}

// Add capturing events (added as bubbling events but with the 'skipBubbling' flag)
for (NSString *eventName in viewConfig[@"capturingEvents"]) {
if (!bubblingEvents[eventName]) {
NSString *bubbleName = [eventName stringByReplacingCharactersInRange:(NSRange){0, 3} withString:@"on"];
bubblingEvents[eventName] = @{
@"phasedRegistrationNames" : @{
@"bubbled" : bubbleName,
@"captured" : [bubbleName stringByAppendingString:@"Capture"],
@"skipBubbling" : @YES
}
};
}
bubblingEventTypes[eventName] = bubblingEvents[eventName];
if (RCT_DEBUG && directEvents[eventName]) {
RCTLogError(
@"Component '%@' re-registered direct event '%@' as a "
"bubbling event",
componentData.name,
eventName);
}
}

return moduleConstants;
}

Expand Down
1 change: 1 addition & 0 deletions React/Views/RCTComponent.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
typedef void (^RCTDirectEventBlock)(NSDictionary *body);
typedef void (^RCTBubblingEventBlock)(NSDictionary *body);
typedef void (^RCTCapturingEventBlock)(NSDictionary *body);

/**
* Logical node in a tree of application components. Both `ShadowView` and
Expand Down
Loading

0 comments on commit 994089c

Please sign in to comment.