- From: shwetabin <notifications@github.com>
- Date: Tue, 23 Jun 2026 01:42:11 -0700
- To: w3c/clipboard-apis <clipboard-apis@noreply.github.com>
- Cc: Subscribed <subscribed@noreply.github.com>
- Message-ID: <w3c/clipboard-apis/pull/248/review/4551488444@github.com>
@shwetabin commented on this pull request.
> @@ -918,6 +934,60 @@ url: https://storage.spec.whatwg.org/#obtain-a-storage-key-for-non-storage-purpo
1. If |representation|'s [=representation/MIME type=] is |mimeType| and |representation|'s [=representation/isCustom=] is |isCustom|, then:
+ 1. If [=this=]'s [=ClipboardItem/clipboard change count at read=] is not null, and the current [=clipboard change count=] is not equal to [=this=]'s [=ClipboardItem/clipboard change count at read=], then [=reject=] |p| with an {{"InvalidStateError"}} {{DOMException}} in |realm|, and return |p|.
+
+ Note: This ensures that stale data is never returned. If the [=system clipboard=] contents have changed since {{Clipboard/read()}} was called, this MUST fail rather than returning data that does not correspond to the current [=system clipboard=] state.
+
+ Note: A null [=ClipboardItem/clipboard change count at read=] indicates that this {{ClipboardItem}} was constructed directly by the author (e.g., via {{ClipboardItem/ClipboardItem(items, options)}}), not obtained from {{Clipboard/read()}}. In that case, no stale-data check is needed because the data does not originate from the [=system clipboard=].
+
+ 1. If [=this=]'s [=ClipboardItem/clipboard change count at read=] is not null, then:
+
+ Note: This branch covers {{ClipboardItem}}s obtained from {{Clipboard/read()}}, for which the OS clipboard read is deferred to this point. To ensure the read happens at most once per type — even if {{ClipboardItem/getType()}} is called multiple times concurrently for the same MIME type — the resulting {{Promise}} is cached in [=this=]'s [=ClipboardItem/representations with resolvers=] map, keyed by a normalized type string so that `"text/html"` and `"web text/html"` are tracked independently while differently-cased spellings of the same type (e.g., `"text/HTML"` and `"text/html"`) collapse to a single entry.
+
+ 1. Let |key| be |mimeType|'s [=MIME type/essence=]. If |isCustom| is true, prefix |key| with `"web "`.
+
+ 1. If [=this=]'s [=ClipboardItem/representations with resolvers=][|key|] [=map/exists=], then return [=this=]'s [=ClipboardItem/representations with resolvers=][|key|].
In ClipboardItem::getType, lazy (read()-created) items cache the resolver in representations_with_resolvers_ and return the same promise for repeated getType() of the same type; eager (author-constructed) items return a fresh .Then(...) promise each call. The cache is what guarantees the OS clipboard is read at most once per type
--
Reply to this email directly or view it on GitHub:
https://github.com/w3c/clipboard-apis/pull/248#discussion_r3458254980
You are receiving this because you are subscribed to this thread.
Message ID: <w3c/clipboard-apis/pull/248/review/4551488444@github.com>
Received on Tuesday, 23 June 2026 08:42:15 UTC