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

feat(clipboard): remove Clipboard.read() options #2527

Merged
merged 1 commit into from
Mar 5, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public void write(PluginCall call) {
if(strVal != null) {
data = ClipData.newPlainText(label, strVal);
} else if(imageVal != null) {
// Does nothing
data = ClipData.newPlainText(label, imageVal);
} else if(urlVal != null) {
data = ClipData.newPlainText(label, urlVal);
}
Expand All @@ -45,24 +45,26 @@ public void write(PluginCall call) {
public void read(PluginCall call) {
Context c = this.getContext();

String type = call.getString("type");
ClipboardManager clipboard = (ClipboardManager)
c.getSystemService(Context.CLIPBOARD_SERVICE);

CharSequence value = "";
if(clipboard.getPrimaryClipDescription().hasMimeType(ClipDescription.MIMETYPE_TEXT_PLAIN)) {
Log.d(getLogTag(), "Got plaintxt");
ClipData.Item item = clipboard.getPrimaryClip().getItemAt(0);

JSObject ret = new JSObject();
ret.put("value", item.getText());
call.success(ret);
value = item.getText();
} else {
Log.d(getLogTag(), "Not plaintext!");
ClipData.Item item = clipboard.getPrimaryClip().getItemAt(0);
String value = item.coerceToText(this.getContext()).toString();
JSObject ret = new JSObject();
ret.put("value", value);
call.success(ret);
value = item.coerceToText(this.getContext()).toString();
}
JSObject ret = new JSObject();
String type = "text/plain";
ret.put("value", value != null ? value : "");
if (value != null && value.toString().startsWith("data:")) {
type = value.toString().split(";")[0].split(":")[1];
}
ret.put("type", type);
call.success(ret);
}
}
7 changes: 2 additions & 5 deletions core/src/core-plugin-definitions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,7 @@ export interface ClipboardPlugin extends Plugin {
/**
* Read a value from the clipboard (the "paste" action)
*/
read(options: ClipboardRead): Promise<ClipboardReadResult>;
read(): Promise<ClipboardReadResult>;
}

export interface ClipboardWrite {
Expand All @@ -390,12 +390,9 @@ export interface ClipboardWrite {
label?: string; // Android only
}

export interface ClipboardRead {
type: 'string' | 'url' | 'image';
}

export interface ClipboardReadResult {
value: string;
type: string;
}

//
Expand Down
36 changes: 22 additions & 14 deletions core/src/web/clipboard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { WebPlugin } from './index';
import {
ClipboardPlugin,
ClipboardWrite,
ClipboardRead,
ClipboardReadResult
} from '../core-plugin-definitions';

Expand All @@ -23,7 +22,7 @@ export class ClipboardPluginWeb extends WebPlugin implements ClipboardPlugin {
return Promise.reject('Clipboard API not available in this browser');
}

if (options.string || options.url) {
if (options.string !== undefined || options.url) {
if (!navigator.clipboard.writeText) {
return Promise.reject('Writting to clipboard not supported in this browser');
}
Expand All @@ -45,32 +44,41 @@ export class ClipboardPluginWeb extends WebPlugin implements ClipboardPlugin {
return Promise.resolve();
}

async read(_options: ClipboardRead): Promise<ClipboardReadResult> {
async read(): Promise<ClipboardReadResult> {
if (!navigator.clipboard) {
return Promise.reject('Clipboard API not available in this browser');
}
if (_options.type === 'string' || _options.type === 'url') {
if (!navigator.clipboard.read) {
if (!navigator.clipboard.readText) {
return Promise.reject('Reading from clipboard not supported in this browser');
}
const text = await navigator.clipboard.readText();
return Promise.resolve({ value: text});
return this.readText();
} else {
if (navigator.clipboard.read) {
try {
const clipboardItems = await navigator.clipboard.read();
const imgBlob = await clipboardItems[0].getType('image/png');
const data = await this._getBlobData(imgBlob);
return Promise.resolve({ value: data});
} else {
return Promise.reject('Reading images not supported in this browser');
const type = clipboardItems[0].types[0];
const clipboardBlob = await clipboardItems[0].getType(type);
const data = await this._getBlobData(clipboardBlob, type);
return Promise.resolve({ value: data, type});
} catch (err) {
return this.readText();
}
}
}

private _getBlobData(imgBlob: Blob) {
private async readText() {
const text = await navigator.clipboard.readText();
return Promise.resolve({ value: text, type: 'text/plain'});
}

private _getBlobData(clipboardBlob: Blob, type: string) {
return new Promise<string>((resolve, reject) => {
var reader = new FileReader();
reader.readAsDataURL(imgBlob);
if (type.includes('image')) {
reader.readAsDataURL(clipboardBlob);
} else {
reader.readAsText(clipboardBlob);
}
reader.onloadend = () => {
const r = reader.result as string;
resolve(r);
Expand Down
65 changes: 30 additions & 35 deletions ios/Capacitor/Capacitor/Plugins/Clipboard.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public class CAPClipboardPlugin : CAPPlugin {
UIPasteboard.general.url = url
}
} else if let imageBase64 = call.options["image"] as? String {
if let data = Data(base64Encoded: imageBase64) {
if let data = Data(base64Encoded: getCleanData(imageBase64)) {
let image = UIImage(data: data)
CAPLog.print("Loaded image", image!.size.width, image!.size.height)
UIPasteboard.general.image = image
Expand All @@ -21,48 +21,43 @@ public class CAPClipboardPlugin : CAPPlugin {
call.success()
}

@objc func read(_ call: CAPPluginCall) {
let type = call.options["type"] as? String ?? "string"
// TODO - move to helper class
func getCleanData(_ data: String) -> String {
let dataParts = data.split(separator: ",")
var cleanData = data
if dataParts.count > 0 {
cleanData = String(dataParts.last!)
}
return cleanData
}

if type == "string" {
if UIPasteboard.general.hasStrings {
call.success([
"value": UIPasteboard.general.string!
])
} else {
call.error("Unable to get string from clipboard")
}
@objc func read(_ call: CAPPluginCall) {
if UIPasteboard.general.hasStrings {
call.success([
"value": UIPasteboard.general.string!,
"type": "text/html"
])
return
}

if type == "url" {
if UIPasteboard.general.hasURLs {
let url = UIPasteboard.general.url!
call.success([
"value": url.absoluteString
])
} else {
call.error("Unable to get url from clipboard")
}
if UIPasteboard.general.hasURLs {
let url = UIPasteboard.general.url!
call.success([
"value": url.absoluteString,
"type": "text/html"
])
return
}

if type == "image" {
if UIPasteboard.general.hasImages {
let image = UIPasteboard.general.image!
let data = image.pngData()
if let base64 = data?.base64EncodedString() {
call.success([
"value": base64
])
}
} else {
call.error("Unable to get image from clipboard")
if UIPasteboard.general.hasImages {
let image = UIPasteboard.general.image!
let data = image.pngData()
if let base64 = data?.base64EncodedString() {
call.success([
"value": "data:image/png;base64," + base64,
"type": "image/png"
])
}
return
}

call.error("Invalid type")
}
}

Expand Down