@amafil/react-native-pdf-toolkit 1.0.8 → 1.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -170,6 +170,13 @@ react-native run-ios
170
170
  ### ChangeLog
171
171
  <details>
172
172
  <summary>ChangeLog details</summary>
173
+
174
+ v7.0.4
175
+ 1. Fixed: Android PDF crash: IllegalStateException: Already closed (#989) (#999)
176
+ 2. Fixed: scrollTop on initial render on iOS (#1001)
177
+ 3. Feature(ios): add text selection support via PDFKit (#1003)
178
+
179
+
173
180
  v7.0.3
174
181
  1. Fixed: RefObject types, and setPage not working in android (#985)
175
182
 
@@ -27,6 +27,11 @@ import android.view.MotionEvent;
27
27
  import android.graphics.Canvas;
28
28
  import android.graphics.pdf.PdfRenderer;
29
29
 
30
+ import io.legere.pdfiumandroid.util.Config;
31
+ import io.legere.pdfiumandroid.util.ConfigKt;
32
+ import io.legere.pdfiumandroid.util.AlreadyClosedBehavior;
33
+ import io.legere.pdfiumandroid.DefaultLogger;
34
+
30
35
  import com.facebook.react.uimanager.ThemedReactContext;
31
36
  import com.facebook.react.uimanager.UIManagerHelper;
32
37
  import com.github.barteksc.pdfviewer.PDFView;
@@ -50,12 +55,6 @@ import com.facebook.react.uimanager.events.EventDispatcher;
50
55
  import com.facebook.react.uimanager.events.Event;
51
56
  import com.facebook.react.uimanager.events.RCTEventEmitter;
52
57
 
53
- import io.legere.pdfiumandroid.util.AlreadyClosedBehavior;
54
- import io.legere.pdfiumandroid.util.Config;
55
- import io.legere.pdfiumandroid.util.ConfigKt;
56
- import io.legere.pdfiumandroid.DefaultLogger;
57
-
58
-
59
58
  import static java.lang.String.format;
60
59
 
61
60
  import java.io.FileNotFoundException;
@@ -108,12 +107,8 @@ public class PdfView extends PDFView implements OnPageChangeListener,OnLoadCompl
108
107
 
109
108
  public PdfView(Context context, AttributeSet set){
110
109
  super(context, set);
111
- autoScrollResumeHandler = new Handler(Looper.getMainLooper());
112
-
113
- // Avoid IllegalStateException("Already closed") when the PDF document is recycled
114
- // on the main thread while the background RenderingHandler thread is still rendering.
115
- // This race condition causes ANRs reported on Google Play Console.
116
110
  ConfigKt.setPdfiumConfig(new Config(new DefaultLogger(), AlreadyClosedBehavior.IGNORE));
111
+ autoScrollResumeHandler = new Handler(Looper.getMainLooper());
117
112
  }
118
113
 
119
114
  @Override
package/index.d.ts CHANGED
@@ -27,6 +27,17 @@ export type Source = {
27
27
  method?: string;
28
28
  };
29
29
 
30
+ export type TextSelectionChangeEvent = {
31
+ nativeEvent:
32
+ | {
33
+ type: 'selectionCleared';
34
+ }
35
+ | {
36
+ type: 'selectionChanged';
37
+ text: string;
38
+ };
39
+ };
40
+
30
41
  export interface PdfProps {
31
42
  style?: ReactNative.StyleProp<ReactNative.ViewStyle>,
32
43
  progressContainerStyle?: ReactNative.StyleProp<ReactNative.ViewStyle>,
@@ -47,6 +58,10 @@ export interface PdfProps {
47
58
  enableRTL?: boolean,
48
59
  enableAnnotationRendering?: boolean,
49
60
  enableDoubleTapZoom?: boolean;
61
+ /**
62
+ * Only works on iOS. Defaults to `true`.
63
+ */
64
+ enableTextSelection?: boolean;
50
65
  /**
51
66
  * Fit policy. This will adjust the initial zoom of the PDF based on the initial size of the view and the scale factor.
52
67
  * 0 = fit width
@@ -64,6 +79,8 @@ export interface PdfProps {
64
79
  onScaleChanged?: (scale: number) => void,
65
80
  onPressLink?: (url: string) => void,
66
81
  onAutoScrollEnd?: () => void,
82
+ onTextSelectionChange?: (event: TextSelectionChangeEvent) => void,
83
+ onAutoScrollEnd?: () => void,
67
84
  }
68
85
 
69
86
  export interface PdfRef {
package/index.js CHANGED
@@ -64,6 +64,8 @@ export default class Pdf extends Component {
64
64
  onScaleChanged: PropTypes.func,
65
65
  onPressLink: PropTypes.func,
66
66
  onAutoScrollEnd: PropTypes.func,
67
+ enableTextSelection: PropTypes.bool,
68
+ onTextSelectionChange: PropTypes.func,
67
69
 
68
70
  // Props that are not available in the earlier react native version, added to prevent crashed on android
69
71
  accessibilityLabel: PropTypes.string,
@@ -108,6 +110,9 @@ export default class Pdf extends Component {
108
110
  },
109
111
  onPressLink: (url) => {
110
112
  },
113
+ enableTextSelection: true,
114
+ onTextSelectionChange: (event) => {
115
+ },
111
116
  onAutoScrollEnd: () => {
112
117
  },
113
118
  };
@@ -408,10 +413,29 @@ export default class Pdf extends Component {
408
413
  }
409
414
 
410
415
  _onChange = (event) => {
416
+ // Handle direct events for text selection/highlight
417
+ if (event.nativeEvent.type) {
418
+ this.props.onTextSelectionChange && this.props.onTextSelectionChange(event);
419
+ return;
420
+ }
411
421
 
412
422
  let message = event.nativeEvent.message.split('|');
413
423
  //__DEV__ && console.log("onChange: " + message);
414
424
  if (message.length > 0) {
425
+
426
+ // Handle text selection messages
427
+ if (message[0] === 'textSelected') {
428
+ this.props.onTextSelectionChange && this.props.onTextSelectionChange({
429
+ nativeEvent: { type: 'selectionChanged', text: message.slice(1).join('|') }
430
+ });
431
+ return;
432
+ } else if (message[0] === 'textSelectionCleared') {
433
+ this.props.onTextSelectionChange && this.props.onTextSelectionChange({
434
+ nativeEvent: { type: 'selectionCleared' }
435
+ });
436
+ return;
437
+ }
438
+
415
439
  if (message.length > 5) {
416
440
  message[4] = message.splice(4).join('|');
417
441
  }
@@ -21,6 +21,8 @@
21
21
  #import <React/RCTViewComponentView.h>
22
22
  #endif
23
23
 
24
+ #import <PDFKit/PDFKit.h>
25
+
24
26
  @class RCTEventDispatcher;
25
27
 
26
28
  NS_CLASS_AVAILABLE_IOS(11_0) @interface RNPDFPdfView :
@@ -54,6 +56,11 @@ UIView
54
56
 
55
57
  @property(nonatomic, copy) RCTBubblingEventBlock onChange;
56
58
 
59
+ @property(nonatomic, strong) NSString *selectedText;
60
+ @property(nonatomic) BOOL enableTextSelection;
61
+ @property(nonatomic, strong) PDFSelection *currentPDFSelection;
62
+
63
+ @property(nonatomic, copy) RCTBubblingEventBlock onTextSelectionChange;
57
64
 
58
65
  @end
59
66
 
@@ -289,6 +289,9 @@ using namespace facebook::react;
289
289
  _showsHorizontalScrollIndicator = YES;
290
290
  _showsVerticalScrollIndicator = YES;
291
291
  _scrollEnabled = YES;
292
+ _enableTextSelection = YES;
293
+ _selectedText = nil;
294
+ _currentPDFSelection = nil;
292
295
 
293
296
  // init and config PDFView
294
297
  _pdfView = [[PDFView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)];
@@ -334,6 +337,12 @@ using namespace facebook::react;
334
337
  }
335
338
 
336
339
  [self bindTap];
340
+
341
+ // Register for selection change notifications
342
+ [[NSNotificationCenter defaultCenter] addObserver:self
343
+ selector:@selector(handleSelectionChanged:)
344
+ name:PDFViewSelectionChangedNotification
345
+ object:_pdfView];
337
346
  }
338
347
 
339
348
  - (void)PDFViewWillClickOnLink:(PDFView *)sender withURL:(NSURL *)url
@@ -345,6 +354,28 @@ using namespace facebook::react;
345
354
  @"linkPressed|%s", _url.UTF8String]]];
346
355
  }
347
356
 
357
+ - (void)handleSelectionChanged:(NSNotification *)notification
358
+ {
359
+ if (!_enableTextSelection || notification.object != _pdfView) return;
360
+
361
+ // Store a copy of the selection to avoid it being cleared
362
+ _currentPDFSelection = [_pdfView.currentSelection copy];
363
+
364
+ if (_currentPDFSelection && _currentPDFSelection.string.length > 0) {
365
+ _selectedText = _currentPDFSelection.string;
366
+
367
+ // Use the existing onChange callback with a message format
368
+ [self notifyOnChangeWithMessage:
369
+ [[NSString alloc] initWithString:
370
+ [NSString stringWithFormat:@"textSelected|%@", _selectedText]]];
371
+ } else {
372
+ _selectedText = nil;
373
+
374
+ // Use the existing onChange callback for clearing
375
+ [self notifyOnChangeWithMessage:@"textSelectionCleared"];
376
+ }
377
+ }
378
+
348
379
  - (void)didSetProps:(NSArray<NSString *> *)changedProps
349
380
  {
350
381
  if (!_initialed) {
@@ -542,13 +573,15 @@ using namespace facebook::react;
542
573
 
543
574
  PDFPage *pdfPage = [_pdfDocument pageAtIndex:_page-1];
544
575
  if (pdfPage && _page == 1) {
545
- // goToDestination() would be better. However, there is an
546
- // error in the pointLeftTop computation that often results in
547
- // scrolling to the middle of the page.
548
- // Special case workaround to make starting at the first page
549
- // align acceptably.
550
576
  dispatch_async(dispatch_get_main_queue(), ^{
551
- [self->_pdfView goToRect:CGRectMake(0, NSUIntegerMax, 1, 1) onPage:pdfPage];
577
+ [self->_pdfView goToFirstPage:nil];
578
+ for (UIView *subview in self->_pdfView.subviews) {
579
+ if ([subview isKindOfClass:[UIScrollView class]]) {
580
+ UIScrollView *scrollView = (UIScrollView *)subview;
581
+ [scrollView setContentOffset:CGPointMake(0, 0) animated:NO];
582
+ break;
583
+ }
584
+ }
552
585
  });
553
586
  } else if (pdfPage) {
554
587
  CGRect pdfPageRect = [pdfPage boundsForBox:kPDFDisplayBoxCropBox];
@@ -610,7 +643,8 @@ using namespace facebook::react;
610
643
  [[NSNotificationCenter defaultCenter] removeObserver:self name:@"PDFViewDocumentChangedNotification" object:nil];
611
644
  [[NSNotificationCenter defaultCenter] removeObserver:self name:@"PDFViewPageChangedNotification" object:nil];
612
645
  [[NSNotificationCenter defaultCenter] removeObserver:self name:@"PDFViewScaleChangedNotification" object:nil];
613
-
646
+ [[NSNotificationCenter defaultCenter] removeObserver:self name:PDFViewSelectionChangedNotification object:nil];
647
+
614
648
  _doubleTapRecognizer = nil;
615
649
  _singleTapRecognizer = nil;
616
650
  _pinchRecognizer = nil;
@@ -51,6 +51,30 @@ RCT_EXPORT_VIEW_PROPERTY(spacing, int);
51
51
  RCT_EXPORT_VIEW_PROPERTY(password, NSString);
52
52
  RCT_EXPORT_VIEW_PROPERTY(onChange, RCTBubblingEventBlock);
53
53
  RCT_EXPORT_VIEW_PROPERTY(singlePage, BOOL);
54
+ RCT_EXPORT_VIEW_PROPERTY(enableTextSelection, BOOL);
55
+ RCT_EXPORT_VIEW_PROPERTY(onTextSelectionChange, RCTBubblingEventBlock);
56
+
57
+ RCT_EXPORT_METHOD(startAutoScroll:(nonnull NSNumber *)reactTag
58
+ pixels:(double)pixels
59
+ resumeDelay:(double)resumeDelay)
60
+ {
61
+ [self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
62
+ RNPDFPdfView *view = (RNPDFPdfView *)viewRegistry[reactTag];
63
+ if ([view isKindOfClass:[RNPDFPdfView class]]) {
64
+ [view startAutoScroll:(CGFloat)pixels resumeDelay:(NSTimeInterval)(resumeDelay / 1000.0)];
65
+ }
66
+ }];
67
+ }
68
+
69
+ RCT_EXPORT_METHOD(stopAutoScroll:(nonnull NSNumber *)reactTag)
70
+ {
71
+ [self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
72
+ RNPDFPdfView *view = (RNPDFPdfView *)viewRegistry[reactTag];
73
+ if ([view isKindOfClass:[RNPDFPdfView class]]) {
74
+ [view stopAutoScroll];
75
+ }
76
+ }];
77
+ }
54
78
 
55
79
  RCT_EXPORT_METHOD(startAutoScroll:(nonnull NSNumber *)reactTag
56
80
  pixels:(double)pixels
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@amafil/react-native-pdf-toolkit",
3
- "version": "1.0.8",
3
+ "version": "1.0.9",
4
4
  "summary": "A react native PDF view component",
5
5
  "description": "A react native PDF view component, support ios and android platform",
6
6
  "main": "index.js",