Skip to content

Commit f696843

Browse files
authored
Add hooks for HTML
"legacy-clone a browsing session storage shed" can be used by HTML to define creation of auxiliary browsing contexts, as part of whatwg/html#5560. "obtain a storage key" can be used by APIs that share keying logic with storage, such as BroadcastChannel and shared workers. See whatwg/html#3054. It's potentially also useful for Indexed DB as discussed in w3c/IndexedDB#334. Also helps a bit with #95 by reorganizing and adding some more detail to how a user agent is supposed to manage storage. Closes #92.
1 parent 6d251ad commit f696843

File tree

1 file changed

+103
-48
lines changed

1 file changed

+103
-48
lines changed

storage.bs

Lines changed: 103 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,8 @@ function retrieveNextChunk(nextChunkInfo) {
8484

8585
<p>This specification depends on the Infra Standard. [[!INFRA]]
8686

87-
<p>This specification uses terminology from the DOM, HTML, IDL, Permissions API, and URL Standards.
88-
[[DOM]] [[HTML]] [[WEBIDL]] [[PERMISSIONS]] [[URL]]
87+
<p>This specification uses terminology from the HTML, IDL, and Permissions Standards.
88+
[[!HTML]] [[!WEBIDL]] [[!PERMISSIONS]]
8989

9090

9191

@@ -195,13 +195,30 @@ anticipated that some APIs will be applicable to both <a>storage types</a> going
195195
<!-- If that does not happen by 2024 we probably ought to admit defeat and simplify this a bit. -->
196196

197197

198-
<h3 id=storage-sheds>Storage sheds</h3>
198+
<h3 id=storage-keys>Storage keys</h3>
199199

200-
<p>A <dfn>storage key</dfn> is an <a for=/>origin</a>. [[HTML]]
200+
<p>A <dfn>storage key</dfn> is an <a for=/>origin</a>. [[!HTML]]
201201

202-
<p class=XXX>This is expected to change, see
202+
<p class=XXX>This is expected to change; see
203203
<a href="https://privacycg.github.io/storage-partitioning/">Client-Side Storage Partitioning</a>.
204204

205+
<p>To <dfn export>obtain a storage key</dfn>, given an <a>environment settings object</a>
206+
<var>environment</var>, run these steps:
207+
208+
<ol>
209+
<li><p>Let <var>key</var> be <var>environment</var>'s
210+
<a for="environment settings object">origin</a>.
211+
212+
<li><p>If <var>key</var> is an <a>opaque origin</a>, then return failure.
213+
214+
<li><p>If the user has disabled storage, then return failure.
215+
216+
<li><p>Return <var>key</var>.
217+
</ol>
218+
219+
220+
<h3 id=storage-sheds>Storage sheds</h3>
221+
205222
<p>A <dfn>storage shed</dfn> is a <a for=/>map</a> of <a>storage keys</a> to <a>storage shelves</a>.
206223
It is initially empty.
207224

@@ -211,15 +228,36 @@ It is initially empty.
211228
<a for=/>storage shed</a>. A user agent's <a for="user agent">storage shed</a> holds all
212229
<dfn>local storage</dfn> data.
213230

214-
<p>A browsing session holds a <dfn for="browsing session">storage shed</dfn>, which is a
215-
<a for=/>storage shed</a>. A browsing session's <a for="browsing session">storage shed</a> holds all
216-
<dfn>session storage</dfn> data.
231+
<p>A <a for=/>browsing session</a> holds a <dfn for="browsing session">storage shed</dfn>, which is
232+
a <a for=/>storage shed</a>. A <a for=/>browsing session</a>'s
233+
<a for="browsing session">storage shed</a> holds all <dfn>session storage</dfn> data.
234+
235+
<p>To <dfn export>legacy-clone a browsing session storage shed</dfn>, given a
236+
<a for=/>browsing session</a> <var>A</var> and a <a for=/>browsing session</a> <var>B</var>, run
237+
these steps:
238+
239+
<ol>
240+
<li>
241+
<p><a for=map>For each</a> <var>key</var><var>shelf</var> of <var>A</var>'s
242+
<a for="browsing session">storage shed</a>:
243+
244+
<ol>
245+
<li><p>Let <var>newShelf</var> be the result of running <a>create a storage shelf</a> with
246+
"<code>session</code>".
247+
248+
<li><p>Set <var>newShelf</var>'s <a>bucket map</a>["<code>default</code>"]'s
249+
<a>bottle map</a>["<code>sessionStorage</code>"]'s <a for="storage bottle">map</a> to a
250+
<a for=map>clone</a> of <var>shelf</var>'s <a>bucket map</a>["<code>default</code>"]'s
251+
<a>bottle map</a>["<code>sessionStorage</code>"]'s <a for="storage bottle">map</a>.
252+
253+
<li><p>Set <var>B</var>'s <a for="browsing session">storage shed</a>[<var>key</var>] to
254+
<var>newShelf</var>.
255+
</ol>
256+
</ol>
217257

218-
<p class="XXX" id=lack-of-browsing-session>See
219-
<a href="https://github.com/whatwg/html/issues/4782">whatwg/html issue #4782</a> and
220-
<a href="https://github.com/whatwg/html/issues/5350">whatwg/html issue #5350</a> for defining
221-
browsing session. It is roughly analogous to <a>top-level browsing context</a> except that it cannot
222-
be replaced due to <code>Cross-Origin-Opener-Policy</code> or navigation.
258+
<p class="note">This is considered legacy as the benefits, if any, do not outweigh the
259+
implementation complexity. And therefore it will not be expanded or used outside of
260+
<cite>HTML</cite>. [[HTML]]
223261

224262

225263
<h3 id=storage-shelves>Storage shelves</h3>
@@ -238,24 +276,14 @@ given a <a for=map>value</a> when a <a>storage shelf</a> is
238276
<var>type</var>, run these steps:
239277

240278
<ol>
241-
<li><p>Let <var>key</var> be <var>environment</var>'s
242-
<a for="environment settings object">origin</a>.
243-
244-
<li><p>If <var>key</var> is an <a>opaque origin</a>, then return failure.
245-
246-
<li><p>If the user has disabled storage, then return failure.
247-
248-
<li>
249-
<p>If <var>shed</var>[<var>key</var>] does not <a for=map>exist</a>, then:
250-
251-
<ol>
252-
<li><p>Let <var>shelf</var> be a new <a>storage shelf</a>.
279+
<li><p>Let <var>key</var> be the result of running <a>obtain a storage key</a> with
280+
<var>environment</var>.
253281

254-
<li><p>Set <var>shelf</var>'s <a>bucket map</a>["<code>default</code>"] to the result of
255-
<a>create a storage bucket</a> with <var>type</var>.
282+
<li><p>If <var>key</var> is failure, then return failure.
256283

257-
<li><p>Set <var>shed</var>[<var>key</var>] to <var>shelf</var>.
258-
</ol>
284+
<li><p>If <var>shed</var>[<var>key</var>] does not <a for=map>exist</a>, then set
285+
<var>shed</var>[<var>key</var>] to the result of running <a>create a storage shelf</a> with
286+
<var>type</var>.
259287

260288
<li><p>Return <var>shed</var>[<var>key</var>].
261289
</ol>
@@ -264,12 +292,22 @@ given a <a for=map>value</a> when a <a>storage shelf</a> is
264292
<var>environment</var>, return the result of running <a>obtain a storage shelf</a> with the user
265293
agent's <a for="user agent">storage shed</a>, <var>environment</var>, and "<code>local</code>".
266294

295+
<p>To <dfn>create a storage shelf</dfn>, given a <a>storage type</a> <var>type</var>, run these
296+
steps:
297+
298+
<ol>
299+
<li><p>Let <var>shelf</var> be a new <a>storage shelf</a>.
300+
301+
<li><p>Set <var>shelf</var>'s <a>bucket map</a>["<code>default</code>"] to the result of running
302+
<a>create a storage bucket</a> with <var>type</var>.
303+
304+
<li><p>Return <var>shelf</var>.
305+
</ol>
306+
267307

268308
<h3 id=buckets oldids=boxes>Storage buckets</h3>
269309

270-
<p>A <dfn>storage bucket</dfn> is a place for <a>storage endpoints</a> to store data. Whenever a
271-
<a>storage bucket</a> is cleared by the user agent, it must be cleared in its entirety.
272-
<!-- This is probably better defined in some kind of storage lifetime section. -->
310+
<p>A <dfn>storage bucket</dfn> is a place for <a>storage endpoints</a> to store data.
273311

274312
<p>A <a>storage bucket</a> has a <dfn>bottle map</dfn> of <a>storage identifiers</a> to
275313
<a>storage bottles</a>.
@@ -352,7 +390,7 @@ standard and standards using this standard can access the contents.
352390
<li><p>Assert: <var>type</var> is "<code>session</code>".
353391

354392
<li><p>Set <var>shed</var> to <var>environment</var>'s
355-
<a class=XXX href=#lack-of-browsing-session>browsing session</a>'s
393+
<a for="environment settings object">browsing session</a>'s
356394
<a for="browsing session">storage shed</a>.
357395
</ol>
358396

@@ -450,28 +488,45 @@ evaluating quotas.
450488

451489

452490

453-
<h2 id=ui-guidelines>User Interface Guidelines</h2>
491+
<h2 id=management>Management</h2>
492+
493+
<p>Whenever a <a>storage bucket</a> is cleared by the user agent, it must be cleared in its
494+
entirety. User agents should avoid clearing <a>storage buckets</a> while script that is able to
495+
access them is running, unless instructed otherwise by the user.
496+
497+
<p>If removal of <a>storage buckets</a> leaves the encompassing <a>storage shelf</a>'s
498+
<a>bucket map</a> <a for=map lt="is empty">empty</a>, then <a for=map>remove</a> that
499+
<a>storage shelf</a> and corresponding <a>storage key</a> from the encompassing
500+
<a for=/>storage shed</a>.
501+
502+
503+
<h3 id=storage-pressure>Storage pressure</h3>
504+
505+
<p>A user agent that comes under storage pressure should clear network state and
506+
<a>local storage buckets</a> whose <a for="local storage bucket">mode</a> is
507+
"<code>best-effort</code>", ideally prioritizing removal in a manner that least impacts the user.
508+
509+
<p>If a user agent continues to be under storage pressure, then the user agent should inform the
510+
user and offer a way to clear the remaining <a>local storage buckets</a>, i.e., those whose
511+
<a for="local storage bucket">mode</a> is "<code>persistent</code>".
512+
513+
<p><a>Session storage buckets</a> must be cleared as <a for=/>browsing sessions</a> are closed.
514+
515+
<p class="note">If the user agent allows for revival of <a for=/>browsing sessions</a>, e.g.,
516+
through reopening <a for=/>browsing sessions</a> or continued use of them after restarting the user
517+
agent, then clearing necessarily involves a more complex set of heuristics.
518+
519+
520+
<h3 id=ui-guidelines>User interface guidelines</h3>
454521

455522
<p>User agents should not distinguish between network state and storage in their user interface.
456-
Instead user agents should offer users the ability to remove all storage for each group of
523+
Instead user agents should offer users the ability to clear all storage for each group of
457524
<a>schemelessly same site</a> <a for=/>origins</a>. This ensures to some extent that network state
458525
cannot be used to revive storage. This also reduces the amount users need to know about the
459526
different ways in which websites can store data.
460-
<!-- To some extent, since HTTP ETag... And also, permissions/credentials, maybe? -->
461527

462528
<p>Credentials should be separated as they contain data the user might not be able to revive, such
463529
as an autogenerated password. Permissions are best separated too to avoid inconveniencing the user.
464-
Credentials and permissions are also somewhat easier to understand and differentiate for users from
465-
network state and storage.
466-
467-
468-
<h3 id=storage-pressure>Storage Pressure</h3>
469-
470-
<p>When the user agent notices it comes under storage pressure and it cannot free up sufficient
471-
space by clearing network state, <a>session storage buckets</a>, and <a>local storage buckets</a>
472-
whose <a for="local storage bucket">mode</a> is "<code>best-effort</code>", then the user agent
473-
should inform the user and offer a way to clear the remaining <a>local storage buckets</a>, i.e.,
474-
those whose <a for="local storage bucket">mode</a> is "<code>persistent</code>".
475530

476531

477532

@@ -486,7 +541,7 @@ Navigator includes NavigatorStorage;
486541
WorkerNavigator includes NavigatorStorage;
487542
</pre>
488543

489-
<p>Each <a>environment settings object</a> has an associated {{StorageManager}} object. [[HTML]]
544+
<p>Each <a>environment settings object</a> has an associated {{StorageManager}} object. [[!HTML]]
490545

491546
<p>The <dfn attribute for=NavigatorStorage><code>storage</code></dfn> getter steps are to return
492547
<a>this</a>'s <a>relevant settings object</a>'s {{StorageManager}} object.

0 commit comments

Comments
 (0)