Skip to content

Commit 0b538e9

Browse files
author
Raphael Kubo da Costa
authored
Make requestPermission()'s behavior more backwards-compatible (#129)
The changes added in #123 have introduced some behavior changes to the two requestPermission() operations that were not originally intended. Although the original steps were heavily modeled after the WebKit implementation and do not follow what other specifications normally do, some behavior changes from #123 have not been discussed and have been made more backwards-compatible: - Calls to "request permission to use" may return "prompt", while the previous version implicitly converted anything that was not "granted" to "denied" (possibly because the current Safari implementation shows a modal dialog asking for access, so users can only allow or deny the permission request, so remaining at the "prompt" state is not possible). From a specification perspective, if a user has not explicitly granted the permission request, "prompt" is essentially the same as "denied" anyway, so we now explicitly set anything that is not "granted" to "denied" again. - The previous steps only checked for transient activation if users had not made an explicit permission choice yet, which basically means that the permission state is set to "prompt". This change restores this behavior by first checking the current permission states for all required permission names and only throwing a NotAllowed exception if one of them is "prompt" and there is no transient activation. In other words, if a permission is either "granted" or "denied" then requestPermission() will resolve to one of the values without requiring transient activation. While here, refer to the right definitions of "granted" and "denied": use the PermissionState enum definitions, which is what the Permissions API algorithms we invoke return, rather than the non-Web IDL definitions that these enum values correspond to.
1 parent 2dab013 commit 0b538e9

File tree

1 file changed

+21
-12
lines changed

1 file changed

+21
-12
lines changed

index.bs

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -306,20 +306,24 @@ The <dfn attribute for="DeviceOrientationEvent">absolute</dfn> attribute must re
306306
The <dfn method for="DeviceOrientationEvent">requestPermission(<var>absolute</var>)</dfn> method steps are:
307307

308308
1. Let <var>global</var> be the <a>current global object</a>.
309-
1. If <a>this</a>'s <a>relevant global object</a> does not have <a>transient activation</a>, return <a>a promise rejected with</a> a "{{NotAllowedError}}" {{DOMException}}.
309+
1. Let <var>hasTransientActivation</var> be true if <a>this</a>'s <a>relevant global object</a> has <a>transient activation</a>, and false otherwise.
310310
1. Let <var>result</var> be <a>a new promise</a> in <a>this</a>'s <a>relevant Realm</a>.
311311
1. Run these steps <a>in parallel</a>:
312312
1. If <var>absolute</var> is true:
313313
1. Let <var>permissions</var> be « "<a permission>accelerometer</a>", "<a permission>gyroscope</a>", "<a permission>magnetometer</a>" ».
314314
1. Otherwise:
315315
1. Let <var>permissions</var> be « "<a permission>accelerometer</a>", "<a permission>gyroscope</a>" ».
316-
1. Let <var>permissionState</var> be "<a for="permission">granted</a>".
316+
1. <a for="list">For each</a> <var>name</var> of <var>permissions</var>:
317+
1. If <var>name</var>'s <a>permission state</a> is "{{PermissionState/prompt}}" and <var>hasTransientActivation</var> is false:
318+
1. <a>Queue a global task</a> on the <a>device motion and orientation task source</a> given <var>global</var> to <a>reject</a> <var>result</var> with a "{{NotAllowedError}}" {{DOMException}}.
319+
1. Return.
320+
1. Let <var>permissionState</var> be "{{PermissionState/granted}}".
317321
1. <a for="list">For each</a> <var>name</var> of <var>permissions</var>:
318322

319323
Note: There is no algorithm for requesting multiple permissions at once. However, user agents are encouraged to bundle concurrent requests for different kinds of media into a single user-facing permission prompt.
320324

321-
1. If the result of <a>requesting permission to use</a> <var>name</var> is "<a for="permission">denied</a>":
322-
1. Set <var>permissionState</var> to "<a for="permission">denied</a>".
325+
1. If the result of <a>requesting permission to use</a> <var>name</var> is not "{{PermissionState/granted}}":
326+
1. Set <var>permissionState</var> to "{{PermissionState/denied}}".
323327
1. <a>Break</a>
324328
1. <a>Queue a global task</a> on the <a>device motion and orientation task source</a> given <var>global</var> to <a>resolve</a> <var>result</var> with <var>permissionState</var>.</li>
325329
1. Return <var>result</var>.
@@ -350,7 +354,7 @@ To <dfn>fire an orientation event</dfn> given a <var>event name</var> (a string)
350354
1. Run these steps <a>in parallel</a>:
351355
1. <a for="list">For each</a> <var>permission name</var> in <var>permissions</var>:
352356
1. Let <var>state</var> be the result of <a>getting the current permission state</a> with <var>permission name</var> and <var>environment</var>.
353-
1. If <var>state</var> is not "<a for="permission">granted</a>", return.
357+
1. If <var>state</var> is not "{{PermissionState/granted}}", return.
354358
1. <a>Queue a global task</a> on the <a>device motion and orientation task source</a> given <var>window</var> to run the following steps:
355359
1. Let <var>z rotation</var> be <var>orientation</var>'s representation as intrinsic Tait-Bryan angles Z - X' - Y'' along the Z axis, or null if the implementation cannot provide an angle value.
356360
1. If <var>z rotation</var> is not null, limit <var>z rotation</var>'s precision to 0.1 degrees.
@@ -529,16 +533,21 @@ The <dfn attribute for="DeviceMotionEvent">interval</dfn> attribute must return
529533
The <dfn method for="DeviceMotionEvent">requestPermission()</dfn> method steps are:
530534

531535
1. Let <var>global</var> be the <a>current global object</a>.
532-
1. If <a>this</a>'s <a>relevant global object</a> does not have <a>transient activation</a>, return <a>a promise rejected with</a> a "{{NotAllowedError}}" {{DOMException}}.
536+
1. Let <var>hasTransientActivation</var> be true if <a>this</a>'s <a>relevant global object</a> has <a>transient activation</a>, and false otherwise.
533537
1. Let <var>result</var> be <a>a new promise</a> in <a>this</a>'s <a>relevant Realm</a>.
534538
1. Run these steps <a>in parallel</a>:
535-
1. Let <var>permissionState</var> be "<a for="permission">granted</a>".
536-
1. <a for="list">For each</a> <var>name</var> of « "<a permission>accelerometer</a>", "<a permission>gyroscope</a>" »:
539+
1. Let <var>permissions</var> be « "<a permission>accelerometer</a>", "<a permission>gyroscope</a>" ».
540+
1. <a for="list">For each</a> <var>name</var> of <var>permissions</var>:
541+
1. If <var>name</var>'s <a>permission state</a> is "{{PermissionState/prompt}}" and <var>hasTransientActivation</var> is false:
542+
1. <a>Queue a global task</a> on the <a>device motion and orientation task source</a> given <var>global</var> to <a>reject</a> <var>result</var> with a "{{NotAllowedError}}" {{DOMException}}.
543+
1. Return.
544+
1. Let <var>permissionState</var> be "{{PermissionState/granted}}".
545+
1. <a for="list">For each</a> <var>name</var> of <var>permissions</var>:
537546

538547
Note: There is no algorithm for requesting multiple permissions at once. However, user agents are encouraged to bundle concurrent requests for different kinds of media into a single user-facing permission prompt.
539548

540-
1. If the result of <a>requesting permission to use</a> <var>name</var> is "<a for="permission">denied</a>":
541-
1. Set <var>permissionState</var> to "<a for="permission">denied</a>".
549+
1. If the result of <a>requesting permission to use</a> <var>name</var> is not "{{PermissionState/granted}}":
550+
1. Set <var>permissionState</var> to "{{PermissionState/denied}}".
542551
1. <a>Break</a>
543552
1. <a>Queue a global task</a> on the <a>device motion and orientation task source</a> given <var>global</var> to <a>resolve</a> <var>result</var> with <var>permissionState</var>.</li>
544553
1. Return <var>result</var>.
@@ -601,7 +610,7 @@ At an <a>implementation-defined</a> interval <var>interval</var>, the user agent
601610
1. Run these steps <a>in parallel</a>:
602611
1. <a for="list">For each</a> <var>permission name</var> in « "<a permission>accelerometer</a>", "<a permission>gyroscope</a>" »:
603612
1. Let <var>state</var> be the result of <a>getting the current permission state</a> with <var>permission name</var> and <var>environment</var>.
604-
1. If <var>state</var> is not "<a for="permission">granted</a>", return.
613+
1. If <var>state</var> is not "{{PermissionState/granted}}", return.
605614
1. <a>Queue a global task</a> on the <a>device motion and orientation task source</a> given <var>window</var> to run the following steps:
606615
1. <a>Fire an event</a> named <a event for="Window"><code>devicemotion</code></a> at <var>window</var>, using {{DeviceMotionEvent}}, with the {{DeviceMotionEvent/acceleration}} attribute initialized to <var>acceleration</var>, the {{DeviceMotionEvent/accelerationIncludingGravity}} attribute initialized to <var>accelerationIncludingGravity</var>, the {{DeviceMotionEvent/rotationRate}} attribute initialized to <var>rotationRate</var>, and the {{DeviceMotionEvent/interval}} attribute initialized to <var>interval</var>.
607616

@@ -1082,4 +1091,4 @@ This section summarizes substantial changes and notable editorial improvements t
10821091
- Make security and privacy considerations normative
10831092
- Add the ondeviceorientationabsolute event handler attribute into the IDL block (was only in prose)
10841093
- Remove '?' from dictionary members of DeviceMotionEventInit
1085-
- Use [Exposed=Window] extended attribute
1094+
- Use [Exposed=Window] extended attribute

0 commit comments

Comments
 (0)