1212#endif // [macOS]
1313
1414#import < React/RCTAssert.h> // [macOS]
15- #import < React/RCTUIManager.h> // [macOS]
1615#import < React/RCTUtils.h>
1716#import < React/UIView+React.h>
1817#import < React/RCTFocusChangeEvent.h> // [macOS]
@@ -61,8 +60,6 @@ @implementation RCTTextView {
6160
6261 id <RCTEventDispatcherProtocol> _eventDispatcher; // [macOS]
6362 NSArray <RCTUIView *> *_Nullable _descendantViews; // [macOS]
64- NSArray <RCTVirtualTextView *> *_Nullable _virtualSubviews; // [macOS]
65- RCTUIView *_Nullable _currentHoveredSubview; // [macOS]
6663 NSTextStorage *_Nullable _textStorage;
6764 CGRect _contentFrame;
6865}
@@ -100,7 +97,6 @@ - (instancetype)initWithFrame:(CGRect)frame
10097 _textView.layoutManager .usesFontLeading = NO ;
10198 _textStorage = _textView.textStorage ;
10299 [self addSubview: _textView];
103- _currentHoveredSubview = nil ;
104100#endif // macOS]
105101 RCTUIViewSetContentModeRedraw (self); // [macOS]
106102 }
@@ -164,20 +160,6 @@ - (void)setTextStorage:(NSTextStorage *)textStorage
164160 contentFrame : (CGRect)contentFrame
165161 descendantViews : (NSArray <RCTPlatformView *> *)descendantViews // [macOS]
166162{
167- // [macOS - to keep track of virtualSubviews as well
168- [self setTextStorage: textStorage
169- contentFrame: contentFrame
170- descendantViews: descendantViews
171- virtualSubviews: nil ];
172- }
173-
174- - (void )setTextStorage : (NSTextStorage *)textStorage
175- contentFrame : (CGRect)contentFrame
176- descendantViews : (NSArray <RCTPlatformView *> *)descendantViews
177- virtualSubviews : (NSArray <RCTVirtualTextView *> *)virtualSubviews
178- {
179- // macOS]
180-
181163 // This lets the textView own its text storage on macOS
182164 // We update and replace the text container `_textView.textStorage.attributedString` when text/layout changes
183165#if !TARGET_OS_OSX // [macOS]
@@ -220,8 +202,6 @@ - (void)setTextStorage:(NSTextStorage *)textStorage
220202 [self addSubview: view];
221203 }
222204
223- _virtualSubviews = virtualSubviews; // [macOS]
224-
225205 [self setNeedsDisplay ];
226206}
227207
@@ -423,21 +403,6 @@ - (void)handleLongPress:(UILongPressGestureRecognizer *)gesture
423403
424404#else // [macOS
425405
426- - (BOOL )hasMouseHoverEvent
427- {
428- if ([super hasMouseHoverEvent ]) {
429- return YES ;
430- }
431-
432- // We only care about virtual subviews here.
433- // Embedded views (e.g., <Text> <View /> </Text>) handle mouse hover events themselves.
434- NSUInteger indexOfChildWithMouseHoverEvent = [_virtualSubviews indexOfObjectPassingTest: ^BOOL (RCTVirtualTextView *_Nonnull childView, NSUInteger idx, BOOL *_Nonnull stop) {
435- *stop = [childView hasMouseHoverEvent ];
436- return *stop;
437- }];
438- return indexOfChildWithMouseHoverEvent != NSNotFound ;
439- }
440-
441406- (NSView *)hitTest : (NSPoint )point
442407{
443408 // We will forward mouse click events to the NSTextView ourselves to prevent NSTextView from swallowing events that may be handled in JS (e.g. long press).
@@ -452,110 +417,6 @@ - (NSView *)hitTest:(NSPoint)point
452417 return isTextViewClick ? self : hitView;
453418}
454419
455- - (NSNumber *)reactTagAtMouseLocationFromEvent : (NSEvent *)event
456- {
457- NSPoint locationInSelf = [self convertPoint: event.locationInWindow fromView: nil ];
458- NSPoint locationInInnerTextView = [self convertPoint: locationInSelf toView: _textView]; // This is needed if the parent <Text> view has padding
459- return [self reactTagAtPoint: locationInInnerTextView];
460- }
461-
462- - (void )mouseEntered : (NSEvent *)event
463- {
464- // superclass invokes self.onMouseEnter, so do this first
465- [super mouseEntered: event];
466-
467- [self updateHoveredSubviewWithEvent: event];
468- }
469-
470- - (void )mouseExited : (NSEvent *)event
471- {
472- [self updateHoveredSubviewWithEvent: event];
473-
474- // superclass invokes self.onMouseLeave, so do this last
475- [super mouseExited: event];
476- }
477-
478- - (void )mouseMoved : (NSEvent *)event
479- {
480- [super mouseMoved: event];
481- [self updateHoveredSubviewWithEvent: event];
482- }
483-
484- - (void )updateHoveredSubviewWithEvent : (NSEvent *)event
485- {
486- RCTUIView *hoveredView = nil ;
487-
488- if ([event type ] != NSEventTypeMouseExited && _virtualSubviews != nil ) {
489- NSNumber *reactTagOfHoveredView = [self reactTagAtMouseLocationFromEvent: event];
490-
491- if (reactTagOfHoveredView == nil ) {
492- // This happens if we hover over an embedded view, which will handle its own mouse events
493- return ;
494- }
495-
496- if ([reactTagOfHoveredView isEqualToNumber: self .reactTag]) {
497- // We're hovering over the root Text element
498- hoveredView = self;
499- } else {
500- // Maybe we're hovering over a child Text element?
501- NSUInteger index = [_virtualSubviews indexOfObjectPassingTest: ^BOOL (RCTVirtualTextView *_Nonnull view, NSUInteger idx, BOOL *_Nonnull stop) {
502- *stop = [[view reactTag ] isEqualToNumber: reactTagOfHoveredView];
503- return *stop;
504- }];
505- if (index != NSNotFound ) {
506- hoveredView = _virtualSubviews[index];
507- }
508- }
509- }
510-
511- if (_currentHoveredSubview == hoveredView) {
512- return ;
513- }
514-
515- // self will always be an ancestor of any views we pass in here, so it serves as a good default option.
516- // Also, if we do set from/to nil, we have to call the relevant events on the entire subtree.
517- RCTUIManager *uiManager = [[_eventDispatcher bridge ] uiManager ];
518- RCTShadowView *oldShadowView = [uiManager shadowViewForReactTag: [(_currentHoveredSubview ?: self ) reactTag ]];
519- RCTShadowView *newShadowView = [uiManager shadowViewForReactTag: [(hoveredView ?: self ) reactTag ]];
520-
521- // Find the common ancestor between the two shadow views
522- RCTShadowView *commonAncestor = [oldShadowView ancestorSharedWithShadowView: newShadowView];
523-
524- for (RCTShadowView *exitedShadowView = oldShadowView; exitedShadowView != commonAncestor && exitedShadowView != nil ; exitedShadowView = [exitedShadowView reactSuperview ]) {
525- RCTPlatformView *exitedView = [uiManager viewForReactTag: [exitedShadowView reactTag ]];
526- if (![exitedView isKindOfClass: [RCTUIView class ]]) {
527- RCTLogError (@" Unexpected view of type %@ found in hierarchy, must be RCTUIView or subclass" , [exitedView class ]);
528- continue ;
529- }
530-
531- RCTUIView *exitedReactView = (RCTUIView *)exitedView;
532- [self sendMouseEventWithBlock: [exitedReactView onMouseLeave ]
533- locationInfo: [self locationInfoFromEvent: event]
534- modifierFlags: event.modifierFlags
535- additionalData: nil ];
536- }
537-
538- // We cache these so we can call them from outermost to innermost
539- NSMutableArray <RCTUIView *> *enteredViewHierarchy = [NSMutableArray new ];
540- for (RCTShadowView *enteredShadowView = newShadowView; enteredShadowView != commonAncestor && enteredShadowView != nil ; enteredShadowView = [enteredShadowView reactSuperview ]) {
541- RCTPlatformView *enteredView = [uiManager viewForReactTag: [enteredShadowView reactTag ]];
542- if (![enteredView isKindOfClass: [RCTUIView class ]]) {
543- RCTLogError (@" Unexpected view of type %@ found in hierarchy, must be RCTUIView or subclass" , [enteredView class ]);
544- continue ;
545- }
546-
547- [enteredViewHierarchy addObject: (RCTUIView *)enteredView];
548- }
549- for (NSInteger i = [enteredViewHierarchy count ] - 1 ; i >= 0 ; i--) {
550- [self sendMouseEventWithBlock: [[enteredViewHierarchy objectAtIndex: i] onMouseEnter ]
551- locationInfo: [self locationInfoFromEvent: event]
552- modifierFlags: event.modifierFlags
553- additionalData: nil ];
554- }
555-
556- _currentHoveredSubview = hoveredView;
557- }
558-
559420- (void )rightMouseDown : (NSEvent *)event
560421{
561422
0 commit comments