本文档指定了一组技术,允许 Web 开发者控制通常由已安装 web 应用在桌面环境中占据的标题栏区域。 这些技术被称为 (WCO)。

本草案旨在作为 WCO 标准化过程的起点,其中描述的技术可能会迁移到不同工作组的其他规范中。

介绍

面向非移动设备的应用通常托管在带有标题栏的窗口中。 标题栏是一个通常表示为窗口顶部的水平条的 UI 元素,显示活动程序的名称或当前活动文档的名称以及 [=窗口控件=]。 现代应用可以利用标题栏中的区域来展示 UI 内容,以创造更好的用户体验。

对于托管在用户代理 (UA) 框架内的已安装 web 应用,可以通过声明首选的显示模式来对框架进行某种定制。 开发者可以通过清单文件的 `display` 成员选择最符合应用需求的模式。 然而,这些模式是有限的,并不能提供对标题栏相同级别的控制,因此希望为其已安装应用创建沉浸式、类似原生的标题栏的开发者无法仅通过上述成员实现。 相反,客户端区域从保留的标题栏区域正下方开始,这会在屏幕较小的便携设备上导致应用空间受限。

WCO 通过只在框架上保留 [=窗口控件=] 的 [=覆盖层=] 来允许创建自定义标题栏 UI,这样 web 内容就可以流入先前由标题栏占据的区域。

显示控件区域的空白窗口框架。

示例

概念

对 `Navigator` 接口的扩展

[[HTML]] 规范定义了 Navigator 接口,本规范对其进行了扩展:

        [SecureContext, Exposed=(Window)]
        partial interface Navigator {
          [SameObject] readonly attribute WindowControlsOverlay windowControlsOverlay;
        };
      

对 `Window` 接口的扩展

内部槽位

内部槽位 初始值 描述
[[\TitleBarArea]] 用于标题栏区域的空 [=struct=]。 一个存储定义标题栏区域的值的 [=struct=]。这些值为 `x`、`y`、`width`、`height`。

WindowControlsOverlay 接口

        [Exposed=Window]
        interface WindowControlsOverlay : EventTarget {
          readonly attribute boolean visible;
          DOMRect getTitlebarAreaRect();
          attribute EventHandler ongeometrychange;
        };

        [Exposed=Window]
        interface WindowControlsOverlayGeometryChangeEvent : Event {
          constructor(DOMString type, WindowControlsOverlayGeometryChangeEventInit eventInitDict);
          [SameObject] readonly attribute DOMRect titlebarAreaRect;
          readonly attribute boolean visible;
        };

        dictionary WindowControlsOverlayGeometryChangeEventInit : EventInit {
          required DOMRect titlebarAreaRect;
          boolean visible = false;
        };
      

visible 属性

`visible` 属性是一个 [=boolean=],当 {{Window/window}}.[[\TitleBarArea]] 的值不为 0 时返回 `true`。

getTitlebarAreaRect 方法

`getTitlebarAreaRect()` 方法返回一个表示可用于显示网页内容的 DOMRect。该可用标题栏区域不包括 [=窗口控件=] [=覆盖层=] 下方的区域。

描绘 getTitlebarAreaRect 方法返回区域的示意图

ongeometrychange 属性

`ongeometrychange` 属性是一个事件处理器,其对应的事件类型为 "change"。

新的 [=display mode/window-controls-overlay=] [=display mode=] 的添加

本规范定义了以下 [=display mode=]:

window-controls-overlay
Web 应用以本机操作系统窗口控件可见的方式打开,但网页内容扩展到标题栏区域的其余部分。应用还可以在网页内容中指定 [=可拖动区域=] 来创建定制的标题栏。

[=display mode/window-controls-overlay=] [=display mode=] 可以在清单的 [=manifest/display_override=] 成员中指定。

标题栏区域环境变量

标题栏区域 env 变量

名称
`titlebar-area-x` length
`titlebar-area-y` length
`titlebar-area-width` length
`titlebar-area-height` length

[=标题栏区域环境变量=] 是四个 env 变量,通过从视口的起点开始的宽度和高度定义一个矩形。该区域对应于标题栏的可用区域,允许在其边界内定位动态 Web 内容。

与 CSSOM 的集成

本规范通过修补 下面的算法 与 [[cssom-view]] 规范集成:

在视口 [=Window/resize=] 算法中,在第 1 步之后运行 [=调整标题栏区域大小=]。

算法

调整标题栏区域大小

要为窗口 |win| 调整标题栏区域大小,运行以下步骤:

  1. If |win|'s [=overlay=] has had its width or height changed (e.g. as a result of the user resizing the browser window, or changing the page zoom factor, or other UI appearing or disappearing on the [=overlay=]), since the last time these steps were run, [=fire an event=] named `ongeometrychange` at the {{Window/window}} object and [=update the overlay area information=].

更新覆盖层区域信息

更新覆盖层区域信息,运行以下步骤:

  1. 令 |ovls| 为一个由窗口框架上容纳 [=窗口控件=] 的 [=覆盖层=] 定义的区域组成的 [=列表=]。
  2. 令 |tba| 为表示可用标题栏区域的空 {{DOMRect}} 对象。
    1. 如果 |ovls| 中只有一个覆盖区域,则将 |tba| 设置为一个 {{DOMRect}},其范围从框架边缘到 |ovls| 的最内侧边缘。
    2. 如果 |ovls| 中有多个覆盖区域,则将 |tba| 设置为一个 {{DOMRect}},其范围为 |ovls| 中区域的交集与 [=document=] 的viewport 之间的区域。
    3. |tba| 的高度应与 |ovls| 中区域的高度相同。
  3. 使 {{Window/window}}.[[\TitleBarArea]] 等于 |tba|。
  4. 使用来自 {{Window/window}}.[[\TitleBarArea]] 的信息更新 [=标题栏区域 env 变量=]。

安全性与隐私考量

安全

欺骗风险

在无框窗口中显示已安装的 web 应用为开发者在先前由用户代理控制的受信任区域中进行内容欺骗提供了空间。

在 Chromium 浏览器中,当前 `standalone` 模式包含一个标题栏,初次启动时左侧显示网页标题,右侧显示页面的来源(后面跟随“设置和更多”按钮以及窗口控件)。几秒钟后,来源文本会消失。

在 RTL(从右到左)配置的浏览器中,此布局会翻转,使得来源文本位于左侧。 如果来源与覆盖层右边缘之间的内边距不足,这会使窗口控件覆盖层存在篡改来源的风险。例如,来源 "evil.ltd" 可能会被拼接上受信任站点 "google.com",从而使用户误以为来源是可信的。

范围外导航

已安装 web 应用的另一个现有安全特性是指示用户何时离开应用声明范围的指示器。 当用户导航到范围外时,标题栏和网页内容之间会出现一条黑色条,并包含以下信息:

  • 一个关闭按钮,允许用户轻松返回到应用范围内
  • 一个安全图标,单击时会打开安全信息弹出窗口
  • 站点的来源和标题

启用窗口控件覆盖层后,如果用户导航到范围外,覆盖层将临时被替换为一个独立的标题栏。 当用户导航回范围内时,独立标题栏将再次隐藏并显示覆盖层。

隐私

启用 Window Controls Overlay 会增加指纹识别的表面,因为覆盖层的大小可能因操作系统、文本缩放、操作系统字体大小、操作系统缩放因子和网页内容的缩放因子而异。

虽然这可能是一个潜在的指纹识别问题,但它仅适用于使用窗口控件覆盖层功能的已安装桌面 web 应用,而不适用于一般的浏览器使用。 此外,windowControlsOverlay API 将不可用于嵌入在已安装 web 应用内的 iframe。

致谢

衷心感谢 Amanda Baker、Joshua Bell 和 Yoav Weiss 对本工作的贡献。