Chrome 76 Beta: dark mode, payments, new PWA features and more


Unless otherwise noted, changes described below apply to the newest Chrome Beta channel release for Android, Chrome OS, Linux, macOS, and Windows. Find more information about the features listed here through the provided links or from the list on ChromeStatus.com. Chrome 76 is beta as of June 13, 2019.
Many operating systems now support inverted color schemes with a system setting referred to as ‘dark theme' or ‘dark mode', depending on the system.


The prefers-color-scheme media query allows a website or web app to adopt the preferred display mode of the user. Use the query in your CSS code like so:


@media (prefers-color-scheme: dark) {
  body {
    color: white;
    background-color: black;
  }
}


What is left out of this is the explanation? For that, watch our web platform blog for an article titled "Hello Darkness, My Old Friend".
Over the last few versions of Chrome we've rolled out a number of improvements to the payments APIs. These APIs provide a way to interact with proprietary payment systems without needing to build your own user interactions. Changes in Chrome 75 included replacing hasEnrolledInstrument() with canMakePayment() and removal of languageCode from the billing address. With the detailsPromise option Chrome 75 gives PaymentRequest.show() a means of performing a quick server call before showing payment details to the buyer.

Chrome 76 brings three changes to the payment realm. Now implemented are features that allow a merchant website or web app to respond when a user changes payment instruments. Additionally, the PaymentRequestEvent has a new method called changePaymentMethod() and the PaymentRequest object now supports an event handler called paymentmethodchange. You can use both to notify a merchant when the user changes payment instruments. The former returns a promise that resolves with a new PaymentRequest instance.

Additionally, Chrome now makes it easier to use the payments APIs for self-signed certificates on the local development environment. To do this, launch Chrome from a command line with the —ignore-certificate-errors flag.

For detailed information about these features, read Web Payments Updates.
On desktop, there is typically no indication to a user that a Progressive Web App is installable, and if it is, the install flow is hidden within the three dot menu.

In Chrome 76, we're making it easier for users to install Progressive Web Apps on the desktop by adding an install button to the omnibox.


If a site meets the Progressive Web App installability criteria, Chrome shows an install icon in the omnibox. There is no extra work required from developers. Clicking the button prompts the user to install the PWA.
In Chrome 76, we're giving you control over the add to home screen mini-infobar.




Chrome shows the mini-infobar the first time a user visits a site that meets the Progressive Web App installability criteria. Developers want to prevent the mini-infobar from appearing, and provide their own install promotion instead.

To do this, listen for the beforeinstallprompt event, and call preventDefault()
on it. Then, update your UI to notify the user by adding an install button or other element. Depending on your app, there are several different patterns you can use to promote installation of your PWA.

The add to home screen mini-infobar is still a temporary measure. We are experimenting with new UI patterns for giving Progressive Web App users the ability to install, and do this in a way that reduces clutter in the browsing experience.
When a PWA is installed on Android, Chrome automatically requests and installs a WebAPK. Chrome periodically checks to see if the manifest has changed, and if a new WebAPK is required. Starting in Chrome 76, Chrome will check the manifest more frequently: checking every day, instead of every three days. If any of the key properties have changed, Chrome will request and install a new WebAPK.
Adds Animation.updatePlaybackRate(), which lets you seamlessly transition the playback rate of an animation such that there is no visible jump in the animation. Current time is preserved at the instance the new playback rate takes effect.
Implements programmatic copying and pasting of images for the Async Clipboard API. This change also updates navigator.clipboard.read() and navigator.clipboard.write() to comply with the specification. Programmatic copying and pasting of images is Chromium's top starred bug.
The escape key is no longer treated as a user activation. Browsers prevent calls to abusable APIs (like popup, fullscreen, vibrate, etc.) unless the user activates the page through direct interactions. Not all interactions trigger user activation. For example, clicking on a link or typing in a textbox does, but swiping fingers on a screen or hovering with the mouse cursor does not. Since users never intend to interact with the page through the escape key, it should not trigger user activation.
Introduces a new HTTP request header that sends additional metadata about a request's provenance (is it cross-site, is it triggered from <img>, etc.) to the server to allow it to make security decisions which might mitigate some kinds of attacks based on timing the server's response (XSS leaks and others).

For example, it is unlikely that a bank's "Transfer all money" endpoint would be referenced from an <img> tag, and likewise unlikely that evil.com is going to be making any legitimate requests whatsoever. Ideally, the server could reject these requests a priori rather than deliver them to the application backend.
Adds the form.requestSubmit() function, which requests form submission. It includes interactive constraint validation, dispatches a submit event, and takes a reference to the submitter button.
The Image Capture API provides a means to set the focusMode to manual which is not useful if you cannot set the focus distance. This change provides an interface for getting focus range values and setting focus distance value.
Adds the pending attribute to the Web Animations API. A pending animation is one that is waiting on an asynchronous operation that affects the play state. Adding support for this attribute does not affect the rendering or timing of animations, but simply exposes the signal.
Adds a commit() function to IDBTransaction objects, which explicitly marks a transaction as not accepting further requests. Currently, IndexedDB only commits a transaction after all associated requests have had their completion event handlers executed, and no new requests have been queued by the event handlers. Developers can use the explicit commit() function to shave a few event loop cycles off of the latency of their transactions.

The primary benefit of explicit commit is that it increases the throughput of read and write requests made on an object store. This is a clear performance benefit in terms of the rate at which operations can be processed. Additionally, the increase in speed is advantageous because it adds stability to IndexedDB by reducing the probability that a disruptive event occurs within the lifetime of a transaction.
DateTimeFormat dateStyle and timeStyle
Adds dateStyle and timeStyle options to functions on Intl.DateTimeFormat, specifically formatToParts() and resolveOptions(). These options provide a compact way to request the appropriate, locale-specific date and time of given length styles.

Locale sensitive BigInt.prototype.toLocaleString and allow Intl.NumberFormat format/formatToParts to take BigInt.
Changes BigInt.prototype.toLocaleString() to locale-sensitive number formatting and changes Intl.NumberFormat.prototype.format() and formatToParts() to accept BigInt as input.
Enables the Media Capabilities API in all types of workers to help website and web apps pick the best media to stream from a worker. The information can then be used to create the MediaStream from a worker.
Adds Promise.allSettled(), which returns a promise that is fulfilled with an array of promise state snapshots, but only after all the original promises have settled, in other words after it has either resolved or rejected.
Adds three new methods to the Blob interface to perform read operations: text(), arrayBuffer(), and stream().
RTCSctpTransport
Exposes information about the SCTP transport that is used to carry WebRTC data channels such as max-message-size and max channels.

RTCRtpSender.setStreams
Allows changing the association between the track associated with an RTCRtpSender and streams. Stream association causes tracks in the same stream to be synchronized. This is useful, for example, if during a call a user switches from a front-facing camera to a back-facing camera and the application uses RTCRtpSender.replaceTrack(). On the receiving end the new track must be associated with the existing stream and synchronized with its auto track.

RTCRtpTransceiver.setCodecPreferences()
Adds the setCodecPreferences() method, which overrides the default codec preferences used by the user agent. This allows applications to disable the negotiation of specific codecs. It also allows an application to cause a remote peer to prefer the codec that appears first in the list for sending.
The white-space:break-spaces value allows authors to specify that any sequence of preserved white space that would otherwise overflow a line and hang (as per the CSS Text Module specification's Trimming and Positioning rules) must be broken.
The lazyload feature policy was intended to allow developers to selectively control the lazyload attribute on the <iframe> and <img> tags to provide more control over loading delay for embedded contents and images on a per origin basis.

The policy is removed in favor of a newer feature policy for loading, namely loading-frame-default-eager which is more aligned with how the loading attribute will be used. The removal applies to both the Feature-Policy header and the <iframe> allow attribute.
According to the specification, the MediaStreamAudioDestinationNode in the Web Audio API should have no outputs. Chrome's implementation has a single output which has been removed.
Chromium has been showing deprecation warnings since 2015 whenever the API is used in a non-secure browsing context. Chrome now restricts the API to secure browsing contexts. This change brings Chromium's implementation in line with the privacy and security recommendations in the specification, and is aligned with the effort to deprecate powerful features on insecure origins.