Manifest Incubations

Draft Community Group Report 13

Latest published version:
https://www.w3.org/manifest-incubations/
Latest editor's draft:
https://wicg.github.io/manifest-incubations/
Editor:
Daniel Murphy
Feedback:
GitHub WICG/manifest-incubations ( pull requests , new issue , open issues )

Abstract

Feature specifications for Web Application Manifest extensions & incubations which Chromium has shipped but do not have committments / implementations from other user agents. Instead of keeping these features as explainers, they are documented more officially here.

Status of This Document

This is a preview

Do not attempt to implement this version of the specification. Do not reference this version as authoritative in any way. Instead, see https://wicg.github.io/manifest-incubations/ for the Editor's draft.

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 .

This is an unofficial proposal.

GitHub Issues are preferred for discussion of this specification.

1. display_override member

For advanced usages, the display_override member can be used to specify a custom fallback order of display mode values for developers to choose their preferred display mode .

The display_override member of the application manifest is a sequence of display mode values . This item represents the developer's preferred fallback chain for display modes . This field overrides the display member. If the user agent does not support any of the display modes specified here, then it falls back to considering the display member. See display modes for the algorithm steps.

The following steps are added to the processing extension-point in determining the web app's chosen display mode :

  1. For each candidate_display_mode of manifest . display_override :
    1. If the user agent supports the candidate_display_mode , then return candidate_display_mode .
Note

This member is intended to be only used for advanced cases, where the developer wants explicit control over the fallback order of their display modes. Otherwise, the display member is sufficient for most use cases.

1.1 Usage Example

This section is non-normative.

The following shows a manifest that prefers the minimal-ui display mode over standalone , but if minimal-ui isn't supported, falls back to standalone as opposed to browser .

Example 1 : Advanced display usage manifest
{
  "name": "Recipe Zone",
  "description": "All of the recipes!",
  "icons": [{
    "src": "icon/hd_hi",
    "sizes": "128x128"
  }],
  "start_url": "/index.html",
  "display_override": ["minimal-ui"],
  "display": "standalone",
  "theme_color": "yellow",
  "background_color": "red"
}

2. share_target member

The share_target member registers a web application as "target" for share actions (e.g., for sharing a text, a URL, or a file). The share_target member is part of the Web Share Target API specification.

3. note_taking member

The note_taking member of the Web Application Manifest is an object that contains information related to note-taking. It has the following members:

A user agent MAY use these members to treat the web application differently as an application with note-taking capabilities (e.g., integrate with operating system note-taking surfaces).

3.1 new_note_url member

The note_taking new_note_url member is a string that represents the URL the developer would prefer the user agent load when the user wants to take a new note using the web application (e.g., from an operating system shortcut icon or keyboard shortcut).

The new_note_url member is purely advisory, and a user agent MAY ignore it or provide the end-user the choice of whether to use it. The user agent MAY provide the end-user the choice to modify it.

Note

3.2 Usage Example

This section is non-normative.

The following shows a manifest for a note-taking application.

Example 2 : Note-taking application
{
  "name": "My Note Taking App",
  "description": "You can take notes!",
  "icons": [{
    "src": "icon/hd_hi",
    "sizes": "128x128"
  }],
  "start_url": "/index.html",
  "display": "standalone",
  "note_taking": {
    "new_note_url": "/new_note.html"
  }
}

3.3 Processing the note_taking member

To process the note_taking member , given ordered map json , ordered map manifest , URL manifest_URL , run the following during the extension point in processing a manifest :

  1. If json ["note_taking"] does not exist , return.
  2. If the type of json ["note_taking"] is not ordered map , return.
  3. Set manifest ["note_taking"] to a new ordered map .
  4. process the new_note_url member passing json ["note_taking"], manifest ["note_taking"], and manifest URL .

3.4 Processing the new_note_url member

To process the new_note_url member , given ordered map json_note_taking , ordered map manifest_note_taking , URL manifest_URL , run the following:

  1. If json_note_taking ["new_note_url"] does not exist , return.
  2. If the type of json_note_taking ["new_note_url"] is not string , return.
  3. Let new_note_url be the result of parsing json_note_taking ["new_note_url"] with manifest URL as the base URL.
  4. If new_note_url is failure, return.
  5. If new_note_url is not within scope of manifest URL , return.
  6. Set manifest_note_taking["new_note_url"] to new_note_url .

3.5 Launching the new_note_url

To launch the new_note_url , given processed manifest manifest , run the following steps:

  1. If manifest ["note_taking"] does not exist , return.
  2. If manifest ["note_taking"]["new_note_url"] does not exist , return.
  3. If the type of manifest ["note_taking"]["new_note_url"] is not URL , return.
  4. Let browsing context be the result of creating a new top-level browsing context .
  5. Navigate browsing context to resource manifest ["note_taking"]["new_note_url"].

4. protocol_handlers member

The manifest's protocol_handlers member is an array of protocol handler description s that allows a web application to handle URL protocols.

On installation, a user agent SHOULD register protocol handlers with the Operating System via interactions that are consistent with:

Note

4.1 Processing the protocol_handlers member

To process the protocol_handlers member , given object json , manifest :

  1. Let processedProtocolHandlers be a new list of json [" protocol_handlers "].
  2. Set manifest[" protocol_handlers "] to processedProtocolHandlers .
  3. For each protocol_handler ( protocol handler description ):
    1. If protocol_handler ["protocol"] or protocol_handler ["url"] is undefined, continue .
    2. Let ( normalizedProtocol , normalizedUrl ) be the result of running normalize protocol handler parameters with protocol_handler ["protocol"], | protocol_handler|["url"] using manifest URL as the base URL, and this 's relevant environment settings object . If the result is failure, continue .
    3. If normalizedUrl is not within scope of manifest , continue .
    4. If processedProtocolHandlers contains the normalizedUrl , continue .
    5. Append protocol_handler to processedProtocolHandlers .
  4. For each processedProtocolHandlers , the user agent SHOULD register a protocol handler .

A user agent SHOULD ask users for permission before registering a protocol handler description protocol_handler s as the default handler for a protocol with the host operating system. A user agent MAY truncate the list of protocol handler description protocol_handlers presented in order to remain consistent with the conventions or limitations of the host operating system.

4.2 ProtocolHandler items

Each protocol handler description is an object that represents a protocol that the web application wants to handle. It has the following members:

A user agent SHOULD use these values to register the web application as a handler with the operating system. When the user activates a protocol handler URL, the user agent SHOULD run handling a protocol launch .

Note

[ HTML ]'s registerProtocolHandler () allows web sites to register themselves as possible handlers for particular protocols. What constitutes valid protocol and url values for protocol handler description s is defined in that API. Also note that the [ HTML ] API uses scheme where we use protocol but the same restrictions apply.

4.2.1 protocol member

The protocol member of a protocol handler description is a string that represents the protocol to be handled, such as mailto or web+auth .

The protocol member of a protocol handler description is equivalent to registerProtocolHandler () 's scheme argument defined in [ HTML ].

4.2.2 url member

The url member of a protocol handler description is the URL within scope of the application that opens when the associated protocol is activated.

The url member of a protocol handler description is equivalent to registerProtocolHandler () 's url argument defined in [ HTML ].

4.2.3 Handling a protocol launch

When a protocol handler description protocol_handler having manifest manifest is invoked, it goes through the same steps used to invoke a protocol handler defined in HTML , where the user agent SHOULD navigate to url and the appropriate browsing context is set to a new top level browsing context.

4.3 Privacy consideration: Default protocol handler

Depending on the operating system capabilities, the protocol handler could become a 'default' handler (e.g. handling launches of a given protocol automatically) of a given protocol without the explicit knowledge of the user. To protect against possible misuse, user agents MAY employ protections such as:

If a user agent removes the the registration of the protocol handler entity it SHOULD provide UX for the user to re-register the web app and protocol with the operating system.

5. user_preferences member

The user_preferences member of the application manifest is an object that can be used to override values of manfiest members depending on which user preferences are set. It has the following members:

Note

This list of members is expected to expand in the future to include other user preference media features such as contrast and forced-colors , as defined in CSS.

The user agent SHOULD use the override values instead of the value of the corresponding member defined at the top level of the manifest.

To process the user_preferences member , given ordered map json , ordered map manifest , run the following during the processing extension-point in processing a manifest :

  1. If json ["user_preferences"] does not exist , return.
  2. If the type of json ["user_preferences"] is not ordered map , return.
  3. Set manifest ["user_preferences"] to a new ordered map .
  4. Process the color_scheme member passing json ["user_preferences"] and manifest ["user_preferences"].

5.1 color_scheme member

The user_preferences color_scheme member is an object that contains the overrides for color scheme preferences. It has the following members:

The dark member specifies the manifest overrides to use when the user prefers a dark theme.

The light member specifies the manifest overrides to use when the user prefers a light theme.

To process the color_scheme member , given ordered map json_user_preferences , ordered map manifest_user_preferences , run the following:

  1. If json_user_preferences ["color_scheme"] does not exist , return.
  2. If the type of json_user_preferences ["color_scheme"] is not ordered map , return.
  3. Set manifest_user_preferences ["color_scheme"] to a new ordered map .
  4. For each member of list « "dark", "light" »:
    1. Let overrides be the result of processing a manifest override object.
    2. Set manifest_user_preferences ["color_scheme"][ member ] to overrides .

5.2 Overridable properties

The proterties that user_preferences can override in the manifest override object are:

6. Manifest override objects

Each manifest override object is a generic object value that allows for certain manifest properties to be overridden within a particular context.

The structure of a manifest override object is as follows:

{  "context_key": {    "property": "new value"
  }
}

Each manifest property that accepts a manifest override object as its value will define the contexts it supports and which properties it supports overriding. User agents MUST ignore any contexts that are not supported by the property as well as any override properties not explicitly allowed within it.

When the manifest property’s context is applicable, the value of each allowable override will be used in place of the original value defined in the Manifest.

Redefined array items will be overridden in the order they are authored. When redefining objects (e.g., shortcuts , icons ), authors will only be able to redefine specific properties of that object. In order to ensure all overrides are applied correctly, the order must match the original array (i.e., each shortcut must be redefined in order, as must their icons, if they also require re-definition).

Redefined array items must also be equal in number to the array being overridden. If there is a mismatch in the number of items in either array, any excess items will be ignored. This is only an issue if the original array has more items than the override array, because any excess items within the original array will not be re-defined.

When there is a conflict because two different properties are attempting to override the same value in their respective active contexts, the one defined last will win. By way of example, consider the following:

{  "lang": "en-US",  "icons": [
    {
      "src": "icon.png",      "sizes": "128x128",      "type": "image/png"
    }
  ],
  "translations": {    "es": {      "icons": [
        {
          "src": "icon-es.png"
        }
      ]
    }
  },
  "user_preferences": {    "color_scheme": {      "dark": {        "icons": [
          {
            "src": "icon-dark.png"
          }
        ]
      }
    }
  }
}

In this example, if the user’s primary language is Español, but their preferred color scheme was set to "dark", the icon supplied would be the dark version and not the localized one. For this reason, it is imperative that properties taking a manifest override object as their value consider whether any other properties that also enable overrides should be able to be redefined within them. In the above example, the author’s intent would likely have been better realized if user_preferences was put before translations and the localized context block redefined the user_preferences value for that language:

{  "lang": "en-US",  "icons": [
    {
      "src": "icon.png",      "sizes": "128x128",      "type": "image/png"
    }
  ],
  "user_preferences": {    "color_scheme": {      "dark": {        "icons": [
          {
            "src": "icon-dark.png"
          }
        ]
      }
    }
  },
  "translations": {    "es": {      "icons": [
        {
          "src": "icon-es.png"
        }
      ],
      "user_preferences": {        "color_scheme": {          "dark": {            "icons": [
              {
                "src": "icon-es-dark.png"
              }
            ]
          }
        }
      }
    }
  },
  
}

User agents MAY ignore any override properties they do not support.

To apply a manifest override object , given ordered_map overrides , ordered map manifest , and array allowed_properties run the following:

  1. Let allowed_overrides be a new ordered map .
  2. For each member of overrides :
    1. If member is not in allowed_properties , continue.
    2. Set allowed_overrides [ member ] to |overrides[ member ]|.
  3. Let overriden_manifest be the result of creating a new ordered map by merging manifest with allowed_overrides .
  4. Set manifest to overriden_manifest .

7. Installation prompts

There are multiple ways that the installation process can be triggered:

In any case, the user agent MUST NOT present an install prompt if the document is not installable.

The user agent MAY , at any time (only if the document is installable), run the steps to notify that an install prompt is available at any time, giving the site the opportunity to show a site-triggered install prompt without the user needing to interact with the user agent UI .

To present an install prompt :

  1. Show some user-agent-specific UI , asking the user whether to proceed with installing the app. The result of this choice is either " accepted " or " dismissed ".
  2. Return result , and in parallel :
    1. If result is " accepted ", run the steps to install the web application .

The steps to notify that an install prompt is available are given by the following algorithm:

  1. Wait until the Document of the top-level browsing context is completely loaded .
  2. If there is already an install prompt being presented or if the steps to install the web application are currently being executed, then abort this step.
  3. Queue a task on the application life-cycle task source to do the following:
    1. Let mayShowPrompt be the result of fire an event named "beforeinstallprompt" at the top-level browsing context 's relevant global object using the BeforeInstallPromptEvent interface, with steps to initialize the cancelable attribute to true .
    2. If mayShowPrompt is true, then the user agent MAY , in parallel , request to present an install prompt with event .

6. 8. Installable web applications

6.1 8.1 Installation process

The steps to install the web application are given by the following algorithm:

  1. Let manifest be the manifest of an installable document.
  2. Perform an unspecified sequence of actions to attempt to register the web application in the user's operating system (e.g., create shortcuts that launch the web application, register the application in the system uninstall menu, etc.). If the installation fails (which can be for any reason, for example, the OS denying permission to the user agent to add an icon to the home screen of the device), abort these steps.
  3. Queue a task on the application life-cycle task source to fire an event named "appinstalled" at the top-level browsing context 's relevant global object for which the installation took place.

6.2 8.2 Installability signals

This section is non-normative.

By design, this specification does not provide developers with an explicit API to "install" a web application. Instead, a manifest can serve as an installability signal to a user agent that a web application can be installed.

Examples of installability signals for a web application:

This list is not exhaustive and some installability signals might not apply to all user agents. How a user agent makes use of these installability signals to determine if a web application can be installed is left to implementers.

7. 9. Installation Events

Events of this specification rely on the application life-cycle task source .

7.1 9.1 BeforeInstallPromptEvent Interface

Note
The beforeinstallprompt event is somewhat misnamed, as it does not necessarily signal that a manual installation will follow (depending on the user agent, it might just be giving the site the ability to trigger an install prompt). It is so named for historical reasons.
WebIDL[Exposed=Window]
interface BeforeInstallPromptEvent : Event {
  constructor(DOMString type, optional EventInit eventInitDict = {});
  Promise<PromptResponseObject> prompt();
};
dictionary PromptResponseObject {
  AppBannerPromptOutcome userChoice;
};
enum AppBannerPromptOutcome {
  "accepted",
  "dismissed"
};


The BeforeInstallPromptEvent is dispatched when the site is allowed to present a site-triggered install prompt , or prior to the user agent presenting an automated install prompt . It allows the site to cancel the automated install prompt , as well as manually present the site-triggered install prompt .

Note
If the BeforeInstallPromptEvent is not cancelled, the user agent is allowed to present an install prompt (specifically, an automated install prompt ) to the end-user. Canceling the default action (via preventDefault () ) prevents the user agent from presenting an install prompt . The user agent is free to run steps to notify that an install prompt is available again at a later time.

The PromptResponseObject contains the result of calling prompt () . It contains one member, userChoice , which states the user's chosen outcome.

An instance of a BeforeInstallPromptEvent has the following internal slots:

[[didPrompt]]
A boolean, initially false . Represents whether this event was used to present an install prompt to the end-user.
[[userResponsePromise]]
A promise that represents the outcome of presenting an install prompt .

7.1.1 9.1.1 prompt() method

The prompt method, when called, runs the following steps:

  1. Let userResponsePromise be [[userResponsePromise]] .
  2. If userResponsePromise is pending:
    1. If this . [[didPrompt]] is true , terminate this algorithm.
    2. If this event's isTrusted attribute is false , reject userResponsePromise with " NotAllowedError " and terminate this algorithm.
    3. Set this . [[didPrompt]] to true .
    4. In parallel , request to present an install prompt with this . Wait, possibly indefinitely, for the end-user to make a choice.
  3. Return userResponsePromise .

To request to present an install prompt with BeforeInstallPromptEvent event :

  1. Present an install prompt and let outcome be the result.
  2. Let response be a newly created PromptResponseObject , initializing its userChoice to outcome .
  3. Resolve event . [[userResponsePromise]] with response .

7.1.2 9.1.2 Usage example

This section is non-normative.

This example shows how one might prevent an automated install prompt from showing until the user clicks a button to show a site-triggered install prompt . In this way, the site can leave installation at the user's discretion (rather than prompting at an arbitrary time), whilst still providing a prominent UI to do so.

Example 4 : Using beforeinstallprompt to present an install button
window.addEventListener("beforeinstallprompt", event => {
  // Suppress automatic prompting.
  event.preventDefault();
  // Show the (disabled-by-default) install button. This button
  // resolves the installButtonClicked promise when clicked.
  installButton.disabled = false;
  // Wait for the user to click the button.
  installButton.addEventListener("click", async e => {
    // The prompt() method can only be used once.
    installButton.disabled = true;
    // Show the prompt.
    const { userChoice } = await event.prompt();
    console.info(`user choice was: ${userChoice}`);
  });
});

7.1.3 9.1.3 AppBannerPromptOutcome enum

The AppBannerPromptOutcome enum's values represent the outcomes from presenting an install prompt .

" accepted ":
The end-user indicated that they would like the user agent to install the web application.
" dismissed ":
The end-user dismissed the install prompt.

7.2 9.2 Extensions to the Window object

WebIDLpartial interface Window {
  attribute EventHandler onappinstalled;
  attribute EventHandler onbeforeinstallprompt;
};


7.2.1 9.2.1 onappinstalled attribute

The onappinstalled event handler IDL attribute handles " appinstalled " events.

7.2.2 9.2.2 onbeforeinstallprompt attribute

The onbeforeinstallprompt event handler IDL attribute handles " beforeinstallprompt " events.

8. 10. Conformance

As well as sections marked as non-normative, all authoring guidelines, diagrams, examples, and notes in this specification are non-normative. Everything else in this specification is normative.

The key words MAY , MUST , MUST NOT , and SHOULD in this document are to be interpreted as described in BCP 14 [ RFC2119 ] [ RFC8174 ] when, and only when, they appear in all capitals, as shown here.

A. References

A.1 Normative references

[appmanifest]
Web Application Manifest . Marcos Caceres; Kenneth Christiansen; Matt Giuca; Aaron Gustafson; Daniel Murphy; Anssi Kostiainen. W3C. 17 February 2022. W3C Working Draft. URL: https://www.w3.org/TR/appmanifest/
[dom]
DOM Standard . Anne van Kesteren. WHATWG. Living Standard. URL: https://dom.spec.whatwg.org/
[HTML]
HTML Standard . Anne van Kesteren; Domenic Denicola; Ian Hickson; Philip Jägenstedt; Simon Pieters. WHATWG. Living Standard. URL: https://html.spec.whatwg.org/multipage/
[image-resource]
Image Resource . Aaron Gustafson; Rayan Kanso; Marcos Caceres. W3C. 4 June 2021. W3C Working Draft. URL: https://www.w3.org/TR/image-resource/
[infra]
Infra Standard . Anne van Kesteren; Domenic Denicola. WHATWG. Living Standard. URL: https://infra.spec.whatwg.org/
[RFC2119]
Key words for use in RFCs to Indicate Requirement Levels . S. Bradner. IETF. March 1997. Best Current Practice. URL: https://www.rfc-editor.org/rfc/rfc2119
[RFC8174]
Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words . B. Leiba. IETF. May 2017. Best Current Practice. URL: https://www.rfc-editor.org/rfc/rfc8174
[url]
URL Standard . Anne van Kesteren. WHATWG. Living Standard. URL: https://url.spec.whatwg.org/
[web-share-target]
Web Share Target API . Matt Giuca; Eric Willigers. W3C. W3C Editor's Draft. URL: https://w3c.github.io/web-share-target/
[WEBIDL]
Web IDL Standard . Edgar Chen; Timothy Gu. WHATWG. Living Standard. URL: https://webidl.spec.whatwg.org/

A.2 Informative references

[mediaqueries-5]
Media Queries Level 5 . Dean Jackson; Florian Rivoal; Tab Atkins Jr.; Daniel Libby. W3C. 18 December 2021. W3C Working Draft. URL: https://www.w3.org/TR/mediaqueries-5/