diff --git a/geolocation-element.html b/geolocation-element.html new file mode 100644 index 0000000..4ccd29b --- /dev/null +++ b/geolocation-element.html @@ -0,0 +1,4194 @@ + + + + The HTML Geolocation Element + + + + + + + + + + + + + + + + + + + + +
+

The HTML Geolocation Element

+

Draft Community Group Report, +

+
+
+
This version: +
https://wicg.github.io/PEPC/geolocation-element.html +
Issue Tracking: +
GitHub +
Inline In Spec +
Editor: +
Daniel Vogelheim (Google LLC) +
+
+
+ +
+
+
+

Abstract

+

An HTML element to let a user trigger access to geolocation.

+

This specifies a new HTML element, <geolocation>, that provides +users with a way to grant apage access to geolocation and the associated +capabilities from within the page.

+

Suitable styling and UI constraints on this new element ensure that the user +understands what a click on it means, and thus gives the browser a high level +of confidence of user intent to make a permission decision. +The geolocation elements aim to be more accessible, more secure, and more +user friendly than the current, script-triggered permission flows.

+
+
+

Status of this document

+
+

+ This specification was published by the Web Platform Incubator Community Group. + It is not a W3C Standard nor is it on the W3C Standards Track. + + Please note that under the + W3C Community Contributor License Agreement (CLA) + there is a limited opt-out and other conditions apply. + + Learn more about + W3C Community and Business Groups. +

+

+
+
+ +
+

1. Introduction and Background

+

User agents expose powerful features to web sites, like geolocation +or camera access. These features are important to some use cases, but can be +easily abused.To handle this, user agents use permissions to ask the user +whether they wish for a particular access to be allowed or not.

+

These permission requests began as a fairly direct passthrough: A site would +ask for some capability and the user agent immediately prompts the user to make +a decision for the request. Meanwhile, spam and abuse have forced user agents +to take a more opinionated approach to protect users' security, privacy, and +attention. The status quo is that users get a multitude of permission requests, +where it’s oftentimes unclear to users what the consequences of these requests +might be.

+

This spec introduces a new mechanism that requests and initiates access to +Geolocation capabilities through in-page elements, with built-in protections +against abuse. Giving access to the location through in in-page lement wants +to tie capability activation to the actual context in which it will be used +, thus reducing "permission spam" and at the same time providing implementations +with a better signal of user intent.

+

The later chapters of this specification are careful to build up the required +spec infrastructure to that it can be re-used on other, similarly spirited +elements providing access to other powerful features and their associated +capabilities.

+

2. The geolocation Element

+

The HTML geolocation element can moderate access to the +"geolocation" permission and the associated Geolocation +capabilities.

+
+
Categories: +
Flow content. +
Phrasing content. +
Interactive content. +
Palpable content. +
Contexts in which this element can be used: +
Where phrasing content is expected. +
Content model: +
Flow content. +
Content attributes: +
Global attributes. +
ActivationBlockersMixin attributes. +
PermissionsMixin attributes. +
autolocate — Whether to locate right away (if permission has already been granted). +
watch — Wether to read the position once, or watch it continously. +
Accessibility considerations: +
See issues below. +
DOM interface: +
HTMLGeolocationElement +
+

[WAI-ARIA] specifies roles for in-page content. + It is yet unclear whether or how the geolocation element fits into + the existing set of roles. + Given that this element triggers permission requests, one could argue + that whatever accessibility concerns apply there should cover this element + as well. On the other hand, more specialized treatment may lead to better + support for users.

+

In § 3.4 Styling, and Styling Restrictions, this specification defines elaborate restrictions on + how geolocation elements can be rendered. It’s unclear whether there + need to be similarly spirited restrictions on which ARIA attributes can + be applied.

+

The isValid and +invalidReason, as well as the global +lang and +tabindex content attributes, and the +onpromptaction, +onpromptdismiss, and +onvalidationstatuschange event handlers follow the +description in § 3 Mixins and Infrastructure.

+

The autolocate attribute determines +whether the geolocation element should start locating immediately (if +permission has already been granted).

+

The watch attribute determine whether +the geolocation element report the location once or continously.

+
[Exposed=Window]
+interface HTMLGeolocationElement : HTMLElement {
+  [HTMLConstructor] constructor();
+
+  readonly attribute GeolocationPosition? position;
+  readonly attribute GeolocationPositionError? error;
+  [CEReactions, Reflect] attribute boolean autolocate;
+  [CEReactions, Reflect] attribute boolean watch;
+
+  attribute EventHandler onlocation;
+};
+HTMLGeolocationElement includes ActivationBlockersMixin;
+HTMLGeolocationElement includes PermissionsMixin;
+
+

If the user has decided to allow access to geolocation information, the +readonly attributes position and +error reflect the current +GeolocationPosition and GeolocationPositionError values, just like +the PositionCallback and +PositionErrorCallback callbacks (respectively) would have returned

+

If the boolean attribute autolocate is true, +and if the "geolocation" permission has already been granted by +the user, then the location should be retrieved immediately when the +geolocation element is attached to the document. If the permission has +not already been granted at insertion time, then this attribute has no effect.

+

If the boolean attribute watch +is set to true, the onlocation event is called +every time the position changes, matching the behaviour of watchPosition.

+

When a location is available, an Event is dispatched on the +onlocation event handler. +When the event is +dispatched, the location, or information about a failure to retrieve the +location, are available in the position or the +error attributes. Depending on the +watch element this happens once (if absent or false), +or continously (if true).

+

HTMLGeolocationElement wants to mirror the Geolocation interface. +There is a direct correspondance:

+ + + + + + +
position + Result of PositionCallback. +
error + Result of PositionErrorCallback. +
watch + Use watchPosition(). +
¬ watch + Use getCurrentPosition(). +
+

The global lang attribute is +observed by the element to select localized text.

+

The default value +for the global tabindex content attribute on the +element is 0.

+

2.1. geolocation element internal state

+

The geolocation element uses all the internal slots from ActivationBlockersMixin and PermissionsMixin. Additionally, +geolocation has the following internal slots:

+ +

2.1.1. Mixin-supporting state at the navigable

+

In order to support the HTMLGeolocationElement, the navigable maintains +an ordered set of elements, [[PermissionElements]]. This ordered set is used to evaluate the blockers of type unsuccesful_registration.

+

2.2. geolocation element algorithms

+
+ +The HTMLGeolocationElement constructor() steps are: + + +
    +
  1. +

    Initialize the internal [[Features]] to +« "geolocation" ».

    +
  2. +

    Initialize the internal [[BlockerList]] to «».

    +
  3. +

    Initialize the internal [[LastNotifiedValidState]] with false.

    +
  4. +

    Initialize the internal [[LastNotifiedInvalidReason]] with the empty +string.

    +
  5. +

    Initialize the internal [[watchIDs]] to « watchID », where +watchID is an implementation-defined unsigned long that is +greater than zero.

    +
  6. +

    Initialize the internal [[position]] to null.

    +
  7. +

    Initialize the internal [[positionError]] to null.

    +
  8. +

    Run PermissionsMixin’s initialization steps.

    +
+
+
+ +The HTMLGeolocationElement’s insertion steps are: + + +
    +
  1. +

    Initialize the internal [[BlockerList]] to «».

    +
  2. +

    Append this to node navigable’s [[PermissionElements]].

    +
  3. +

    Initialize the internal [[IntersectionRect]] with undefined.

    +
  4. +

    Initialize the internal [[IntersectionObserver]] with the result of +constructing a new IntersectionObserver with +IntersectionObserver callback and +«[ "rootMargin" → "-4px" ]».

    +
  5. +

    Call [[IntersectionObserver]].observe(this).

    +
  6. +

    Run PermissionsMixin’s insertion steps.

    +
  7. +

    If this is not type permissible, then add a temporary blocker +with unsuccesful_registration.

    +
  8. +

    Add an expiring blocker with reason +recently_attached.

    +
  9. +

    If the traversable navigable of the node navigable of +this +is a fenced navigable, then add a permanent blocker +with illegal_subframe.

    +
  10. +

    Maybe dispatch onvalidstatechange on this.

    +
  11. +

    Maybe autolocate.

    +
+
+
+ +The HTMLGeolocationElement removing steps are: + + +
    +
  1. +

    Remove this from node navigable’s [[PermissionElements]].

    +
  2. +

    Recheck type permissibility for this’s node navigable.

    +
  3. +

    Maybe dispatch onvalidstatechange on this.

    +
+
+
+ +The HTMLGeolocationElement element’s activation behavior given event is: + + +
    +
  1. +

    Assert: element’s [[Features]] is not null.

    +
  2. +

    If element’s [[Features]] is empty, then return.

    +
  3. +

    If event.isTrusted is false, then return.

    +
  4. +

    If element.isValid is false, then return.

    +
  5. +

    Let descriptor be the result of build a permission descriptor for +element.

    +
  6. +

    Request permission to use the powerful features described by +descriptor.

    +
  7. +

    If the previous step was cancelled or dismissed by the user, then +dispatch onpromptdismiss on this and return.

    +

    The [Permissions] spec assumes that request permission to use +will always succeed. That is, it assumes that the user will always make a +choice and that the algorithm will always deliver a grant/deny +answer corresponding to that choice. But you can’t force a user to do that. +Some user agents may have different UI affordances for an explicit +denial (e.g. a "deny" button) on one hand, and cancelling or dismissing the +request dialog (e.g. an "X" button in the top right corner). Here, we +distinguish between these two actions, despite no clear hook for this +in the underlying specification.

    +
  8. +

    Dispatch onpromptaction on this.

    +
  9. +

    Fetch location.

    +
+
+
+The position getter steps are to return the value +of [[position]]. +
+
+The error getter steps are to return the value of +[[positionError]]. +
+
+ +To maybe autolocate: + + +
    +
  1. +

    If get the current permission state is not +granted, then return.

    +
  2. +

    If autolocate is not true, then return.

    +
  3. +

    Fetch location.

    +
+
+
+ +To fetch location: + + +
    +
  1. +

    Let positionCallback be a PositionCallback that performs the following steps:

    +
      +
    1. +

      Set this’s [[positionError]] to undefined.

      +
    2. +

      Set this’s [[position]] to PositionCallback’s position +argument.

      +
    3. +

      Dispatch onlocation to this.

      +
    +
  2. +

    Let errorCallback be a PositionErrorCallback that performs the following steps:

    +
      +
    1. +

      Set this’s [[position]] to undefined.

      +
    2. +

      Set this’s [[positionError]] to PositionCallback’s +positionError argument.

      +
    3. +

      Dispatch onlocation to this.

      +
    +
  3. +

    Let positionOptions be «[]»

    +
  4. +

    Let geolocation be the relevant global object’s Geolocation.

    +
  5. +

    If this’s watch is true:

    +
      +
    1. +

      Request a position with geolocation, positionCallback, +errorCallback, positionOptions, and this’s [[watchIDs]].

      +
    +
  6. +

    Otherwise:

    +
      +
    1. +

      Request a position with geolocation, positionCallback, +errorCallback, positionOptions.

      +
    +
+
+
+ +To determine whether an element is type permissible: + + +
    +
  1. +

    Assert: element’s node navigable’s [[PermissionElements]] +contains element.

    +
  2. +

    Let count be 0.

    +
  3. +

    For each current in +element’s node navigable’s [[PermissionElements]]:

    +
      +
    1. +

      If current is element, then break.

      +
    2. +

      If element.[[Features]] equals current.[[Features]]

      +

      then increment count by 1.

      +
    +
  4. +

    Return whether count is less than 3.

    +
+
+
+ +To recheck type permissibility for a +document: + + +
    +
  1. +

    For each current in document’s +[[PermissionElements]]:

    +
      +
    1. +

      If current is type permissible, then remove blockers with +unsuccesful_registration from +current.

      +
    +
+
+
+ +To dispatch onlocation for element: + +
    +
  1. +

    Let event be a new Event.

    +
  2. +

    Initialize event with type +"onlocation".

    +
  3. +

    Dispatch event to element.

    +
+
+

2.3. geolocation element rendering

+

The geolocation element is a non-devolvable widget and is chiefly +rendered like a button. The button label is largely expected to be +determined by the browser, rather than the page, and reflects its function of given +access to Geolocation functionality. The element may also convey information about +the current permission state of the "geolocation" powerful feature.

+

The page can influence the permission elements' styling, but with +constraints to prevent abuse (e.g. minimum and maximum sizes for fonts and +the label itself). These are described in § 3.4 Styling, and Styling Restrictions. +The page can also select a locale for the text via the lang attribute.

+

The permission elements support fallback content, which will be +displayed by any browser not yet supporting that element. Note that +there are also conditions under which a browser that supports +a respective permission element falls back to its fallback content.

+

3. Mixins and Infrastructure

+

This section defines several mixins and supporting algorithms.

+

3.1. Activation Blockers

+

To support a meaningful user intent signal and to conditionally block element +activation, you can use the ActivationBlockersMixin

+
+
Content attributes: +
isValid — query whether the element can currently be activated. +
invalidReason — return a string representation of why the element currently cannot be activated. +
onvalidationstatuschange — notifies when the validation status changes. +
DOM interface: +
+
interface mixin ActivationBlockersMixin {
+  readonly attribute boolean isValid;
+  readonly attribute ActivationBlockersMixinBlockerReason invalidReason;
+  attribute EventHandler onvalidationstatuschange;
+};
+
+
+

The isValid attribute reflects whether the +element is currently blocked.

+

The invalidReason attribute is an +enumerated attribute that informs the caller of the reason why activation +is currently blocked. If there are multiple reasons, it picks one. +Its value set is ActivationBlockersMixinBlockerReason.

+

The following are the event handler (and their corresponding event handler event type) that +must be supported on elements that include the ActivationBlockersMixin:

+ + + +
onvalidationstatuschange + Event +
+

The ActivationBlockersMixin attributes +are:

+ +

3.1.1. Internal state

+

ActivationBlockersMixin elements have the following internal slots:

+ +

3.1.2. Action Blockers, Blocker Reasons, and Blocker Lifetimes

+

The key goal of the elements in this specification is to reflect a user’s +conscious choice, and we need to make sure the user cannot easily be tricked +into activating it. To do so, we maintain a list of blocker reasons, which may - +permanently or temporarily - prevent the element from being activated.

+

Conceptually, a blocker reason is just an arbitrary string identifier. We +provide an enumeration of its value set. It’s expected that not all users +of the ActivationBlockersMixin will support all reasons.

+
enum ActivationBlockersMixinBlockerReason {
+  "",   // No blocker reason.
+  "illegal_subframe", "unsuccesful_registration",
+  "recently_attached", "intersection_changed",
+  "intersection_out_of_viewport_or_clipped",
+  "intersection_occluded_or_distorted", "style_invalid",
+  "type_invalid",
+};
+
+

These blockers come with three lifetimes: Permanent, temporary, and expiring.

+
+
Permanent blocker +
+

Once an element has a permanent blocker, it will be disabled permanently. +There are used for issues that the website owner is expected to fix. +An example is an element inside a fencedframe.

+
Temporary blocker +
+

This is a blocker that will only be valid until the blocking condition no +no longer occurs. An example is an element that is not +currently in view. All temporary blockers turn into +expiring blockers once the condition no longer applies.

+
Expiring blocker +
+

This is a blocker that is only valid for a fixed period of time. This is +used to block abuse scenarios like "click jacking". An example is +an element that has recently been moved.

+
+
+ + + + + + + + + + + + + + + +
Blocker name + + Blocker type + + Example condition + + Order hint + +
type_invalid + + permanent + + When an unsupported permission type has been + set. + + 1 + +
illegal_subframe + + permanent + + When the element is used inside a fencedframe. + + 2 + +
unsuccesful_registration + + temporary + + When too many other elements for the same + powerful feature have been inserted into the same document. + + 3 + +
recently_attached + + expiring + + When the element has just been attached to the + DOM. + + 4 + +
intersection_changed + + expiring + + When the element is being moved. + + 6 + +
intersection_out_of_viewport_or_clipped + + temporary + + When the element is not or not fully in the viewport. + + 7 + +
intersection_occluded_or_distorted + + temporary + + When the element is fully in the viewport, + but still not fully visible (e.g. because it’s partly behind other content). + + 8 + +
style_invalid + + temporary + + + 9 + +
+
+

3.1.3. Algorithms

+
+ +To add a blocker with a +ActivationBlockersMixinBlockerReason reason and an optional flag expires: + + +
    +
  1. +

    Assert: reason is not "". +(The empty string in ActivationBlockersMixinBlockerReason signals no blocker +is present. Why would you add a non-blocking empty string blocker?)

    +
  2. +

    Let timestamp be None.

    +
  3. +

    If expires, then let timestamp be current high resolution time +plus the blocker delay.

    +
  4. +

    Append an entry to the internal [[BlockerList]] +with reason and timestamp.

    +
+
+
+The blocker delay is 500ms. +
+
+ +To add an expiring blocker with a +ActivationBlockersMixinBlockerReason reason: + + +
    +
  1. +

    Assert: reason is listed as "expiring" in the blocker reason table.

    +
  2. +

    Add a blocker with reason and true.

    +
+
+
+ +To add a temporary blocker with a +ActivationBlockersMixinBlockerReason reason: + + +
    +
  1. +

    Assert: reason is listed as "temporary" in the blocker reason table.

    +
  2. +

    Add a blocker with reason and false.

    +
+
+
+ +To add a permanent blocker with a +ActivationBlockersMixinBlockerReason reason: + + +
    +
  1. +

    Assert: reason is listed as "permanent" in the blocker reason table.

    +
  2. +

    Add a blocker with reason and false.

    +
+
+
+ +To remove blockers with +ActivationBlockersMixinBlockerReason reason from an element: + + +
    +
  1. +

    Assert: reason is listed as "temporary" in the +blocker reason table.

    +
  2. +

    For each entry in element’s [[BlockerList]]:

    +
      +
    1. +

      If entry’s reason equals reason, then remove +entry from element’s [[BlockerList]].

      +
    +
  3. +

    Add a blocker with reason and true.

    +
+
+
+ +To determine a ActivationBlockersMixin element’s +blocker: + + +
    +
  1. +

    Let blockers be the result of sorting element’s [[BlockerList]] +with the blocker ordering algorithm.

    +
  2. +

    If blockers is not empty and blockers[0] is blocking, then return blockers[0].

    +
  3. +

    Return nothing.

    +
+
+
+ +To determine blocker ordering for +two blockers a and b: + + +
    +
  1. +

    Let really large number be 99.

    +
  2. +

    Assert: No order hint in the blocker reason table is equal to or +greater than really large number.

    +
  3. +

    If a is blocking, then let a hint be the +order hint of a’s reason in the +blocker reason table, otherwise let a hint be really large number.

    +
  4. +

    If b is blocking, then let b hint be the +order hint of b’s reason in the +blocker reason table, otherwise let b hint be really large number.

    +
  5. +

    Return whether a hint is less than or equal to b hint.

    +
+
+
+ +An ActivationBlockersMixin’s blocker list’s entry is +blocking if: + + +
    +
  1. +

    entry has no blocker timestamp,

    +
  2. +

    or entry has a blocker timestamp, and the blocker timestamp is +greater or equal to the current high resolution time.

    +
+
+

NOTE: The spec maintains blockers as a list [[BlockerList]], which may + potentially grow indefinitely (since some blocker types simply expire, + but are not removed). + This structure is chosen for the simplicity of explanation, rather than for + efficiency. The details of this blocker structure are not observable except + for a handful of algorithms defined here, which should open plenty of + opportunities for implementations to handle this more efficiently.

+
+ +An ActivationBlockersMixin element’s isValid getter steps are: + + +
    +
  1. +

    Return whether element’s blocker is Nothing.

    +
+
+
+ +An ActivationBlockersMixin element’s invalidReason getter steps are: + + +
    +
  1. +

    If element’s blocker is Nothing, return "".

    +
  2. +

    Otherwise, element’s blocker’s reason string.

    +
+
+
+ +To maybe dispatch onvalidstatechange for element: + + +
    +
  1. +

    Let oldState be [[LastNotifiedValidState]].

    +
  2. +

    Let newState be whether element’s blocker is Nothing.

    +
  3. +

    Set [[LastNotifiedValidState]] to newState.

    +
  4. +

    Let oldReason be [[LastNotifiedInvalidReason]].

    +
  5. +

    Let newReason be whether element’s +invalidReason.

    +
  6. +

    Set [[LastNotifiedInvalidReason]] to newReason.

    +
  7. +

    If oldState != newState or oldReason != newReason, then:

    +
      +
    1. +

      Let event be a new Event.

      +
    2. +

      Initialize event with +type +"onvalidationstatuschange", +bubbles +true, and +cancelable +true.

      +
    3. +

      Dispatch event to element.

      +
    +
+
+
+ +An ActivationBlockersMixin’s IntersectionObserver callback implements IntersectionObserverCallback and runs the following steps: + + +
    +
  1. +

    Assert: The IntersectionObserver’s root +is the document

    +
  2. +

    Let entries be the value of the first callback parameter, the +list of intersection observer entries.

    +
  3. +

    Assert: entries is not empty.

    +
  4. +

    Let entry be entries’s last item.

    +
  5. +

    If entry.isVisible, then:

    +
      +
    1. +

      Remove blockers with intersection_occluded_or_distorted.

      +
    2. +

      Remove blockers with intersection_out_of_viewport_or_clipped.

      +
    +
  6. +

    Otherwise:

    +
      +
    1. +

      If entry.intersectionRatio >= 1, then:

      +
        +
      1. +

        Let reason be intersection_occluded_or_distorted.

        +
      +
    2. +

      Otherwise:

      +
        +
      1. +

        Let reason be intersection_out_of_viewport_or_clipped.

        +
      +
    3. +

      Add a temporary blocker with reason.

      +
    +
  7. +

    If [[IntersectionRect]] does not equal +entry.intersectionRect then +add an expiring blocker with +intersection_changed.

    +
  8. +

    Set [[IntersectionRect]] to +entry.intersectionRect

    +
  9. +

    Maybe dispatch onvalidstatechange on this.

    +
+

Do I need to define dictionary equality?

+
+

3.2. Powerful Features, aka Permissions

+

To support elements that gate access to powerful features, you can use the +PermissionsMixin.

+
+
DOM interface: +
+
interface mixin PermissionsMixin {
+  readonly attribute PermissionState initialPermissionStatus;
+  readonly attribute PermissionState permissionStatus;
+  attribute EventHandler onpromptaction;
+  attribute EventHandler onpromptdismiss;
+};
+
+
+

The following are the event handlers (and their corresponding event handler event types) that must be supported on elements that include the PermissionsMixin:

+ + + + +
onpromptaction + Event +
onpromptdismiss + Event +
+

The PermissionsMixin attributes are:

+ +

3.2.1. Internal state

+

The PermissionsMixin represents capabilities gated by user-requestable +permissions, which the user can activate to allow the site to start accessing them. +It is core to the these elements that such requests are +triggered by the user, and not by the page’s script. To enforce +this, the element checks whether the activation event is trusted. Additionally it watches a number of conditions, like whether the element is +(partially) occluded, or if it has recently been moved. The element maintains +an internal [[BlockerList]] to keep track of this.

+

PermissionsMixin elements have the following internal slots:

+ +

3.2.2. Algorithms

+
+ +A PermissionsMixin’s initialization steps are: + + +
    +
  1. +

    Assert: The internal [[Features]] slot has been +initialized. The including element must define and initialize this.

    +
  2. +

    Initialize the internal [[InitialPermissionStatus]] to +the result of get the current permission state.

    +
+
+
+ +A PermissionsMixin’s insertion steps are: + + +
    +
  1. +

    If [[Features]] is empty or is null, +then add a permanent blocker +with reason type_invalid.

    +
+
+
+ +An PermissionsMixin element’s +initialPermissionStatus +getter steps are: + + +
    +
  1. +

    Return element’s internal [[InitialPermissionStatus]].

    +
+
+
+ +An PermissionsMixin element’s +permissionStatus +getter steps are: + + +
    +
  1. +

    Return get the current permission state for +element.

    +
+
+
+ +To get the current permission state for +an PermissionsMixin element: + + +
    +
  1. +

    Let features be element’s internal [[Features]].

    +
  2. +

    If features is null or features is empty, +return "prompt".

    +
  3. +

    Let current be "granted".

    +
  4. +

    For each feature of features:

    +
      +
    1. +

      Let state be the result of get the current permission state for +feature.

      +
    2. +

      Let current be the smaller of current and state, assuming the +following ordering:
      +"granted" > +"prompt" > +"denied".

      +
    +
  5. +

    Return current.

    +
+

It’s not clear what the PermissionState for 'no valid permission type' + should be. Here I pick "prompt" based on Chrome’s implementation; but that + choice is arbitrary.

+
+
+ +To dispatch onpromptaction for element: + + +
    +
  1. +

    Let event be a new Event.

    +
  2. +

    Initialize event with +type +"onpromptaction", +bubbles +true, and +cancelable +true.

    +
  3. +

    Dispatch event to element.

    +
+
+
+ +To dispatch onpromptdismiss for element: + + +
    +
  1. +

    Let event be a new Event.

    +
  2. +

    Initialize event with +type +"onpromptdismiss", +bubbles +true, and +cancelable +true.

    +
  3. +

    Dispatch event to element.

    +
+
+
+ +To build a permission descriptor for an +element: + + +

The [Permissions] specification assumes a descriptor describes a +single permission without parameters (like an equivalent of +enableHighAccuracy). Here, we assume a permissions model +that is more expressive. This needs to be resolved -- likely upstream, +in [Permissions], plus adaptions here.

+
    +
  1. +

    Let result be a new PermissionDescriptor.

    +
  2. +

    Fill in result, by including the powerful feature names contained in +element’s [[Features]].

    +
  3. +

    Return result.

    +
+
+

3.2.3. Presentation

+

There isn’t much precedence for describing the user agent UI in detail. + It may be better to leave more freedom to user agents.

+

An element using the PermissionsMixin contains browser-chosen content, text and maybe an +icon. Activating them will often prompt the user to choose. +This provides two bits of user interface that a user can interact with. +The user agent is largely free to determine these — rendering of the +element and the subsequent permission +prompt — in whichever way it thinks best convey’s the element’s intent.

+

UI options for the elements' presentation include:

+ +

User agents are encouraged to name or describe the powerful features +in a way that’s consistent with similar usage in program or the platform it +is running on.

+

Very non-normative examples might be:

+ +

3.3. Falling Back

+

A user agent that does not support a particular element would +recognize them as HTMLUnknownElement and render their children as +regular HTML. +User agents that support such an element should usually +render the element as described in § 3.4 Styling, and Styling Restrictions, but are still +required to render the fallback content under one condition:

+

If the internal [[BlockerList]] contains a record whose +blocker reason is type_invalid, +then the element should render the fallback content +instead of its usual rendering.

+

3.4. Styling, and Styling Restrictions

+

Permission elements constrain the styling that can be applied to them. +These constraints come in three flavours:

+
    +
  1. +

    If the condition isn’t met, the element is deactivated.

    +
  2. +

    A user-agent defined stylesheet enforces certain styling.

    +
  3. +

    The user-agent enforces bounds on additional styles, where the bounds +cannot be easily expressed in CSS. For example, if the style bounds are +expressed relative to the computed style of the element.

    +
+

3.4.1. Conditions that Deactivate the Element

+

If one of these conditions is not met, then a +temporary blocker is added with type +style_invalid.

+ + + + +
'color', 'background-color' + +Set by default to the user agent’s default button colors. +The contrast ratio between the 2 colors needs to be at least 3. +Alpha has to be 1. + +
'font-size' + + +If specified value is expressed as <relative-size>: + + +
+

Define "alpha".

+

3.4.2. User-Agent Defined Stylesheet

+

A permission element is expected to render with the following styles:

+
@namespace "http://www.w3.org/1999/xhtml";
+geolocation {
+  opacity: 1.0;
+  line-height: normal !important;
+  whitespace: nowrap !important;
+  user-select: none !important;
+  appearance: auto !important;
+  box-sizing: content-box !important;
+  vertical-align: middle !important;
+  text-emphasis: initial !important;
+  text-shadow: initial !important;
+}
+
+

3.4.3. Additional User-Agent Defined Style Bounds

+ +Permission elements define several bounds on styles. For example, we want +the font size are constraints on the The style bounds are explained below. + + +

For notational convenience, we imagine that the computed value of an element +could be accessed in CSS rules with computed, just like the +inherited value of an element can via the inherit keyword. +Then the following sheet expresses the style bounds:

+
@namespace "http://www.w3.org/1999/xhtml";
+geolocation {
+  outline-offset: clamp(0, computed, none); /* No negative outline-offsets. */
+  font-weight: clamp(200, computed, none);  /* No font-weights below 200. */
+  word-spacing: clamp(0, computed, 0.5em);  /* Word-spacing between 0..0.5em */
+  letter-spacing: clamp(-0.05em, commputed, 0.2em);  /* Letter spacing between -0.05..0.2em */
+
+  min-height: clamp(1em, computed, none);
+  max-height: clamp(none, computed, 3em);
+  min-width: clamp(none, computed, calc(fit-content));
+
+  border-width: clamp(none, computed, 1em);
+
+  font-style: if(computed = "normal" or computed = "italic", computed, "normal");
+  display: if (computed = "inline-block" or computed = "none", computed, "inline-block");
+  cursor: if (computed = "pointer" or computed = "not-allowed", computed, "pointer")
+}
+
+

Additionally, some rules apply based on conditions not easily expressible as +CSS.

+

If height is auto, then apply:

+
@namespace "http://www.w3.org/1999/xhtml";
+geolocation {
+  padding-top: clamp(1em, computed, none);
+  padding-bottom: calc(padding-top);
+}
+
+

If width is auto, then apply:

+
@namespace "http://www.w3.org/1999/xhtml";
+geolocation {
+  padding-left: clamp(none, computed, 5em);
+  padding-right: calc(padding-left);
+}
+
+

Apply the following sheet, if the element does not have all of the following:

+ +
@namespace "http://www.w3.org/1999/xhtml";
+geolocation {
+  max-width: clamp(none, computed, calc(3 * fit-content));
+}
+
+

The following CSS properties can be used normally:

+ +

Properties that are not listed above, or in the rules in this section, +and aren’t logically equivalent to one of the properties mentioned here, +will be ignored.

+

4. Security & Privacy Considerations

+

Note: Security & Privacy Considerations can be found +here & +there, +in the Explainer. +This section will eventually contain a specification-worthy transcription +of those Explainer sections.

+
+ +

Index

+

Terms defined by this specification

+ +

Terms defined by reference

+ +

References

+

Normative References

+
+
[COMPOSITING-2] +
Compositing and Blending Level 2. Editor's Draft. URL: https://drafts.fxtf.org/compositing-2/ +
[CSS-ALIGN-3] +
Elika Etemad; Tab Atkins Jr.. CSS Box Alignment Module Level 3. URL: https://drafts.csswg.org/css-align/ +
[CSS-ANCHOR-POSITION-1] +
Tab Atkins Jr.; Elika Etemad; Ian Kilpatrick. CSS Anchor Positioning Module Level 1. URL: https://drafts.csswg.org/css-anchor-position-1/ +
[CSS-BACKGROUNDS-3] +
Elika Etemad; Brad Kemper. CSS Backgrounds and Borders Module Level 3. URL: https://drafts.csswg.org/css-backgrounds/ +
[CSS-BORDERS-4] +
Elika Etemad; et al. CSS Borders and Box Decorations Module Level 4. URL: https://drafts.csswg.org/css-borders-4/ +
[CSS-BREAK-3] +
Rossen Atanassov; Elika Etemad. CSS Fragmentation Module Level 3. URL: https://drafts.csswg.org/css-break/ +
[CSS-COLOR-ADJUST-1] +
Elika Etemad; et al. CSS Color Adjustment Module Level 1. URL: https://drafts.csswg.org/css-color-adjust-1/ +
[CSS-CONDITIONAL-5] +
Chris Lilley; et al. CSS Conditional Rules Module Level 5. URL: https://drafts.csswg.org/css-conditional-5/ +
[CSS-DISPLAY-4] +
Elika Etemad; Tab Atkins Jr.. CSS Display Module Level 4. URL: https://drafts.csswg.org/css-display-4/ +
[CSS-FLEXBOX-1] +
Elika Etemad; Tab Atkins Jr.; Rossen Atanassov. CSS Flexible Box Layout Module Level 1. URL: https://drafts.csswg.org/css-flexbox/ +
[CSS-FONTS-4] +
Chris Lilley. CSS Fonts Module Level 4. URL: https://drafts.csswg.org/css-fonts-4/ +
[CSS-LISTS-3] +
Elika Etemad; Tab Atkins Jr.. CSS Lists and Counters Module Level 3. URL: https://drafts.csswg.org/css-lists-3/ +
[CSS-OVERSCROLL-1] +
Majid Valipour. CSS Overscroll Behavior Module Level 1. URL: https://drafts.csswg.org/css-overscroll-1/ +
[CSS-PAGE-3] +
Elika Etemad. CSS Paged Media Module Level 3. URL: https://drafts.csswg.org/css-page-3/ +
[CSS-POSITION-3] +
Elika Etemad; Tab Atkins Jr.. CSS Positioned Layout Module Level 3. URL: https://drafts.csswg.org/css-position-3/ +
[CSS-RUBY-1] +
Elika Etemad; et al. CSS Ruby Annotation Layout Module Level 1. URL: https://drafts.csswg.org/css-ruby-1/ +
[CSS-SCROLL-ANCHORING-1] +
Tab Atkins Jr.. CSS Scroll Anchoring Module Level 1. URL: https://drafts.csswg.org/css-scroll-anchoring/ +
[CSS-SCROLL-SNAP-1] +
Matt Rakow; et al. CSS Scroll Snap Module Level 1. URL: https://drafts.csswg.org/css-scroll-snap-1/ +
[CSS-SIZING-3] +
Tab Atkins Jr.; Elika Etemad. CSS Box Sizing Module Level 3. URL: https://drafts.csswg.org/css-sizing-3/ +
[CSS-SIZING-4] +
Tab Atkins Jr.; Elika Etemad; Jen Simmons. CSS Box Sizing Module Level 4. URL: https://drafts.csswg.org/css-sizing-4/ +
[CSS-TEXT-4] +
Elika Etemad; et al. CSS Text Module Level 4. URL: https://drafts.csswg.org/css-text-4/ +
[CSS-UI-4] +
Florian Rivoal. CSS Basic User Interface Module Level 4. URL: https://drafts.csswg.org/css-ui-4/ +
[CSS-WILL-CHANGE-1] +
Tab Atkins Jr.. CSS Will Change Module Level 1. URL: https://drafts.csswg.org/css-will-change/ +
[CSS2] +
Bert Bos; et al. Cascading Style Sheets Level 2 Revision 1 (CSS 2.1) Specification. URL: https://drafts.csswg.org/css2/ +
[DOM] +
Anne van Kesteren. DOM Standard. Living Standard. URL: https://dom.spec.whatwg.org/ +
[FENCED-FRAME] +
Fenced Frame. Draft Community Group Report. URL: https://wicg.github.io/fenced-frame/ +
[GEOLOCATION] +
Marcos Caceres; Reilly Grant. Geolocation. URL: https://w3c.github.io/geolocation/ +
[GEOMETRY-1] +
Sebastian Zartner; Yehonatan Daniv. Geometry Interfaces Module Level 1. URL: https://drafts.csswg.org/geometry/ +
[HR-TIME-3] +
Yoav Weiss. High Resolution Time. URL: https://w3c.github.io/hr-time/ +
[HTML] +
Anne van Kesteren; et al. HTML Standard. Living Standard. URL: https://html.spec.whatwg.org/multipage/ +
[INFRA] +
Anne van Kesteren; Domenic Denicola. Infra Standard. Living Standard. URL: https://infra.spec.whatwg.org/ +
[INTERSECTION-OBSERVER] +
Stefan Zager; Emilio Cobos Álvarez; Traian Captan. Intersection Observer. URL: https://w3c.github.io/IntersectionObserver/ +
[MANIFEST-APP-INFO] +
Aaron Gustafson. Web App Manifest - Application Information. URL: https://w3c.github.io/manifest-app-info/ +
[MEDIAQUERIES-5] +
Dean Jackson; et al. Media Queries Level 5. URL: https://drafts.csswg.org/mediaqueries-5/ +
[Permissions] +
Marcos Caceres; Mike Taylor. Permissions. URL: https://w3c.github.io/permissions/ +
[SVG2] +
Amelia Bellamy-Royds; et al. Scalable Vector Graphics (SVG) 2. URL: https://svgwg.org/svg2-draft/ +
[WAI-ARIA-1.2] +
Joanmarie Diggs; et al. Accessible Rich Internet Applications (WAI-ARIA) 1.2. URL: https://w3c.github.io/aria/ +
[WEBIDL] +
Edgar Chen; Timothy Gu. Web IDL Standard. Living Standard. URL: https://webidl.spec.whatwg.org/ +
+

Informative References

+
+
[WAI-ARIA] +
James Craig; Michael Cooper; et al. Accessible Rich Internet Applications (WAI-ARIA) 1.0. 20 March 2014. REC. URL: https://www.w3.org/TR/wai-aria/ +
+

IDL Index

+
[Exposed=Window]
+interface HTMLGeolocationElement : HTMLElement {
+  [HTMLConstructor] constructor();
+
+  readonly attribute GeolocationPosition? position;
+  readonly attribute GeolocationPositionError? error;
+  [CEReactions, Reflect] attribute boolean autolocate;
+  [CEReactions, Reflect] attribute boolean watch;
+
+  attribute EventHandler onlocation;
+};
+HTMLGeolocationElement includes ActivationBlockersMixin;
+HTMLGeolocationElement includes PermissionsMixin;
+
+interface mixin ActivationBlockersMixin {
+  readonly attribute boolean isValid;
+  readonly attribute ActivationBlockersMixinBlockerReason invalidReason;
+  attribute EventHandler onvalidationstatuschange;
+};
+
+enum ActivationBlockersMixinBlockerReason {
+  "",   // No blocker reason.
+  "illegal_subframe", "unsuccesful_registration",
+  "recently_attached", "intersection_changed",
+  "intersection_out_of_viewport_or_clipped",
+  "intersection_occluded_or_distorted", "style_invalid",
+  "type_invalid",
+};
+
+interface mixin PermissionsMixin {
+  readonly attribute PermissionState initialPermissionStatus;
+  readonly attribute PermissionState permissionStatus;
+  attribute EventHandler onpromptaction;
+  attribute EventHandler onpromptdismiss;
+};
+
+
+

Issues Index

+
+
[WAI-ARIA] specifies roles for in-page content. + It is yet unclear whether or how the geolocation element fits into + the existing set of roles. + Given that this element triggers permission requests, one could argue + that whatever accessibility concerns apply there should cover this element + as well. On the other hand, more specialized treatment may lead to better + support for users.
+
In § 3.4 Styling, and Styling Restrictions, this specification defines elaborate restrictions on + how geolocation elements can be rendered. It’s unclear whether there + need to be similarly spirited restrictions on which ARIA attributes can + be applied.
+
The [Permissions] spec assumes that request permission to use +will always succeed. That is, it assumes that the user will always make a +choice and that the algorithm will always deliver a grant/deny +answer corresponding to that choice. But you can’t force a user to do that. +Some user agents may have different UI affordances for an explicit +denial (e.g. a "deny" button) on one hand, and cancelling or dismissing the +request dialog (e.g. an "X" button in the top right corner). Here, we +distinguish between these two actions, despite no clear hook for this +in the underlying specification.
+
Do I need to define dictionary equality?
+
It’s not clear what the PermissionState for 'no valid permission type' + should be. Here I pick "prompt" based on Chrome’s implementation; but that + choice is arbitrary.
+
The [Permissions] specification assumes a descriptor describes a +single permission without parameters (like an equivalent of +enableHighAccuracy). Here, we assume a permissions model +that is more expressive. This needs to be resolved -- likely upstream, +in [Permissions], plus adaptions here.
+
There isn’t much precedence for describing the user agent UI in detail. + It may be better to leave more freedom to user agents.
+
Define "alpha".
+
+ + + + \ No newline at end of file diff --git a/permission-element.bs b/permission-element.bs index 92fd1d4..6016d23 100644 --- a/permission-element.bs +++ b/permission-element.bs @@ -37,6 +37,7 @@ spec:css2; type:property; text:padding-bottom spec:css2; type:property; text:padding-top spec:css2; type:property; text:padding-left spec:css2; type:property; text:padding-right +spec:css-borders-4; type:property; text:border spec:css-borders-4; type:property; text:border-right spec:css-borders-4; type:property; text:border-left spec:css-borders-4; type:property; text:border-top