Opera 35 released

Opera 35 (based on Chromium 48) for Mac, Windows, Linux and Android is out! To find out what’s new for users, see our Desktop and Mobile blogs. Here’s what it means for web developers.

ES6: more well-known symbols

Two more well-known symbols have been implemented:

  • Symbol.isConcatSpreadable points to a boolean value that indicates if an object should be flattened to its array elements by Array.prototype.concat (true) or not (false).
  • Symbol.toPrimitive points to a method that converts an object to a corresponding primitive value.

CSS: improved auto

The implied minimum size of a flex item (i.e. min-width: auto or min-height: auto) is now also computed correctly when flex-basis is not auto.

CSS Writing Modes updates

The CSS properties text-combine-upright, text-orientation, and writing-mode are now available without the -webkit- prefix, and with new syntax matching the spec.

The isolate, isolate-override, and plaintext values for the unicode-bidi CSS property can now be used without the -webkit- prefix. Support for the non-standard horizontal-bt value (as in -webkit-writing-mode: horizontal-bt) has been removed.

Unprefixed CSS font-feature-settings

The CSS font-feature-settings property now works without the -webkit- prefix. This property provides low-level control over OpenType font features.

The -webkit--prefixed version is now deprecated and will be removed in a future release.

CSS Font Loading API improvements

Our implementation of the FontFaceSet interface (e.g. document.fonts) is now set-like, matching the spec. This means it has entries(), keys(), and values() iterators, and is itself an iterator (over the individual FontFace entries).

Also, the add() and remove() methods don’t throw InvalidModificationError anymore when adding or deleting a CSS-connected font-face to the same FontFaceSet. Here’s an example of that:

<style>
	@font-face {
		font-family: Test;
		src: local('Helvetica');
	}
</style>
<script>
	var face;
	document.fonts.forEach(function(f) { face = f; });
	document.fonts.add(face);    // no-op
	document.fonts.remove(face); // no-op, returns `false`
</script>

Previously, the above add() and remove() both threw InvalidModificationError exceptions.

A demo is available.

Fetch API: data: and blob: URL scheme support

Our Fetch API implementation now supports the data: and blob: URL schemes.

IndexedDB API additions

The IndexedDB getAll() and getAllKeys() methods are now supported on the IDBObjectStore and IDBIndex interfaces. Additionally, IDBObjectStore.prototype.openKeyCursor() and IDBTransaction.prototype.objectStoreNames have been implemented.

A demo is available.

MediaStreamTrack.prototype.remote

The remote property on WebRTC MediaStreamTrack instances is now available. It can be used to determine whether a stream track is from a remote source or a local one.

ServiceWorkerRegistration.prototype.update() more spec-compliant

The update method on ServiceWorkerRegistration instances used to always bypass the browser cache. Now, it only bypasses the browser cache if the previous update check occurred over 24 hours ago.

Touch and TouchEvent constructors

The Touch and TouchEvent constructors make it easy to programmatically create Touch and TouchEvent instances from an object literal.

const t = new Touch({
	'identifier': 42,
	'target': document.body,
	'clientX': 200,
	'clientY': 200,
	'screenX': 300,
	'screenY': 300,
	'pageX': 250,
	'pageY': 250,
	'radiusX': 2.5,
	'radiusY': 2.5,
	'rotationAngle': 10,
	'force': 0.5
});

A demo with more examples is available.

KeyboardEvent.prototype.code

The code property on KeyboardEvent instances is now implemented. The value of this property identifies the physical key that generated the keyboard event, regardless of the user’s current keyboard layout. For example, the physical Q key represents the symbol q on a QWERTY keyboard layout, but represents a on an AZERTY keyboard layout — but its .code value is 'KeyQ' in both configurations.

A demo is available.

Web Audio API: .connect() chaining

The connect method on AudioNode and AudioParam instances now supports chaining, as per the spec.

Before this change, you’d write code like this:

sourceNode.connect(gainNode);
sourceNode.connect(filterNode);
sourceNode.connect(destination);

Now that can be simplified as follows:

sourceNode
	.connect(gainNode)
	.connect(filterNode)
	.connect(destination);

A demo is available.

Deprecated and removed features

Support for the non-standard CSS values intrinsic and min-intrinsic has been removed. Use the standardized values max-content and min-content instead.

Support for CSS composite-mode: darker has been removed since darker is a non-standard value.

The glyph-orientation-horizontal and glyph-orientation-vertical CSS properties for SVG elements have been removed. Use text-orientation instead, just like you would for HTML elements.

The offsetParent, offsetTop, offsetLeft, offsetWidth, and offsetHeight properties on SVGElement instances are now deprecated and will be removed in an upcoming release. Per the spec, these properties should only exist on HTMLElements. For SVGElements, you can use getBoundingClientRect() instead.

The getTransformToElement method on SVGGraphicsElement instances has been removed, matching the spec.

The SVGPathSeg and SVGPathSegList constructors have been removed. They were part of the old SVG 1.1 spec, but have since been removed from the standard. If you rely on these APIs, you’ll be pleased to hear that a polyfill is available for them.

The getSVGDocument method is no longer available on HTMLFrameElement instances. We now match the spec, which makes this method available on HTMLEmbedElement, HTMLIFrameElement, and HTMLObjectElement instances only.

The non-standard item() method on TextTrackList and TextTrackCueList has been removed. Use tracks[index] instead of tracks.item(index).

Following the recommendation in RFC 7465, support for the RC4 cipher has finally been removed. HTTPS connections that rely on RC4 exclusively cannot be considered secure anymore and will therefore fail from now on.

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.