Skip to content

Commit

Permalink
feat: multiple type can be detected
Browse files Browse the repository at this point in the history
  • Loading branch information
telesoho committed Sep 16, 2024
1 parent 026f367 commit 789c4da
Show file tree
Hide file tree
Showing 7 changed files with 162 additions and 247 deletions.
28 changes: 28 additions & 0 deletions src/clipboard/base_clipboard.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { URL } from "url";
import { ClipboardType, IClipboard } from "../clipboard_interface";

export abstract class BaseClipboard implements IClipboard {
abstract getImage(imagePath: string): Promise<string>;
abstract getTextPlain(): Promise<string>;
abstract getTextHtml(): Promise<string>;
abstract copyImage(imageFile: URL): Promise<boolean>;
abstract copyTextPlain(textFile: URL): Promise<boolean>;
abstract copyTextHtml(htmlFile: URL): Promise<boolean>;
abstract getContentType(): Promise<Set<ClipboardType> | ClipboardType>;

abstract onDetectType(types: string[]): Set<ClipboardType>;

detectType(types: string[]): Set<ClipboardType> | ClipboardType {
if (!types) {
return ClipboardType.Unknown;
}

const detectedTypes = this.onDetectType(types);
if (detectedTypes.size == 1) {
return detectedTypes.values().next().value;
} else if (detectedTypes.size > 1) {
return detectedTypes;
}
return ClipboardType.Unknown;
}
}
70 changes: 24 additions & 46 deletions src/clipboard/darwin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { ClipboardType, IClipboard } from "../clipboard_interface";
import { getShell } from "../os";
import * as path from "path";
import { stripFinalNewline } from "../utils";
import { BaseClipboard } from "./base_clipboard";

function darwin_HextoHtml(str: string) {
const regex = /«data HTML(.*?)»/;
Expand All @@ -19,49 +20,7 @@ function darwin_HextoHtml(str: string) {
return buff.toString("utf8");
}

/**
* Detected the type of content in the clipboard
* Detect order: Image > Html > Text
* @param types string[]
* @returns ClipboardType
*/
function detectType(types: string[]): ClipboardType {
if (!types) {
return ClipboardType.Unknown;
}

const detectedTypes = new Set();
for (const type of types) {
switch (type) {
case "Text":
detectedTypes.add(ClipboardType.Text);
break;
case "HTML":
detectedTypes.add(ClipboardType.Html);
break;
case "Image":
detectedTypes.add(ClipboardType.Image);
break;
}
}
// Set priority based on which to return type
const priorityOrdering = [
ClipboardType.Image,
ClipboardType.Html,
ClipboardType.Text,
];
if (
detectedTypes.has(ClipboardType.Image) &&
detectedTypes.has(ClipboardType.Html)
) {
return ClipboardType.Html;
}
for (const type of priorityOrdering) if (detectedTypes.has(type)) return type;
// No known types detected
return ClipboardType.Unknown;
}

class DarwinClipboard implements IClipboard {
class DarwinClipboard extends BaseClipboard {
SCRIPT_PATH = "../../res/scripts/";

async copyImage(imageFile: URL): Promise<boolean> {
Expand Down Expand Up @@ -115,7 +74,26 @@ class DarwinClipboard implements IClipboard {
return false;
}
}
async getContentType(): Promise<ClipboardType> {

onDetectType(types: string[]): Set<ClipboardType> {
const detectedTypes = new Set<ClipboardType>();
for (const type of types) {
switch (type) {
case "Text":
detectedTypes.add(ClipboardType.Text);
break;
case "HTML":
detectedTypes.add(ClipboardType.Html);
break;
case "Image":
detectedTypes.add(ClipboardType.Image);
break;
}
}
return detectedTypes;
}

async getContentType(): Promise<Set<ClipboardType> | ClipboardType> {
const script = path.join(
__dirname,
this.SCRIPT_PATH,
Expand All @@ -128,7 +106,7 @@ class DarwinClipboard implements IClipboard {
console.debug("getClipboardContentType", data);
const types = data.split(/\r\n|\n|\r/);

return detectType(types);
return this.detectType(types);
} catch (e) {
return ClipboardType.Unknown;
}
Expand Down Expand Up @@ -168,4 +146,4 @@ class DarwinClipboard implements IClipboard {
}
}

export { DarwinClipboard, detectType };
export { DarwinClipboard };
77 changes: 28 additions & 49 deletions src/clipboard/linux.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,53 +3,9 @@ import { ClipboardType, IClipboard } from "../clipboard_interface";
import { getShell } from "../os";
import * as path from "path";
import { stripFinalNewline } from "../utils";
import { BaseClipboard } from "./base_clipboard";

/**
* Detected the type of content in the clipboard
* Detect order: Image > Html > Text
* @param types string[]
* @returns ClipboardType
*/
function detectType(types: string[]): ClipboardType {
if (!types) {
return ClipboardType.Unknown;
}

const detectedTypes = new Set();
for (const type of types) {
switch (type) {
case "no xclip":
console.error("You need to install xclip command first.");
return ClipboardType.Unknown;
case "image/png":
detectedTypes.add(ClipboardType.Image);
break;
case "text/html":
detectedTypes.add(ClipboardType.Html);
break;
default:
detectedTypes.add(ClipboardType.Text);
break;
}
}
// Set priority based on which to return type
const priorityOrdering = [
ClipboardType.Image,
ClipboardType.Html,
ClipboardType.Text,
];
if (
detectedTypes.has(ClipboardType.Image) &&
detectedTypes.has(ClipboardType.Html)
) {
return ClipboardType.Html;
}
for (const type of priorityOrdering) if (detectedTypes.has(type)) return type;
// No known types detected
return ClipboardType.Unknown;
}

class LinuxClipboard implements IClipboard {
class LinuxClipboard extends BaseClipboard {
SCRIPT_PATH = "../../res/scripts/";

async copyImage(imageFile: URL): Promise<boolean> {
Expand Down Expand Up @@ -103,7 +59,30 @@ class LinuxClipboard implements IClipboard {
return false;
}
}
async getContentType(): Promise<ClipboardType> {
onDetectType(types: string[]): Set<ClipboardType> {
const detectedTypes = new Set<ClipboardType>();

for (const type of types) {
switch (type) {
case "no xclip":
console.error("You need to install xclip command first.");
detectedTypes.add(ClipboardType.Unknown);
return detectedTypes;
case "image/png":
detectedTypes.add(ClipboardType.Image);
break;
case "text/html":
detectedTypes.add(ClipboardType.Html);
break;
default:
detectedTypes.add(ClipboardType.Text);
break;
}
}
return detectedTypes;
}

async getContentType(): Promise<Set<ClipboardType> | ClipboardType> {
const script = path.join(
__dirname,
this.SCRIPT_PATH,
Expand All @@ -116,7 +95,7 @@ class LinuxClipboard implements IClipboard {
console.debug("getClipboardContentType", data);
const types = data.split(/\r\n|\n|\r/);

return detectType(types);
return this.detectType(types);
} catch (e) {
return ClipboardType.Unknown;
}
Expand Down Expand Up @@ -156,4 +135,4 @@ class LinuxClipboard implements IClipboard {
}
}

export { LinuxClipboard, detectType };
export { LinuxClipboard };
74 changes: 25 additions & 49 deletions src/clipboard/win10.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,53 +3,9 @@ import { ClipboardType, IClipboard } from "../clipboard_interface";
import { getShell } from "../os";
import * as path from "path";
import { stripFinalNewline } from "../utils";
import { BaseClipboard } from "./base_clipboard";

/**
* Detected the type of content in the clipboard
* Detect order: Image > Html > Text
* @param types string[]
* @returns ClipboardType
*/
function detectType(types: string[]): ClipboardType {
if (!types) {
return ClipboardType.Unknown;
}

const detectedTypes = new Set();
for (const type of types) {
switch (type) {
case "PNG":
case "Bitmap":
case "DeviceIndependentBitmap":
detectedTypes.add(ClipboardType.Image);
break;
case "HTML Format":
detectedTypes.add(ClipboardType.Html);
break;
case "Text":
case "UnicodeText":
detectedTypes.add(ClipboardType.Text);
break;
}
}
// Set priority based on which to return type
const priorityOrdering = [
ClipboardType.Image,
ClipboardType.Html,
ClipboardType.Text,
];
if (
detectedTypes.has(ClipboardType.Image) &&
detectedTypes.has(ClipboardType.Html)
) {
return ClipboardType.Html;
}
for (const type of priorityOrdering) if (detectedTypes.has(type)) return type;
// No known types detected
return ClipboardType.Unknown;
}

class Win10Clipboard implements IClipboard {
class Win10Clipboard extends BaseClipboard {
SCRIPT_PATH = "../../res/scripts/";

async copyImage(imageFile: URL): Promise<boolean> {
Expand Down Expand Up @@ -103,7 +59,27 @@ class Win10Clipboard implements IClipboard {
return false;
}
}
async getContentType(): Promise<ClipboardType> {
onDetectType(types: string[]): Set<ClipboardType> {
const detectedTypes = new Set<ClipboardType>();
for (const type of types) {
switch (type) {
case "PNG":
case "Bitmap":
case "DeviceIndependentBitmap":
detectedTypes.add(ClipboardType.Image);
break;
case "HTML Format":
detectedTypes.add(ClipboardType.Html);
break;
case "Text":
case "UnicodeText":
detectedTypes.add(ClipboardType.Text);
break;
}
}
return detectedTypes;
}
async getContentType(): Promise<Set<ClipboardType> | ClipboardType> {
const script = path.join(
__dirname,
this.SCRIPT_PATH,
Expand All @@ -116,7 +92,7 @@ class Win10Clipboard implements IClipboard {
console.debug("getClipboardContentType", data);
const types = data.split(/\r\n|\n|\r/);

return detectType(types);
return this.detectType(types);
} catch (e) {
return ClipboardType.Unknown;
}
Expand Down Expand Up @@ -156,4 +132,4 @@ class Win10Clipboard implements IClipboard {
}
}

export { Win10Clipboard, detectType };
export { Win10Clipboard };
Loading

0 comments on commit 789c4da

Please sign in to comment.