1. 简介
用户 代理向网站公开强大功能,这些功能对某些用例非常重要, 但也很容易被滥用。此类强大功能中可以说最典型的 示例是摄像头访问,它对于在线会议等许多用例 至关重要,但未经请求便激活摄像头会造成严重的隐私问题。为处理此问题,用户 代理使用权限来询问用户是否希望允许某项特定 访问。
这些权限请求最初是一种相当直接的传递机制:网站会 请求某项能力,而用户代理会立即提示用户对该请求 作出决定。然而,垃圾信息和滥用迫使用户代理 采取更具倾向性的方式来保护用户的安全、隐私和 注意力。当前的情况是,用户会收到大量权限请求, 而用户往往并不清楚这些请求可能产生什么后果。
本规范引入了一种新机制,通过页面内元素请求并启动对 强大功能的访问,并内置防止 滥用的保护措施。此机制旨在将权限请求与其实际使用的上下文 关联起来,从而减少“权限轰炸”,同时 为实现提供更可靠的用户意图信号。
2. HTML 权限元素的共同行为:InPagePermissionMixin
本规范中的元素具有许多共同行为,这些行为
由InPagePermissionMixin
及其相关状态、
算法和渲染规则进行定义。
InPagePermissionMixin
接口混入定义如下:
interface mixin {InPagePermissionMixin readonly attribute boolean isValid ;readonly attribute InPagePermissionMixinBlockerReason invalidReason ;readonly attribute PermissionState initialPermissionStatus ;readonly attribute PermissionState permissionStatus ;attribute EventHandler ;onpromptaction attribute EventHandler ;onpromptdismiss attribute EventHandler ; };onvalidationstatuschange
使用此混入的元素应支持以下 内容属性:
isValid- 查询元素当前是否可以激活。
invalidReason- 返回表示元素当前无法激活原因的字符串。
onpromptdismiss- 当用户关闭因与该元素交互而产生的权限提示时发出通知
onpromptaction- 当用户回答了因与该元素交互而产生的权限提示时发出通知 (无论肯定还是否定)。
onvalidationstatuschange- 当验证状态发生变化时发出通知。
isValid
属性反映该
权限元素当前是否未被阻止。
invalidReason
属性是一个
枚举属性,它反映权限
元素的内部状态。其值集合为InPagePermissionMixinBlockerReason。
元素会观察全局lang 属性, 以选择本地化文本。
元素上的全局
tabindex
内容属性的默认
值
为 0。
以下是包含InPagePermissionMixin
的元素必须支持的事件处理器(及其对应的事件处理器事件类型):
| onpromptaction | 事件 |
|---|---|
| onpromptdismiss | 事件 |
| onvalidationstatuschange | 事件 |
2.1. Mixin
内部状态
HTML 权限元素表示
由用户可请求的权限所管控的能力,
用户可以激活这些元素,使网站开始访问相应能力。
这些元素的核心在于,此类请求应由用户
触发,而不是由页面脚本触发。为强制执行
此要求,元素会检查激活事件是否为受信任的。
此外,它还会监视多种条件,例如元素是否
(部分)被遮挡,或者最近是否被移动。元素维护一个内部[[BlockerList]]
来跟踪这些情况。
InPagePermissionMixin
元素具有以下内部槽:
-
[[Features]]为 null 或由有序集合组成,其中包含强大功能。对于大多数权限 元素,这可能是固定集合,而对于某些元素则可能是可变的。 将其设为内部槽,使我们能够编写适用于所有 此类元素的算法。 -
[[InitialPermissionStatus]]是一个PermissionState, 用于存储[[Features]]的初始PermissionState。 -
[[BlockerList]]是一个 记录列表,其中包含 阻止器时间戳和 阻止原因。阻止原因是一个InPagePermissionMixinBlockerReason, 但不能是空字符串。 -
[[IntersectionObserver]]是对IntersectionObserver的引用。 -
[[IntersectionRect]]是 一个DOMRectReadOnly, 用于存储最近一次观察到的交叉区域,即permission相对于视口的位置。 -
[[LastNotifiedInvalidReason]]是一个字符串,用于存储最近一次通知的invalidReason状态。[[LastNotifiedValidState]]和[[LastNotifiedInvalidReason]]用于 确定是否需要分派onvalidationstatuschange事件。
2.2. Mixin
在
可导航对象上的支持状态
为了支持InPagePermissionMixin,
可导航对象维护一个元素的有序集合,即[[PermissionElements]]。此有序
集合用于评估类型为unsuccesful_registration
的阻止器。
2.3. Mixin
激活和激活阻止器
权限元素系列的关键目标是反映用户的 有意识选择,我们需要确保用户不会轻易被欺骗 而激活它。为此,权限元素会维护一个 阻止原因列表,这些原因可能永久或暂时阻止元素 被激活。
这些行为中的大多数对于所有权限元素都应相同。 为简单起见,我们还会包含仅适用于一个元素或某些 元素的阻止器。
enum { // 无阻止原因。InPagePermissionMixinBlockerReason , // 所有 InPagePermissionMixin 使用者均支持的阻止原因。"" ,"illegal_subframe" ,"unsuccesful_registration" ,"recently_attached" ,"intersection_changed" ,"intersection_out_of_viewport_or_clipped" ,"intersection_occluded_or_distorted" , // HTMLPermissionElement 特有的阻止原因。"style_invalid" , };"type_invalid"
权限元素会跟踪“阻止器”,即元素(当前)无法激活的原因。 这些阻止器具有三种生命周期:永久、临时和到期。
- 永久 阻止器
-
一旦元素具有永久阻止器,它将被永久禁用。 这类阻止器用于网站所有者应当修复的问题。 一个示例是位于
fencedframe内的permission元素。 - 临时 阻止器
-
这种阻止器仅在阻止条件仍然存在时有效。 一个示例是当前不在视野中的
permission元素。所有临时阻止器都会在条件不再适用后 转变为到期阻止器。 - 到期 阻止器
-
这种阻止器仅在固定时间段内有效。它用于 阻止诸如“点击劫持”之类的滥用场景。一个示例是 最近被移动过的
permission元素。
| 阻止器名称 | 阻止器类型 | 示例条件 | 顺序提示 |
|---|---|---|---|
type_invalid
| 永久 | 设置了不受支持的权限类型
时。
| 1 |
illegal_subframe
| 永久 | 元素在
fencedframe
内使用时。
| 2 |
unsuccesful_registration
| 临时 | 同一文档中插入了过多针对同一 强大功能的其他元素时。 | 3 |
recently_attached
| 到期 | 元素刚刚附加到 DOM 时。 | 4 |
intersection_changed
| 到期 | 元素正在移动时。 | 6 |
intersection_out_of_viewport_or_clipped
| 临时 | 元素未处于或未完全处于视口中时。 | 7 |
intersection_occluded_or_distorted
| 临时 | 元素完全位于视口中, 但仍未完全可见时(例如部分位于其他内容之后)。 | 8 |
style_invalid
| 临时 | 9 |
InPagePermissionMixinBlockerReason
reason 和可选标志 expires
添加阻止器:
-
断言:reason 不是
""。 (InPagePermissionMixinBlockerReason中的空字符串表示不存在阻止器。 为什么要添加一个不产生阻止作用的空字符串阻止器?) -
令 timestamp 为 None。
-
向内部
[[BlockerList]]中追加一个包含 reason 和 timestamp 的条目。
InPagePermissionMixinBlockerReason
reason
添加到期阻止器:
InPagePermissionMixinBlockerReason
reason
添加临时阻止器:
InPagePermissionMixinBlockerReason
reason
添加永久阻止器:
InPagePermissionMixinBlockerReason
reason
移除阻止器:
-
对于 element 的
[[BlockerList]]中的每个 entry:-
如果 entry 的 reason 与 reason相等, 则从 element 的
[[BlockerList]]中移除 entry。
-
-
使用 reason 和 true添加阻止器。
InPagePermissionMixin
element 的
阻止器:
-
令 blockers 为使用阻止器排序算法对 element 的
[[BlockerList]]进行排序的结果。 -
不返回任何内容。
InPagePermissionMixin
的阻止器列表的 entry
正在阻止:
注:本规范以列表[[BlockerList]]
的形式维护阻止器,该列表
可能会无限增长(因为某些阻止器类型只是到期,
但不会被移除)。
选择这种结构是为了便于说明,而不是为了
提高效率。除这里定义的少数算法之外,此阻止器结构的细节
不可观察,这应当为实现以更高效的方式处理它
提供充足空间。
2.4. Mixin
算法
InPagePermissionMixin
element 的invalidReason 获取器步骤为:
InPagePermissionMixin
element 的
initialPermissionStatus
获取器步骤为:
-
返回 element 的内部
[[InitialPermissionStatus]]。
InPagePermissionMixin
element
获取当前权限状态
取决于包含该混入的具体元素。
因此,每个元素都必须定义自己的算法。
2.5. Mixin
事件算法
-
令 oldState 为
[[LastNotifiedValidState]]。 -
令 newState 为 element 的阻止器是否为 Nothing。
-
将
[[LastNotifiedValidState]]设置为 newState。 -
令 oldReason 为
[[LastNotifiedInvalidReason]]。 -
令 newReason 为 element 的
invalidReason。 -
将
[[LastNotifiedInvalidReason]]设置为 newReason。 -
如果 oldState != newState 或 oldReason != newReason, 则:
-
令 event 为一个新的
Event。 -
使用 type “
onvalidationstatuschange”、 bubbles true 和 cancelable true初始化 event。 -
将 event分派给 element。
-
-
令 event 为一个新的
Event。 -
使用 type “
onpromptaction”、 bubbles true 和 cancelable true初始化 event。 -
将 event分派给 element。
-
令 event 为一个新的
Event。 -
使用 type “
onpromptdismiss”、 bubbles true 和 cancelable true初始化 event。 -
将 event分派给 element。
3. 共同渲染和样式限制
权限元素是不可退化部件,主要
像
button
一样渲染。
按钮标签在很大程度上应由浏览器而非页面
决定,并以文本和图标的形式反映[[Features]]
中列出的一个或多个
强大功能。该元素还可以传达
底层强大功能当前状态的信息。实际渲染由各
元素定义。
页面可以影响权限元素的样式,但会受到
防止滥用的约束(例如字体和标签本身的最小及
最大尺寸)。页面还可以通过
lang
属性为文本选择区域设置。
权限元素支持回退内容,尚不支持相应元素的 浏览器将显示这些内容。请注意, 即使浏览器支持相应权限元素,也存在 回退到其回退内容的情况。
3.1. 呈现
详细描述用户代理 UI 的先例并不多。 给用户代理保留更多自由度可能更好。
权限元素包含由浏览器选择的内容、文本,或许还有一个 图标。激活它们通常会提示用户作出选择。 这提供了两部分用户可以交互的用户界面。 用户 代理可以在很大程度上自由决定这两者——元素的渲染以及 后续的权限 提示——采用它认为最能传达元素意图的方式。
权限元素呈现的 UI 选项包括:
-
使用元素的语言所指示的语言, 对
[[Features]]中列出的强大功能进行命名。 请注意,如果存在lang属性,则始终使用该属性所指示的语言。 -
指示强大功能类型的一个或多个图标。
-
所涉及强大功能的当前 权限状态。 例如,如果相应权限已经
授予, 则permission元素可以标记为 “地理位置已在使用中”。 -
带有“遮罩层”的模态提示。 (即将提示后方的页面变暗。) 这通常会非常具有干扰性。但这里的目标是确保 用户确实有意作出此选择。
鼓励用户 代理以与程序或其运行平台中类似用法一致的方式 命名或描述强大功能。
非常非规范性的示例可能包括:
-
<permission lang="de" types="geolocation">:“Standort verwenden”。 -
<permission types="microphone">(位于英语页面中):“使用麦克风。🎤”。 -
激活
<permission types="microphone">后,当相应 权限状态为拒绝时, 将文本修改为 “继续阻止”。
3.2. 样式
权限元素会限制可应用于它们的样式。 这些约束分为三类:
-
如果条件不满足,则停用该元素。
-
由用户代理定义的样式表强制应用某些样式。
-
用户代理对其他样式强制实施界限,这些界限 无法轻易用 CSS 表达。例如,当样式界限是 相对于元素的计算样式表示时。
3.2.1. 停用元素的条件
如果其中一个条件未满足,则添加一个
类型为style_invalid
的临时阻止器。
| 'color'、'background-color' |
默认设置为用户代理的默认 button 颜色。
两种颜色之间的对比度必须至少为 3。
Alpha 必须为 1。
|
|---|---|
| 'font-size' | 如果指定值表示为<relative-size>: |
3.2.2. 用户代理定义的样式表
权限元素应使用以下样式渲染:
@namespace "http://www.w3.org/1999/xhtml" ; permission, 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.2.3. 用户代理定义的其他样式界限
权限元素为样式定义了若干界限。例如,我们希望 字体大小受到约束。样式界限说明如下。为了便于表示,我们设想可以在 CSS 规则中通过 computed
访问元素的计算
值,就像可以通过
inherit
关键字访问元素的继承值一样。
那么,以下样式表可表示这些样式界限:
@namespace "http://www.w3.org/1999/xhtml" ; permission{ outline-offset : clamp ( 0 , computed, none); /* 不允许负的 outline-offset。 */ font-weight:clamp ( 200 , computed, none); /* 不允许低于 200 的 font-weight。 */ word-spacing:clamp ( 0 , computed, 0.5 em ); /* word-spacing 介于 0..0.5em */ letter-spacing:clamp ( -0.05 em , commputed, 0.2 em ); /* letter-spacing 介于 -0.05..0.2em */ min-height:clamp ( 1 em , computed, none); max-height : clamp ( none, computed, 3 em ); min-width : clamp ( none, computed, calc ( fit-content)); border-width : clamp ( none, computed, 1 em ); 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" ) }
此外,还会根据难以用 CSS 表达的条件应用一些规则。
如果height 为
auto,则应用:
@namespace "http://www.w3.org/1999/xhtml" ; permission{ padding-top : clamp ( 1 em , computed, none); padding-bottom : calc ( padding-top); }
如果width 为
auto,则应用:
@namespace "http://www.w3.org/1999/xhtml" ; permission{ padding-left : clamp ( none, computed, 5 em ); padding-right : calc ( padding-left); }
如果元素不具备以下全部条件,则应用以下样式表:
-
边框宽度至少为
1px, -
color 与 background-color 的对比度至少为 3,
-
并且 alpha 为 1。
@namespace "http://www.w3.org/1999/xhtml" ; permission{ max-width : clamp ( none, computed, calc ( 3 * fit-content)); }
以下 CSS 属性可以正常使用:
-
border 及所有 border 简写 属性、 border-top、border-right、border-bottom、border-left
-
flex 及其展开属性:flex-grow、flex-shrink、flex-basis
-
outline 及其大多数展开属性: outline-color 和outline-style。
请注意,outline-offset 受到上述规则的限制。 -
overscroll-behavior 及其 展开属性: overscroll-behavior-inline、overscroll-behavior-block、 overscroll-behavior-x、overscroll-behavior-y
-
scroll-margin 及其展开属性: scroll-margin-top、scroll-margin-right、scroll-marginbottom'、 scroll-margin-left
-
scroll-padding 及其展开属性: scroll-padding-top、scroll-padding-right、scroll-padding-bottom、 scroll-padding-left、scroll-padding-inline-start、 scroll-padding-block-start、scroll-padding-block-start、 scroll-padding-inline-end、scroll-padding-block-end
未在上文或本节规则中列出,且在逻辑上不等同于 此处提到的某个属性的属性,将被忽略。
3.3. 回退
不支持某个特定权限元素的用户
代理会将其识别为HTMLUnknownElement
并将其子项渲染为
普通 HTML。
支持此类元素的用户
代理通常应按§ 3 共同渲染和样式限制中的描述
渲染元素,但在一种情况下仍
必须渲染回退内容:
如果内部[[BlockerList]]
包含一个记录,其
阻止原因为type_invalid,
则
permission
元素应渲染回退内容,
而不是
permission
的通常渲染。
4. permission 元素
注:
permission
元素是最初提出的页面内权限
元素,可以与任何强大功能或功能组合配合使用。
虽然我们不希望预先限制未来的标准讨论,但目前
预计此元素将被删除,转而采用后续章节中详细说明的
更具体元素。
permission
元素可以请求任意强大功能。
- 类别:
- 流式内容。
- 短语内容。
- 交互式内容。
- 可感知内容。
- 短语内容。
- 可以使用此元素的上下文:
- 需要短语内容的地方。
- 内容模型:
- 流式内容。
- 内容属性:
- 全局属性
- 权限元素属性
type— 此元素适用的权限类型。lang— 类似于全局lang 属性。 - 权限元素属性
- 无障碍考量:
- DOM 接口:
HTMLPermissionElement
permission
元素的内容(如有)是其回退内容。
type 属性控制
permission
元素被激活时的行为。它是一个枚举属性,
其值为强大功能的名称。它既没有
缺失值默认状态,也没有无效值默认状态。
lang 属性与
全局lang 属性相同。
permission
元素会观察该属性,以选择本地化文本。
tabindex
全局内容属性在
permission
元素上的默认
值为 0。
[Exposed =Window ]interface :HTMLPermissionElement HTMLElement { [HTMLConstructor ]constructor (); [CEReactions ,Reflect ]attribute DOMString ;type static boolean (isTypeSupported DOMString ); };type HTMLPermissionElement includes InPagePermissionMixin ;
isTypeSupported(type)
静态操作用于确定给定的DOMString
type,
即给定的枚举形式的强大功能是否受支持。
它可预测创建
permission
元素并为其分配给定
type
字符串是否可行,或者是否会创建
一个被type_invalid
永久阻止器阻止的元素。
4.1.
permission
元素内部状态
permission
元素具有与InPagePermissionMixin
相同的内部槽,如§ 2.1 Mixin 内部状态中所述。
4.2.
permission
元素的特殊行为
permission
元素具有一些出人意料的行为,以支持其
安全属性:
4.2.1.
type
属性
权限类型不能修改。随意修改权限类型
可能导致用户困惑,因此我们希望阻止这种情况。不过,
由于页面可能动态创建
permission
元素,我们仍需要提供
修改它的 API。为此,我们区分新初始化状态和
空状态或无效状态(无权限),前者允许设置
类型,后者则不允许。
示例:
// 更改有效类型: var pepc= document. createElement( "permission" ); pepc. type= "camera" ; // 可以。 pepc. type; // "camera"。 pepc. type= "geolocation" ; // 不可以。若作为初始赋值则可以。 pepc. type; // "camera"。反映未发生变化的内部状态。 // 设置无效类型: pepc= document. createElement( "permission" ); pepc. type= "icecream" ; // 冰淇淋不是强大的浏览器功能。不可以。 pepc. type; // ""。反映内部状态。 pepc. type= "camera" ; // 仍然不可以,因为 type 已经设置过。 // 若作为初始赋值则可以。 pepc. type; // ""。反映未发生变化的内部状态。
type
获取器步骤为:
-
如果
[[Features]]为 null:返回""。 -
返回一个字符串,其中包含
[[Features]]中所有强大功能名称的连接结果, 并以“ ”分隔。
type
设置器步骤为:
-
如果
[[Features]]不为 null:返回。 -
将
[[Features]]设置为 «»。 -
令 features 为使用输入字符串调用解析类型字符串的结果。
-
如果 features 为 None,则返回。
-
将每个强大功能名称追加到
[[Features]]有序集合中。 -
将
[[InitialPermissionStatus]]设置为获取当前 权限状态的结果。
要查询某项功能(或一组功能)是否受支持:
isTypeSupported()
方法
使用DOMString
type 参数时的步骤为:
-
令 features 为使用 type 调用解析类型字符串的结果。
-
返回 features 是否不为 None。
-
令 list 为将 type 解析为由空白分隔的 强大功能名称字符串的结果。
-
如果发生任何错误,则返回 None。
-
检查强大功能集合是否受 用户代理为
HTMLPermissionElement所支持。如果不支持,则返回 None。 -
返回 list。
4.3.
permission
元素算法
HTMLPermissionElement
constructor() 的步骤为:
-
将内部
[[Features]]槽初始化为 null。 -
将内部
[[BlockerList]]初始化为 «»。 -
将内部
[[LastNotifiedValidState]]初始化为 false。 -
将内部
[[LastNotifiedInvalidReason]]初始化为空 字符串。 -
将内部
[[InitialPermissionStatus]]初始化为获取当前 权限状态的结果。
HTMLPermissionElement
的插入步骤为:
-
如果
[[Features]]为 null,则将[[Features]]设置为 «»。 -
将内部
[[BlockerList]]初始化为 «»。 -
将内部
[[IntersectionRect]]初始化为 undefined。 -
使用 IntersectionObserver 回调和 «[ "
rootMargin" →"-4px"]» 构造新的IntersectionObserver, 并将内部[[IntersectionObserver]]初始化为其结果。 -
调用
[[IntersectionObserver]].observe(this)。 -
如果
[[Features]]为空,则使用原因type_invalid添加永久阻止器。 -
使用原因
recently_attached添加到期阻止器。 -
如果this 的节点可导航对象的可遍历可导航对象 是一个围栏可导航对象,则使用
illegal_subframe添加永久阻止器。
permission
element 的激活行为为:
-
断言:element 的
[[Features]]不为 null。 -
如果 element 的
[[Features]]为空,则返回。 -
如果 event.
isTrusted为 false,则返回。 -
如果 element.
isValid为 false,则返回。 -
令 descriptor 为为 element构建权限 描述符的结果。
-
如果上一步被用户取消或关闭,则在 this 上分派 onpromptdismiss 并返回。
[PERMISSIONS] 规范假定请求使用权限 总会成功。也就是说,它假定用户总会作出 选择,并且算法总会给出与该选择对应的
grant/deny答案。但你无法强迫用户这样做。 一些用户代理可能一方面为明确 拒绝提供一种 UI 控件(例如“拒绝”按钮),另一方面为取消或关闭 请求对话框提供另一种控件(例如右上角的“X”按钮)。尽管底层规范中 没有明确的挂钩,我们仍在此区分这两种操作。
HTMLPermissionElement
element
构建权限描述符:
[Permissions]
规范假定描述符描述的是
不带参数的单个权限(例如
enableHighAccuracy
的等效项)。
在此,我们假定一种表达能力更强的权限模型。
这需要解决——很可能应在上游
[Permissions]
中解决,并在此处作相应调整。
-
令 result 为一个新的
PermissionDescriptor。 -
填充 result:
-
包含 element 的
[[Features]]中包含的强大功能名称。
-
-
返回 result。
IntersectionObserverCallback
并运行以下步骤:
-
令 entry 为 entries 的最后一个项。
-
如果 entry.
isVisible, 则: -
否则:
-
如果 entry.
intersectionRatio>= 1,则:-
令 reason 为
intersection_occluded_or_distorted。
-
-
否则:
-
令 reason 为
intersection_out_of_viewport_or_clipped。
-
-
使用 reason添加临时 阻止器。
-
-
如果
[[IntersectionRect]]不等于 entry.intersectionRect, 则使用intersection_changed添加到期阻止器。 -
将
[[IntersectionRect]]设置为 entry.intersectionRect
-
断言:element 的节点可导航对象的
[[PermissionElements]]包含 element。 -
令 count 为 0。
-
对于 element 的节点可导航对象的
[[PermissionElements]]中的每个 current:-
如果 current 是 element,则中断。
-
如果 element.
[[Features]]与 current.[[Features]]相等,则将 count 加 1。
-
-
返回 count 是否小于 3。
-
对于 document 的
[[PermissionElements]]中的每个 current:-
如果 current 的类型允许,则从 current 中使用
unsuccesful_registration移除阻止器。
-
HTMLPermissionElement
element
获取当前权限状态:
-
令 types 为 element 的内部
[[Features]]。 -
令 current 为
granted。 -
对于 types 中的每个 type:
-
返回 current。
“没有有效权限类型” 的 PermissionState 应为何值尚不明确。 此处我根据 Chrome 的实现选择了“prompt”,但该 选择是任意的。
5. geolocation 元素
HTML
geolocation
元素可以请求访问
"geolocation"。
- 类别:
- 流式内容。
- 短语内容。
- 交互式内容。
- 可感知内容。
- 短语内容。
- 可以使用此元素的上下文:
- 需要短语内容的地方。
- 内容模型:
- 流式内容。
- 内容属性:
- 全局属性。
- 权限元素属性。
autolocate— 是否立即定位(如果权限已授予)。watch— 是读取一次位置,还是持续监视位置。 - 权限元素属性。
- 无障碍考量:
- DOM 接口:
HTMLGeolocationElement
isValid
和
invalidReason,
以及全局
lang 和
tabindex
内容属性,以及
onpromptaction、
onpromptdismiss
和
onvalidationstatuschange
事件处理器遵循§ 2 HTML 权限元素的共同行为:
InPagePermissionMixin中的描述。
autolocate 属性决定
geolocation
元素是否应立即开始定位(如果
权限已授予)。
watch 属性决定
geolocation
元素是报告一次位置还是持续报告。
[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 InPagePermissionMixin ;
如果用户已决定允许访问地理位置信息,则
只读属性position 和
error 会反映当前
GeolocationPosition
和GeolocationPositionError
值,就像
PositionCallback
和
PositionErrorCallback
回调(分别)会返回的值一样
如果布尔属性autolocate 为 true,
且用户已经授予
"geolocation" 权限,则
geolocation
元素附加到文档时应立即检索位置。如果在
插入时权限尚未授予,则此属性不起作用。
如果布尔属性watch
设置为 true,则每次位置变化时都会调用onlocation
事件,其行为与watchPosition
一致。
当位置可用时,会在
onlocation 事件处理器上
分派一个Event。
分派事件时,位置或关于位置检索失败的信息
可通过position
或
error
属性获取。根据
watch
元素,此操作可能发生一次(缺失或为 false 时),
或持续发生(为 true 时)。
HTMLGeolocationElement
旨在映射Geolocation
接口。
两者存在直接对应关系:
| position | PositionCallback
的结果。
|
|---|---|
| error | PositionErrorCallback
的结果。
|
| watch | 使用watchPosition()。
|
| ¬ watch | 使用getCurrentPosition()。
|
5.1.
geolocation
元素内部状态
geolocation
元素使用InPagePermissionMixin
的所有内部槽,如§ 2.1 Mixin 内部状态中所述。此外,
geolocation
还具有以下内部槽:
-
常量
[[watchIDs]], 用于请求位置算法。 -
[[position]], 其中包含最近的GeolocationPosition。 -
[[positionError]], 其中包含最近的GeolocationPositionError。
5.2. geolocation
元素算法
HTMLGeolocationElement
constructor() 的步骤为:
-
将内部
[[Features]]槽初始化为 « "geolocation" » -
将内部
[[BlockerList]]初始化为 «»。 -
将内部
[[LastNotifiedValidState]]初始化为 false。 -
将内部
[[LastNotifiedInvalidReason]]初始化为空 字符串。 -
将内部
[[InitialPermissionStatus]]初始化为获取当前 权限状态的结果。 -
将内部
[[watchIDs]]初始化为 « watchID »,其中 watchID 是一个大于零的、由实现定义的unsigned long。 -
将内部
[[position]]初始化为 null。 -
将内部
[[positionError]]初始化为 null。
HTMLGeolocationElement
的插入步骤为:
-
将内部
[[BlockerList]]初始化为 «»。 -
将内部
[[IntersectionRect]]初始化为 undefined。 -
使用 IntersectionObserver 回调和 «[ "
rootMargin" →"-4px"]» 构造新的IntersectionObserver, 并将内部[[IntersectionObserver]]初始化为其结果。 -
调用
[[IntersectionObserver]].observe(this)。 -
如果
[[Features]]为空,则使用原因type_invalid添加永久阻止器。 -
使用原因
recently_attached添加到期阻止器。 -
如果this 的节点可导航对象的可遍历可导航对象 是一个围栏可导航对象,则使用
illegal_subframe添加永久阻止器。
HTMLGeolocationElement
element 的激活行为为:
-
断言:element 的
[[Features]]不为 null。 -
如果 element 的
[[Features]]为空,则返回。 -
如果 event.
isTrusted为 false,则返回。 -
如果 element.
isValid为 false,则返回。 -
令 descriptor 为为 element构建权限 描述符的结果。
-
如果上一步被用户取消或关闭,则在 this 上分派 onpromptdismiss 并返回。
[Permissions] 规范假定请求使用权限 总会成功。也就是说,它假定用户总会作出 选择,并且算法总会给出与该选择对应的
grant/deny答案。但你无法强迫用户这样做。 一些用户代理可能一方面为明确 拒绝提供一种 UI 控件(例如“拒绝”按钮),另一方面为取消或关闭 请求对话框提供另一种控件(例如右上角的“X”按钮)。尽管底层规范中 没有明确的挂钩,我们仍在此区分这两种操作。 -
获取位置。
position
获取器步骤为返回
[[position]]
的值。
error
获取器步骤为返回
[[positionError]]
的值。
-
如果
autolocate不为 true,则返回。 -
获取位置。
-
令 positionCallback 为一个执行以下步骤的
PositionCallback:-
将this的
[[positionError]]设置为 undefined。 -
将this的
[[position]]设置为PositionCallback的 position 参数。
-
-
令 errorCallback 为一个执行以下步骤的
PositionErrorCallback:-
将this的
[[position]]设置为 undefined。 -
将this的
[[positionError]]设置为PositionCallback的 positionError 参数。
-
-
令 positionOptions 为 «[]»
-
令 geolocation 为相关全局对象的
Geolocation。 -
-
使用 geolocation、positionCallback、 errorCallback、positionOptions 和this的
[[watchIDs]]请求位置。
-
-
否则:
-
使用 geolocation、positionCallback、 errorCallback 和 positionOptions 请求位置。
-
5.3.
geolocation
元素事件算法
-
令 event 为一个新的
Event。 -
使用
type“onlocation” 初始化 event。 -
将 event分派给 element。
6. 安全与隐私考量
注:安全与隐私考量可在说明文档中的 此处和 此处找到, 参见说明文档。 本节最终将包含这些说明文档章节中 适合纳入规范的转述。