carl.hiass
carl.hiass

Reputation: 1784

Grabbing partial data from the clipboard in javascript

I have copied an Excel table which is about a million rows. When I look at the clipboard on my system, it seems to contain about 250MB of data. However, I only need to grab the styling information from it, for example:

enter image description here

This entire data comes out to (far) less than 1MB of data. Is there a way to read the clipboard as if it were a file or stream, so that I can just do, for example:

clipboard.read(1024)

Otherwise, if I do the straight:

evt.clipboardData.getData('text/html')

And grab the section of data I want after getting the data, it takes me over 10 seconds to do! Whereas I believe the event should only take 0.1s or so, if I'm able to read the clipboard data in a partial manner, as if it were a file.

What can I do here? Is it possible to use FileReader on the clipboard? If so, how could that be done?

Upvotes: 4

Views: 993

Answers (2)

dumbass
dumbass

Reputation: 27239

The Clipboard.read API cited in the comments can return clipboard contents as a list of ClipboardItem objects, from which you can then obtain a Blob object, which you can then .slice to perform partial reads.

const perm = await navigator.permissions.query({ name: 'clipboard-read' });
switch (perm.state) {
case 'granted':
case 'prompt':
    break;
default:
    throw new Error("clipboard-read permission not granted");
}

const items = await navigator.clipboard.read();
for (const item of items) {
    const blob = await item.getType('text/html');
    const first1M = await blob.slice(0, 1048576).arrayBuffer();
    
    /* process first1M */
}

However, the Clipboard API is nowhere near universally available as of yet. Firefox ESR 78.9 doesn’t implement it. (I haven’t tried other browsers yet; perhaps in Chrome it’s already usable.)

Upvotes: 5

marcos
marcos

Reputation: 4510

After a lot a research, this is not possible in Javascript, there is no support for stream manipulation using the clipboard object so u have to read the entire content at once.

However, u can use MacOS (inferred from your picture) native tools for processing the clipboard data: pbcopy and pbpaste, and they are extremely fast, orders of magnitude faster than Javascript, so u can delegate the heavy processing of the text to them.

So, after u copy the 250MB of text, you can slice it and read only the first n bytes (in this case 1024) and substitute the content of the clipboard with that, so now u it will be available for u to use it in Javascript:

pbpaste | cut -b 1-1024 | pbcopy

If u need any documentation about each terminal command, u can run man command_name. Extracting the first 1024 bytes of the clipboard took less than a second with this approach.

I tested it with a sample text file of 390MB created with python with this script:

c = 30000000

with open('sample.txt', 'w') as file:
    file.writelines('a sample code' for i in range(c))

Upvotes: 1

Related Questions