Skip to main content

ClipboardModel

A utility class for interacting with the system clipboard, providing methods to read and write various types of data including text, HTML, and images.

Class Methods

readText()

Reads plain text from the system clipboard.

Returns: Promise resolving to the clipboard text content or null if the operation fails

Example:

const text = await ClipboardModel.readText();
if (text) {
console.log("Clipboard text:", text);
}

readClipboardDataAsText()

Reads text data from the clipboard using the Clipboard API.

Returns: Promise resolving to the clipboard text content or null if no text data is available

Example:

const text = await ClipboardModel.readClipboardDataAsText();
if (text) {
console.log("Clipboard text:", text);
}

readClipboardDataAsHTML()

Reads HTML content from the clipboard using the Clipboard API.

Returns: Promise resolving to the clipboard HTML content or null if no HTML data is available

Example:

const html = await ClipboardModel.readClipboardDataAsHTML();
if (html) {
console.log("Clipboard HTML:", html);
}

readClipboardDataAsImage()

Reads image data from the clipboard using the Clipboard API.

Parameters:

  • options: Optional configuration object
    • asBlob: If true, returns the image as a Blob. If false, returns a blob URL string

Returns: Promise resolving to either a Blob, blob URL string, or null if no image data is available

Example:

// Get as blob URL
const imageUrl = await ClipboardModel.readClipboardDataAsImage();
if (imageUrl) {
const img = new Image();
img.src = imageUrl;
}

// Get as blob
const imageBlob = await ClipboardModel.readClipboardDataAsImage({
asBlob: true,
});
if (imageBlob) {
// Use the blob directly
}

copyText()

Copies text to the system clipboard.

Parameters:

  • text: The text string to copy to the clipboard

Example:

await ClipboardModel.copyText("Hello, World!");

hasTextCopied()

Checks if the clipboard contains text data.

Returns: Promise resolving to true if text data is available in the clipboard

Example:

const hasText = await ClipboardModel.hasTextCopied();
if (hasText) {
// Handle text data
}

hasImageCopied()

Checks if the clipboard contains image data.

Returns: Promise resolving to true if image data is available in the clipboard

Example:

const hasImage = await ClipboardModel.hasImageCopied();
if (hasImage) {
// Handle image data
}

copyImage()

Copies an image to the clipboard from a given path.

Parameters:

  • path: The path or URL of the image to copy
  • mimeType: The MIME type of the image (e.g., "image/png", "image/jpeg")

Example:

await ClipboardModel.copyImage("path/to/image.png", "image/png");

Private Methods

The class includes several private utility methods:

  • copyBlobToClipboard: Handles copying blob data to clipboard
  • createClipboardItem: Creates a ClipboardItem from blob data
  • setCanvasImage: Converts image path to blob using canvas

Class

export default class ClipboardModel {
static async readText() {
try {
return await navigator.clipboard.readText();
} catch (err) {
return null;
}
}

static async readClipboardDataAsText() {
if (await ClipboardModel.hasTextCopied()) {
const [clipboardItem] = await navigator.clipboard.read();
let blob = await clipboardItem.getType("text/plain");
return blob.text();
}
return null;
}

static async readClipboardDataAsHTML() {
if (await ClipboardModel.hasTextCopied()) {
const [clipboardItem] = await navigator.clipboard.read();
let blob = await clipboardItem.getType("text/html");
return blob.text();
}
return null;
}

static async readClipboardDataAsImage(options?: { asBlob?: boolean }) {
if (await ClipboardModel.hasImageCopied()) {
const [clipboardItem] = await navigator.clipboard.read();
const mimeType = clipboardItem.types.find((type) =>
type.startsWith("image/")
);
if (!mimeType) return null;
const blob = await clipboardItem.getType(mimeType);
if (options?.asBlob) {
return blob;
}
const blobUrl = URL.createObjectURL(blob);
return blobUrl;
}
return null;
}

static async copyText(text: string) {
await navigator.clipboard.writeText(text);
}

static async hasTextCopied() {
const [clipboardItem] = await navigator.clipboard.read();
const typeMapping = clipboardItem.types.map((type) => type.split("/")[0]);
return typeMapping.includes("text");
}

static async hasImageCopied() {
const [clipboardItem] = await navigator.clipboard.read();
const typeMapping = clipboardItem.types.map((type) => type.split("/")[0]);
return typeMapping.includes("image");
}

static async copyImage(path: string, mimeType: `image/${string}`) {
if (mimeType === "image/png") {
const response = await fetch(path);
const imageBlob = await response.blob();
await ClipboardModel.copyBlobToClipboard(imageBlob, mimeType);
} else {
const imageBlob = await ClipboardModel.setCanvasImage(path);
await ClipboardModel.copyBlobToClipboard(imageBlob, mimeType);
}
}

private static async copyBlobToClipboard(blob: Blob, mimeType: string) {
const data = [ClipboardModel.createClipboardItem(blob, mimeType)];
await navigator.clipboard.write(data);
}

private static createClipboardItem(blob: Blob, mimeType: string) {
const _blob = new Blob([blob], { type: mimeType });
return new ClipboardItem({ [mimeType]: _blob });
}

private static setCanvasImage(path: string): Promise<Blob> {
return new Promise((resolve, reject) => {
const img = new Image();
const c = document.createElement("canvas");
const ctx = c.getContext("2d")!;

img.onload = function () {
c.width = img.naturalWidth;
c.height = img.naturalHeight;
ctx.drawImage(img, 0, 0);
c.toBlob((blob) => {
if (!blob) {
reject("Failed to convert canvas to blob");
} else {
resolve(blob);
}
}, `image/png`);
};
img.src = path;
});
}
}