Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add onPaste to TextInput #45425

Draft
wants to merge 20 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Pass URI instead of base64 encoded data for files
  • Loading branch information
s77rt committed Aug 5, 2024
commit 8bf252a13b44d64e961735b791b017de1e72a4d7
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#import <React/RCTBackedTextInputDelegateAdapter.h>
#import <React/RCTTextAttributes.h>

#import <MobileCoreServices/UTType.h>
#import <UIKit/UIKit.h>

@implementation RCTUITextView {
Expand Down Expand Up @@ -176,45 +177,26 @@ - (void)paste:(id)sender
_textWasPasted = YES;
UIPasteboard *clipboard = [UIPasteboard generalPasteboard];
if (clipboard.hasImages) {
NSArray *clipboardTypes = [clipboard pasteboardTypes];
if ([clipboardTypes containsObject:@"com.compuserve.gif"]) {
NSString *type = @"image/gif";
NSString *encodedData = [[clipboard dataForPasteboardType:@"com.compuserve.gif"] base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
NSString *data = [NSString stringWithFormat:@"data:%@;base64,%@", type, encodedData];
[_textInputDelegateAdapter didPaste:type withData:data];
} else if ([clipboardTypes containsObject:@"public.png"]) {
NSString *type = @"image/png";
NSString *encodedData = [[clipboard dataForPasteboardType:@"public.png"] base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
NSString *data = [NSString stringWithFormat:@"data:%@;base64,%@", type, encodedData];
[_textInputDelegateAdapter didPaste:type withData:data];
} else if ([clipboardTypes containsObject:@"public.jpeg"]) {
NSString *type = @"image/jpeg";
NSString *encodedData = [[clipboard dataForPasteboardType:@"public.jpeg"] base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
NSString *data = [NSString stringWithFormat:@"data:%@;base64,%@", type, encodedData];
[_textInputDelegateAdapter didPaste:type withData:data];
} else if ([clipboardTypes containsObject:@"org.webmproject.webp"]) {
NSString *type = @"image/webp";
NSString *encodedData = [[clipboard dataForPasteboardType:@"org.webmproject.webp"] base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
NSString *data = [NSString stringWithFormat:@"data:%@;base64,%@", type, encodedData];
[_textInputDelegateAdapter didPaste:type withData:data];
} else if ([clipboardTypes containsObject:@"public.tiff"]) {
NSString *type = @"image/tiff";
NSString *encodedData = [[clipboard dataForPasteboardType:@"public.tiff"] base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
NSString *data = [NSString stringWithFormat:@"data:%@;base64,%@", type, encodedData];
[_textInputDelegateAdapter didPaste:type withData:data];
} else if ([clipboardTypes containsObject:@"com.microsoft.bmp"]) {
NSString *type = @"image/bmp";
NSString *encodedData = [[clipboard dataForPasteboardType:@"com.microsoft.bmp"] base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
NSString *data = [NSString stringWithFormat:@"data:%@;base64,%@", type, encodedData];
[_textInputDelegateAdapter didPaste:type withData:data];
} else if ([clipboardTypes containsObject:@"public.svg-image"]) {
NSString *type = @"image/svg+xml";
NSString *encodedData = [[clipboard dataForPasteboardType:@"public.svg-image"] base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
NSString *data = [NSString stringWithFormat:@"data:%@;base64,%@", type, encodedData];
[_textInputDelegateAdapter didPaste:type withData:data];
for (NSItemProvider *itemProvider in [clipboard itemProviders]) {
if ([itemProvider canLoadObjectOfClass:[UIImage class]]) {
NSString *identifier = itemProvider.registeredTypeIdentifiers.firstObject;
if (identifier != nil) {
NSString *MIMEType = (__bridge_transfer NSString *)UTTypeCopyPreferredTagWithClass((__bridge CFStringRef)identifier, kUTTagClassMIMEType);
NSString *fileExtension = (__bridge_transfer NSString *)UTTypeCopyPreferredTagWithClass((__bridge CFStringRef)identifier, kUTTagClassFilenameExtension);
NSString *fileName = [NSString stringWithFormat:@"%@.%@", itemProvider.suggestedName ?: @"file", fileExtension];
NSString *filePath = [NSTemporaryDirectory() stringByAppendingPathComponent:fileName];
NSURL *fileURL = [NSURL fileURLWithPath:filePath];
NSData *fileData = [clipboard dataForPasteboardType:identifier];
[fileData writeToFile:filePath atomically:YES];
[_textInputDelegateAdapter didPaste:MIMEType withData:[fileURL absoluteString]];
}
break;
}
}
} else {
[_textInputDelegateAdapter didPaste:@"text/plain" withData:clipboard.string];
if (clipboard.hasStrings) {
[_textInputDelegateAdapter didPaste:@"text/plain" withData:clipboard.string];
}
[super paste:sender];
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#import <React/RCTUtils.h>
#import <React/UIView+React.h>

#import <MobileCoreServices/UTType.h>
#import <UIKit/UIKit.h>

@implementation RCTUITextField {
Expand Down Expand Up @@ -230,45 +231,26 @@ - (void)paste:(id)sender
_textWasPasted = YES;
UIPasteboard *clipboard = [UIPasteboard generalPasteboard];
if (clipboard.hasImages) {
NSArray *clipboardTypes = [clipboard pasteboardTypes];
if ([clipboardTypes containsObject:@"com.compuserve.gif"]) {
NSString *type = @"image/gif";
NSString *encodedData = [[clipboard dataForPasteboardType:@"com.compuserve.gif"] base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
NSString *data = [NSString stringWithFormat:@"data:%@;base64,%@", type, encodedData];
[_textInputDelegateAdapter didPaste:type withData:data];
} else if ([clipboardTypes containsObject:@"public.png"]) {
NSString *type = @"image/png";
NSString *encodedData = [[clipboard dataForPasteboardType:@"public.png"] base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
NSString *data = [NSString stringWithFormat:@"data:%@;base64,%@", type, encodedData];
[_textInputDelegateAdapter didPaste:type withData:data];
} else if ([clipboardTypes containsObject:@"public.jpeg"]) {
NSString *type = @"image/jpeg";
NSString *encodedData = [[clipboard dataForPasteboardType:@"public.jpeg"] base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
NSString *data = [NSString stringWithFormat:@"data:%@;base64,%@", type, encodedData];
[_textInputDelegateAdapter didPaste:type withData:data];
} else if ([clipboardTypes containsObject:@"org.webmproject.webp"]) {
NSString *type = @"image/webp";
NSString *encodedData = [[clipboard dataForPasteboardType:@"org.webmproject.webp"] base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
NSString *data = [NSString stringWithFormat:@"data:%@;base64,%@", type, encodedData];
[_textInputDelegateAdapter didPaste:type withData:data];
} else if ([clipboardTypes containsObject:@"public.tiff"]) {
NSString *type = @"image/tiff";
NSString *encodedData = [[clipboard dataForPasteboardType:@"public.tiff"] base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
NSString *data = [NSString stringWithFormat:@"data:%@;base64,%@", type, encodedData];
[_textInputDelegateAdapter didPaste:type withData:data];
} else if ([clipboardTypes containsObject:@"com.microsoft.bmp"]) {
NSString *type = @"image/bmp";
NSString *encodedData = [[clipboard dataForPasteboardType:@"com.microsoft.bmp"] base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
NSString *data = [NSString stringWithFormat:@"data:%@;base64,%@", type, encodedData];
[_textInputDelegateAdapter didPaste:type withData:data];
} else if ([clipboardTypes containsObject:@"public.svg-image"]) {
NSString *type = @"image/svg+xml";
NSString *encodedData = [[clipboard dataForPasteboardType:@"public.svg-image"] base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
NSString *data = [NSString stringWithFormat:@"data:%@;base64,%@", type, encodedData];
[_textInputDelegateAdapter didPaste:type withData:data];
for (NSItemProvider *itemProvider in [clipboard itemProviders]) {
if ([itemProvider canLoadObjectOfClass:[UIImage class]]) {
NSString *identifier = itemProvider.registeredTypeIdentifiers.firstObject;
if (identifier != nil) {
NSString *MIMEType = (__bridge_transfer NSString *)UTTypeCopyPreferredTagWithClass((__bridge CFStringRef)identifier, kUTTagClassMIMEType);
NSString *fileExtension = (__bridge_transfer NSString *)UTTypeCopyPreferredTagWithClass((__bridge CFStringRef)identifier, kUTTagClassFilenameExtension);
NSString *fileName = [NSString stringWithFormat:@"%@.%@", itemProvider.suggestedName ?: @"file", fileExtension];
NSString *filePath = [NSTemporaryDirectory() stringByAppendingPathComponent:fileName];
NSURL *fileURL = [NSURL fileURLWithPath:filePath];
NSData *fileData = [clipboard dataForPasteboardType:identifier];
[fileData writeToFile:filePath atomically:YES];
[_textInputDelegateAdapter didPaste:MIMEType withData:[fileURL absoluteString]];
}
break;
}
}
} else {
[_textInputDelegateAdapter didPaste:@"text/plain" withData:clipboard.string];
if (clipboard.hasStrings) {
[_textInputDelegateAdapter didPaste:@"text/plain" withData:clipboard.string];
}
[super paste:sender];
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
import android.text.TextWatcher;
import android.text.method.KeyListener;
import android.text.method.QwertyKeyListener;
import android.util.Base64;
import android.util.TypedValue;
import android.view.ActionMode;
import android.view.Gravity;
Expand Down Expand Up @@ -74,7 +73,6 @@
import com.facebook.react.views.text.internal.span.ReactUnderlineSpan;
import com.facebook.react.views.text.internal.span.TextInlineImageSpan;
import com.facebook.react.views.view.ReactViewBackgroundManager;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Objects;

Expand Down Expand Up @@ -346,14 +344,7 @@ public boolean onTextContextMenuItem(int id) {
if (itemUri != null) {
ContentResolver cr = getReactContext(this).getContentResolver();
type = cr.getType(itemUri);
if (type != null) {
try {
String encodedData = Base64.encodeToString(cr.openInputStream(itemUri).readAllBytes(), Base64.DEFAULT);
data = "data:" + type + ";base64," + encodedData;
} catch (IOException e) {
e.printStackTrace();
}
}
data = itemUri.toString();
}
}
if (type != null && data != null) {
Expand Down
Loading