Open snianu opened 1 year ago
It looks like we still need a resolution for this issue.
There are mainly three different API shapes for delay rendering support:
typedef (DOMString or Blob) ClipboardItemValue; callback ClipboardItemValueCallback = ClipboardItemValue(); typedef Promise<(ClipboardItemValue or ClipboardItemValueCallback)> ClipboardItemData;
This provides a callback for the formats being delay rendered. It's ergonomical to the web authors and doesn't have any race issue when formats are written to the clipboard as the browsers can check which formats have callback associated with them and which ones have data already populated during write()
before the formats are written to the system clipboard.
navigator.clipboard.write(new ClipboardItem({ 'text/html': new Promise(resolve => { // somehow this event target is scoped to this clipboard item? // event will only be fired once, even if paste happens again? some_target.addEventListener('some_event_type', async e => { // are we the type handler that's actually desired here? if (e.requestedType === 'text/html') { // do a bunch of stuff here, probably async resolve(results); } }; }), / repeat the above for every supported type, but we'll only ever call resolve() for one Promise / }));
This has several issues:
write()
. Without this info we have to assume all the formats are delay rendered?Add a new method to ClipboardItem called addDelayedWriteCallback, that takes in a map of formats to callbacks(addDelayedWriteCallback's).
Issues with this approach:
We would like to propose the first option:
typedef (DOMString or Blob) ClipboardItemValue; callback ClipboardItemValueCallback = ClipboardItemValue(); typedef Promise<(ClipboardItemValue or ClipboardItemValueCallback)> ClipboardItemData;
RESOLUTION: Option 1 with the callback approach is the resolution for delay rendering Minutes 6:56 PM snianu: documented in the latest comment various API shapes 6:59 PM smaug: could we let one to use streams 7:01 PM with stream we could avoid quite a memory overhead 7:01 PM snianu: can we get resolution on having callback to let authors specify what formats can be delay rendered? 7:02 PM RESOLUTION: to have callback (Option 1)
Hmm, I was not fully understanding this issue back in the meeting, as my focus was on a different issue. To reiterate what @smaug---- said with some code, can this be:
navigator.clipboard.write(new ClipboardItem({
'text/html': new ReadableStream({
pull(controller) {
// This will only be called when the consumer reads it, so this is still about "have callback".
controller.enqueue(bytes);
},
type: "bytes",
}, { highWaterMark: 0 }),
}));
I think this can coexist with callback, though.
To coexist with callbacks, if I understand the union issue correctly, that would have to be:
navigator.clipboard.write(new ClipboardItem({
'text/html': Promise.resolve(new ReadableStream({
pull(controller) {
// This will only be called when the consumer reads it, so this is still about "have callback".
controller.enqueue(bytes);
}),
type: "bytes",
}, { highWaterMark: 0 })),
}));
No?
I'm not sure why promise would be needed there?
My understanding is that we can't have a union of Promise
and anything. Otherwise, we might have implemented the callback as just a function rather than a promise of a function. No?
Having Promise in Web IDL doesn't mean that the user needs to explicitly pass Promise, the IDL layer will automatically wrap it with a promise.
Oh, that's great!
Hmm, I was not fully understanding this issue back in the meeting, as my focus was on a different issue. To reiterate what @smaug---- said with some code, can this be:
navigator.clipboard.write(new ClipboardItem({ 'text/html': new ReadableStream({ pull(controller) { // This will only be called when the consumer reads it, so this is still about "have callback". controller.enqueue(bytes); }, type: "bytes", }, { highWaterMark: 0 }), }));
I think this can coexist with callback, though.
What would the IDL look like? Can Blob APIs be used to stream data instead? Basically, in the callback, can the web authors use the streaming APIs to write data into the Blob? If so, then I'm not sure if this option would be helpful to add to the ClipboardItem IDL -- creates complexity in how the different chunks of data get written to the clipboard when the format is being requested during paste.
Can Blob APIs be used to stream data instead?
One can convert blobs into streams and streams into blobs, but a blob itself is by design a readonly snapshot object that does not change after its construction. Not sure that's the proper answer for your question, could you provide some example in your mind if not?
Basically, in the callback, can the web authors use the streaming APIs to write data into the Blob?
One cannot "write data into the (existing) blob" in any way as Blob is designed to be constant. But you can create a new blob from a stream: new Response(stream).blob()
One can convert blobs into streams and streams into blobs
Right, that is why I'm confused if a ReadableStream
would add any value to this API when it already allows Blob data to be returned from the callback.
But you can create a new blob from a stream:
new Response(stream).blob()
Sorry for the confusion, but that is what I meant in can the web authors use the streaming APIs to write data into the Blob?
comment.
Using a stream could let implementations to optimize memory usage, as an example.
Right, that is why I'm confused if a
ReadableStream
would add any value to this API when it already allows Blob data to be returned from the callback.
Having to get a memory blob (which is what you get when converting from stream) means potentially having to consume huge memory. Having stream can reduce that. And also the consumer can get the first chunk of bytes earlier without waiting for the complete data.
I think another important question is, though: does any OS support reading from clipboard progressively?
Even if OSes didn't support that, streaming from the content/renderer process to the process which would then interact with the OS could save quite a bit memory in many cases.
Tagging few people who would be interested in this discussion. @evanstade @inexorabletash @sanketj
From #417 There are few comments about the shape of the new delayed rendering API in the async clipboard API. Creating this issue to continue the discussion here. Explainer: https://github.com/MicrosoftEdge/MSEdgeExplainers/blob/main/DelayedClipboard/DelayedClipboardRenderingExplainer.md Proposed solution: Add a callback to ClipboardItemData Discussions related to this: @annevk asked:
This led to the following discussions about the shape of the API:
@evanstade @sanketj @tilgovi @inexorabletash @anaskim @whsieh