Search code examples
javascriptperformanceclipboard

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?


Solution

  • 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.)