What’s new in Chromium 49 and Opera 36

March 15th, 2016

Opera 36 (based on Chromium 49) for Mac, Windows, Linux is out! To find out what’s new for users, see our Desktop blog. Here’s what it means for web developers.

ES6 default function parameter values

ES6 allows formal parameters to be initialized with default values if no value (or undefined) is passed.

function fn(x, y = 0) {
	return [x, y];

In this example, omitting the second parameter triggers the default value:

// → [1, 0]
// → [undefined, 0]

For more information, see “Parameter handling in ES6” or check out the demo.

ES6 destructuring assignment

Destructuring assignment makes it possible to extract data from arrays or objects using a syntax that mirrors the construction of array and object literals.

let a, b, rest;
[a, b] = [1, 2];
// → a = 1; b = 2
[a, b,] = [1, 2, 3, 4, 5];
// → a = 1; b = 2; rest = [3, 4, 5]
{a, b} = { a: 1, b: 2 };
// → a = 1; b = 2

Check out the demo for more examples.

ES6 Proxy and Reflect

Proxy objects can be used to define custom behavior for fundamental operations such as property lookup, assignment, enumeration, function invocation, etc.

The Reflect API offers imperative methods for invoking, examining or modifying values at runtime, and is very useful for working with Proxies.

Read “ES2015 proxies” for more information on both Proxy and Reflect.

ES6 block-scoped bindings in sloppy mode

const, let, class, and function now follow the proper ES6 semantics even in sloppy (i.e. non-strict) mode.


Using Symbol.toStringTag, user-defined types can return customized output when passed to Object.prototype.toString (either directly or as a result of string coercion) by storing a descriptive string in a Symbol.toStringTag-keyed property.

const object = {};
object[Symbol.toStringTag] = 'yoloswag';
// → '[object yoloswag]'

Promise rejection events

Two new global events, unhandledrejection and rejectionhandled, can be used to keep track of Promise rejections, including whether those rejections are handled after the fact.

See the demo for more information.

CSS Custom Properties (CSS Variables)

The CSS Variables spec defines a new primitive value type that is accepted by all CSS properties, as well as custom properties for defining them. As with other CSS values, they can be updated programmatically using JavaScript. See “CSS Variables: why should you care?” for more info. A demo is available.

Case-insensitive attribute value selectors

In HTML, the attribute values of certain attributes are compared ASCII-case-insensitively.

Consider the following CSS:

/* Every paragraph whose ID starts with `note` (case-sensitively) gets a lime background. */
p[id^="note"] {
	background-color: lime;
/* Every paragraph whose `lang` is `no` (ASCII-case-insensitively, in HTML) get underlined */
p[lang="no"] {
	text-decoration: underline;

And the following markup:

<p id="note-1" lang="no">1</p>
<p id="nOtE-2" lang="No">2</p>
<p id="NOTE-3" lang="NO">3</p>

In HTML and XML/XHTML, only the first paragraph gets a green background. In HTML, all paragraphs are underlined, but in XML/XHTML only the first is underlined.

Luckily, the i identifier can now be used in CSS selectors to opt-in to case-insensitive matching for attribute values, regardless of document language rules. With the i flag, all three paragraphs are highlighted and underlined in HTML and XML/XHTML environments:

/* Every paragraph whose ID starts with `note` (ASCII-case-insensitively) gets a lime background. */
p[id^="note" i] {
	background-color: lime;
/* Every paragraph whose `lang` is `no` (ASCII-case-insensitively) get underlined */
p[lang="no" i] {
	text-decoration: underline;

Note that the i flag only affects the case of matching the attribute value; not the attribute name or anything else.

Web Audio API updates

The Web Audio API defines IIRFilterNode, which is an AudioNode processor implementing a general IIR filter. Once created, the coefficients of the IIR filter cannot be changed, and no automation functions are allowed.

Additionally, Chromium now supports suspend() and resume() methods on OfflineAudioContext instances.

AudioContext.prototype.decodeAudioData now returns a Promise<AudioBuffer> that is resolved when decoding the audio data is finished. This is in addition to the existing callbacks, which are now optional.

Service worker: WindowClient.prototype.navigate()

It is now possible to trigger navigation from a service worker using the navigate() method on a WindowClient instance. Check out the demo.

Audio Output Devices API

The Audio Output Devices API specification defines a set of JavaScript APIs that let a web app manage how audio is rendered on the user’s audio output devices. With this feature it’s now possible for web apps to send audio to authorized output devices other than the system default. A demo is available.

Fetch API updates

The 'navigate' request mode as defined in the Fetch API specification is now supported. Check out the “custom offline page” service worker demo where this is being used.

Additionally, FetchEvent.prototype.clientId is now implemented. This read-only property returns the ID of the Client that the current service worker is controlling. The Clients.get() method can then be passed this ID to retrieve the associated client.


The Remote Playback API specification defines a disableRemotePlayback setter on HTMLMediaElement instances, which can be used to signal to the browser that this media element should not be played remotely. Enabling disableRemotePlayback by setting it to true causes the browser to not show any UI advertising remote playback, and prevents the element from being played remotely.

High-resolution event time stamps

Event.prototype.timeStamp indicates the time at which a given event took place. Previously, this timeStamp value was represented as a DOMTimeStamp, which was a whole number of milliseconds since the system epoch.

Starting with Chromium 49, timeStamp is a DOMHighResTimeStamp value. This value is still a number of milliseconds, but with a resolution of 5 microseconds, meaning the value now includes a decimal component. Additionally, instead of the value being relative to the epoch, the value is relative to performance.timing.navigationStart, i.e. the time at which the user navigated to the page. (We’re working on getting this into the spec.)

To convert a DOMHighResTimeStamp value to an absolute number of milliseconds since the epoch (e.g., to get a value to pass to the Date() constructor), use performance.timing.navigationStart + event.timeStamp.

A demo is available.


The URLSearchParams API defines helper methods for working with the query string of a URL (i.e. everything after ?). A demo is available.

<a rel=noopener>

You may be familiar with <a rel=noreferrer>, which prevents sending the Referer HTTP header and sets window.opener to null when following a link.

If you only want to disable window.opener but still send the Referer header, you can now use rel=noopener. Note that this is only needed for links that open a new navigation context, i.e. target="_blank".

Why would you want to do this? Well, if window.opener is set, a page can trigger a navigation in the opener regardless of origin, which is a potential security risk. Check out the demo for a more elaborate explanation.

Cookie Prefixes

Cookie Prefixes are a way of “smuggling” information in the name prefix of a cookie to ensure that certain attributes accompany the request to set a cookie. Chromium now supports the following cookie prefixes:

  • __Secure-, which signals to the browser that the Secure attribute is required.
  • __Host-, which signals to the browser that both the Path=/ and Secure attributes are required, and at the same time, that the Domain attribute must not be present.

Check out the demo for more information..

Improved handling of insecure source expressions in CSP

Sniffly is a timing attack to sniff browser history. One of its variants was based on a clever trick combining CSP and HSTS. In response, the CSP matching algorithm was updated to make insecure schemes in source expressions match their secure variants. That is, http: is now equivalent to http: https:, and to Likewise, 'self' now matches https and wss variants of the page’s origin, even on pages whose scheme is http.

Faster and more secure HTTPS connections

The standardized versions of the ChaCha20 stream cipher and Poly1305 authenticator are now used for TLS connections in Chromium. Compared to AES-GCM, this new TLS cipher suite is more secure, saves network bandwidth, and operates three times faster on devices that lack AES hardware acceleration such as most Android devices.

Geolocation now HTTPS-only

The Secure Contexts specification lists the Geolocation API as an example of an API that should only be available over secure contexts such as HTTPS. As of Chromium 49, the Geolocation API won’t work over insecure contexts anymore. If you need to use Geolocation, use HTTPS.

Smooth scrolling

As of Chromium 49, scrolling is getting smoother on Windows and Linux. But that’s not all: there are more potential improvements that may land soon, through Houdini and CSS properties like scroll-behavior: smooth. (On OS X, nothing has changed yet; smooth scrolling was already enabled, but only for keyboard-triggered scrolls.)

If you were using a JS library to implement smooth scrolling, now is a good time to stop using them. Scrolling in JavaScript has worse performance than native smooth scrolling, and old versions of SmoothScroll.js will stop scrolling entirely in the future when the scrollTop bug is fixed.

Deprecated or removed features

Support for the Pointer Lock API’s prefixed event properties MouseEvent.prototype.webkitMovementX and MouseEvent.prototype.webkitMovementY has been removed. Use the standardized versions, i.e. MouseEvent.prototype.movementX and MouseEvent.prototype.movementY, instead.

Support for the <keygen> HTML element has been removed. See the intent to deprecate mail for some background on this decision.

The non-standard TouchEvent.prototype.initTouchEvent is now deprecated. Use the Touch and TouchEvent constructors instead.

The non-standard navigator.getStorageUpdates() has been removed. It used to be a no-op anyway.

The presence of getComputedStyle(element).css* (except for .cssFloat) is non-standard behavior, so support for it has been removed. Use getComputedStyle(element).* instead.

Previously, Chromium treated the first two arguments (type and listener) of addEventListener and removeEventListener as optional, while they are non-optional in the spec and in other browsers. This has changed: calling these methods with zero or one argument now throws an exception.

document.defaultCharset has been deprecated and will be removed in a future release.

Object.observe has been deprecated as it is no longer on the standardization track and will be removed in a future release.

The WebRTC RTCPeerConnection methods createOffer() and createAnswer() now require an error handler as well as a success handler, matching the spec. Previously it was possible to call these methods with only a success handler. That usage is deprecated. This change paves the way for introducing promises on these methods, as required by the WebRTC spec.

What’s next?

If you’re interested in experimenting with features that are in the pipeline for future versions of Opera, we recommend following our Opera Developer stream.