<?xml version="1.0" encoding="UTF-8"?> <feed xmlns="http://www.w3.org/2005/Atom"><title>Dev.Opera</title><link href="https://dev.opera.com/"/><link type="application/atom+xml" rel="self" href="https://dev.opera.com/feed/"/><updated>2017-02-07T17:38:22+00:00</updated><id>https://dev.opera.com/</id><author><name>Dev.Opera editors</name><email></email></author><entry><id>https://dev.opera.com/blog/opera-43/</id><link type="text/html" rel="alternate" href="https://dev.opera.com/blog/opera-43/"/><title>What’s new in Chromium 56 and Opera 43</title><published>2017-02-07T00:00:00+00:00</published><updated>2017-02-07T00:00:00+00:00</updated><author><name>Simon Pieters</name></author><content type="html" xml:base="https://dev.opera.com/"><![CDATA[<p>Opera 43 (based on Chromium 56) for <a href="https://www.opera.com/computer">Mac, Windows, Linux</a> is out! To find out what’s new for users, see our <a href="https://www.opera.com/blogs/desktop/">Desktop</a> blog. Here’s what it means for web developers.</p>

<h2 id="prerender-from-address-bar">Prerender from address bar</h2>

<p>Opera will now prerender pages that are typed into the address bar, before the user hits enter,
which can make the page finish loading much sooner.</p>

<p>If you can predict what the user’s likely next navigation will be, you can start a prerender from
the current page by using <a href="https://w3c.github.io/resource-hints/#dfn-prerender"><code>&lt;link rel=prerender&gt;</code></a>.
This has actually been supported since Opera 15, but this seemed like a good opportunity for a
reminder. 🙂 For more information about how to use <code>prerender</code> and other resource hints, see
<a href="https://www.keycdn.com/blog/resource-hints/">Resource Hints – What is Preload, Prefetch, and Preconnect?</a>
by Brian Jackson.</p>

<h2 id="classic-link-selection">Classic link selection</h2>

<p>Opera now allows users to select link text instead of always dragging the link (like in Opera 12).
The user can select by dragging left or right, and start a drag-and-drop by dragging up or down.</p>

<p>Not being able to select text to copy and paste is often frustrating for users. But in some cases it
can be justified, like if a link is being used to act as a button, or if text is used only for
decoration. To disable text selection in general, CSS <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/user-select"><code>user-select: none</code></a>
can be used.</p>

<h2 id="scroll-anchoring-intervention">Scroll anchoring intervention</h2>

<p>When some content changes above the viewport (e.g., an image is loaded), what used to happen is that
the rest of the content is pushed down. With the <a href="https://github.com/WICG/ScrollAnchoring/blob/master/explainer.md">scroll anchoring</a>
intervention the scroll position is updated to keep the content currently in the viewport stable.
This behavior can be disabled for a specific subtree or for the whole page by using CSS <code>overflow-anchor: none</code>.
See <a href="https://www.youtube.com/watch?v=fejv0cM7Jig">this video</a> for a comparison with and without this
intervention.</p>

<h2 id="css">CSS</h2>

<ul>
  <li>Opera now supports <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/position#Sticky_positioning"><code>position: sticky</code></a>,
a new way to position elements. A <code>position: sticky</code> element is relatively-positioned, but becomes
<code>position: fixed</code> after the user reaches a certain scroll position. This results in smoother scroll
without jumps compared to trying to achieve the same thing with <code>scroll</code> events and JavaScript.
For more info see <a href="https://developers.google.com/web/updates/2016/12/position-sticky">this article</a>
by Paul Kinlan.</li>
  <li>The <a href="https://drafts.csswg.org/css-fonts-4/#extended-generics">new generic font family</a> <code>system-ui</code>
is now supported, which matches the platform’s default UI font.</li>
  <li><a href="https://developer.mozilla.org/en-US/docs/Web/CSS/touch-action"><code>touch-action: pinch-zoom</code></a> is now supported.</li>
  <li>Non-whitespace Unicode control characters will now be rendered according to the
<a href="https://drafts.csswg.org/css-text/#white-space-processing">specification</a>, rather than being ignored.</li>
</ul>

<h2 id="http-referrer-policy-header">HTTP <code>Referrer-Policy</code> header</h2>

<p>The new <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy"><code>Referrer-Policy</code></a>
HTTP header allows sites to forward site traffic by URL without leaking the user’s session identifier
or other private information.</p>

<h2 id="events-keyboardeventiscomposing">Events: <code>keyboardEvent.isComposing</code></h2>

<p>The <a href="https://w3c.github.io/uievents/#idl-keyboardevent"><code>KeyboardEvent</code></a> interface now supports the
<a href="https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/isComposing"><code>isComposing</code></a> attribute
which returns <code>true</code> if this event is fired between <code>compositionstart</code> and <code>compositionend</code> events.</p>

<h2 id="canvas">Canvas</h2>

<p><a href="https://developer.mozilla.org/en-US/docs/Web/API/ImageBitmapRenderingContext"><code>ImageBitmapRenderingContext</code></a>
can be used to reduce memory consumption and compositing overhead by rendering pixel data in the form
of an <a href="https://developer.mozilla.org/en-US/docs/Web/API/ImageBitmap"><code>ImageBitmap</code></a>.</p>

<h2 id="audiovideo">Audio/video</h2>

<ul>
  <li><a href="https://webaudio.github.io/web-audio-api/#ConstantSourceNode"><code>ConstantSourceNode</code></a> is a new audio source node that produces a constant output mixed with an <code>AudioParam</code>.</li>
  <li>Two Web Audio <a href="https://webaudio.github.io/web-audio-api/#the-channelsplitternode-interface"><code>ChannelSplitterNode</code></a> interface attributes are now read-only: <code>channelCount</code>, which is defined by <code>numberOfOutputs</code> in <code>createChannelSplitter()</code>, and <code>channelCountMode</code>, which is set to explicit.</li>
  <li><a href="https://webaudio.github.io/web-audio-api/#widl-PannerNode-rolloffFactor"><code>PannerNode.rolloffFactor</code></a> now clamps to the nominal range of a PannerNode’s distance model to describe the volume reduction rate as the source moves away from the listener.</li>
  <li>Support for <a href="https://en.wikipedia.org/wiki/FLAC">FLAC</a> is enabled within the FLAC and <a href="https://xiph.org/flac/ogg_mapping.html">Ogg</a> containers for the <code>audio</code> HTML element and <a href="https://developer.mozilla.org/en-US/docs/Web/API/AudioContext/decodeAudioData"><code>decodeAudioData()</code></a>.</li>
  <li><a href="http://opus-codec.org/">OPUS</a> can now be used with <a href="https://developer.mozilla.org/en-US/docs/Web/API/AudioContext/decodeAudioData"><code>decodeAudioData()</code></a>, expanding the variety of audio codecs supported by the <a href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API">Web Audio API</a>.</li>
</ul>

<h2 id="shadow-dom">Shadow DOM</h2>

<ul>
  <li>Shadow DOM’s <a href="https://dom.spec.whatwg.org/#signaling-slot-change"><code>slotchange</code></a> events bubble, but no longer re-fires, at a <code>slot</code>’s <code>assignedSlot</code>.</li>
</ul>

<h2 id="deprecated-and-removed-features">Deprecated and removed features</h2>

<ul>
  <li>Non-script MIME types for external scripts (e.g., <code>&lt;script src="foo" type="something/something"&gt;</code>) was deprecated (generated a message in the console) in Opera 42 and now in Opera 43 are no longer pre-fetched. This typically results in less wasted fetches. <code>&lt;script data-src="foo" type="something/something"&gt;</code> is recommended instead.</li>
  <li>The Web Audio API no longer includes the deprecated Doppler API, including <code>speedOfSound</code>, <code>dopplerFactor</code>, and <code>setVelocity</code>.</li>
  <li><a href="https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/RTCPeerConnection#RTCConfiguration_dictionary"><code>RTCPeerConnection</code></a> now accepts <code>iceTransportPolicy</code> as an <code>RTCConfiguration</code> parameter as well as <code>iceTransports</code>.</li>
  <li><a href="https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection"><code>RTCPeerConnection</code></a> is now available without a webkit prefix, though <code>webkitRTCPeerConnection</code> still remains.</li>
  <li>The <code>reflected-xss</code> directive has been removed from <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy">Content Security Policy 2</a> since it was solely a wrapper for the <code>X-XSS-Protection</code> header and provided no additional functionality.</li>
  <li>Support for the <code>MediaStreamTrack.getSources()</code> method has been removed in favor of <code>MediaDevices.enumerateDevices()</code>.</li>
  <li>The CSP <code>referrer</code> directive is no longer supported in favor of the new <code>Referrer-Policy</code> header mentioned above.</li>
  <li>Legacy CBC-mode <a href="https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm">ECDSA</a> cipher suites ECDHE_ECDSA_WITH_AES_128_CBC_SHA and ECDHE_ECDSA_WITH_AES_256_CBC_SHA have been removed in favor of modern ciphers such as ECDHE_ECDSA_WITH_AES_128_GCM_SHA256.</li>
  <li>ECDSA with both SHA-1 and SHA-512 have been removed to reduce dependencies on SHA-1 and align with TLS 1.3’s new ECDSA handling.</li>
  <li><code>MIDIMessageEvent.receivedTime</code> has been deprecated in favor of <code>Event.timeStamp</code>, since <code>Event.timeStamp</code> now supports high-resolution monotonic time instead of epoch time.</li>
</ul>

<h2 id="whats-next">What’s next?</h2>

<p>If you’re interested in experimenting with features that are in the pipeline for future versions of Opera, we recommend following <a href="https://www.opera.com/developer">our Opera Developer stream</a>.</p>
]]></content></entry><entry><id>https://dev.opera.com/blog/opera-42/</id><link type="text/html" rel="alternate" href="https://dev.opera.com/blog/opera-42/"/><title>What’s new in Chromium 55 and Opera 42</title><published>2016-12-14T00:00:00+00:00</published><updated>2016-12-14T00:00:00+00:00</updated><author><name>Simon Pieters</name></author><content type="html" xml:base="https://dev.opera.com/"><![CDATA[<p>Opera 42 (based on Chromium 55) for <a href="https://www.opera.com/computer">Mac, Windows, Linux</a> is out! To find out what’s new for users, see our <a href="https://www.opera.com/blogs/desktop/">Desktop</a> blog. Here’s what it means for web developers.</p>

<h2 id="built-in-currency-converter">Built-in currency converter</h2>

<p>Opera is now the first of the major browsers to add a built-in currency converter.</p>

<p>The user select the price they want to convert on the page and Opera will automatically show it in their local currency. Opera 42 supports conversion in 32 currencies based on daily values from the European Central Bank.</p>

<p>Currency symbols are supported, but for ambiguous symbols (e.g. “$”, “kr”) we recommend using the <a href="https://en.wikipedia.org/wiki/ISO_4217">ISO 4217</a> alphabetic code before or after the amount, as selectable text. This makes it unambiguous for Opera’s currency converter what to convert from, but it should also be helpful for end users and other tools in general.</p>

<pre><code>&lt;p&gt;USD 50&lt;/p&gt;
&lt;p&gt;995 SEK&lt;/p&gt;
</code></pre>

<h2 id="input-handling-improvements">Input handling improvements</h2>

<p>The <a href="https://developer.mozilla.org/en-US/docs/Web/API/PointerEvent"><code>PointerEvent</code></a> standard is now supported. It gives developers a unified API for handling “pointer” user input, whether that is mouse, touch, pen, etc. <code>PointerEvent</code> also does not block scrolling, which should reduce jank during scrolling. When using <code>TouchEvent</code>, the same performance benefit can be achieved using <a href="https://developers.google.com/web/updates/2016/06/passive-event-listeners">passive event listeners</a>. The <a href="https://developers.google.com/web/updates/2016/10/pointer-events#default_actions"><code>touch-action</code></a> CSS property is now also supported, to allow reacting to gestures such as panning. For more information, see <a href="https://developers.google.com/web/updates/2016/10/pointer-events">Pointing the Way Forward</a> by Sérgio Gomes.</p>

<p>The <a href="https://developers.google.com/web/updates/2016/10/auxclick"><code>auxclick</code></a> event is now fired for non-primary mouse buttons, instead of <code>click</code>.</p>

<h2 id="javascript-async-and-await">JavaScript <code>async</code> and <code>await</code></h2>

<p>The <code>async</code> and <code>await</code> keywords are now supported, which allows writing Promise-based JavaScript with a neater syntax, and enables use of <code>try</code>/<code>catch</code> to catch rejected promises.</p>

<pre><code>async function myFirstAsyncFunction() {
	try {
		const fulfilledValue = await promise;
	}
	catch (rejectedValue) {
		// …
	}
}
</code></pre>

<p>For more information, see <a href="https://developers.google.com/web/fundamentals/getting-started/primers/async-functions">Async functions - making promises friendly</a> by Jake Archibald.</p>

<h2 id="css-automatic-hyphenation">CSS automatic hyphenation</h2>

<p>The <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/hyphens"><code>hyphens</code></a> CSS property is now supported (on Mac), which can be used to enable automatic hyphenation when text is broken across multiple lines. Possible values are <code>none</code>, <code>manual</code> (initial value) and <code>auto</code>.</p>

<p>For <code>none</code>, hyphenation will not happen even when <code>&amp;shy;</code> is used. For <code>manual</code>, hyphenation only happens for <code>&amp;shy;</code>. For <code>auto</code>, automatic hyphenation happens, based on the language specified in the <code>lang</code> attribute.</p>

<pre><code>html { hyphens: auto; }
code { hyphens: manual; }
</code></pre>

<p>See <a href="https://googlechrome.github.io/samples/css-hyphens/">demo</a>.</p>

<h2 id="once-event-listener-option"><code>once</code> event listener option</h2>

<p>The <a href="https://dom.spec.whatwg.org/#dom-addeventlisteneroptions-once"><code>once</code> event listener option`</a> is now supported, for a convenient way to only invoke an event listener once and then remove the listener.</p>

<pre><code>element.addEventListener('click', function(event) {
	// ...one-time handling of the click event...
}, {once: true});
</code></pre>

<p>For more information, see <a href="https://developers.google.com/web/updates/2016/10/addeventlistener-once">Once Upon an Event Listener</a> by Jeff Posnick.</p>

<h2 id="persistent-storage">Persistent storage</h2>

<p><a href="https://developers.google.com/web/updates/2016/06/persistent-storage">Persistent storage</a> is now on by default.</p>

<h2 id="tls">TLS</h2>

<ul>
  <li>The TLS stack now implements <a href="https://tools.ietf.org/id/draft-davidben-tls-grease-00.html">GREASE</a>, a mechanism to help prevent problems with buggy TLS servers.</li>
  <li>RSA-PSS signature algorithms have been added to TLS to prepare for <a href="https://tlswg.github.io/tls13-spec/">TLS 1.3</a>.</li>
</ul>

<h2 id="new-constructors">New constructors</h2>

<p><code>new MediaStreamTrackEvent(type, options)</code> and <code>new AudioNode(context, options)</code> constructors are now available.</p>

<h2 id="documentwrite-intervention"><code>document.write()</code> intervention</h2>

<p>Cross-origin and parser-blocking scripts injected using <code>document.write()</code> will no longer load over 2G connections. See <a href="https://developers.google.com/web/updates/2016/08/removing-document-write">this article</a> by Paul Kinlan for more information.</p>

<h2 id="deprecated-and-removed-features">Deprecated and removed features</h2>

<ul>
  <li>As mentioned above, the <code>click</code> event is no longer fired for non-primary mouse buttons. In most cases this is desirable; <code>click</code> event handlers are most often intended to handle primary clicks. But if you need to handle non-primary clicks (e.g., middle mouse button), the <code>auxclick</code> event can be used. The <code>contextmenu</code> event can also be used to handle clicks that would open a context menu (typically right-click).</li>
  <li><code>BaseAudioContext</code> will replace <code>AudioContext</code> in the <a href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API">Web Audio API</a>.</li>
  <li>CSS Clipping Path properties no longer require the <code>webkit</code> prefix.</li>
  <li>The <code>MediaStream</code> constructor is now available without prefix alongside the existing <code>webkitMediaStream</code>.</li>
  <li>Non-script MIME types for external scripts (e.g., <code>&lt;script src="foo" type="something/something"&gt;</code>) is deprecated and will from M56 (Opera 43) no longer be pre-fetched. This typically results in less wasted fetches. <code>&lt;script data-src="foo" type="something/something"&gt;</code> is recommended instead.</li>
  <li><code>&lt;textarea maxlength=""&gt;</code> and <code>&lt;textarea minlength=""&gt;</code> have been updated to count each line break as one character, instead of two.</li>
  <li>The <code>webkit</code> prefix has been removed from the <code>imageSmoothingEnabled</code> property of <code>CanvasRenderingContext2D</code>.</li>
</ul>

<h2 id="whats-next">What’s next?</h2>

<p>If you’re interested in experimenting with features that are in the pipeline for future versions of Opera, we recommend following <a href="https://www.opera.com/developer">our Opera Developer stream</a>.</p>
]]></content></entry><entry><id>https://dev.opera.com/articles/pwa-resources/</id><link type="text/html" rel="alternate" href="https://dev.opera.com/articles/pwa-resources/"/><title>Progressive Web Apps: The definitive collection of resources</title><published>2016-11-11T00:00:00+00:00</published><updated>2016-11-11T00:00:00+00:00</updated><author><name>Bruce Lawson, Shwetank Dixit</name></author><content type="html" xml:base="https://dev.opera.com/"><![CDATA[<h2 id="introduction">Introduction</h2>

<p>Want to get started with progressive web apps, but not sure where to start? This page will list the best resources we know of to help you understand Progressive Web Apps (PWAs), get started and learn things in depth.</p>

<p>Make sure to bookmark this page, as this is a living document that we’ll be adding to from time to time.</p>

<h2 id="progressive-web-apps-the-what-how-and-why">Progressive Web Apps: The what, how and why</h2>

<p>These articles introduce the concept of Progressive Web apps and serve as a jumping point to learn more about them.</p>

<ul>
  <li><a href="https://dev.opera.com/blog/pwa-taipei/">Progressive Web Apps: the future of Apps</a>: A 20 minute video of a presentation by Opera’s Bruce Lawson, introducing the overall “why” and “what” of PWAs.</li>
  <li><a href="https://www.youtube.com/watch?v=MyQ8mtR9WxI">Progressive Web Apps (Chrome Dev Summit 2015)</a>: Alex Russell (Google) and Andreas Bovens (Opera) introduce the concepts, code and cross-browser nature of PWAs.</li>
  <li><a href="https://infrequently.org/2015/06/progressive-apps-escaping-tabs-without-losing-our-soul/">Progressive Web Apps: Escaping Tabs without losing our soul</a>: Alex Russell’s original blog post outlining the concept of PWAs. A must-read.</li>
  <li><a href="https://developers.google.com/web/progressive-web-apps/">Progressive Web Apps on Google Web Fundamentals</a>: This is a comprehensive set of tutorials various aspects of developing PWAs from the Google Team.</li>
  <li><a href="https://addyosmani.com/blog/getting-started-with-progressive-web-apps/">Getting Started with Progressive Web apps</a>: Addy Osmani’s guide to getting started with PWAs</li>
  <li><a href="https://www.smashingmagazine.com/2016/08/a-beginners-guide-to-progressive-web-apps/">A Beginner’s Guide to Progressive Web Apps</a>: A good intro article by Smashing Magazine</li>
</ul>

<h2 id="ui-concepts">UI Concepts</h2>

<p>One of the best things about PWAs are that they can be added to the home screen of your Android device, just like native apps can. This section contains relevant articles covering the ‘Add to Home Screen’ capability, as well as a few articles on how to make your web app UI running smoothly.</p>

<ul>
  <li><a href="https://medium.com/net-magazine/html-manifest-402e6a8cc0e9">Adding to Home Screen</a>: Bruce Lawson on adding your site to the mobile home screen.</li>
  <li><a href="https://developers.google.com/web/updates/2014/11/Support-for-installable-web-apps-with-webapp-manifest-in-chrome-38-for-Android">The Google Team’s Overview of Adding to Home Screen</a>: A nice overview of the options available for various use cases when implementing ‘Add to Home Screen’ functionality.</li>
  <li><a href="https://aerotwist.com/blog/flip-your-animations/">FLIP your animations</a>: It’s important that your PWA runs smoothly. Paul Lewis explains how to implement smooth animations in your app.</li>
  <li><a href="http://engineering.flipboard.com/2015/02/mobile-web/">Jankfree</a>: A collection of resources all about improving web UI performance and reducing ‘Jank’.</li>
  <li><a href="http://engineering.flipboard.com/2015/02/mobile-web/">60fps on the Mobile Web</a>: The Flipboard team discusses how to get 60fps performance for your web frontend on mobile devices.</li>
  <li><a href="https://w3c.github.io/manifest/">The Web App Manifest Specification</a>.</li>
</ul>

<h2 id="offline">Offline</h2>

<p>Progressive Web Apps are capable of running offline just like native apps. This is primarily through a feature called ‘Service Worker’. Service Workers are great, and besides being used to make web apps run offline, are also required for other functionality like Push Notifications and Background Sync.</p>

<ul>
  <li><a href="https://vimeo.com/175121061">What we need from the Web, and what it needs from us</a>: A 43 minute video by Shwetank Dixit, introducing PWAs from the perspective of web users in India. Service Workers begins at minute 18.</li>
  <li><a href="https://www.youtube.com/watch?v=cmGr0RszHc8">Instant Loading: Building offline-first Progressive Web Apps</a>: A 45 minute video by Jake Archibald, one of the designers of Service Workers.</li>
  <li><a href="https://developers.google.com/web/fundamentals/primers/service-worker/">Service Workers: An Introduction</a>: A great intro by the Google Team on what you need to know to get started with Service Workers.</li>
  <li><a href="https://jakearchibald.com/2014/offline-cookbook/">The Offline Cookbook</a>: Jake Archibald covers a variety of use cases for offline functionality along with helpful illustrations and code examples for the service wokers code. Very well worth a look!</li>
  <li><a href="http://12devsofxmas.co.uk/2016/01/day-9-service-worker-santas-little-performance-helper/">Service Worker: Santa’s Little Performance Helper</a>: Phil Nash covers Service Worker through a practical example. Its also contains a great example of caching web fonts for offline use using Service Workers.</li>
  <li><a href="https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API/Using_Service_Workers">Using Service Workers</a>: The Mozilla team’s introduction to Service Workers on MDN. It contains some useful infographics on various parts of the Service Worker lifecycle, and more.</li>
  <li><a href="https://www.smashingmagazine.com/2016/02/making-a-service-worker/">Making a Service Worker</a>: A fantastic article by Lyza Danger Gardner going in-depth with Service Workers.</li>
  <li><a href="https://serviceworke.rs">serviceworke.rs</a>: Mozilla’s site detailing various caching strategies and use cases along with code examples.</li>
  <li><a href="https://medium.com/dev-channel/offline-storage-for-progressive-web-apps-70d52695513c#.9n1e1i81i">Offline Storage for Progressive Web Apps</a>: Addy Osmani lists out a number of libraries and tools available for making web apps run offline.</li>
  <li><a href="https://remysharp.com/2016/03/22/the-copy--paste-guide-to-your-first-service-worker">The Copy and Paste Guide to your first Service Worker</a>: Remy Sharp writes about how to get started quickly.</li>
  <li><a href="http://alistapart.com/article/offline-first">Designing Offline-first Web Apps</a>: Besides giving helpful tips on good offline experiences, this article helps you think differently about offline as a user state in the first place.</li>
  <li><a href="https://w3c.github.io/ServiceWorker/">The Service Workers Specification</a></li>
</ul>

<h2 id="push-notifications">Push Notifications</h2>

<p>Push notifications are helpful in notifying the user of important, relevant or timely events, even if your site isn’t open in the browser, or even when the browser is closed. With the Push API spec and Service Workers, you can finally implement this in your progressive web app too. Be careful not to spam your users!</p>

<ul>
  <li><a href="https://opbeat.com/community/posts/towards-better-apps-the-what-why-of-progressive-web-apps-by-andreas-bovens/">Towards better apps: the what &amp; why of progressive web apps</a>: A 43 minute video in which Andreas Bovens introduces PWAs, Service Workers and — around the 23 minute mark — Push Notifications.</li>
  <li><a href="https://developers.google.com/web/fundamentals/engage-and-retain/push-notifications/">Web Push Notifications: Timely, Relevant and Precise</a>: Google’s introduction to Web Push notifications.</li>
  <li><a href="https://developer.mozilla.org/en/docs/Web/API/Push_API">Push API documentation on MDN</a></li>
  <li><a href="https://hacks.mozilla.org/2015/10/keep-pushing-it-with-the-w3c-push-api/">Keep Pushing it, with the Web Push API</a>: Chris Mills explains the Web Push API.</li>
  <li><a href="https://www.w3.org/TR/push-api/">The Push API specification</a></li>
</ul>

<h2 id="tools-and-libraries">Tools and Libraries</h2>

<p>This section lists out a number of tools which might end up saving you a lot of time and effort when coding up for your PWAs.</p>

<ul>
  <li><a href="https://github.com/GoogleChrome/sw-toolbox">sw-toolbox</a>: A helpful library with account for a lot of different caching use-cases.</li>
  <li><a href="https://github.com/GoogleChrome/sw-precache">sw-precache</a>: A tool to pre-emptively cache all static resources for offline use.</li>
  <li><a href="https://github.com/GoogleChrome/lighthouse">Lighthouse</a>: Auditing and performance metrics for Progressive Web Apps.</li>
  <li><a href="https://brucelawson.github.io/manifest/">Manifest Generator</a>: A tool which automatically generates a web manifest file for you.</li>
  <li><a href="https://www.npmjs.com/package/manifest-json">manifest-json</a>: Another tool (this is using the command line) to generate a web manifest file for you.</li>
  <li><a href="https://github.com/hemanth/generator-pwa">generator-pwa</a>: A yeoman generator for a basic PWA app.</li>
  <li><a href="https://github.com/TalAter/UpUp">UpUp</a>: Read the <a href="https://dev.opera.com/articles/offline-with-upup-service-workers/">article by the library’s author</a> on how to use it.</li>
  <li><a href="https://github.com/google/web-starter-kit">Web Starter Kit</a>: A boilerplate for web development including sw-toolbox and sw-precache libraries.</li>
  <li><a href="https://github.com/sdgluck/fetch-sync">Fetch-sync</a>: Fetch Sync allows you to proxy fetch requests through the Background Sync API so that they are honoured if made when the UA is offline.</li>
  <li><a href="https://github.com/sdgluck/msgr">Msgr</a>: Nifty service worker/client message utility.</li>
</ul>

<h2 id="showcases-case-studies-and-more">Showcases, case studies and more</h2>

<p>Take a look at what others are doing with Progressive Web Apps. Get inspiration and see how it has benefitted others in key business metrics.</p>

<ul>
  <li><a href="https://pwa.rocks">PWA.Rocks</a>: The showcase for the best Progressive Web Apps in the world. It’s maintained by the Opera Developer Relations team, and we accept Pull Requests if you have a great-looking responsive PWA. Remember, sites aren’t “mobile-only” so the best PWAs look great on desktop and devices.</li>
  <li><a href="https://developers.google.com/web/showcase/">Google PWA Showcase</a>: Google’s showcase of companies which have befitted from PWAs.</li>
  <li><a href="https://cloudfour.com/thinks/the-business-case-for-progressive-web-apps/">The Business Case for Progressive Web Apps</a>: Jason Grigsby writes a compelling case for the business benefits of PWAs.</li>
  <li><a href="https://dev.opera.com/articles/pwa-nigeria-kenya-interview/">PWAs: An African Perspective</a>: We interview two great developers from Nigeria and Kenya about PWAs. Read their thoughts on how PWAs can help solve problems in that region.</li>
</ul>
]]></content></entry><entry><id>https://dev.opera.com/blog/opera-41/</id><link type="text/html" rel="alternate" href="https://dev.opera.com/blog/opera-41/"/><title>What’s new in Chromium 54 and Opera 41</title><published>2016-10-25T00:00:00+00:00</published><updated>2016-10-25T00:00:00+00:00</updated><author><name>Mathias Bynens</name></author><content type="html" xml:base="https://dev.opera.com/"><![CDATA[<p>Opera 41 (based on Chromium 54) for <a href="https://www.opera.com/computer">Mac, Windows, Linux</a> is out! To find out what’s new for users, see our <a href="https://www.opera.com/blogs/desktop/">Desktop</a> blog. Here’s what it means for web developers.</p>

<h2 id="web-components-custom-elements-v1">Web Components: Custom Elements v1</h2>

<p>Custom elements form the foundation of <a href="http://webcomponents.org/">web components</a>. The initial version of the API, also known as Custom Elements v0, has been supported since Opera 20 &amp; Chrome 33. With the v0 API, a new custom element was defined using <code>document.registerElement()</code>.</p>

<p>Since then, the spec has been updated based on web developer and browser vendor feedback. The improved API is called <a href="https://html.spec.whatwg.org/multipage/scripting.html#custom-elements">Custom Elements v1</a>. The new hip &amp; trendy way of defining a custom element is through <code>customElements.define()</code>. The v0 API is now deprecated and will be removed in a future release.</p>

<p>For more details, check out <a href="https://developers.google.com/web/fundamentals/getting-started/primers/customelements">Eric Bidelman’s custom elements guide</a>.</p>

<h2 id="dom-convenience-methods-on-parentnode--childnode">DOM convenience methods on <code>ParentNode</code> &amp; <code>ChildNode</code></h2>

<p>We now support the following convenience methods on <a href="https://dom.spec.whatwg.org/#parentnode">ParentNode</a> and <a href="https://dom.spec.whatwg.org/#childnode">ChildNode</a> for working with DOM trees:</p>

<ul>
  <li><code>ParentNode.prototype.prepend()</code></li>
  <li><code>ParentNode.prototype.append()</code></li>
  <li><code>ChildNode.prototype.before()</code></li>
  <li><code>ChildNode.prototype.after()</code></li>
  <li><code>ChildNode.prototype.replaceWith()</code></li>
</ul>

<h2 id="canvasrenderingcontext2dprototypeimagesmoothingquality"><code>CanvasRenderingContext2D.prototype.imageSmoothingQuality</code></h2>

<p><a href="https://html.spec.whatwg.org/multipage/scripting.html#imagesmoothingquality"><code>CanvasRenderingContext2D.prototype.imageSmoothingQuality</code></a> allows developers to balance performance and image quality by adjusting resolution when scaling.</p>

<pre><code>const canvas = document.querySelector('canvas');
const context = canvas.getContext('2d');
const image = new Image();
image.src = 'image.png';
image.onload = function() {
	context.imageSmoothingEnabled = true;
	context.imageSmoothingQuality = 'high'; // or 'low', or 'medium'
	context.drawImage(image, 0, 0, 320, 180);
};
</code></pre>

<h2 id="broadcastchannel-api">BroadcastChannel API</h2>

<p><a href="https://html.spec.whatwg.org/multipage/comms.html#broadcasting-to-other-browsing-contexts">The BroadcastChannel API</a> allows same-origin scripts to send messages to other browsing contexts. It can be thought of as a simple message bus that allows publish-subscribe semantics between windows, tabs, <code>iframe</code>s, web workers, and service workers. Think of it as a simpler, same-origin version of the good ol’ <code>postMessage()</code> API.</p>

<p>For more information, check out <a href="https://developers.google.com/web/updates/2016/09/broadcastchannel">this article</a>.</p>

<h2 id="cache-storage-api-cachequeryoptions">Cache Storage API: <code>CacheQueryOptions</code></h2>

<p>The full set of <a href="https://w3c.github.io/ServiceWorker/#dictdef-cache-cachequeryoptions"><code>CacheQueryOptions</code></a> is now supported, making it easier to find the cached responses you’re looking for. Here’s the complete list of available options:</p>

<ul>
  <li><code>ignoreSearch</code></li>
  <li><code>ignoreMethod</code></li>
  <li><code>ignoreVary</code></li>
  <li><code>cacheName</code></li>
</ul>

<p>See <a href="https://developers.google.com/web/updates/2016/09/cache-query-options">Jeff Posnick’s excellent article</a> for more information.</p>

<h2 id="css-text-size-adjust">CSS <code>text-size-adjust</code></h2>

<p><a href="https://drafts.csswg.org/css-size-adjust/">The <code>text-size-adjust</code> property</a> lets web developers control and disable <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/text-size-adjust">the text autosizing feature</a> which increases font sizes on mobile.</p>

<h2 id="unprefixed-css-user-select">Unprefixed CSS <code>user-select</code></h2>

<p>You can now use <a href="https://drafts.csswg.org/css-ui-4/#content-selection"><code>user-select</code></a> instead of <code>-webkit-user-select</code> in CSS. The <code>user-select</code> property makes it possible to specify which elements in the document can be selected by the user and how.</p>

<h2 id="navigations-in-unload-handlers-now-blocked">Navigations in <code>unload</code> handlers now blocked</h2>

<p>Navigations initiated in an <code>unload</code> handler are now <a href="https://groups.google.com/a/chromium.org/d/msg/blink-dev/VfItzNe3WO0/Zo95RMlTAwAJ">blocked</a>. Instead, any prior navigation will continue. This matches the behavior in Firefox, and matches Edge’s behavior more closely than before.</p>

<h2 id="nodeprototypegetrootnode"><code>Node.prototype.getRootNode</code></h2>

<p>Sites can use <a href="https://dom.spec.whatwg.org/#dom-node-getrootnode">Node.prototype.getRootNode(options)</a> to obtain the root for a given node.</p>

<h2 id="experimenting-with-post-quantum-crypto-for-tls">Experimenting with post-quantum crypto for TLS</h2>

<p>CECPQ1 is a post-quantum cipher suite: one that is designed to provide confidentiality even against an attacker who possesses a large quantum computer. It is a key-agreement algorithm plugged into TLS that combines X25519 and NewHope, a ring-learning-with-errors primitive. Even if NewHope turns out to be breakable, the X25519 key-agreement will ensure that it provides at least the security of our existing connections.</p>

<p>Note that this is only an experiment. In fact, the plan is to discontinue this experiment within two years, hopefully by replacing it with something better. See <a href="https://security.googleblog.com/2016/07/experimenting-with-post-quantum.html">“Experimenting with post-quantum cryptography”</a> for more details.</p>

<h2 id="deprecated-and-removed-features">Deprecated and removed features</h2>

<p><code>URL.createObjectURL</code> and <code>URL.revokeObjectURL</code> are now deprecated in service worker contexts.</p>

<p><a href="https://w3c.github.io/mediacapture-main/">The MediaStream API</a> dropped <code>MediaStream.prototype.ended</code> a long time ago. Its usage has been <a href="https://dev.opera.com/blog/opera-32/#mediastream-api">deprecated since Opera 32 &amp; Chromium 45</a>. As of this release, the <code>ended</code> event is no longer supported.</p>

<p>Similarly, <a href="https://w3c.github.io/FileAPI/">the File API spec</a> once removed the <code>FileError</code> interface. It has been deprecated since 2013. Any usage of <code>FileError</code> triggered a warning in the DevTools console <a href="https://dev.opera.com/blog/opera-40/#deprecated-and-removed-features">since Opera 40 &amp; Chromium 53</a>. As of this release, <code>FileError</code> is no longer supported.</p>

<p>Support for the non-standard <code>TouchEvent.prototype.initTouchEvent</code> has been removed, after being <a href="https://dev.opera.com/blog/opera-36/#deprecated-or-removed-features">deprecated since Opera 36 &amp; Chromium 49</a>. Use <a href="https://dev.opera.com/blog/opera-35/#touch-and-touchevent-constructors">the <code>Touch</code> and <code>TouchEvent</code> constructors</a> instead.</p>

<p>To more closely match other browser’s behavior, <code>window.external.IsSearchProviderInstalled</code> and <code>window.external.AddSearchProvider</code> (originally intended to <a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/sidebar/Adding_search_engines_from_Web_pages">add search engines programmatically</a>) are now both no-ops. This functionality was never implemented in Safari. In IE10, these methods are (mostly) no-ops: <code>IsSearchProviderInstalled</code> always returns <code>2</code>, and <code>AddSearchProvider</code> always returns <code>S_OK</code>. Firefox still implements this, but notes that it may be removed at any time.</p>

<p><code>KeyboardEvent.prototype.keyIdentifier</code> has been removed. Use <a href="https://w3c.github.io/uievents/#dom-keyboardevent-key"><code>KeyboardEvent.prototype.key</code></a> (or <a href="https://github.com/cvan/keyboardevent-key-polyfill">its polyfill</a>) instead.</p>

<h2 id="whats-next">What’s next?</h2>

<p>If you’re interested in experimenting with features that are in the pipeline for future versions of Opera, we recommend following <a href="https://www.opera.com/developer">our Opera Developer stream</a>.</p>
]]></content></entry><entry><id>https://dev.opera.com/blog/opera-40/</id><link type="text/html" rel="alternate" href="https://dev.opera.com/blog/opera-40/"/><title>What’s new in Chromium 53 and Opera 40</title><published>2016-09-20T00:00:00+00:00</published><updated>2016-09-20T00:00:00+00:00</updated><author><name>Mathias Bynens</name></author><content type="html" xml:base="https://dev.opera.com/"><![CDATA[<p>Opera 40 (based on Chromium 53) for <a href="https://www.opera.com/computer">Mac, Windows, Linux</a> is out! To find out what’s new for users, see our <a href="https://www.opera.com/blogs/desktop/">Desktop</a> blog. Here’s what it means for web developers.</p>

<h2 id="improved-input-pattern">Improved <code>&lt;input pattern="…"&gt;</code></h2>

<p><a href="https://mathiasbynens.be/notes/es6-unicode-regex">The <code>u</code> flag (which stands for Unicode)</a> is now applied to any regular expressions compiled through <a href="https://html.spec.whatwg.org/multipage/forms.html#the-pattern-attribute">the <code>pattern</code> attribute</a> for <code>&lt;input&gt;</code> and <code>&lt;textarea&gt;</code> elements.
This enables more Unicode-friendly features, and generally more sensible behavior.</p>

<pre><code>&lt;input pattern="[🍪🎂🍩]"&gt;
&lt;!--
	The input only validates when it is either 🍪, 🎂, or 🍩.
	(Previously, those strings would fail validation.)
--&gt;
</code></pre>

<p><a href="https://mathiasbynens.be/demo/pattern-u">A demo is available.</a></p>

<h2 id="iframe-sandboxallow-presentation"><code>&lt;iframe sandbox="allow-presentation"&gt;</code></h2>

<p><a href="https://w3c.github.io/presentation-api/#sandboxing-and-the-allow-presentation-keyword">The Presentation API</a> defines the nw <code>allow-presentation</code> sandboxing flag for <a href="https://html.spec.whatwg.org/multipage/embedded-content.html#attr-iframe-sandbox"><code>&lt;iframe sandbox="…"&gt;</code></a> which gives web developers control over whether an <code>iframe</code> can start a presentation session. By default, the Presentation API is disabled in sandboxed <code>&lt;iframe&gt;</code>s.</p>

<h2 id="shadow-dom-v1">Shadow DOM v1</h2>

<p>All browser vendors finally agreed on <a href="https://w3c.github.io/webcomponents/spec/shadow/">the Shadow DOM spec</a>, called <em>v1</em>. The new Shadow DOM APIs include:</p>

<ul>
  <li><code>Element.attachShadow</code></li>
  <li><code>Event.prototype.composed</code></li>
  <li><code>Event.prototype.composedPath()</code></li>
  <li><code>HTMLSlotElement</code></li>
  <li><code>Slotable.prototype.assignedSlot</code></li>
</ul>

<p>For more information, check out <a href="http://hayato.io/2016/shadowdomv1/">Hayato Ito’s overview of the differences between Shadow DOM v0 and v1</a>.</p>

<h2 id="mediastreamtrack-constraints-api"><code>MediaStreamTrack</code> Constraints API</h2>

<p>The following <a href="https://w3c.github.io/mediacapture-main/getusermedia.html#mediastreamtrack"><code>MediaStreamTrack</code></a> methods are now supported:</p>

<ul>
  <li><code>getCapabilities</code></li>
  <li><code>getConstraints</code></li>
  <li><code>getSettings</code></li>
  <li><code>applyConstraints</code></li>
</ul>

<p>These APIs allow getting, setting, and querying constraints on a <code>MediaStreamTrack</code>.</p>

<p>Additionally, <a href="https://w3c.github.io/mediacapture-main/getusermedia.html#idl-def-mediatrackconstraints"><code>MediaTrackConstraints</code></a> instances now have <code>video</code> and <code>audio</code> properties.</p>

<h2 id="promise-based-getusermedia">Promise-based <code>getUserMedia</code></h2>

<p><a href="https://w3c.github.io/mediacapture-main/#dom-mediadevices-getusermedia">The <code>navigator.mediaDevices.getUserMedia()</code> API</a>, which returns a promise, is now supported. Also, the unprefixed version of <a href="https://w3c.github.io/mediacapture-main/getusermedia.html#local-content"><code>navigator.getUserMedia()</code></a> (which uses callbacks) is now available. For more info, see <a href="https://developers.google.com/web/updates/2015/10/media-devices#getusermedia">Sam Dutton’s write-up</a>.</p>

<h2 id="unprefixed-css-filter">Unprefixed CSS <code>filter</code></h2>

<p><a href="https://drafts.fxtf.org/filters/">The CSS <code>filter</code> property</a> is now supported in its unprefixed form. For now, <code>-webkit-filter</code> is still supported as an alias for <code>filter</code>. <a href="http://bennettfeely.com/filters/">A demo featuring SpongeBob SquarePants is available.</a></p>

<h2 id="css--webkit-user-select-all">CSS <code>-webkit-user-select: all</code></h2>

<p>Chromium already supported <code>-webkit-user-select</code>, the prefixed version of <a href="https://drafts.csswg.org/css-ui-4/#content-selection"><code>user-select</code></a>, but it didn’t recognize every value the spec defines. As of this update, the <code>-webkit-user-select: all</code> is supported. This property/value pair makes it so that if a selection would contain only part of an element, then the selection must contain the entire element including all its descendants.</p>

<p>For example, if you apply this on all <code>&lt;p&gt;</code> elements, and you then try to select a single word in a paragraph, the entire paragraph is selected automatically.</p>

<p>The <a href="https://css-tricks.com/almanac/properties/u/user-select/">CSS Tricks Almanac entry for <code>user-select</code></a> features a nice demo.</p>

<h2 id="force-flattening-when-ancestor-has-opacity">Force flattening when ancestor has opacity</h2>

<p>3D-positioned descendants are now flattened by an ancestor that has opacity. Previously that didn’t happen if that ancestor also specified <code>transform-style: preserve-3d</code>. <a href="https://googlechrome.github.io/samples/css-opacity-force-flattening/">A visual demo explains this better than words ever could.</a></p>

<h2 id="rasterization--will-change-transform">Rasterization &amp; <code>will-change: transform</code></h2>

<p>Generally, all content is re-rastered when its transform scale changes, unless <code>will-change: transform</code> is applied to it. In other words, <code>will-change: transform</code> effectively means “please apply the transformation quickly, without taking the additional time for rasterization”. This only applies to scaling that happens via JavaScript manipulation, and does not apply to CSS animations. For more information, see the <a href="https://docs.google.com/document/d/1f8WS99F9GORWP_m74l_JfsTHgCrHkbEorHYu72D4Xag/edit?usp=sharing">technical summary for this change</a>. <a href="https://googlechrome.github.io/samples/css-will-change-transform-rasterization/">A demo is available.</a></p>

<h2 id="deprecated-and-removed-features">Deprecated and removed features</h2>

<p>Synthetic events (i.e. those who are created by JavaScript, and are thus untrusted) are now prevented from executing their default action. <code>click</code> is the only exception for backwards compatibility with legacy content. This change matches <a href="https://w3c.github.io/uievents/#trusted-events">the spec</a> and other browsers.</p>

<p><a href="https://github.com/whatwg/html/commit/99f0f1ae017523276ea4dd5784ec63a23a23834d">The HTML spec</a> was changed so that <code>&lt;label&gt;</code> elements aren’t form-associated elements anymore. As a result, support for the <code>form</code> attribute on <code>&lt;label&gt;</code> elements was removed, and <code>labelElement.form</code> is now an alias for <code>labelElement.control.form</code> (instead of mapping to the <code>form</code> attribute value).</p>

<p>HTTP/0.9, the predecessor to HTTP/1.x, is now deprecated, and will be removed in a future release. Its replacement, HTTP/1.0, was standardized 20 years ago.</p>

<p>Support for DHE-based TLS ciphers has been removed, after being <a href="https://dev.opera.com/blog/opera-38/#deprecated-and-removed-features">deprecated in Chromium 51 &amp; Opera 38</a>. Servers should upgrade to ECDHE ciphers instead.</p>

<p>A long time ago, <a href="https://w3c.github.io/FileAPI/">the File API spec</a> was changed to remove the <code>FileError</code> interface. It has been deprecated since 2013. As we’re preparing to remove this interface entirely in a future release, any usage of <code>FileError</code> now triggers a warning in the DevTools console.</p>

<p><a href="https://encoding.spec.whatwg.org/#textencoder">The TextEncoder API</a> no longer accepts an argument that specifies the encoding. Instead, it always uses UTF-8. If an argument is passed, it is ignored. This means that <code>new TextEncoder('utf-16')</code> and <code>new TextEncoder('utf-16be')</code> no longer work.</p>

<h2 id="whats-next">What’s next?</h2>

<p>If you’re interested in experimenting with features that are in the pipeline for future versions of Opera, we recommend following <a href="https://www.opera.com/developer">our Opera Developer stream</a>.</p>
]]></content></entry><entry><id>https://dev.opera.com/blog/opera-39/</id><link type="text/html" rel="alternate" href="https://dev.opera.com/blog/opera-39/"/><title>What’s new in Chromium 52 and Opera 39</title><published>2016-08-02T00:00:00+00:00</published><updated>2016-08-02T00:00:00+00:00</updated><author><name>Mathias Bynens</name></author><content type="html" xml:base="https://dev.opera.com/"><![CDATA[<p>Opera 39 (based on Chromium 52) for <a href="https://www.opera.com/computer">Mac, Windows, Linux</a> is out! To find out what’s new for users, see our <a href="https://www.opera.com/blogs/desktop/2016/08/personalized-newsreader-improved-video-popout-in-opera39/">Desktop</a> blog. Here’s what it means for web developers.</p>

<h2 id="es2016-exponentiation-operator">ES2016 exponentiation operator</h2>

<p>ES2016 introduces <a href="https://tc39.github.io/ecma262/#sec-exp-operator">an arithmetic operator equivalent</a> of <code>Math.pow(base, exponent)</code>, in which the lefthand-side expression serves as the base value, and the righthand-side expression serves as the exponent.</p>

<pre><code>4 ** 3;
// → 64

let value = 4;
value **= 3;
value;
// → 64
</code></pre>

<h2 id="fetch-api-response-construction-with-readablestream">Fetch API: <code>Response</code> construction with <code>ReadableStream</code></h2>

<p>It’s now possible to construct your own <code>ReadableStream</code> instances and to use them as bodies for <code>Response</code> objects, including from within service workers. This functionality is part of <a href="https://fetch.spec.whatwg.org/">the Fetch standard</a>. See <a href="https://developers.google.com/web/updates/2016/06/sw-readablestreams">Jeff Posnick’s write-up</a> for details, or <a href="https://jakearchibald.com/2016/streams-ftw/">Jake Archibald’s</a> in-depth blog post on streams for even more info.</p>

<h2 id="fetch-api-referrer-policy">Fetch API: referrer policy</h2>

<p>Requests made using <a href="https://fetch.spec.whatwg.org/">the Fetch API</a> can use a specific referrer policy, which affects the value of the <code>Referer</code> HTTP header that’s sent to remote servers. This can be done by adding a <code>referrerPolicy</code> property to the options object passed to <code>fetch</code>, which accepts the following values:</p>

<ul>
  <li><code>'no-referrer'</code></li>
  <li><code>'no-referrer-when-downgrade'</code></li>
  <li><code>'origin'</code></li>
  <li><code>'origin-when-cross-origin'</code></li>
  <li><code>'unsafe-url'</code></li>
</ul>

<p>See <a href="https://hacks.mozilla.org/2016/03/referrer-and-cache-control-apis-for-fetch/">Ehsan Akhgari’s write-up</a> for a straight-forward  explanation of these values.</p>

<pre><code>fetch(url, { 'referrerPolicy': 'no-referrer' })
	.then(function(response) {
		// Do something with the `response`…
	});
</code></pre>

<p><a href="https://googlechrome.github.io/samples/fetch-api/fetch-referrer-policy.html">A demo is available.</a></p>

<h2 id="d-canvas-filters">2D canvas filters</h2>

<p><code>CanvasRenderingContext2D</code> instances now support the <code>filter</code> property that applies effects to primitives drawn to the canvas. The <code>filter</code> value is parsed in the same way as <a href="https://drafts.fxtf.org/filters/#FilterProperty">CSS filters</a>.</p>

<pre><code>const canvas = document.querySelector('canvas');
const context = canvas.getContext('2d');
context.filter = 'saturate(6.3)';
</code></pre>

<h2 id="createimagebitmap-options"><code>createImageBitmap</code> options</h2>

<p>An <code>ImageBitmapOptions</code> object is an <code>options</code> object that can be passed to <code>createImageBitmap()</code>.</p>

<pre><code>createImageBitmap(image, options).then(function(response) {
	// Do something with the `response`…
});
</code></pre>

<p>The available options are:</p>

<ul>
  <li><code>colorSpaceConversion</code> indicates whether the image is decoded using color space conversion. Either <code>'none'</code> or <code>'default'</code> (default). The value <code>'default'</code> indicates that implementation-specific behavior is used.</li>
  <li><code>imageOrientation</code> indicates whether the image is presented as-is or flipped vertically. Either <code>'flipY'</code> or <code>'none'</code> (default).</li>
  <li><code>premultiplyAlpha</code> indicates that the bitmap color channels are premultiplied by the alpha channel. One of <code>'none'</code>, <code>'premultiply'</code>, or <code>'default'</code> (default).</li>
  <li><code>resizeWidth</code> indicates the new width.</li>
  <li><code>resizeHeight</code> indicates the new height.</li>
  <li><code>resizeQuality</code> specifies an image scaling algorithm. One of <code>'pixelated'</code>, <code>high'</code>, <code>'medium'</code>, or <code>'low'</code> (default).</li>
</ul>

<h2 id="invalid-track-kind-values-are-no-longer-treated-as-subtitles">Invalid <code>&lt;track kind&gt;</code> values are no longer treated as subtitles</h2>

<p>Invalid values for <a href="https://html.spec.whatwg.org/multipage/embedded-content.html#attr-track-kind"><code>&lt;track kind&gt;</code></a> were previously treated as <code>'subtitles'</code>. This means that any new values would be treated as subtitles by old browsers. Chromium now uses <code>'metadata'</code> instead as the “invalid value default”, to avoid browsers showing <code>&lt;track&gt;</code>s with unrecognized values.</p>

<h2 id="htmlmediaelementprototypesrcobject"><code>HTMLMediaElement.prototype.srcObject</code></h2>

<p>The <code>srcObject</code> property on HTMLMediaElement instances enables associating a <code>MediaStream</code> to a media element using a simple assignment. Previously, achieving this required first obtaining a URL associated to the <code>MediaStream</code>, and then associating this URL to the media element.</p>

<p>Currently, only <code>MediaStream</code> objects are accepted because it is the only type currently supported by other major browsers, but Chromium aims to support more types in the future. (Per the spec, a <code>MediaProvider</code> can be a <code>MediaStream</code>, a <code>MediaSource</code>, or a <code>Blob</code>.)</p>

<h2 id="web-audio-updates">Web Audio updates</h2>

<p><a href="https://webaudio.github.io/web-audio-api/#AudioParam"><code>AudioParam</code> instances</a> now have readonly <code>minValue</code> and <code>maxValue</code> properties that specify the minimum and maximum values the <code>AudioParam</code> can have. The <code>value</code> is clamped to lie in this range</p>

<p>Automation methods for the position and orientation coordinates of <a href="https://webaudio.github.io/web-audio-api/#the-pannernode-interface"><code>PannerNode</code></a> and the <code>position{X,Y,Z}</code>, <code>up{X,Y,Z}</code>, and <code>forward{X,Y,Z}</code> vectors of <a href="https://webaudio.github.io/web-audio-api/#AudioListener"><code>AudioListener</code></a> are now available. This allows smooth changes in the coordinates using <code>AudioParam</code> methods.</p>

<p>Chromium now implements the <code>reduction</code> property on <code>DynamicsCompressorNode</code> instances as a readonly float, matching the spec. Previously, the value was represented as an <code>AudioParam</code>.</p>

<h2 id="idbkeyrangeprototypeincludes"><code>IDBKeyRange.prototype.includes()</code></h2>

<p><a href="https://w3c.github.io/IndexedDB/#dom-idbkeyrange-includes">The <code>includes</code> method on <code>IDBKeyRange</code> instances</a> tests whether or not a key exists within the bounds of the range. Until all other browsers support this natively, <a href="https://developer.mozilla.org/en-US/docs/Web/API/IDBKeyRange/includes#Polyfill">a polyfill</a> can be used.</p>

<h2 id="webrtc-storing-rtccertificates-in-indexeddb">WebRTC: Storing <code>RTCCertificate</code>s in IndexedDB</h2>

<p><a href="https://w3c.github.io/webrtc-pc/#rtccertificate-interface"><code>RTCCertificate</code>s</a> are self-signed certificates used in the DTLS handshake when setting up a connection with an <code>RTCPeerConnection</code>. Chromium now allows web applications to store <code>RTCCertificate</code>s by implementing the structured clone algorithm. This means <code>RTCCertificate</code>s can be saved and loaded from an IndexedDB database, saving the cost of generating new certificates for new sessions.</p>

<h2 id="performance-observer">Performance Observer</h2>

<p><a href="https://w3c.github.io/performance-timeline/#the-performanceobserver-interface">The Performance Observer API</a> is essentially a streaming interface that can be used to gather low-level timing information asynchronously, as it’s gathered by the browser. <a href="https://developers.google.com/web/updates/2016/06/performance-observer">Marc Cohen’s write-up</a> does a great job explaining it.</p>

<h2 id="pause-event-loop-during-modal-dialogs">Pause event loop during modal dialogs</h2>

<p>When using <code>alert()</code>, <code>confirm()</code> or <code>onbeforeunload</code>, Chromium’s old behavior was to block JavaScript while waiting for the result, but to allow all declarative animations to continue. As of this update, Chromium makes all main-thread tasks (such as <code>&lt;marquee&gt;</code> and CSS 2D animations) also <a href="https://html.spec.whatwg.org/multipage/webappapis.html#pause">pause</a> during this interval.</p>

<p><a href="https://jsfiddle.net/v07nfvf9/">Here’s a demo</a> showing the impact of <code>alert()</code> on a CSS 2D animation.</p>

<h2 id="css-containment">CSS <code>contain</code>ment</h2>

<p><a href="https://drafts.csswg.org/css-containment/#contain-property">The CSS <code>contain</code> property</a> indicates that an element and its contents are, as much as possible, independent of the rest of the document tree. This allows the browser to recalculate layout (<code>contain: layout</code>), style (<code>contain: style</code>), paint (<code>contain: paint</code>), size (<code>contain: size</code>), or any combination of them for a limited area of the DOM and not the entire page. For more details, <a href="https://developers.google.com/web/updates/2016/06/css-containment">check out Paul Lewis’ explanation</a>.</p>

<h2 id="css-font-variant-caps--font-variant-numeric">CSS <code>font-variant-caps</code> &amp; <code>font-variant-numeric</code></h2>

<p>The CSS properties <a href="https://drafts.csswg.org/css-fonts/#font-variant-caps-prop"><code>font-variant-caps</code></a> and <a href="https://drafts.csswg.org/css-fonts/#font-variant-caps-numeric"><code>font-variant-numeric</code></a> are now supported.</p>

<h2 id="meter---webkit-appearance-none-"><code>meter { -webkit-appearance: none; }</code></h2>

<p>Previously, there was no way to completely disable the browser’s default rendering of <code>&lt;meter&gt;</code> elements and to restyle them using CSS. As of Chrome 52 / Opera 39, this finally became possible using <a href="https://drafts.csswg.org/css-ui-4/#appearance-switching"><code>-webkit-appearance: none</code></a>.</p>

<h2 id="new-css-flexbox-behavior-for-absolutely-positioned-children">New CSS Flexbox behavior for absolutely-positioned children</h2>

<p>The static position of absolutely-positioned children used to be set as though they were a 0×0 flex item. <a href="https://drafts.csswg.org/css-flexbox/#abspos-items">The CSS Flexible Box Layout spec</a> has since been updated to <a href="https://developers.google.com/web/updates/2016/06/absolute-positioned-children">take such children fully out of flow</a> and to set the static position based on <code>align</code> and <code>justify</code> properties. <a href="https://googlechrome.github.io/samples/css-flexbox-abspos/">Check out the demo.</a></p>

<h2 id="alternative-services">Alternative Services</h2>

<p><a href="https://tools.ietf.org/html/rfc7838">Alternative Services</a> allow an origin serving an <code>http://</code> or <code>https://</code> resource to nominate additional origins that the client can choose to request the resource from instead when making subsequent requests. This can be used, for example, as a protocol upgrade mechanism, for connection pooling, or for load balancing.</p>

<p>This is done through the <code>Alt-Used</code> HTTP header.</p>

<p>For example, if the resource at <code>https://origin.example.com/foo</code> returns the following response headers:</p>

<pre><code>Alt-Used: https://alternate.example.net
</code></pre>

<p>…and <code>https://origin.example.com/bar</code> is requested afterwards, then the browser may fetch either <code>https://origin.example.com/bar</code> or <code>https://alternate.example.net/bar</code>.</p>

<h2 id="csp3-strict-dynamic">CSP3 <code>strict-dynamic</code></h2>

<p><a href="https://w3c.github.io/webappsec-csp/#strict-dynamic-usage">The <code>'strict-dynamic'</code> source expression</a> allows scripts loaded via nonce- or hash-based whitelists to load other scripts. Deploying CSP is now simpler than ever before. <a href="https://csp-experiments.appspot.com/unsafe-dynamic">A demo is available.</a></p>

<h2 id="deprecated-and-removed-features">Deprecated and removed features</h2>

<p><code>X-Frame-Options</code> is now ignored when present inside a <code>&lt;meta&gt;</code> tag, e.g. <code>&lt;meta http-equiv="X-Frame-Options" contents="DENY"&gt;</code>, matching <a href="https://tools.ietf.org/html/rfc7034#section-4">the spec</a>. Use an HTTP header (<code>X-Frame-Options: DENY</code>) instead.</p>

<p>A non-standard and little-used variant of the <code>postMessage()</code> API is being deprecated, specifically <code>postMessage(message, transferables, targetOrigin)</code>. Use <code>postMessage(message, targetOrigin, transferables)</code> instead.</p>

<p>The <code>ended</code> event &amp; property and the <code>onended</code> event handler have been removed from <a href="https://w3c.github.io/mediacapture-main/">the Media Capture and Streams spec</a> and are now being deprecated in Chromium.</p>

<h2 id="whats-next">What’s next?</h2>

<p>If you’re interested in experimenting with features that are in the pipeline for future versions of Opera, we recommend following <a href="https://www.opera.com/developer">our Opera Developer stream</a>.</p>
]]></content></entry><entry><id>https://dev.opera.com/articles/pwa-desktop/</id><link type="text/html" rel="alternate" href="https://dev.opera.com/articles/pwa-desktop/"/><title>Progressive web apps running as native OS X apps</title><published>2016-07-26T00:00:00+00:00</published><updated>2016-07-26T00:00:00+00:00</updated><author><name>Vlad Filippov</name></author><content type="html" xml:base="https://dev.opera.com/"><![CDATA[<h2 id="progressive-web-apps-are-getting-ready-for-desktop">Progressive Web Apps are getting ready for desktop</h2>

<p>If you follow the Progressive Web App scene you’ve probably already seen multiple examples of the <a href="https://airhorner.com/">Air Horner app</a> in mobile browsers such as Opera Mobile and Chrome for Android. However it is not easy to get your favorite PWA (such as Air Horner) to be a primary citizen on your favorite <em>desktop</em> operating system.</p>

<p>Browser makers are working on getting better support for PWAs in desktop, but it’s not quite ready yet. This is why I started the <a href="https://github.com/vladikoff/PWAify">PWAify</a> project. This project is powered by Node.js and Electron, which already have a huge community and provide ease of use for new and experienced developers. The PWAify project is still in the early experimental stages — use it at your own risk.</p>

<p>The goal of the PWAify project is to provide a solution for PWAs on desktop while we wait for browsers to develop support. In addition this project allows developers to experiment, give better feedback to browser makers, and improve the <a href="https://www.w3.org/TR/appmanifest/">Web App Manifest specification</a>.</p>

<figure block="figure">
	<img elem="media" src="/articles/pwa-desktop/android-vs-osx.jpg" alt="Installed Air Horner app on Android and OS X" />
	<figcaption elem="caption">What the installed Air Horner app looks like on Android and OS X</figcaption>
</figure>

<h2 id="bringing-your-pwa-to-desktop">Bringing your PWA to desktop</h2>

<p>To create a sample app with PWAify follow the <a href="https://github.com/vladikoff/PWAify#readme">latest documentation on GitHub</a>.</p>

<p>Currently the simplest use case is to just provide an HTTPS URL to the remote app. For example:</p>

<pre><code>pwaify https://voice-memos.appspot.com/
</code></pre>

<p>There are some advanced options for the tool as well. You can specify the platform of your choice and an icon file once you are ready to distribute your app:</p>

<pre><code>pwaify https://voice-memos.appspot.com/ \
	--platforms=darwin \
	--icon chrome-touch-icon-384x384.icns
</code></pre>

<p>When you run the <code>pwaify</code> command it fetches and processes the <code>manifest.json</code> for the given PWA. Some early work is in place to simplify the process of generating desktop icons by looking at icons provided in the manifest. The current downside of the <code>pwaify</code> approach is the size of the executable for each application, but there is already huge list of <a href="http://electron.atom.io/apps/">Electron apps</a> out there that require the download. In my mind I try not to worry about the download size. Instead I try to focus on the future of progressive apps instead.</p>

<p>Here’s an example of <a href="https://voice-memos.appspot.com/">a simple progressive web app</a> working on Windows, Ubuntu and OS X:</p>

<figure block="figure">
	<img elem="media" src="/articles/pwa-desktop/multi-platform.jpg" alt="Voice Memos PWA running on Windows, Linux, and OS X" />
	<figcaption elem="caption">Voice Memos PWA running on Windows, Linux, and OS X</figcaption>
</figure>

<p>For the purposes of the screenshot I rebuilt the Voice Memos app on all platforms. It is also possible to setup a build server for your application once you want to add multi-platform support. You can use the PWAify tool today by pointing it at your own app or one of the apps in the <a href="https://pwa.rocks/">pwa.rocks list</a>.</p>

<p>Besides the Voice Memos application, my second favorite example is the 2048 tile game, by using PWAify with <a href="https://2048-opera-pwa.surge.sh/">2048-opera-pwa.surge.sh</a> I can easily jump back to the saved game state after I restart the application.</p>

<p>The PWAify project is open source, so you can fork it and extend functionality. For example you can add auto-update and custom UI for your application. In the spirit of keeping as much as possible of the application on the web I suggest only introducing minimal changes to the application wrapper. Treat the PWAify’d version of the app just like any other desktop browser would treat it.</p>

<h2 id="the-future">The Future</h2>

<p>Recently <a href="https://medium.com/web-on-the-edge/progressive-web-apps-on-windows-8d8eb68d524e">Microsoft announced</a> that the Windows Store will start supporting the W3C Web App Manifest. This will help you distribute the applications for Windows Store users, but you don’t have wait for Microsoft. There is nothing stopping you today to build one version of your web application and get it in the hands of your users on desktop. You can even go beyond Windows users and distribute on other operating systems.</p>

<p>Some future ideas for the PWAify project itself include:</p>

<ul>
  <li>implementing more of the Web App Manifest spec.</li>
  <li>reloading <code>manifest.json</code> from the server, which would allow dynamically changing certain properties of the application by updating the <code>manifest.json</code> remotely.</li>
  <li>experimenting with new manifest features, such as window size and minimal UI.</li>
  <li>working with the Electron app community to make it easier to generate application icons for cross-platform use.</li>
</ul>

<p>Tools like Electron and PWAify put yourself in control of application distribution while allowing you to use the latest web technologies. Write one awesome progressive web application for multiple distribution targets!</p>

<p>Feel free to <a href="https://github.com/vladikoff/PWAify/issues/new">file an issue against the PWAify project</a> if you have other ideas that will benefit the future of progressive web apps.</p>
]]></content></entry><entry><id>https://dev.opera.com/blog/recent-pwa-talks-videos/</id><link type="text/html" rel="alternate" href="https://dev.opera.com/blog/recent-pwa-talks-videos/"/><title>Progressive Web Apps presentations at Web Rebels and the PWA Dev Summit</title><published>2016-06-29T00:00:00+00:00</published><updated>2016-06-29T00:00:00+00:00</updated><author><name>Andreas Bovens</name></author><content type="html" xml:base="https://dev.opera.com/"><![CDATA[<p>A few weeks ago, I had the pleasure to <a href="https://opbeat.com/events/web-rebels-2016/#towards-better-apps-the-what-why-of-progressive-web-apps">give a talk</a> about progressive web apps at the <a href="https://www.webrebels.org/">Web Rebels conference</a> in Oslo. If you want to get a quick intro to the what and why of progressive web apps, do check it out.</p>

<figure block="figure">
	<iframe elem="media" width="560" height="348" src="https://fast.wistia.net/embed/iframe/k88z4s2qtp" allowfullscreen=""></iframe>
</figure>

<p>Last week, I <a href="https://www.youtube.com/watch?v=yMxQ0fhj89I">presented</a> at Google’s <a href="https://events.withgoogle.com/progressive-web-app-dev-summit/">Progressive Web App Dev Summit</a> in Amsterdam. In my talk, I covered novel UX patterns in progressive web apps, emerging markets and Opera Mini compatibility, and introduced a couple of <a href="https://dev.opera.com/blog/pwa-badge-pop/">new ideas</a> to solve some of the discoverability issues progressive web apps struggle with.</p>

<figure block="figure">
	<iframe elem="media" width="560" height="315" src="https://www.youtube.com/embed/yMxQ0fhj89I" allowfullscreen=""></iframe>
</figure>

<p>My talk there was followed by a <a href="https://www.youtube.com/watch?v=EyyEfxrk_NU">browser panel</a>, in which I participated as well. You can find a video of it below.</p>

<figure block="figure">
	<iframe elem="media" width="560" height="315" src="https://www.youtube.com/embed/EyyEfxrk_NU" allowfullscreen=""></iframe>
</figure>

<p>If you have any questions about progressive web apps, do check out our <a href="https://dev.opera.com/tags/pwa/">other articles</a> or <a href="https://twitter.com/odevrel">ask a question</a>.</p>
]]></content></entry><entry><id>https://dev.opera.com/blog/pwa-badge-pop/</id><link type="text/html" rel="alternate" href="https://dev.opera.com/blog/pwa-badge-pop/"/><title>Making progressive web apps even better: ambient badging and “pop into browser”</title><published>2016-06-21T00:00:00+00:00</published><updated>2016-06-21T00:00:00+00:00</updated><author><name>Andreas Bovens</name></author><content type="html" xml:base="https://dev.opera.com/"><![CDATA[<figure block="figure" mod="right">
	<img elem="media" src="/blog/pwa-badge-pop/picture.png" width="360" style="margin: 0 0 15px 15px" alt="Add to home screen badge in URL bar" />
</figure>

<p>We’re excited to release a <a href="https://www.opera.com/download/get/?partner=www&amp;product=android&amp;level=Labs">Labs build of Opera</a> for Android with support for two experimental features that enhance the discoverability and use of progressive web apps.</p>

<h2 id="ambient-badging">Ambient badging</h2>

<p>Earlier this month, <a href="https://infrequently.org/2016/06/pwa-discovery-you-aint-seen-nothin-yet/">Alex Russell wrote</a>:</p>

<blockquote>
  <p>Wouldn’t it be great if there were a button in the URL bar that appeared whenever you landed on a PWA that you could always tap to save it to your homescreen?</p>
</blockquote>

<p>We have been exploring this idea for a while, and are previewing an early version of this idea in this Labs build.</p>

<p>If you load a site that passes the criteria to qualify as a progressive web app, a small phone icon is shown to the left of the URL bar, labeling it as such. Note that this is different from the <a href="https://dev.opera.com/blog/web-app-install-banners/">“add to home screen” install banner</a>, which requires a user engagement check.</p>

<p>Give it a spin on one of the sites listed on <a href="https://pwa.rocks/">pwa.rocks</a> and <a href="https://twitter.com/odevrel/">let us know</a> how it goes.</p>

<h2 id="pop-into-browser">Pop into browser</h2>

<figure block="figure" mod="right">
	<video elem="media" controls="" cover="/blog/pwa-badge-pop/video.jpg" width="360" style="margin: 0 0 15px 15px">
		<source src="/blog/pwa-badge-pop/video.mp4" type="video/mp4" />
		<source src="/blog/pwa-badge-pop/video.webm" type="video/webm" />
	</video>
</figure>

<p>A few weeks ago, there were <a href="https://adactio.com/journal/10708">some discussions</a> around the lack of visibility of URLs in progressive web apps. What to do for instance if you want to find out the URL of a page inside a progressive web app?</p>

<p><a href="https://twitter.com/adactio/status/734875747169501185">Jeremy Keith tweeted</a>:</p>

<blockquote>
  <p>I want people to be able to copy URLs. I want people to be able to hack URLs. I’m not ashamed of my URLs …I’m downright proud.</p>
</blockquote>

<p>Also here, we’ve been doing some explorations: initially, we thought we could surface the URL by requiring the user to long-press anywhere in the web app and <a href="http://www.brucelawson.co.uk/2016/on-urls-in-progressive-web-apps/">show it in a context menu</a>. However, after further investigations, this turned out to be harder than expected — e.g. what to do with form fields, where context menus serve a different purpose? Then we had the idea to somehow connect it to the “pull-to-refresh” spinner, as a secondary gesture to the left or right. You can see in the video how this works. Quite useful, and it’s discoverable, without getting in the way.</p>

<p>These are just early proposals, and we may or may not include them in a final Opera for Android build. In the meanwhile, we’re happy to hear your feedback: give it a spin and <a href="https://twitter.com/odevrel/">let us know</a> what you think.</p>
]]></content></entry><entry><id>https://dev.opera.com/articles/pwa-nigeria-kenya-interview/</id><link type="text/html" rel="alternate" href="https://dev.opera.com/articles/pwa-nigeria-kenya-interview/"/><title>Progressive Web Apps in Nigeria and Kenya: a Double Interview</title><published>2016-06-16T00:00:00+00:00</published><updated>2016-06-16T00:00:00+00:00</updated><author><name>Andreas Bovens, Bruce Lawson</name></author><content type="html" xml:base="https://dev.opera.com/"><![CDATA[<p>While keeping an eye on Twitter mentions of progressive web apps, I came across a number of conversations between web developers in Nigeria and Kenya. Intrigued, I got in touch with them to hear their thoughts on progressive web apps, resulting in this double interview.</p>

<p><strong>Hi! Please tell us a little about yourselves.</strong></p>

<figure block="figure">
	<img elem="media" src="/articles/pwa-nigeria-kenya-interview/constance-okoghenun.jpg" width="200" alt="Constance Okoghenun" />
</figure>

<p><em>Constance Okoghenun, <a href="https://twitter.com/okoghenun">@okoghenun</a>:</em> I’m from Lagos, Nigeria. I work as a UI Specialist for <a href="https://konga.com/">Konga</a>, Nigeria’s largest online marketplace helping tens of thousands of merchants selling over 200,000 products on our platform. At Konga I help to build products that provide great shopping experiences for our customers. I also help organise and speak from time to time at <a href="http://usable.ng/">Usable</a> (formerly UXLagos), where designers, developers and enthusiasts here in Lagos and, recently, Abuja Nigeria, have monthly conversations about how to improve the experiences we deliver to our customers.</p>

<p>I love the web and have been working on the web for about 5 years now. It has been a delight to see it mature and become better as a platform, enabling me and other developers and designers to offer increasingly better experiences to our users.</p>

<figure block="figure">
	<img elem="media" src="/articles/pwa-nigeria-kenya-interview/eugene-mutai.jpg" width="200" alt="Eugene Mutai" />
</figure>

<p><em>Eugene Mutai, <a href="https://twitter.com/kn9ts">@kn9ts</a>:</em> I’m from Nairobi, Kenya. I’m currently working for/with <a href="https://andela.com/">Andela</a>. Andela is new startup, with a revolutionary model founded on the principle that brilliance is evenly distributed around the world, but opportunity is not. Andela is transforming the brightest minds in Africa into world-class developers, who then are fused into startups or Fortune 500 companies all over the world. I am currently working as a full-time full-stack developer for <a href="http://www.rbi.com/">RBI</a>, a Canadian multinational company (and one of the largest fast food brands in the world) whose brands include Burger King and Tim Hortons.</p>

<p>I have been a web enthusiast and developer for at least four years now. I am also a <a href="https://developers.google.com/experts/people/eugene-mutai">Google Developer Expert on Web Technologies</a>, attributed by one of my community contributions such as being the lead manager of the <a href="http://www.meetup.com/nairobi-js/">Nairobi JavaScript Community</a> growing it to over 450 members, and I regularly speak at a variety of programming and tech meetups.</p>

<p><strong>We met online because you were talking about Progressive Web Apps (PWAs) on Twitter. What is it about them that excites you?</strong></p>

<p><em>Eugene:</em> I haven’t talked about progressive web apps on Twitter only; I have evangelized about them wherever I got the chance to. My last talk on progressive web apps was at <a href="http://nairobitechweek.com/">Nairobi Tech Week</a>, the largest tech event in Sub-Saharan Africa this year. I’ve also written a blog post about it — <a href="https://medium.com/@kn9ts/progressive-webs-apps-africa-may-be-the-biggest-gainer-b45e05b14893">Progressive Webs Apps: Africa may be the biggest gainer</a> — which is a robust answer to the above question.</p>

<p>In summary, I am excited that finally web technology is earning its place on mobile. PWAs are changing the way web apps have been viewed: a secondary, less-intuitive and less-performant alternative to using a mobile app’s service. While settling in on mobile, leveraging its greatest advantage over native mobile apps — very low friction in usage — it may solve problems that make the daily usage of native mobile applications in Africa a challenge, e.g. the size of apps and requirement of new downloads every time they are updated, <a href="http://slides.com/eugenemutai/progressive-web-apps#/34">among many others</a>.</p>

<p>On a side note, as a passionate web developer, it’s been tons of losing development battles with Android developers, and I’m finally unquantifiably happy we are becoming a force to be reckoned with.</p>

<p><em>Constance:</em> There are lots of exciting things about progressive web apps and the new range of possibilities they bring to the web. If I were to pick just one feature of progressive web apps that I’m super-excited about, it’s the ability to detect and handle offline / unreliable network conditions with service workers.</p>

<p>This is vitally important, as web apps finally now have a space on user home screens — so being slow to load or breaking because of network unreliability is not acceptable. And, in my part of the world, where getting good connectivity speeds on mobile is pretty difficult, service workers present an opportunity for developers to build apps that aren’t just fast, but which are also resilient.</p>

<p>An example of this is Konga’s PWA: when we detect that the user is offline and has items in their shopping cart, we provide them the option of going through an offline checkout experience, thereby preventing internet connectivity from becoming a bottleneck when they shop with us.</p>

<p><strong>Constance, what are the characteristics of the Nigerian market that make PWAs an appealing development route?</strong></p>

<p><em>Constance:</em> Data is pretty expensive in Nigeria. Over the last 12 months, <a href="https://techpoint.ng/2016/05/17/data-plan-wars-nigeria/">data prices have become lower</a>, but not low enough to make the majority of the Nigerian internet market data insensitive. On average, it costs about NGN 1000 (about $5) to get 1GB of data. In a country where minimum wage is about NGN 18,000 (about $90) that is already 5.6% of the monthly salaries. So, as you can imagine, Nigerians are extremely data sensitive.</p>

<p>A huge number of smartphone users do not download their apps and never update their apps. Instead, people side-load apps and other content from third parties who have these apps downloaded to a PC and for a small fee will install apps from their computers to users’ phones. Among younger, more tech-savvy Nigerians, the app <a href="https://play.google.com/store/apps/details?id=cn.xender">Xender</a> is really popular as it allows them skip app downloads and just send it from one device to another.</p>

<p>As you can imagine, these workarounds for downloading apps from the app store create all sorts of problems for developers — from app distribution, to getting the most recent, bug-free versions of apps in the hands of users.</p>

<p>With PWAs giving web apps a place in the user’s home screen, without the download overhead of native apps, this becomes more exciting; developers in Nigeria can now always give a great and up-to-date experience to their users. Also, they have the ability to re-engage with their users via push notifications, and improve conversions.</p>

<p><strong>Eugene, is it similar in Kenya?</strong></p>

<p><em>Eugene:</em> The average pay is Kenya is approximately $300-400 a month. On a good month, with tough choices made in budgeting, one gets to barely spare $30 after covering monthly expenses. It costs $1 for 135MB of data and $5 for 1GB of data. On average a user has 15+ apps installed (extrapolated from global mobile app install stats). At least half of these apps demand to be updated after a day or two (best case scenario is weekly).</p>

<p>If each app is on average 15MB, this means 150MB of data used up on downloads from re-installations without considering each user’s unique personal data usage. If at least $5 of data is being used for updates only, I’d say this is very challenging to a user if they are is to keep up with these updates. Some updates also are just bug fixes — I kid you not, no one would update the app for that (including me) unless the bug is not negligible.</p>

<p><strong>Constance, what were the challenges of making the Konga PWA?</strong></p>

<p><em>Constance:</em> The biggest for us at Konga was time: we had only about six weeks to build a stable version of our app and we did it in time. Thinking offline-first was something we had to get used to doing. Apart from those, building our PWA wasn’t very difficult.</p>

<p><strong>And how was user feedback for your PWA, Constance?</strong></p>

<p><em>Constance:</em> Though we haven’t officially launched the app yet, feedback has been overwhelmingly positive. It requires 84% less data to complete the first transaction vs the previous mobile web experience, and 63% less data for initial load, and we are not even done building and optimizing the app. It certainly will be a delight for our users when it gets into their hands.</p>

<p>To quote our CEO Shola Adekoya:</p>

<blockquote>
  <p>We estimate that with our new light, super-fast, UX-rich browsing capability, customers’ data consumption will fall dramatically.</p>
</blockquote>

<p><strong>Back to Eugene now. How was user feedback to your evangelism, Eugene?</strong></p>

<p><em>Eugene:</em> I’m been satisfactorily happy with the feedback I have got from my blog post and all my talks on PWAs. In the last talk I gave, at one point a member of the audience who was an Android developer (among many others in the room) who became anxious and disturbed that PWAs would render native Android developers jobless. The best answer I could give was we’re only moving in the mobile department since we’re now in a sharing economy, and not kicking them out, and the hype was to only create awareness to all web tech developers and not to cause panic among Android developers.</p>

<p><strong>Do you think those Android developers’ concerns are justified? Do you see PWAs becoming dominant in the kind of markets that you work in?</strong></p>

<p><em>Eugene:</em> No, I don’t think they’re justified. First of all, awareness about PWAs is something that needs to be urgently addressed. Every time I give a talk on PWAs the facial response of the audience is like “Why didn’t I know about this? This is revolutionary!” and the question that always follows is “Where can I find more information and learn about PWAs?”</p>

<p>Furthermore, I don’t envision PWAs being dominant in the mobile apps space, but I see their presence vastly increasing once knowledge about them is in the hands of every web developer. PWAs solve a number of challenges for entrepreneurs: it’s a cross-platform solution, there’s very low friction compared to native apps, there’s no APK size limitation, and so on.</p>

<p><em>Constance:</em> I also don’t think that fear of PWAs is justified. I think both PWAs and native SDKs are just tools in a good developer’s tool box. There are use cases where a PWA would be perfect, and there are others for which a native app is best. Each developer just needs to evaluate when to use what. Moreover, there is nothing stopping native mobile developers from working on the web; Konga’s PWA was built by both our current mobile team (Android and iOS developers) and our front-end team.</p>

<p><strong>What else would you like to see browsers do to make PWAs more widely available and accepted?</strong></p>

<p><em>Constance:</em> Lots of developers use frameworks; it would be great to see vendors reach out to the maintainers of those frameworks and work with them improving their tooling and processes, so that it’s super easy to build PWAs with their frameworks and tools. More importantly, I’d like to see a more consistent implementation of the web specs that PWAs are based on.</p>

<p><em>Eugene:</em> Opera and Google Chrome have done a wonderful job so far. When talking about PWAs being installable, the “Add to home screen” option isn’t that convincing. I’d like to see something like “Install Web App” or “Add to Your Apps”.</p>

<p>Browsers should offer APIs so that PWAs can compete on an equal footing as native mobile apps. I am aware these missing APIs such as Bluetooth, NFC, USB access and so forth are currently being worked on. So this is just a matter of time.</p>

<p><strong>Thank you both!</strong></p>
]]></content></entry><entry><id>https://dev.opera.com/tv/tv-snap-mrss-requirements/</id><link type="text/html" rel="alternate" href="https://dev.opera.com/tv/tv-snap-mrss-requirements/"/><title>Opera TV Snap Data Format Requirements</title><published>2016-06-09T00:00:00+00:00</published><updated>2016-06-09T00:00:00+00:00</updated><author><name>Oskar Furga</name></author><content type="html" xml:base="https://dev.opera.com/"><![CDATA[<h2 id="table-of-contents">Table of Contents</h2>

<ul>
  <li><a href="#introduction">Introduction</a>
    <ul>
      <li><a href="#basics">Basics</a></li>
    </ul>
  </li>
  <li><a href="#mrss">Opera MRSS</a>
    <ul>
      <li><a href="#feed">Feed example</a></li>
      <li><a href="#metadata">Opera metadata</a></li>
      <li><a href="#item">Item example</a></li>
      <li><a href="#visualization">Visualization</a></li>
    </ul>
  </li>
</ul>

<h2 id="introduction">Introduction</h2>

<p>Opera TV Snap is an industry-first, end-to-end solution that allows content publishers to create and submit a Smart TV app to the Opera TV Store quickly and easily, for free. See the <a href="http://www.opera.com/tvsnap/">Opera TV Snap page</a> for more details.</p>

<h3 id="basics">Basics</h3>

<p>Specifications you should be aware of before preparing a video feed for the TV Snap Template:</p>

<ul>
  <li><a href="http://rssboard.org/rss-specification/">RSS specification</a>.</li>
  <li><a href="http://rssboard.org/media-rss/">MRSS specification</a>.</li>
  <li><a href="http://rssboard.org/rss-validator/">RSS feed validator</a>.</li>
  <li><a href="http://rssboard.org/rss-validator/">RFC822</a> for date and time.</li>
  <li><a href="https://dev.opera.com/tv/html5-audio-video-in-opera-tv-store-apps/">HTML5 Audio and Video Support in Opera TV Store Applications</a></li>
  <li>16:9 thumbnail ratio is a must. 256 × 144 px is minimal and recommended for the best user experience. If the image is greater, it will be scaled down to 256 px.</li>
</ul>

<h2 id="mrss">Opera MRSS</h2>

<p>TV Snap 3.0 Template uses Opera Media RSS Specification (OMRSS).</p>

<ul>
  <li>Feed must point to the MRSS compliant data.</li>
  <li>MRSS may contain more tags than TV Snap Template supports, but they will be ignored.</li>
  <li>We are still trying to provide backward compatibility with RSS, but OMRSS format is recommended and contains many improvements. Feed without <code>media</code> namespace will be parsed, but support for this format might be removed in the future.</li>
</ul>

<h3 id="feed">Feed example</h3>

<p>Required tags are:</p>

<ul>
  <li><code>&lt;rss&gt;</code> as a top level tag.</li>
  <li>One <code>&lt;channel&gt;</code> as a child of <code>&lt;rss&gt;</code>.</li>
  <li><code>&lt;channel&gt;</code> must contain <code>&lt;title&gt;</code> and at least one <code>&lt;item&gt;</code>.</li>
  <li>Each <code>&lt;item&gt;</code> must be a child of <code>&lt;channel&gt;</code>.</li>
</ul>

<p>Optional tags:</p>

<ul>
  <li><code>&lt;link rel="next"&gt;</code> with proper <code>href</code> should point to the next page of results.</li>
  <li><code>&lt;opera:metadata&gt;</code> as a child of <code>&lt;channel&gt;</code>
    <ul>
      <li>It is used as a wrapper to define nested categories.</li>
      <li>You can indefinitely nest categories inside another one.</li>
    </ul>
  </li>
</ul>

<p>Example feed: <a href="http://apps.tvstore.opera.com/broadcastspec/opera_mrss_for_broadcasters.xml">Opera MRSS</a></p>

<p>Feed structure:</p>

<pre><code>&lt;rss xmlns:media="http://search.yahoo.com/mrss/" xmlns:opera="http://apps.tvstore.opera.com/broadcastspec/" version="2.0"&gt;
	&lt;channel&gt;
		&lt;title&gt;Channel Title&lt;/title&gt;
		&lt;description&gt;Description of channel content&lt;/description&gt;
		&lt;opera:metadata&gt;
			&lt;!-- categoryData items - see next section --&gt;
		&lt;/opera:metadata&gt;
		&lt;item&gt;&lt;!-- See example in next section --&gt;&lt;/item&gt;
		&lt;item&gt;&lt;!-- … --&gt;&lt;/item&gt;
		&lt;!-- More items --&gt;
		&lt;link rel="next" href="[next results page]"/&gt;
	&lt;/channel&gt;
&lt;/rss&gt;
</code></pre>

<h3 id="metadata">Opera metadata</h3>

<p>Inside <code>&lt;opera:metadata&gt;</code> you can put <code>&lt;opera:categoryData&gt;</code> to define categories and collections (nested categories).</p>

<p><strong>Important</strong>: If you use metadata to define categories then in <code>&lt;media:category&gt;</code> you should use <code>path</code> instead of real category name (it will be taken from <code>categoryData</code>’s <code>label</code>)</p>

<p>Required attributes of <code>categoryData</code>:
- <code>path</code> argument defines category nesting. For each nested category you should define exactly one <code>categoryData</code> with correct <code>path</code>.
- <code>label</code> is name of category</p>

<p>Optional attributes of <code>categoryData</code>:
- <code>description</code> is description of category.
- <code>order</code> argument is optional. If it’s not passed then order will be based on MRSS feed order.
- <code>background</code> attribute replaces application’s background whenever user visits the category. This image should be in jpg format, 1280x720.
- <code>thumbnail</code>, <code>thumbnailwidth</code> &amp; <code>thumbnailheight</code> are used to display category thumbnail.</p>

<p>Example:</p>

<pre><code>&lt;opera:metadata&gt;
	&lt;!-- 1st category level. --&gt;
	&lt;opera:categoryData order="1" path="videos" label="Clips" description="Section with cool clips."/&gt;
	&lt;!-- 2nd category level. --&gt;
	&lt;opera:categoryData order="1" path="videos/fail" label="Fail Compilations" description="Fail compilations" background="http://domain.com/category55image-background.jpg" thumbnail="http://domain.com/category55image.jpg" thumbwidth="256" thumbheight="144" /&gt;
	&lt;opera:categoryData order="2" path="videos/cats" label="Cute Cats" description="All the cute cats in one place" background="http://domain.com/category55image-background.jpg" thumbnail="http://domain.com/category55image.jpg" thumbwidth="256" thumbheight="144" /&gt;
	&lt;!-- 3rd category level. --&gt;
	&lt;opera:categoryData order="1" path="videos/cats/black" label="Black Cats" description="Only black cats" /&gt;
	&lt;opera:categoryData order="2" path="videos/cats/white" label="White Cats" description="Only white cats" background="http://domain.com/category55image-background.jpg" thumbnail="http://domain.com/category55image.jpg" thumbwidth="256" thumbheight="144" /&gt;
&lt;/opera:metadata&gt;
</code></pre>

<h3 id="item">Item example</h3>

<p>Required tags are:</p>

<ul>
  <li><code>&lt;media:title&gt;</code></li>
  <li><code>&lt;media:content&gt;</code> with correct <code>url</code> &amp; <code>type</code>.
    <ul>
      <li>You might also use <code>&lt;media:group&gt;</code> to group multiple media elements (like video in different formats)</li>
      <li>Content might also contain <code>duration</code> &amp; <code>bitrate</code> attributes.</li>
      <li>Duration should be set as a number of seconds.</li>
      <li>For widest device support and best user experience use mp4 video type with bitrate up to 4000 kbit (see our <a href="https://dev.opera.com/tv/html5-audio-video-in-opera-tv-store-apps/">Audio &amp; Video Support</a>).</li>
    </ul>
  </li>
  <li><code>&lt;media:thumbnail&gt;</code> with correct <code>url</code> pointing to an image.
    <ul>
      <li>256 × 144 px format is recommended (see <a href="#basics">Basics</a> for more info)</li>
      <li>If there is more than one thumbnail then best will be selected based on <code>width</code> attribute (if present).</li>
    </ul>
  </li>
  <li>At least one <code>&lt;media:category&gt;</code> is needed but item can belong to many categories. It should contain path to the actual category defined in <code>&lt;opera:metadata&gt;</code> tag if one is present or just a simple name of the category.</li>
</ul>

<p>Optional tags:</p>

<ul>
  <li><code>&lt;pubDate&gt;</code> used to sort movies from newest to oldest
    <ul>
      <li>if not set then order will be set based on feed appearence</li>
    </ul>
  </li>
  <li><code>&lt;media:description&gt;</code> if exist it will be displayed as description for the video.</li>
  <li><code>&lt;media:restriction&gt;</code> used to define country restrictions</li>
  <li><code>&lt;media:keywords&gt;</code> for movie keywords (used in search)</li>
  <li><code>&lt;media:credit&gt;</code> for move credits</li>
  <li><code>&lt;media:subTitle&gt;</code> providing subtitles in VTT format</li>
  <li><code>&lt;opera:orderInCategory&gt;</code> is used to set order of item in category. If item is in many categories then it can have order set to each category separately. It has two required attributes:
    <ul>
      <li><code>path</code> with value the same as defined in category</li>
      <li><code>value</code> as a number (ascending)</li>
    </ul>
  </li>
  <li>Any other MRSS tag (see <a href="http://rssboard.org/media-rss/">MRSS specification</a>)</li>
</ul>

<p>Item structure:</p>

<pre><code>&lt;item&gt;
	&lt;pubDate&gt;Mon, 21 Mar 2016 11:00:01 GMT&lt;/pubDate&gt;
	&lt;media:title&gt;
		Sam Smoothy Follows His Fathers
		Footsteps In The Andes | Lost…
	&lt;/title&gt;
	&lt;media:description&gt;
		Many years ago, Sam Smoothy’s father
		climbed in the Andes mountains…
	&lt;/description&gt;
	&lt;media:category&gt;Skiing&lt;/category&gt;
	&lt;media:category&gt;Winter/Events&lt;/category&gt;
	&lt;opera:orderInCategory path="Winter/Events" value="12"/&gt;
	&lt;media:content url="video.mp4" type="video/mp4"
		bitrate="2200" duration="772"/&gt;
	&lt;media:thumbnail url="thumb.jpg" width="256" height="144"/&gt;
&lt;/item&gt;
</code></pre>

<h3 id="visualization">Visualization</h3>

<p>Below is example application look with defined categories. <em>Latest</em> and <em>Popular Videos</em> categories are generated automatically. Background and thumbnail of this app (right top corner) is provided through the <a href="https://publish.tvstore.opera.com/metadata/new/mrss">submission panel</a> and is not a part of Opera MRSS format.</p>

<figure block="figure">
	<img elem="media" src="/tv/tv-snap-mrss-requirements/example-1.jpg" alt="Main page view" />
	<figcaption elem="caption">Main page view</figcaption>
</figure>

<p>Example of TV Snap player.</p>

<figure block="figure">
	<img elem="media" src="/tv/tv-snap-mrss-requirements/example-2.jpg" alt="View with collections" />
	<figcaption elem="caption">View with collections</figcaption>
</figure>
]]></content></entry><entry><id>https://dev.opera.com/blog/opera-38/</id><link type="text/html" rel="alternate" href="https://dev.opera.com/blog/opera-38/"/><title>What’s new in Chromium 51 and Opera 38</title><published>2016-06-08T00:00:00+00:00</published><updated>2016-06-08T00:00:00+00:00</updated><author><name>Mathias Bynens</name></author><content type="html" xml:base="https://dev.opera.com/"><![CDATA[<p>Opera 38 (based on Chromium 51) for <a href="https://www.opera.com/computer">Mac, Windows, Linux</a> is out! To find out what’s new for users, see our <a href="https://www.opera.com/blogs/desktop/">Desktop</a> blog. Here’s what it means for web developers.</p>

<h2 id="es6-symbolhasinstance">ES6 <code>Symbol.hasInstance</code></h2>

<p>Constructors can now implement their own <code>Symbol.hasInstance</code> method, which is used by <code>instanceof</code> to determine whether a constructor object recognizes an object as its instance.</p>

<h2 id="es6-subclassing-using-symbolspecies">ES6 subclassing using <code>Symbol.species</code></h2>

<p><a href="https://tc39.github.io/ecma262/#sec-symbol.species">The <code>Symbol.species</code> accessor property</a> allows subclasses to <a href="https://tc39.github.io/ecma262/#sec-speciesconstructor">override</a> the default constructor for objects.</p>

<p>For example, <code>Array.prototype.map</code> constructs instances of the subclass as its return value, with the option to customize this by changing <code>Symbol.species</code>.</p>

<pre><code>class MyArray extends Array {
	static get [Symbol.species]() {
		// Return the parent `Array` constructor.
		return Array;
	}
}
const foo = new MyArray(1, 2, 3);
console.log(foo instanceof MyArray); // true
console.log(foo instanceof Array);   // true
const mapped = foo.map(x =&gt; x * x);
console.log(mapped instanceof MyArray); // false
console.log(mapped instanceof Array);   // true
</code></pre>

<h2 id="es6-regexp-subclassing">ES6 <code>RegExp</code> subclassing</h2>

<p>Previous versions of the JavaScript spec always used the original value of <code>RegExp.prototype.exec</code> in other methods such as <code>String.prototype.replace</code> — there was no way to override <code>exec</code> programmatically to change the core matching algorithm. In ES6 this is finally possible, which enables subclassing <code>RegExp</code> without having to duplicate any higher-level integration logic:</p>

<pre><code>class MyRegExp extends RegExp {
	exec() {
		return ['Hello from MyRegExp!'];
	}
}

const re = new MyRegExp('foo');
'bar'.match(re);
// ['Hello from MyRegExp!']
</code></pre>

<h2 id="es6-functionprototypename">ES6 <code>Function.prototype.name</code></h2>

<p>In ES6, the <code>name</code> property is sometimes set even on anonymous functions, based on the syntactic position of the function or class expression.</p>

<pre><code>const foo = function() {};
const bar = () =&gt; {};
console.log(foo.name); // 'foo'
console.log(bar.name); // 'bar'
</code></pre>

<h2 id="es6-iterator-closing">ES6 iterator closing</h2>

<p>Iterators are now checked for a <code>close</code> method which is called if the loop terminates early. This can be used for clean-up duty after the iteration has finished.</p>

<h2 id="es6-arrayprototypevalues">ES6 <code>Array.prototype.values</code></h2>

<p><a href="https://tc39.github.io/ecma262/#sec-array.prototype.values">The <code>values</code> method for arrays</a> returns an iterator over the contents of the array. This is similar to <code>Map.prototype.values</code> for maps or <code>Set.prototype.values</code> for sets.</p>

<h2 id="iterable-array-like-dom-interfaces">Iterable array-like DOM interfaces</h2>

<p>Any DOM interfaces containing indexed property getters and <code>length</code> properties now have a <code>Symbol.iterator</code> that makes them <a href="https://heycam.github.io/webidl/#es-iterators">iterable</a>. This means that things like <code>NodeList</code>, <code>HTMLAllCollection</code>, <code>FileList</code>, or <code>MediaList</code> can now be looped over by using <code>forEach</code> or <code>for-of</code>.</p>

<pre><code>for (const element of document.querySelectorAll('p')) {
	element.textContent += ' Hurray!';
}
</code></pre>

<h2 id="passive-event-listeners">Passive event listeners</h2>

<p>Passive event listeners are a new feature <a href="https://dom.spec.whatwg.org/#dom-eventlisteneroptions-passive">in the DOM spec</a> that enable developers to opt-in to better scroll performance by eliminating the need for scrolling to block on touch and wheel event listeners. Developers can annotate touch and wheel listeners with <code>{ passive: true }</code> to indicate that they don’t invoke <code>preventDefault</code> to get a massive scroll performance boost.</p>

<p>For more information, read <a href="https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md">the explainer document</a> or <a href="https://rbyers.github.io/scroll-latency.html">check out the demo</a>.</p>

<h2 id="keyboardeventprototypekey"><code>KeyboardEvent.prototype.key</code></h2>

<p><a href="https://w3c.github.io/uievents/#events-keyboard-key-location">The <code>key</code> property on <code>KeyboardEvent</code> instances</a> is now implemented. It returns the string value of the key (or keys) pressed by the user to generate the event. Check out <a href="https://googlechrome.github.io/samples/keyboardevent-key-attribute/">the demo for <code>key</code> specifically</a> or play around with <a href="https://w3c.github.io/uievents/tools/key-event-viewer.html">the keyboard event viewer</a>.</p>

<h2 id="intersection-observer-api">Intersection Observer API</h2>

<p>The brand-new <a href="https://wicg.github.io/IntersectionObserver/">Intersection Observer API</a> makes it easy to efficiently track when a given element in the DOM enters the visible viewport or leaves it. For more information, check out <a href="https://developers.google.com/web/updates/2016/04/intersectionobserver">Surma’s write-up</a> or <a href="https://github.com/WICG/IntersectionObserver/blob/gh-pages/explainer.md">the explainer document</a>, or <a href="https://wilsonpage.github.io/in-sixty/intersection-observer/">view a demo</a>.</p>

<h2 id="presentation-api">Presentation API</h2>

<p><a href="https://w3c.github.io/presentation-api/">The Presentation API</a> enables accessing external presentation-type displays and using them for presenting web content. <a href="https://storage.googleapis.com/presentation-api/index.html">A demo is available.</a></p>

<h2 id="service-workers-extendablemessageevent">Service workers: <code>ExtendableMessageEvent</code></h2>

<p><code>ServiceWorker.prototype.postMessage()</code> now results in an <a href="https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#extendablemessage-event-section"><code>ExtendableMessageEvent</code></a> fired on <code>ServiceWorkerGlobalScope</code> as a <code>'message'</code> event. Before this change, <code>postMessage()</code> resulted in a <code>MessageEvent</code> fired on the global scope.</p>

<p>Calling <a href="https://slightlyoff.github.io/ServiceWorker/spec/service_worker/index.html#extendable-event-waituntil-method">the <code>waitUntil(promise)</code> method</a> of an <code>ExtendableMessageEvent</code> instance extends its lifetime until <code>promise</code> is settled.</p>

<p>To experiment with this, view <a href="https://googlechrome.github.io/samples/service-worker/post-message/">the service worker <code>postMessage()</code> demo</a>.</p>

<h2 id="web-audio-api-offlineaudiocontextprototypelength">Web Audio API: <code>OfflineAudioContext.prototype.length</code></h2>

<p><a href="https://webaudio.github.io/web-audio-api/#idl-def-OfflineAudioContext"><code>OfflineAudioContext</code></a> instances now have a <code>length</code> that indicates the number of frames that the offline context will render.</p>

<h2 id="webrtc-promise-based-rtcpeerconnection-methods">WebRTC: promise-based <code>RTCPeerConnection</code> methods</h2>

<p>The following <code>RTCPeerConnection</code> methods are now promise-based, matching <a href="https://w3c.github.io/webrtc-pc/">the updated spec</a>:</p>

<ul>
  <li><a href="https://w3c.github.io/webrtc-pc/#dom-rtcpeerconnection-addicecandidate"><code>addIceCandidate</code></a></li>
  <li><a href="https://w3c.github.io/webrtc-pc/#dom-rtcpeerconnection-createanswer"><code>createAnswer</code></a></li>
  <li><a href="https://w3c.github.io/webrtc-pc/#dom-rtcpeerconnection-createoffer"><code>createOffer</code></a></li>
  <li><a href="https://w3c.github.io/webrtc-pc/#dom-rtcpeerconnection-setlocaldescription!overload-1"><code>setLocalDescription</code></a></li>
  <li><a href="https://w3c.github.io/webrtc-pc/#dom-rtcpeerconnection-setremotedescription!overload-1"><code>setRemoteDescription</code></a></li>
</ul>

<h2 id="css-border-image-now-follows-the-spec">CSS <code>border-image</code> now follows the spec</h2>

<p>Chrome and Opera now require a border style in order to paint <code>border-image</code>s, matching <a href="https://www.w3.org/TR/css3-background/#the-border-image">the spec</a>. If you’re affected by this change, add e.g. <code>border-style: solid</code> where <code>border-image</code> is used.</p>

<h2 id="percentage-sizes-of-flex-item-children">Percentage sizes of flex item children</h2>

<p>According to the spec, certain flex items have <a href="https://drafts.csswg.org/css-flexbox/#definite-sizes">definite sizes</a>. If a child element of such a flex item uses percentage-based sizes, these are now handled correctly. <a href="http://jsbin.com/zefuxiviso/2/edit?html,output">A visual demo is available.</a></p>

<h2 id="samesite-cookie-attribute"><code>SameSite</code> cookie attribute</h2>

<p>The <a href="https://tools.ietf.org/html/draft-west-first-party-cookies-07">cookie attribute</a> formerly known as “First-Party-Only” or “First-Party” allows servers to mitigate the risk of <a href="https://www.owasp.org/index.php/Cross-Site_Request_Forgery_%28CSRF%29">CSRF</a> and information leakage attacks by asserting that a particular cookie should only be sent with requests initiated from the same domain.</p>

<h2 id="aes256gcm-for-tls"><code>AES_256_GCM</code> for TLS</h2>

<p>To simplify server configuration and negotiate modern ciphers with more existing servers, Chrome and Opera now offer the <code>AES_256_GCM</code> cipher suite for TLS connections. See <a href="https://groups.google.com/a/chromium.org/d/msg/blink-dev/5BmCy4Gx3gs/ShdUGrLqAQAJ">the intent to implement</a> for details.</p>

<h2 id="deprecated-and-removed-features">Deprecated and removed features</h2>

<p>For security reasons, custom messages in <code>onbeforeunload</code> dialogs are <a href="https://groups.google.com/a/chromium.org/d/msg/blink-dev/YIH8CoYVGSg/Di7TsljXDQAJ">no longer used</a>.</p>

<p>DHE-based TLS ciphers are now deprecated and support for them will be removed at some point in the future. A warning message is logged to the DevTools console whenever such a cipher is used. Servers should upgrade to ECDHE ciphers instead.</p>

<p>Chromium 51 / Opera 38 no longer negotiates SPDY over HTTPS connections. Sites using it return to negotiating HTTP/1.1, unless they upgrade to HTTP/2. <a href="https://blog.chromium.org/2016/02/transitioning-from-spdy-to-http2.html">Use HTTP/2 instead.</a></p>

<p>A related feature removal is that of NPN, which was the TLS extension used to negotiate SPDY. During the standardization process, NPN was replaced with <a href="https://tools.ietf.org/html/rfc7301">ALPN</a>.</p>

<p>The non-standard <code>results</code> attribute for <code>&lt;input type=search&gt;</code> is now deprecated. In Chrome and Opera, it’s a purely cosmetic feature that adds a magnifier icon to the input field. In desktop Safari, it controls <a href="https://developer.apple.com/library/iad/documentation/AppleApplications/Reference/SafariHTMLRef/Articles/Attributes.html#//apple_ref/doc/uid/TP40008058-results">how many submitted queries are shown</a> in a popup opened by clicking the magnifier icon.</p>

<h2 id="whats-next">What’s next?</h2>

<p>If you’re interested in experimenting with features that are in the pipeline for future versions of Opera, we recommend following <a href="https://www.opera.com/developer">our Opera Developer stream</a>.</p>
]]></content></entry><entry><id>https://dev.opera.com/blog/opera-37/</id><link type="text/html" rel="alternate" href="https://dev.opera.com/blog/opera-37/"/><title>What’s new in Chromium 50 and Opera 37</title><published>2016-05-04T00:00:00+00:00</published><updated>2016-05-04T00:00:00+00:00</updated><author><name>Mathias Bynens</name></author><content type="html" xml:base="https://dev.opera.com/"><![CDATA[<p>Opera 37 (based on Chromium 50) for <a href="https://www.opera.com/computer">Mac, Windows, Linux</a> is out! To find out what’s new for users, see our <a href="https://www.opera.com/blogs/desktop/">Desktop</a> blog. Here’s what it means for web developers.</p>

<h2 id="es6-regexp-unicode-flag">ES6: <code>RegExp</code> Unicode flag</h2>

<p>ES6 specifies the <code>u</code> flag which enables more Unicode-friendly features and behavior in regular expressions. For example, it allows using astral symbols in character class ranges:</p>

<pre><code>// Match any symbol from U+1F4A9 PILE OF POO to U+1F4AB DIZZY SYMBOL.
const regex = /[💩-💫]/u; // Or, `/[\u{1F4A9}-\u{1F4AB}]/u`.
console.log(
	regex.test('💨'), // false
	regex.test('💩'), // true
	regex.test('💪'), // true
	regex.test('💫'), // true
	regex.test('💬')  // false
);
</code></pre>

<p>For more information on the effects of the <code>u</code> flag, see <a href="https://mathiasbynens.be/notes/es6-unicode-regex">“Unicode-aware regular expressions in ECMAScript 6”</a>.</p>

<h2 id="es6-more-well-known-symbols">ES6: more well-known symbols</h2>

<p>Five more <a href="https://tc39.github.io/ecma262/#sec-well-known-symbols">ECMAScript well-known symbols</a> have been implemented:</p>

<ul>
  <li><a href="https://tc39.github.io/ecma262/#sec-function.prototype-@@hasinstance"><code>Function.prototype[Symbol.hasInstance]</code></a>, used in <a href="https://tc39.github.io/ecma262/#sec-instanceofoperator">the <code>instanceof</code> operator</a>.</li>
  <li><a href="https://tc39.github.io/ecma262/#sec-regexp.prototype-@@match"><code>RegExp.prototype[Symbol.match]</code></a>, used to <a href="https://tc39.github.io/ecma262/#sec-isregexp">brand an object as <code>RegExp</code>-like</a>, and used in <a href="https://tc39.github.io/ecma262/#sec-string.prototype.match"><code>String.prototype.match</code></a>;</li>
  <li><a href="https://tc39.github.io/ecma262/#sec-regexp.prototype-@@replace"><code>RegExp.prototype[Symbol.replace]</code></a>, used in <a href="https://tc39.github.io/ecma262/#sec-string.prototype.replace"><code>String.prototype.replace</code></a>;</li>
  <li><a href="https://tc39.github.io/ecma262/#sec-regexp.prototype-@@search"><code>RegExp.prototype[Symbol.search]</code></a>, used in <a href="https://tc39.github.io/ecma262/#sec-string.prototype.search"><code>String.prototype.search</code></a>;</li>
  <li><a href="https://tc39.github.io/ecma262/#sec-regexp.prototype-@@split"><code>RegExp.prototype[Symbol.split]</code></a>, used in <a href="https://tc39.github.io/ecma262/#sec-string.prototype.split"><code>String.prototype.split</code></a>.</li>
</ul>

<p>These last four symbols act as hooks for <code>RegExp</code> subclasses to change the semantics of matching. By overriding <code>MyRegExpSubclass.prototype[Symbol.match]</code> etc. developers can change how the subclass behaves with respect to <code>String.prototype.match</code> and similar methods.</p>

<h2 id="bold-emoji-on-os-x">Bold emoji on OS X</h2>

<p>Previously, emoji with <code>font-weight: bold</code> applied to them failed to render in Chromium on OS X. This is now fixed. <strong>🙌🎉</strong></p>

<h2 id="link-relpreload-as"><code>&lt;link rel="preload" as="…"&gt;</code></h2>

<p><a href="https://w3c.github.io/preload/#link-type-preload">The <code>preload</code> link relation</a> makes it possible to define custom loading logic without suffering the performance penalty that script-based resource loaders incur. It can be combined with the <code>as</code> attribute to signal to the browser <a href="https://fetch.spec.whatwg.org/#concept-request-destination">what kind of resource</a> is being preloaded. This enables various optimizations that <code>&lt;link rel="prefetch"&gt;</code> or <code>preload</code>’s predecessor <code>&lt;link rel="subresource"&gt;</code> don’t offer. See <a href="https://www.smashingmagazine.com/2016/02/preload-what-is-it-good-for/">Yoav Weiss’ excellent article</a> for more information.</p>

<h2 id="css-column-fill">CSS <code>column-fill</code></h2>

<p>When using multi-column layouts, <a href="https://drafts.csswg.org/css-multicol-1/#cf">the CSS <code>column-fill</code> property</a> indicates whether columns should be balanced or not. If they are balanced, each column gets similar amounts of content inside. If they are not balanced, each column is filled to the height of the multicol container, until all the content is displayed. <a href="https://drafts.csswg.org/css-multicol-1/#cf">The spec</a> contains some examples with visualizations.</p>

<h2 id="canvas-updates">Canvas updates</h2>

<p><code>&lt;canvas&gt;</code> element instances now support <a href="https://html.spec.whatwg.org/multipage/scripting.html#dom-canvas-toblob">the <code>toBlob()</code> method</a> alongside the <code>toDataURL()</code> method. <code>toBlob()</code> is typically more efficient than <code>toDataURL</code>, as it enables you to work with the encoded binary data directly rather than with a Base64-encoded string.</p>

<p>The global <a href="https://html.spec.whatwg.org/multipage/webappapis.html#dom-createimagebitmap"><code>createImageBitmap()</code></a> method decodes an image in the background and returns an <a href="https://html.spec.whatwg.org/multipage/scripting.html#the-imagebitmap-rendering-context"><code>ImageBitmap</code></a> which you can draw onto a <code>&lt;canvas&gt;</code> in the same way you would an <code>&lt;img&gt;</code> element, another canvas, or a video. See <a href="https://developers.google.com/web/updates/2016/03/createimagebitmap-in-chrome-50">Paul Lewis’ write-up</a> for more details.</p>

<h2 id="domtokenlist-validation"><code>DOMTokenList</code> validation</h2>

<p>It’s now possible to programmatically detect support of values for HTML attributes that are backed by <code>DOMTokenList</code> instances in JavaScript. Currently, those HTML attributes are the following:</p>

<ul>
  <li><a href="https://html.spec.whatwg.org/multipage/semantics.html#attr-link-rel"><code>&lt;link rel&gt;</code> relations</a></li>
  <li><a href="https://html.spec.whatwg.org/multipage/embedded-content.html#attr-iframe-sandbox"><code>&lt;iframe sandbox&gt;</code> directives</a></li>
</ul>

<p>To test a value, just use <a href="https://dom.spec.whatwg.org/#dom-domtokenlist-supports"><code>.supports(value)</code></a> on the <code>DOMTokenList</code> instance. For more information, check out <a href="https://developers.google.com/web/updates/2016/03/domtokenlist-validation-added-in-chrome-50">the Google Developers blog post</a>.</p>

<h2 id="formdata-updates"><code>FormData</code> updates</h2>

<p><a href="https://xhr.spec.whatwg.org/#interface-formdata">The <code>FormData</code> interface</a> provides a way to easily construct a set of key/value pairs representing form fields and their values, which can then be easily sent using <code>XMLHttpRequest</code> or <code>fetch</code>. Previously, <code>FormData</code> objects had a single <code>append()</code> method, and were thus write-only. The spec has now added <code>has()</code>, <code>get()</code>, <code>getAll()</code>, <code>delete()</code>, <code>set()</code>, <code>entries()</code>, <code>keys()</code>, <code>values()</code>, <code>forEach()</code> and <code>Symbol.iterator()</code> methods to allow inspection, iteration, and modification. <a href="https://googlechrome.github.io/samples/formdata-methods/">Check out the demo.</a></p>

<h2 id="htmlmediaelementprototypeplay-returns-a-promise"><code>HTMLMediaElement.prototype.play()</code> returns a promise</h2>

<p><a href="https://html.spec.whatwg.org/multipage/embedded-content.html#dom-media-play">The <code>play</code> method</a> on <code>&lt;video&gt;</code> or <code>&lt;audio&gt;</code> element instances now returns a promise. If playback succeeds, the promise is fulfilled, and if playback fails, the promise is rejected along with an error message explaining the failure. For more details, check out <a href="https://developers.google.com/web/updates/2016/03/play-returns-promise">Jeff Posnick’s blog post</a> or <a href="https://googlechrome.github.io/samples/play-return-promise/">view the demo</a>.</p>

<h2 id="presentation-api-updates">Presentation API updates</h2>

<p>Support for the <code>statechange</code> event on <code>PresentationConnection</code> instances has been removed since it’s no longer part of <a href="https://w3c.github.io/presentation-api/#event-handlers-1">the spec</a>. On the other hand, the <code>message</code>, <code>connect</code>, <code>close</code>, and <code>terminate</code> event are now implemented.</p>

<h2 id="web-animations-api-updates">Web Animations API updates</h2>

<p>This release introduces the following Web Animations API changes to improve interoperability with other browsers and to improve spec compliance:</p>

<ul>
  <li><a href="https://w3c.github.io/web-animations/#the-animation-interface"><code>Animation.prototype.id</code></a></li>
  <li><code>cancel</code> events</li>
  <li>Deprecation of dashed names as keys in keyframes (to be removed in the next release)</li>
  <li>State change for the <code>pause()</code> method</li>
</ul>

<p>For details, see <a href="https://developers.google.com/web/updates/2016/03/web-animations-improvements">Alex Danilo’s write-up about these features</a>.</p>

<h2 id="web-audio-api-updates">Web Audio API updates</h2>

<p>Automations for the <a href="https://webaudio.github.io/web-audio-api/#the-biquadfilternode-interface"><code>BiquadFilter</code></a> node now run at a-rate (updated every frame) instead of at k-rate (updated every rendering quantum of 128 frames). This change matches the spec.</p>

<h2 id="push-notifications-on-opera-for-android">Push Notifications on Opera for Android</h2>

<p>Opera for Android now supports <a href="https://developers.google.com/web/fundamentals/getting-started/push-notifications/">push notifications</a>.</p>

<h2 id="sequential-focus-navigation-starting-point">Sequential focus navigation starting point</h2>

<p>The <a href="https://html.spec.whatwg.org/multipage/interaction.html#sequential-focus-navigation-starting-point">sequential focus navigation starting point</a> is how the HTML spec defines where browsers should start to search for focusable areas when pressing Tab or Shift+Tab while there is no focused area. This is now implemented according to the spec.</p>

<h2 id="x25519-for-tls">X25519 for TLS</h2>

<p>Chromium 50 brings support for X25519, the Diffie-Hellman primitive over <a href="https://tools.ietf.org/html/draft-ietf-tls-curve25519-01">Curve25519</a>, to TLS. When compared to P-256, the most commonly used curve in TLS today, it admits simpler, faster implementations that are more naturally resistant to side-channels. Servers may <a href="https://tlswg.github.io/tls13-spec/#rfc.section.6.3.2.2">negotiate</a> X25519 for ECDH instead of existing curves.</p>

<h2 id="deprecated-or-removed-features">Deprecated or removed features</h2>

<p>The Geolocation API <a href="https://developers.google.com/web/updates/2016/04/geolocation-on-secure-contexts-only">no longer works on insecure origins</a>. Use HTTPS instead.</p>

<p>The use of <a href="https://html.spec.whatwg.org/multipage/browsers.html#applicationcache">the application cache API</a> on insecure origins has been deprecated and will be removed in a future release. Use HTTPS and service workers instead.</p>

<p>Support for <a href="https://bugs.chromium.org/p/chromium/issues/detail?id=583787">the insecure TLS fallback mechanism</a> has been removed. This does <em>not</em> remove support for older versions of TLS — it just prevents attackers from downgrading the connection to use outdated, insecure ciphers. If your server is affected by this change, it does not implement TLS correctly. Consider upgrading to TLS 1.2 — all ciphers in prior versions have known problems.</p>

<p><a href="https://svgwg.org/svg2-draft/single-page.html#script-InterfaceSVGZoomEvent">The SVG <code>zoom</code> event</a> was never fully implemented in Chromium, causing false positives in feature detection scripts. It has now been deprecated and its removal is planned for Chromium 52 / Opera 39.</p>

<p>Support for the non-standard <code>-webkit-background-composite</code> CSS property has been removed.</p>

<p>The WebRTC <code>RTCPeerConnection</code> instance methods <a href="https://w3c.github.io/webrtc-pc/#widl-RTCPeerConnection-createOffer-Promise-RTCSessionDescription--RTCOfferOptions-options"><code>createOffer()</code></a> and <a href="https://w3c.github.io/webrtc-pc/#widl-RTCPeerConnection-createAnswer-void-RTCSessionDescriptionCallback-successCallback-RTCPeerConnectionErrorCallback-failureCallback"><code>createAnswer()</code></a> now require an error handler as well as a success handler. Previously it was possible to call these methods with only a success handler. This non-standard behavior has been deprecated.</p>

<p>Support for <code>&lt;link rel="subresource"&gt;</code> has been removed. It never worked as intended, and no other browser engines implemented it. Use the <code>preconnect</code>, <code>prefetch</code>, <code>preload</code>, or <code>prerender</code> link relations instead, or use a service worker in combination with the Cache API for more fine-grained control.</p>

<p>The non-standard <code>KeyboardEvent.prototype.keyLocation</code> alias has been removed. To disambiguate between keys that are on multiple places on a keyboard, like numbers and Enter, use <a href="https://w3c.github.io/uievents/#events-keyboard-key-location"><code>KeyboardEvent.prototype.location</code></a> instead.</p>

<p>Support for <a href="https://github.com/whatwg/dom/issues/58#issuecomment-162481999"><code>document.defaultCharset</code></a> has been removed.</p>

<p><code>Object.observe()</code> has been <a href="https://esdiscuss.org/topic/an-update-on-object-observe">removed</a> from the ECMAScript spec and is now no longer supported in Chromium. Use the <code>Proxy</code> API to observe objects instead.</p>

<p>The <code>SVGElement</code> instance properties <code>offsetParent</code>, <code>offsetTop</code>, <code>offsetLeft</code>, <code>offsetWidth</code>, and <code>offsetHeight</code> has been removed. They are now only supported on <code>HTMLElement</code>s, matching the spec. If you need similar functionality for SVG elements, use <code>getBoundingClientRect()</code> instead.</p>

<p>The <code>XMLHttpRequestProgressEvent</code> interface has been removed, together with the <code>position</code> and <code>totalSize</code> properties. Use the <code>ProgressEvent</code> interface with the <code>loaded</code> and total <code>properties</code> instead.</p>

<p><a href="https://developers.google.com/web/updates/2016/03/chrome-50-deprecations">The Google Developers blog</a> has more details on some of these feature removals/deprecations.</p>

<h2 id="whats-next">What’s next?</h2>

<p>If you’re interested in experimenting with features that are in the pipeline for future versions of Opera, we recommend following <a href="https://www.opera.com/developer">our Opera Developer stream</a>.</p>
]]></content></entry><entry><id>https://dev.opera.com/blog/better-extensions-ecosystem/</id><link type="text/html" rel="alternate" href="https://dev.opera.com/blog/better-extensions-ecosystem/"/><title>For a Better Extensions Ecosystem</title><published>2016-05-03T00:00:00+00:00</published><updated>2016-05-03T00:00:00+00:00</updated><author><name>Shwetank Dixit</name></author><content type="html" xml:base="https://dev.opera.com/"><![CDATA[<p>In 2013, when Opera desktop and Opera for Android switched over to Chromium, we faced a choice on how to go about our extensions ecosystem. We decided to look to the future and anticipated that someday developers might want to have a standardised way to make extensions (or at least, have a common set of APIs) so that the effort of making a separate extension for each browser is reduced.</p>

<p>That is why we chose our extension packaging format as <code>.nex</code> which stands for ‘navigator extensions’, signifying our take on a vendor-neutral format for extensions. Back it 2013, <a href="https://dev.opera.com/blog/introducing-nex/">we wrote the following</a>:</p>

<blockquote>
  <p>…NEX — a vendor-neutral packaging format for browser add-ons that we have initially implemented on top of the Chromium <code>.crx</code> format in Opera. We intend to further develop this as an open add-ons format through international standards bodies. Initially we intend to consolidate the differences between add-on execution environments themselves considering their current similarities. As a secondary objective we then aim to kick-start meaningful discussion around shared system and device-level APIs with a view to making browser add-ons first-class citizens of the web core.</p>
</blockquote>

<p>Years later, it seems a lot of other browser makers are also on board with getting some common extension APIs which work cross-browser. In order to do this, <a href="https://lists.w3.org/Archives/Public/public-browserext/2016May/0000.html">Opera, Microsoft, and Mozilla have begun work in the Extensions Community Group</a> where we will try to agree upon a set of common APIs, as well as a common manifest and packaging format for browser extensions. The goal is to enable extension developers to write one extension and have it work cross-browser.</p>

<p>This does not mean that browsers will not have their own proprietary APIs — they will, for some features. However, if we can work out a common manifest and packaging format, along with a core set of APIs to have in common, then this will go a long way in having interoperability of extensions across browsers. This could also open the door to a type of ‘progressive enhancement’ model for developing extensions (where instead of making a separate extension for each browser, we could make one extension and feature detect for various APIs), much like we have for web sites.</p>

<p>We appeal to the community to participate in the discussion in the group, and to give their feedback and ideas. We hope other browser makers will join us, so that together we can make extension development for multiple browsers much smoother than it is right now.</p>
]]></content></entry><entry><id>https://dev.opera.com/blog/timing-attacks/</id><link type="text/html" rel="alternate" href="https://dev.opera.com/blog/timing-attacks/"/><title>Front-End Performance: The Dark Side</title><published>2016-04-25T00:00:00+00:00</published><updated>2016-04-25T00:00:00+00:00</updated><author><name>Mathias Bynens</name></author><content type="html" xml:base="https://dev.opera.com/"><![CDATA[<p>On April 1st, I spoke at the very first <a href="https://fronteers.nl/congres/2016-spring">Fronteers Spring Conference</a>. The theme of the whole conference was <strong>performance</strong>. For my presentation, I decided to try something a little bit different: instead of talking about techniques that lead to better client-side performance, I focused on security-sensitive situations in which performance can actually be a <em>bug</em> rather than a feature.</p>

<p>View <a href="https://speakerdeck.com/mathiasbynens/front-end-performance-the-dark-side-at-fronteers-spring-conference-2016">the slides</a> here:</p>

<figure block="figure">
	<iframe elem="media" src="https://speakerdeck.com/player/63fc31552bd24a5dbf3bf22f9454c35f" width="767" height="493" allowfullscreen=""></iframe>
</figure>

<p>Check out the video below.</p>

<figure block="figure">
	<iframe elem="media" src="https://player.vimeo.com/video/163113209" width="640" height="360" allowfullscreen=""></iframe>
</figure>

<p>The Q&amp;A session after the talk was recorded as well.</p>

<figure block="figure">
	<iframe elem="media" src="https://player.vimeo.com/video/163232535" width="640" height="360" allowfullscreen=""></iframe>
</figure>

<p>The presentation walks through what <em>timing attacks</em> are, explains how they can occur on the web through client-side code, and demonstrates how modern performance-related web APIs can sometimes have a negative security impact. To get the point across, I showcased some brilliant research by <a href="https://zyan.scripts.mit.edu/sniffly/">Yan Zhu</a> and <a href="https://tom.vg/academic/#ccs2015-timing">Tom Van Goethem</a>. My favorite demo was one of Tom’s, where a client-side timing attack (using nothing but JavaScript) is used to figure out the exact age of the current visitor. (This demo starts around 16:03 in the first video.)</p>

<p>To me, this stuff is extremely interesting on a technical level. It’s also a little scary, however, to realize that malicious actors can use these techniques to invade your privacy while you’re browsing the web, without you ever knowing. Embedded third-party advertisements could be running timing attacks in the background, leaking pieces of private info (such as age, gender, location), which in turn enables them to serve you more targeted advertisements, fingerprint and track you across the web, or even de-anonymize you completely.</p>

<p>The sad news is that, as a web developer, there’s no obvious way to prevent this type of attack. Using <a href="http://www.sjoerdlangkemper.nl/2016/04/14/preventing-csrf-with-samesite-cookie-attribute/"><code>Same-Site</code> cookies</a> helps, but its <code>strict</code> mode seems a bit too aggressive for mainstream usage, and its <code>lax</code> mode might still not fully protect against timing attacks.</p>

<p>End users should consider <a href="opera://settings/?search=third-party%20cookies">blocking third-party cookies</a>, or using a content blocker (not just an ad blocker) in their browser.</p>
]]></content></entry><entry><id>https://dev.opera.com/blog/web-app-install-banners/</id><link type="text/html" rel="alternate" href="https://dev.opera.com/blog/web-app-install-banners/"/><title>Progressive Web App install banners come to Opera for Android</title><published>2016-03-31T00:00:00+00:00</published><updated>2016-03-31T00:00:00+00:00</updated><author><name>Andreas Bovens</name></author><content type="html" xml:base="https://dev.opera.com/"><![CDATA[<figure block="figure" mod="right">
	<img elem="media" src="/blog/web-app-install-banners/pd-1-banner.png" width="360" style="margin: 0 0 15px 15px" alt="PD-1 web app install banner" />
</figure>

<p>Since we first shipped support for web manifest and “add to home screen” in Opera 32 for Android <a href="https://dev.opera.com/articles/installable-web-apps/">last year</a>, we’ve seen an increasing amount of interest in progressive web apps.</p>

<p>Here at Opera, we’re excited about progressive web apps’ potential to bring the web on par with native apps’ capabilities, and this while avoiding the whole app store submission process — indeed, web apps can be discovered in a low friction way on the web, and changes can be pushed instantly to all users, while preserving their privacy with a conservative ask-when-needed permissions model. Additionally, from our initial observations, it seems like web apps are especially suited for devices with limited storage space, which is great news. If you haven’t seen it yet, I recommend reading <a href="https://developers.google.com/web/showcase/case-study/flipkart">Flipkart’s interesting report</a> about the boost in conversions and re-engagements they experienced after launching their <a href="https://m.flipkart.com/">Flipkart Lite</a> web app back in November 2015.</p>

<p>However, one hurdle with our implementation thus far has been that, in order for progressive web apps to appear like native apps on the home screen, users have to tap the + sign, and pick “Add to home screen” by themselves, and that can be quite a roadblock.</p>

<p>That’s why in Opera 36, we’ve started showing a “progressive web app install banner” for sites that meet a set of criteria, qualifying them as a progressive web app. These criteria are as follows. The site must:</p>

<ul>
  <li>Be served over HTTPS</li>
  <li>Have a manifest with a <code>short_name</code> and <code>name</code>, <code>start_url</code>, and a PNG icon of at least 144×144 pixels</li>
  <li>Have a service worker (making sure that the <code>start_url</code> functions offline)</li>
</ul>

<p>In addition, we also have a user engagement condition, so as to not show the install banner too aggressively. The condition there is that: the user has visited your site at least twice, with 5 minutes or more between visits. Careful readers will notice these conditions are the same as in <a href="https://developers.google.com/web/updates/2015/03/increasing-engagement-with-app-install-banners-in-chrome-for-android?hl=en">Chrome</a>, but we may change this in the future.</p>

<p>If you want to try this out without waiting between visits, simply go to <code>opera:flags</code>, enable “Bypass user engagement checks” and restart the browser. If you then visit a site like <a href="https://alexgibson.github.io/wavepad/">WAVE-PD1</a>, you’ll get prompted right away to add the web app in question to your home screen.</p>

<p>It’s also worth noting that in some cases, you may want to cancel the install banner from being shown. You can do this by intercepting the <code>onbeforeinstallprompt</code> event and preventing default on the event. You can see this in action on <a href="https://m.flipkart.com/">Flipkart Lite</a>. When you load their site (with “Bypass user engagement checks” enabled), you’ll feel a vibration and a small icon animation in the top right corner, suggesting to “Install this webapp to your phone”. If the user taps this icon, Opera’s own install banner is shown, which the user is likely to accept; if she does not tap the icon, Flipkart can remind her one of the next times, whenever it seems convenient to do so. This is of course somewhat more complex to implement, but it offers more possibilities to re-engage the user at the right point in time, later on.</p>

<p>That’s it! Try it out with the apps listed on our <a href="https://operasoftware.github.io/pwa-list/">Progressive Web Apps</a> list, and let us know how it goes!</p>
]]></content></entry><entry><id>https://dev.opera.com/blog/pwa-taipei/</id><link type="text/html" rel="alternate" href="https://dev.opera.com/blog/pwa-taipei/"/><title>Progressive Web Apps: the future of Apps</title><published>2016-03-30T00:00:00+00:00</published><updated>2016-03-30T00:00:00+00:00</updated><author><name>Bruce Lawson</name></author><content type="html" xml:base="https://dev.opera.com/"><![CDATA[<p>On 26 March, I gave a presentation at iWeb Summit 2016 in Taipei about Progressive Web Apps. Here’s the 20 minute video.</p>

<figure block="figure">
	<iframe elem="media" width="420" height="315" src="https://www.youtube.com/embed/MSldc28Hvp0" allowfullscreen=""></iframe>
</figure>

<p>If you don’t like my voice, just <a href="http://www.slideshare.net/brucelawson/bruce-lawson-progressive-web-apps-the-future-of-apps">see the slides</a>.</p>

<h2 id="more-resources">More resources</h2>

<ul>
  <li><a href="https://medium.com/net-magazine/html-manifest-402e6a8cc0e9#.kyg4r82s2">Non-technical guide to HTML Manifest</a> that I wrote for .net magazine</li>
  <li><a href="http://brucelawson.github.io/manifest/">Manifest generator</a></li>
  <li><a href="https://developers.google.com/web/showcase/case-study/flipkart?hl=en">New Progressive Web App helps Flipkart boost conversions 70%</a> and other business benefits of PWAs.</li>
  <li><a href="/articles/installable-web-apps/">Installable Web Apps and Add to Home screen</a>: a longer tutorial on how to make a Progressive Web App.</li>
  <li><a href="https://dev.opera.com/blog/web-app-install-banners/">Progressive Web App install banners come to Opera for Android</a></li>
  <li><a href="https://pwa.rocks/">List of good Progressive Web Apps</a></li>
</ul>
]]></content></entry><entry><id>https://dev.opera.com/blog/opera-36/</id><link type="text/html" rel="alternate" href="https://dev.opera.com/blog/opera-36/"/><title>What’s new in Chromium 49 and Opera 36</title><published>2016-03-15T00:00:00+00:00</published><updated>2016-03-15T00:00:00+00:00</updated><author><name>Mathias Bynens</name></author><content type="html" xml:base="https://dev.opera.com/"><![CDATA[<p>Opera 36 (based on Chromium 49) for <a href="https://www.opera.com/computer">Mac, Windows, Linux</a> and <a href="https://play.google.com/store/apps/details?id=com.opera.browser">Android</a> is out! To find out what’s new for users, see our <a href="https://www.opera.com/blogs/desktop/">Desktop</a> and <a href="http://www.opera.com/blogs/mobile/2016/03/brand-new-tab-switcher-web-app-discovery-opera-36-android/">Mobile</a> blogs. Here’s what it means for web developers.</p>

<h2 id="es6-default-function-parameter-values">ES6 default function parameter values</h2>

<p>ES6 allows formal parameters to be <a href="https://tc39.github.io/ecma262/#sec-functions-and-classes">initialized with default values</a> if no value (or <code>undefined</code>) is passed.</p>

<pre><code>function fn(x, y = 0) {
	return [x, y];
}
</code></pre>

<p>In this example, omitting the second parameter triggers the default value:</p>

<pre><code>console.log(fn(1));
// → [1, 0]
console.log(fn());
// → [undefined, 0]
</code></pre>

<p>For more information, see <a href="http://www.2ality.com/2015/01/es6-destructuring.html#parameter_handling">“Parameter handling in ES6”</a> or <a href="https://googlechrome.github.io/samples/default-parameters-es6/">check out the demo</a>.</p>

<h2 id="es6-destructuring-assignment">ES6 destructuring assignment</h2>

<p><a href="https://tc39.github.io/ecma262/#sec-destructuring-assignment">Destructuring assignment</a> makes it possible to extract data from arrays or objects using a syntax that mirrors the construction of array and object literals.</p>

<pre><code>let a, b, rest;
[a, b] = [1, 2];
// → a = 1; b = 2
[a, b, ...rest] = [1, 2, 3, 4, 5];
// → a = 1; b = 2; rest = [3, 4, 5]
{a, b} = { a: 1, b: 2 };
// → a = 1; b = 2
</code></pre>

<p><a href="https://googlechrome.github.io/samples/destructuring-es6/">Check out the demo for more examples.</a></p>

<h2 id="es6-proxy-and-reflect">ES6 <code>Proxy</code> and <code>Reflect</code></h2>

<p><a href="https://tc39.github.io/ecma262/#sec-proxy-object-internal-methods-and-internal-slots"><code>Proxy</code> objects</a> can be used to define custom behavior for fundamental operations such as property lookup, assignment, enumeration, function invocation, etc.</p>

<p><a href="https://tc39.github.io/ecma262/#sec-reflection">The <code>Reflect</code> API</a> offers imperative methods for invoking, examining or modifying values at runtime, and is very useful for working with Proxies.</p>

<p>Read <a href="https://developers.google.com/web/updates/2016/02/es2015-proxies">“ES2015 proxies”</a> for more information on both <code>Proxy</code> and <code>Reflect</code>.</p>

<h2 id="es6-block-scoped-bindings-in-sloppy-mode">ES6 block-scoped bindings in sloppy mode</h2>

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

<h2 id="symboltostringtag"><code>Symbol.toStringTag</code></h2>

<p>Using <a href="https://tc39.github.io/ecma262/#sec-symbol.tostringtag"><code>Symbol.toStringTag</code></a>, user-defined types can return customized output when passed to <code>Object.prototype.toString</code> (either directly or as a result of string coercion) by storing a descriptive string in a <code>Symbol.toStringTag</code>-keyed property.</p>

<pre><code>const object = {};
object[Symbol.toStringTag] = 'yoloswag';
String(object);
// → '[object yoloswag]'
</code></pre>

<h2 id="promise-rejection-events">Promise rejection events</h2>

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

<p><a href="https://googlechrome.github.io/samples/promise-rejection-events/">See the demo for more information.</a></p>

<h2 id="css-custom-properties-css-variables">CSS Custom Properties (CSS Variables)</h2>

<p><a href="https://drafts.csswg.org/css-variables/">The CSS Variables spec</a> 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 <a href="https://developers.google.com/web/updates/2016/02/css-variables-why-should-you-care">“CSS Variables: why should you care?”</a> for more info. <a href="https://googlechrome.github.io/samples/css-custom-properties/">A demo is available.</a></p>

<h2 id="case-insensitive-attribute-value-selectors">Case-insensitive attribute value selectors</h2>

<p>In HTML, the attribute <em>values</em> of <a href="https://html.spec.whatwg.org/multipage/scripting.html#case-sensitivity">certain attributes are compared ASCII-case-insensitively</a>.</p>

<p>Consider the following CSS:</p>

<pre><code>/* 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;
}
</code></pre>

<p>And the following markup:</p>

<pre><code>&lt;p id="note-1" lang="no"&gt;1&lt;/p&gt;
&lt;p id="nOtE-2" lang="No"&gt;2&lt;/p&gt;
&lt;p id="NOTE-3" lang="NO"&gt;3&lt;/p&gt;
</code></pre>

<p>In HTML and XML/<a href="https://mathiasbynens.be/notes/xhtml5">XHTML</a>, only the first paragraph gets a green background. In HTML, all paragraphs are underlined, but in XML/XHTML only the first is underlined.</p>

<p>Luckily, the <code>i</code> 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 <code>i</code> flag, all three paragraphs are highlighted and underlined in HTML and XML/XHTML environments:</p>

<pre><code>/* 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;
}
</code></pre>

<p>Note that the <code>i</code> flag only affects the case of matching the attribute <em>value</em>; not the attribute <em>name</em> or anything else.</p>

<h2 id="web-audio-api-updates">Web Audio API updates</h2>

<p>The Web Audio API defines <a href="https://webaudio.github.io/web-audio-api/#the-iirfilternode-interface"><code>IIRFilterNode</code></a>, which is an <code>AudioNode</code> processor implementing a general IIR filter. Once created, the coefficients of the IIR filter cannot be changed, and no automation functions are allowed.</p>

<p>Additionally, Chromium now supports <code>suspend()</code> and <code>resume()</code> methods on <code>OfflineAudioContext</code> instances.</p>

<p><a href="https://webaudio.github.io/web-audio-api/#widl-BaseAudioContext-decodeAudioData-Promise-AudioBuffer--ArrayBuffer-audioData-DecodeSuccessCallback-successCallback-DecodeErrorCallback-errorCallback"><code>AudioContext.prototype.decodeAudioData</code></a> now returns a <code>Promise&lt;AudioBuffer&gt;</code> that is resolved when decoding the audio data is finished. This is in addition to the existing callbacks, which are now optional.</p>

<h2 id="service-worker-windowclientprototypenavigate">Service worker: <code>WindowClient.prototype.navigate()</code></h2>

<p>It is now possible to trigger navigation from a service worker using <a href="https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#client-navigate-method">the <code>navigate()</code> method on a <code>WindowClient</code> instance</a>. <a href="https://googlechrome.github.io/samples/service-worker/windowclient-navigate/">Check out the demo.</a></p>

<h2 id="audio-output-devices-api">Audio Output Devices API</h2>

<p><a href="https://w3c.github.io/mediacapture-output/">The Audio Output Devices API specification</a> 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 href="https://webrtc.github.io/samples/src/content/devices/multi/">A demo is available.</a></p>

<h2 id="fetch-api-updates">Fetch API updates</h2>

<p>The <code>'navigate'</code> <a href="https://fetch.spec.whatwg.org/#concept-request-mode">request mode</a> as defined in the Fetch API specification is now supported. Check out <a href="https://googlechrome.github.io/samples/service-worker/custom-offline-page/">the “custom offline page” service worker demo</a> where this is being used.</p>

<p>Additionally, <a href="https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#fetch-event-clientid"><code>FetchEvent.prototype.clientId</code></a> is now implemented. This read-only property returns the ID of the <code>Client</code> that the current service worker is controlling. The <code>Clients.get()</code> method can then be passed this ID to retrieve the associated client.</p>

<h2 id="htmlmediaelementprototypedisableremoteplayback"><code>HTMLMediaElement.prototype.disableRemotePlayback</code></h2>

<p><a href="https://w3c.github.io/remote-playback/">The Remote Playback API specification</a> defines a <code>disableRemotePlayback</code> setter on <code>HTMLMediaElement</code> instances, which can be used to signal to the browser that this media element should not be played remotely. Enabling <code>disableRemotePlayback</code> by setting it to <code>true</code> causes the browser to not show any UI advertising remote playback, and prevents the element from being played remotely.</p>

<h2 id="high-resolution-event-time-stamps">High-resolution event time stamps</h2>

<p><a href="https://dom.spec.whatwg.org/#dom-event-timestamp"><code>Event.prototype.timeStamp</code></a> indicates the time at which a given event took place. Previously, this <code>timeStamp</code> value was represented as a <code>DOMTimeStamp</code>, which was a whole number of milliseconds since the system epoch.</p>

<p>Starting with Chromium 49, <code>timeStamp</code> is a <code>DOMHighResTimeStamp</code> value. This value is still a number of milliseconds, but with <a href="https://bugs.chromium.org/p/chromium/issues/detail?id=506723#c8">a resolution of 5 microseconds</a>, meaning the value now includes a decimal component. Additionally, instead of the value being relative to the epoch, the value is relative to <code>performance.timing.navigationStart</code>, i.e. the time at which the user navigated to the page. (<a href="https://github.com/whatwg/dom/issues/23">We’re working on getting this into the spec.</a>)</p>

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

<p><a href="https://googlechrome.github.io/samples/event-timestamp/">A demo is available.</a></p>

<h2 id="urlsearchparams"><code>URLSearchParams</code></h2>

<p><a href="https://url.spec.whatwg.org/#interface-urlsearchparams">The <code>URLSearchParams</code> API</a> defines helper methods for working with the query string of a URL (i.e. everything after <code>?</code>). <a href="https://googlechrome.github.io/samples/urlsearchparams/">A demo is available.</a></p>

<h2 id="a-relnoopener"><code>&lt;a rel=noopener&gt;</code></h2>

<p>You may be familiar with <a href="https://html.spec.whatwg.org/multipage/semantics.html#link-type-noreferrer"><code>&lt;a rel=noreferrer&gt;</code></a>, which prevents sending the <code>Referer</code> HTTP header and sets <code>window.opener</code> to <code>null</code> when following a link.</p>

<p>If you only want to disable <code>window.opener</code> but still send the <code>Referer</code> header, you can now use <a href="https://html.spec.whatwg.org/multipage/semantics.html#link-type-noopener"><code>rel=noopener</code></a>. Note that this is only needed for links that open a new navigation context, i.e. <code>target="_blank"</code>.</p>

<p>Why would you want to do this? Well, if <code>window.opener</code> is set, a page can trigger a navigation in the opener regardless of origin, which is a potential security risk. <a href="https://mathiasbynens.github.io/rel-noopener/">Check out the demo for a more elaborate explanation.</a></p>

<h2 id="cookie-prefixes">Cookie Prefixes</h2>

<p><a href="https://tools.ietf.org/html/draft-ietf-httpbis-cookie-prefixes-00">Cookie Prefixes</a> 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:</p>

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

<p><a href="https://googlechrome.github.io/samples/cookie-prefixes/">Check out the demo for more information.</a>.</p>

<h2 id="improved-handling-of-insecure-source-expressions-in-csp">Improved handling of insecure source expressions in CSP</h2>

<p><a href="https://zyan.scripts.mit.edu/sniffly/">Sniffly</a> is a timing attack to sniff browser history. One of its variants was based on a clever trick combining CSP and HSTS. In response, <a href="https://w3c.github.io/webappsec-csp/#changes-from-level-2">the CSP matching algorithm was updated</a> to make insecure schemes in source expressions match their secure variants. That is, <code>http:</code> is now equivalent to <code>http: https:</code>, and <code>http://example.com</code> to <code>http://example.com https://example.com</code>. Likewise, <code>'self'</code> now matches <code>https</code> and <code>wss</code> variants of the page’s origin, even on pages whose scheme is <code>http</code>.</p>

<h2 id="faster-and-more-secure-https-connections">Faster and more secure HTTPS connections</h2>

<p>The standardized versions of <a href="https://tools.ietf.org/html/rfc7539">the ChaCha20 stream cipher and Poly1305 authenticator</a> are now <a href="https://tools.ietf.org/html/draft-ietf-tls-chacha20-poly1305-04">used for TLS connections</a> in Chromium. Compared to <a href="https://tools.ietf.org/html/rfc5288">AES-GCM</a>, this new TLS cipher suite is <a href="https://security.googleblog.com/2014/04/speeding-up-and-strengthening-https.html">more secure</a>, saves network bandwidth, and operates three times faster on devices that lack AES hardware acceleration such as most Android devices.</p>

<h2 id="geolocation-now-https-only">Geolocation now HTTPS-only</h2>

<p>The <a href="https://w3c.github.io/webappsec-secure-contexts/#legacy-example">Secure Contexts specification</a> 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.</p>

<h2 id="smooth-scrolling">Smooth scrolling</h2>

<p>As of Chromium 49, <a href="https://developers.google.com/web/updates/2016/02/smooth-scrolling-in-chrome-49">scrolling is getting smoother</a> on Windows and Linux. But that’s not all: there are more potential improvements that may land soon, through Houdini and CSS properties like <code>scroll-behavior: smooth</code>. (On OS X, <a href="https://bugs.chromium.org/p/chromium/issues/detail?id=574283">nothing has changed yet</a>; smooth scrolling was already enabled, but only for keyboard-triggered scrolls.)</p>

<p>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 <a href="https://plus.google.com/+RickByers/posts/RdYaYF5DTF4">old versions of SmoothScroll.js will stop scrolling entirely</a> in the future when <a href="https://dev.opera.com/articles/fixing-the-scrolltop-bug/">the <code>scrollTop</code> bug</a> is fixed.</p>

<h2 id="deprecated-or-removed-features">Deprecated or removed features</h2>

<p>Support for the <a href="https://w3c.github.io/pointerlock/">Pointer Lock API</a>’s prefixed event properties <code>MouseEvent.prototype.webkitMovementX</code> and <code>MouseEvent.prototype.webkitMovementY</code> has been removed. Use the standardized versions, i.e. <code>MouseEvent.prototype.movementX</code> and <code>MouseEvent.prototype.movementY</code>, instead.</p>

<p>Support for <a href="https://html.spec.whatwg.org/multipage/forms.html#the-keygen-element">the <code>&lt;keygen&gt;</code> HTML element</a> has been removed. See the <a href="https://groups.google.com/a/chromium.org/d/msg/blink-dev/pX5NbX0Xack/kmHsyMGJZAMJ">intent to deprecate mail</a> for some background on this decision.</p>

<p>The non-standard <code>TouchEvent.prototype.initTouchEvent</code> is now deprecated. Use <a href="https://dev.opera.com/blog/opera-35/#touch-and-touchevent-constructors">the <code>Touch</code> and <code>TouchEvent</code> constructors</a> instead.</p>

<p>The non-standard <code>navigator.getStorageUpdates()</code> has been removed. It <a href="https://groups.google.com/a/chromium.org/d/msg/blink-dev/ak1kVjiX9T4/mo1rqcyQAQAJ">used to be a no-op</a> anyway.</p>

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

<p>Previously, Chromium treated the first two arguments (<code>type</code> and <code>listener</code>) of <code>addEventListener</code> and <code>removeEventListener</code> as optional, while they are non-optional in the spec and in other browsers. <a href="https://googlechrome.github.io/samples/event-listeners-mandatory-arguments/">This has changed</a>: calling these methods with zero or one argument now throws an exception.</p>

<p><code>document.defaultCharset</code> <a href="https://github.com/whatwg/dom/issues/58#issuecomment-162933700">has been deprecated</a> and will be removed in a future release.</p>

<p><code>Object.observe</code> has been deprecated as it is <a href="https://esdiscuss.org/topic/an-update-on-object-observe">no longer on the standardization track</a> and will be removed in a future release.</p>

<p>The WebRTC <code>RTCPeerConnection</code> methods <a href="https://w3c.github.io/webrtc-pc/#widl-RTCPeerConnection-createOffer-Promise-RTCSessionDescription--RTCOfferOptions-options"><code>createOffer()</code></a> and <a href="https://w3c.github.io/webrtc-pc/#widl-RTCPeerConnection-createAnswer-Promise-RTCSessionDescription--RTCAnswerOptions-options"><code>createAnswer()</code></a> 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.</p>

<h2 id="whats-next">What’s next?</h2>

<p>If you’re interested in experimenting with features that are in the pipeline for future versions of Opera, we recommend following <a href="https://www.opera.com/developer">our Opera Developer stream</a>.</p>
]]></content></entry><entry><id>https://dev.opera.com/articles/web-bluetooth-intro/</id><link type="text/html" rel="alternate" href="https://dev.opera.com/articles/web-bluetooth-intro/"/><title>An introduction to the Web Bluetooth API</title><published>2016-03-02T00:00:00+00:00</published><updated>2016-03-02T00:00:00+00:00</updated><author><name>Shwetank Dixit</name></author><content type="html" xml:base="https://dev.opera.com/"><![CDATA[<h2 id="introduction">Introduction</h2>

<figure block="figure" mod="right">
	<video elem="media" controls="" cover="/articles/web-bluetooth-intro/video.jpg" width="360" height="640" style="margin: 0 0 15px 15px;">
		<source src="/articles/web-bluetooth-intro/video.mp4" type="video/mp4" />
		<source src="/articles/web-bluetooth-intro/video.webm" type="video/webm" />
	</video>
</figure>

<p>There is an explosion of electronic devices nowadays, and with many of them, it’s possible to interact with them via <a href="https://en.wikipedia.org/wiki/Bluetooth_low_energy">Bluetooth Low Energy</a>, or BLE. However, installing a separate app for interacting with every single bluetooth gadget is impractical. What if we could communicate with them through a web browser? The Web Bluetooth API aims to do exactly that with a promise-based API, which allows you to interact with many BLE enabled devices. This is also great for companies intending to launch new gadgets, as instead of spending time and money on developing a separate app for multiple platforms, they can offer interaction with their gadget in a cross-platform manner, as it could be controlled directly from a web page.</p>

<h2 id="the-web-bluetooth-api">The Web Bluetooth API</h2>

<p>So far, the ability to communicate with BLE devices has been possible only for native apps. The Web Bluetooth API aims to change that and brings this to web browsers as well. The <a href="https://webbluetoothcg.github.io/web-bluetooth/">specification for the Web Bluetooth API</a> is not final yet, and you’re free to <a href="https://github.com/WebBluetoothCG/web-bluetooth/issues">share your feedback</a> on what you would want in it as well.</p>

<p>Right now, the Web Bluetooth API is in <a href="https://play.google.com/store/apps/details?id=com.opera.browser.beta">Opera for Android beta</a>. You can activate it by going to <code>opera://flags</code> and enabling Web Bluetooth in the options provided on that page.</p>

<h2 id="some-prerequisites">Some prerequisites</h2>

<ul>
  <li><strong>HTTPS only</strong>: The API only works on pages served over HTTPS. Most privacy-sensitive web APIs are now switching over to the HTTPS-only model, and this one is no exception.</li>
  <li><strong>Requires user action</strong>: We want to make sure that the API doesn’t work in the background without the user knowing about it, which is why there is a prompt shown to user to choose which device to pair with. Additionally, we also don’t want sites to show up this prompt straightaway without any user interaction. That is why methods in this API only work when called in response to a user action (like responding to a <code>click</code> event).</li>
</ul>

<h2 id="getting-basic-device-information">Getting Basic Device Information</h2>

<p>Let’s take a look at some code to figure out how to use this API to get some basic information regarding a BLE device.</p>

<p>Here is a very simple example, showing a button:</p>

<pre><code>&lt;button id="the-button"&gt;Try it&lt;/button&gt;
</code></pre>

<p>…and the following JavaScript:</p>

<pre><code>const button = document.querySelector('#the-button');
button.addEventListener('click', function() {
	navigator.bluetooth.requestDevice({
		filters: [{
			services: ['battery_service']
		}]
	}).then(device =&gt; {
		console.log('Got device:', device.name);
		console.log('id:', device.id);
	});
});
</code></pre>

<p>As mentioned earlier, the method <code>navigator.bluetooth.requestDevice()</code> can only be called in response to a user action like a button click. This method calls up a dialog box showing the list of available BLE devices matching the query filter. In our case, the filter we have set pertains to BLE devices which expose a so-called “GATT service” called <code>battery_service</code>. We’ll find out more about GATT services in the next section.</p>

<p>Keep in mind that it is necessary to include at least one filter when requesting device access using the Web Bluetooth API.</p>

<p>Once the user selects the device and connects to it, it can then print out the device name and its ID.</p>

<h2 id="what-are-gatt-services">What are GATT services?</h2>

<p>GATT stands for <a href="https://developer.bluetooth.org/TechnologyOverview/Pages/GATT.aspx">Generic Attribute Profile</a> and provides a standard way for Bluetooth devices to advertise their services to the outside world. Your cell phone might provide a GATT service to show the current battery level. Your fitness band might provide a service that too, along with another one showing the current heart rate count. There are a <a href="https://developer.bluetooth.org/gatt/services/Pages/ServicesHome.aspx">number of services which are exposed through GATT</a>, and we can listen to those services depending on which of those services are exposed by the device.</p>

<p>Some devices may not list their services in the standardized list of GATT services, in which case you could use their full Bluetooth UUID or a short 16- or 32-bit ID instead. Of course, this depends on whether the device has any documentation mentioning these UUIDs and what they are for.</p>

<pre><code>navigator.bluetooth.requestDevice({
	filters: [{
		services: ['0009180d-0000-1000-8000-00705f9b34fb']
	}]
});
</code></pre>

<h2 id="reading-and-writing-gatt-services">Reading and writing GATT services</h2>

<p>Once we have connected to a device, the next step is of course, to read some useful data from it. To do that, we need to connect to the device’s GATT server by using the method <code>gatt.connect()</code>. Let’s take our previous code sample and extend it. This is based on the <a href="https://googlechrome.github.io/samples/web-bluetooth/battery-level.html">Battery Level Sample Code</a> demo, which you can also check out (Note however that it uses the <code>connectGATT()</code> method which is deprecated from Chromium 50 onwards).</p>

<pre><code>navigator.bluetooth.requestDevice({
	filters: [{
		services: ['battery_service']
	}]
}).then(device =&gt; {
	console.log('Got device:', device.name);
	console.log('id:', device.id);
	return device.gatt.connect(); // Chromium 49 and below use `connectGATT()` but from Chromium 50 it will use gatt.connect();
})
.then(server =&gt; {
	console.log('Getting Battery Service…');
	return server.getPrimaryService('battery_service');
})
.then(service =&gt; {
	console.log('Getting Battery Characteristic…');
	return service.getCharacteristic('battery_level');
})
.then(characteristic =&gt; {
	console.log('Reading battery level…');
	return characteristic.readValue();
})
.then(value =&gt; {
	value = value.buffer ? value : new DataView(value);
	console.log('Battery percentage:', value.getUint8(0));
})
.catch(exception =&gt; {
	console.log(exception);
});
</code></pre>

<p>Here we are reading the <a href="https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.battery_level.xml">standardized battery level GATT characteristic</a>. Keep in mind that the value in the end is given as a <a href="https://docs.webplatform.org/wiki/javascript/DataView"><code>DataView</code></a> object which then needs to be parsed correctly to get the final value.</p>

<p>Writing values would typically require entering the appropriate values to be parsed as a <code>BufferSource</code>, which are either an <code>ArrayBuffer</code> or a view onto an <code>ArrayBuffer</code> like a <code>DataView</code> object (You can see a <a href="https://heycam.github.io/webidl/#idl-buffer-source-types">list of buffer source types</a>). For example, for resetting the <code>enerygyExpended</code> field in a heart rate monitor, we can use the <a href="https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-writevalue"><code>writeValue()</code></a> method like so:</p>

<pre><code>navigator.bluetooth.requestDevice({
	filters: [{
		services: ['heart_rate']
	}]
}).then(device =&gt; {
	console.log('Got device:', device.name);
	console.log('id:', device.id);
	return device.gatt.connect();
})
.then(server =&gt; server.getPrimaryService('heart_rate'))
.then(service =&gt; service.getCharacteristic('heart_rate_control_point'))
.then(characteristic =&gt; {
	const resetEnergyExpended = new Uint8Array([1]);
	// A value of `1` is a signal to reset it.
	return characteristic.writeValue(resetEnergyExpended);
})
.then(value =&gt; {
	console.log('Reset value of energy expended field');
})
.catch(exception =&gt; {
	console.log(exception);
});
</code></pre>

<p>If you don’t have a device which exposes GATT services but still want to play with the API, try out the <a href="https://github.com/WebBluetoothCG/ble-test-peripheral-android">BLE Peripheral Simulator App</a>.</p>

<h2 id="advanced-uses">Advanced uses</h2>

<p>Different devices will expose different services and have documentation describing how to access those services. For example, the BB-8 Toy by Sphero has some of their documentation on how to do that <a href="https://github.com/orbotix/DeveloperResources/blob/master/docs/Sphero_API_1.50.pdf">over here</a>.</p>

<p>Using this, it’s possible to create a <a href="https://operasoftware.github.io/bb8/">web app</a> that can control the BB-8 toy! Check out the <a href="https://github.com/operasoftware/bb8">code for it</a>.</p>

<p>Others have made web apps to <a href="https://github.com/poshaughnessy/web-bluetooth-parrot-drone">control drones</a>, <a href="https://github.com/WebBluetoothCG/demos/blob/gh-pages/heart-rate-sensor">heart-rate sensors</a>, <a href="https://github.com/WebBluetoothCG/demos">and more</a>. If you make a demo, be sure to add it to the list!</p>

<h2 id="whats-to-come">What’s to come</h2>

<p>The implementation of the Web Bluetooth API in Chromium in definitely not complete yet. Check out the <a href="https://github.com/WebBluetoothCG/web-bluetooth/issues">list of issues regarding implementation</a> in the spec. One of the most promising things to look forward to is the capability for websites to scan for <a href="https://github.com/WebBluetoothCG/web-bluetooth/issues/191">nearby BLE advertisements themselves</a>.</p>

<p>It would also be cool for websites to access the current RSSI (Received Signal Strength Indicator) and txPower levels, as well as any associated URLs shared through the <a href="https://en.wikipedia.org/wiki/Eddystone_%28Google%29">Eddystone protocol</a> without the need to pair with each individual device. All these exciting things are yet to come.</p>

<p>You can check out the <a href="https://github.com/WebBluetoothCG/web-bluetooth/blob/gh-pages/implementation-status.md">implementation status on various platforms</a> as well as a hardware compatibility list. If using Android, we recommend using the latest version for best and most consistent results.</p>

<h2 id="further-reading">Further Reading</h2>

<ul>
  <li><a href="https://webbluetoothcg.github.io/web-bluetooth">The Web Bluetooth Specification</a></li>
  <li><a href="https://github.com/WebBluetoothCG/demos">A collection of Web Bluetooth API Demos</a></li>
  <li><a href="https://github.com/operasoftware/bb8">Opera’s BB-8 Demo</a></li>
  <li><a href="https://github.com/WebBluetoothCG/ble-test-peripheral-android">BLE Peripheral Simulator App</a></li>
</ul>
]]></content></entry><entry><id>https://dev.opera.com/articles/working-with-theme-overlay/</id><link type="text/html" rel="alternate" href="https://dev.opera.com/articles/working-with-theme-overlay/"/><title>The New Start Page: Working With the Theme Overlay</title><published>2016-02-15T00:00:00+00:00</published><updated>2016-02-15T00:00:00+00:00</updated><author><name>Shwetank Dixit</name></author><content type="html" xml:base="https://dev.opera.com/"><![CDATA[<p>From Opera 36 onwards, the start page will have a brand new look. It introduces various design improvements, right from the placement of key icons, to the sizes of the speed dial tiles. As part of this, it also introduces a translucent gray overlay on themes.</p>

<p>Previously the title text for speed dial tiles was always having a white background and black text. The new design got rid of it, and overall speed dial tiles look much better. However, a side-effect of it was that reading the text totally depended on the background picture in the theme.</p>

<p>A solution to this is to introduce a subtle gray translucent overlay on themes and have the title text color for speed dial tiles white by default. We wanted to create a design that could work for any image you would try (or already have installed), meaning that even busy images would work just well and you will have a good experience using the new start page. While this solves the legibility issue by making the text very easy to read, some theme designers might want to not have this overlay, depending on their preference.</p>

<p>So we have introduced an option for theme authors to specify whether an overlay should be applied to their theme or not. If they choose not to apply an overlay on their theme images, then they can do so, and even specify the color for the speed dial text and other icons on the start page. This gives greater control in the hands of the theme creator.</p>

<h2 id="what-does-this-mean-for-theme-designers">What does this mean for theme designers?</h2>

<p>As a theme designer, you have two choices. If you want the background image to work with the overlay, then there is nothing extra you need to do. The overlay is applied by default, and all the text and icons will be white in color to contrast with the overlay (which gives it a nice contrast, making sure its readable) so no extra work needed there.</p>

<p>However, if you would like the overlay not to be applied to your background image, you now have the option to do so. However, keep in mind that in this case, you have the responsibility to make sure that all text and icons are properly visible to users.</p>

<h2 id="disabling-the-theme-overlay">Disabling the theme overlay</h2>

<figure block="figure">
    <img elem="media" src="/articles/working-with-theme-overlay/theme-comparison.gif" alt="Theme comparison" />
    <figcaption elem="caption">Theme with overlay enabled and disabled</figcaption>
</figure>

<p>We have introduced a new option in the Persona.ini file. You can now use <code>Use Overlay</code> to tell Opera whether to have it enabled or not. If you don’t want the overlay, simply write</p>

<pre><code>[Start Page]
Background					= background.jpg
Position					= center
Use Overlay					= false;
</code></pre>

<p>This will disable the overlay.</p>

<h2 id="making-text-and-icons-readable">Making text and icons readable</h2>

<p>Once you disable the overlay, it is up to you to make sure all the text and icons are having proper contrast and are readable by the user. For this, the existing option of <code>Title Text Color</code> will matter a lot.</p>

<p>Let’s take the example of the following of a theme with a disabled overlay.</p>

<figure block="figure">
    <img elem="media" src="/articles/working-with-theme-overlay/birdtheme-disabled.jpg" alt="Bird theme with disabled overlay" />
</figure>

<p>Now the image here is very light and provides very little contrast to the text, which is white in color. Let’s make it dark to provide it proper contrast. Let’s write the following:</p>

<pre><code>[Start Page]
Background				= background.jpg
Position				= center
Use Overlay				= false;
Title Text Color		= #000000
</code></pre>

<p>This gives us the following result:</p>

<figure block="figure">
    <img elem="media" src="/articles/working-with-theme-overlay/birdtheme-black.jpg" alt="Bird theme with black text and icon colors" />
</figure>

<p>This is much better. However, you could go ahead and provide more style which matches the color scheme (rather than the standard black) while still providing good contrast. Let’s change the text color like so:</p>

<pre><code>Title Text Color     = #ff0000
</code></pre>

<p>This results in the image having good contrast and matching the color scheme.</p>

<figure block="figure">
    <img elem="media" src="/articles/working-with-theme-overlay/birdtheme-main.jpg" alt="Bird theme with text and icon colors matching the color scheme" />
</figure>

<p>Keep in mind that, despite the name, using <code>Title Text Color</code> will affect the color of not just the text, but also the icons on the start page.</p>

<p>In the above image, you can notice how the icons have the color applied to it too.</p>

<h2 id="conclusion">Conclusion</h2>

<p>The new start page for Opera features an all new re-design. This features a new overlay for images which makes it work with a lot of images, even <em>busy</em> images, while still providing readability for users. Theme designers get greater control over how they want their background images to be displayed.</p>

<p>If they want to disable the overlay, they can use <code>Use Overlay = false</code> in the <code>Persona.ini</code> file. If overlay is disabled, then theme designers should keep in mind readability for text and icons on the start page by specifying an appropriate color for them using <code>Title Text Color</code> in the <code>Persona.ini</code> file.</p>
]]></content></entry><entry><id>https://dev.opera.com/blog/opera-35/</id><link type="text/html" rel="alternate" href="https://dev.opera.com/blog/opera-35/"/><title>Opera 35 released</title><published>2016-02-02T00:00:00+00:00</published><updated>2016-02-02T00:00:00+00:00</updated><author><name>Mathias Bynens</name></author><content type="html" xml:base="https://dev.opera.com/"><![CDATA[<p>Opera 35 (based on Chromium 48) for <a href="https://www.opera.com/computer">Mac, Windows, Linux</a> and <a href="https://play.google.com/store/apps/details?id=com.opera.browser">Android</a> is out! To find out what’s new for users, see our <a href="https://www.opera.com/blogs/desktop/">Desktop</a> and <a href="https://www.opera.com/blogs/mobile/2016/02/save-space-on-your-android-phone-with-web-apps/">Mobile</a> blogs. Here’s what it means for web developers.</p>

<h2 id="es6-more-well-known-symbols">ES6: more well-known symbols</h2>

<p>Two more <a href="https://tc39.github.io/ecma262/#sec-well-known-symbols">well-known symbols</a> have been implemented:</p>

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

<h2 id="css-improved-auto">CSS: improved <code>auto</code></h2>

<p>The <a href="https://drafts.csswg.org/css-flexbox/#min-size-auto">implied minimum size of a flex item</a> (i.e. <code>min-width: auto</code> or <code>min-height: auto</code>) is now also computed correctly when <code>flex-basis</code> is not <code>auto</code>.</p>

<h2 id="css-writing-modes-updates">CSS Writing Modes updates</h2>

<p>The CSS properties <a href="https://drafts.csswg.org/css-writing-modes-3/#text-combine-upright"><code>text-combine-upright</code></a>, <a href="https://drafts.csswg.org/css-writing-modes-3/#text-orientation"><code>text-orientation</code></a>, and <a href="https://drafts.csswg.org/css-writing-modes-3/#block-flow"><code>writing-mode</code></a> are now available without the <code>-webkit-</code> prefix, and with new syntax matching the spec.</p>

<p>The <code>isolate</code>, <code>isolate-override</code>, and <code>plaintext</code> values for <a href="https://drafts.csswg.org/css-writing-modes-3/#unicode-bidi">the <code>unicode-bidi</code> CSS property</a> can now be used without the <code>-webkit-</code> prefix. Support for the non-standard <code>horizontal-bt</code> value (as in <code>-webkit-writing-mode: horizontal-bt</code>) has been removed.</p>

<h2 id="unprefixed-css-font-feature-settings">Unprefixed CSS <code>font-feature-settings</code></h2>

<p><a href="https://drafts.csswg.org/css-fonts/#font-feature-settings-prop">The CSS <code>font-feature-settings</code> property</a> now works without the <code>-webkit-</code> prefix. This property provides low-level control over <a href="https://dev.opera.com/articles/state-of-web-type/#opentype-features">OpenType font features</a>.</p>

<p>The <code>-webkit-</code>-prefixed version is now deprecated and will be removed in a future release.</p>

<h2 id="css-font-loading-api-improvements">CSS Font Loading API improvements</h2>

<p>Our implementation of the <code>FontFaceSet</code> interface (e.g. <code>document.fonts</code>) is now set-like, <a href="https://drafts.csswg.org/css-font-loading/#FontFaceSet-interface">matching the spec</a>. This means it has <code>entries()</code>, <code>keys()</code>, and <code>values()</code> iterators, and is itself an iterator (over the individual <code>FontFace</code> entries).</p>

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

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

<p>Previously, the above <code>add()</code> and <code>remove()</code> both threw <code>InvalidModificationError</code> exceptions.</p>

<p><a href="https://googlechrome.github.io/samples/font-face-set/">A demo is available.</a></p>

<h2 id="fetch-api-data-and-blob-url-scheme-support">Fetch API: <code>data:</code> and <code>blob:</code> URL scheme support</h2>

<p>Our <a href="https://fetch.spec.whatwg.org/">Fetch API</a> implementation now supports the <code>data:</code> and <code>blob:</code> URL schemes.</p>

<h2 id="indexeddb-api-additions">IndexedDB API additions</h2>

<p>The IndexedDB <code>getAll()</code> and <code>getAllKeys()</code> methods are now supported on the <a href="https://w3c.github.io/IndexedDB/#object-store"><code>IDBObjectStore</code></a> and <a href="https://w3c.github.io/IndexedDB/#index"><code>IDBIndex</code></a> interfaces. Additionally, <a href="https://w3c.github.io/IndexedDB/#dom-idbobjectstore-openkeycursor"><code>IDBObjectStore.prototype.openKeyCursor()</code></a> and <a href="https://w3c.github.io/IndexedDB/#dom-idbtransaction-objectstorenames"><code>IDBTransaction.prototype.objectStoreNames</code></a> have been implemented.</p>

<p><a href="https://googlechrome.github.io/samples/idb-getall/">A demo is available.</a></p>

<h2 id="mediastreamtrackprototyperemote"><code>MediaStreamTrack.prototype.remote</code></h2>

<p><a href="https://w3c.github.io/mediacapture-main/getusermedia.html#widl-MediaStreamTrack-remote">The <code>remote</code> property</a> on WebRTC <code>MediaStreamTrack</code> instances is now available. It can be used to determine whether a stream track is from a remote source or a local one.</p>

<h2 id="serviceworkerregistrationprototypeupdate-more-spec-compliant"><code>ServiceWorkerRegistration.prototype.update()</code> more spec-compliant</h2>

<p><a href="https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#service-worker-registration-update">The <code>update</code> method on <code>ServiceWorkerRegistration</code> instances</a> used to always bypass the browser cache. Now, it only bypasses the browser cache if the previous update check occurred over 24 hours ago.</p>

<h2 id="touch-and-touchevent-constructors"><code>Touch</code> and <code>TouchEvent</code> constructors</h2>

<p>The <a href="https://w3c.github.io/touch-events/#touch-interface"><code>Touch</code></a> and <a href="https://w3c.github.io/touch-events/#touchevent-interface"><code>TouchEvent</code></a> constructors make it easy to programmatically create <code>Touch</code> and <code>TouchEvent</code> instances from an object literal.</p>

<pre><code>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
});
</code></pre>

<p>A <a href="https://output.jsbin.com/lohuwa">demo with more examples</a> is available.</p>

<h2 id="keyboardeventprototypecode"><code>KeyboardEvent.prototype.code</code></h2>

<p><a href="https://w3c.github.io/uievents/#widl-KeyboardEvent-code">The <code>code</code> property on <code>KeyboardEvent</code> instances</a> 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 <code>Q</code> key represents the symbol <code>q</code> on a QWERTY keyboard layout, but represents <code>a</code> on an AZERTY keyboard layout — but its <code>.code</code> value is <code>'KeyQ'</code> in both configurations.</p>

<p><a href="https://googlechrome.github.io/samples/keyboardevent-code-attribute/">A demo is available.</a></p>

<h2 id="web-audio-api-connect-chaining">Web Audio API: <code>.connect()</code> chaining</h2>

<p>The <code>connect</code> method on <code>AudioNode</code> and <code>AudioParam</code> instances now supports chaining, <a href="https://webaudio.github.io/web-audio-api/#widl-AudioNode-connect-AudioNode-AudioNode-destination-unsigned-long-output-unsigned-long-input">as per the spec</a>.</p>

<p>Before this change, you’d write code like this:</p>

<pre><code>sourceNode.connect(gainNode);
sourceNode.connect(filterNode);
sourceNode.connect(destination);
</code></pre>

<p>Now that can be simplified as follows:</p>

<pre><code>sourceNode
	.connect(gainNode)
	.connect(filterNode)
	.connect(destination);
</code></pre>

<p><a href="https://googlechrome.github.io/samples/webaudio-method-chaining/">A demo is available.</a></p>

<h2 id="deprecated-and-removed-features">Deprecated and removed features</h2>

<p>Support for the non-standard CSS values <code>intrinsic</code> and <code>min-intrinsic</code> has been removed. Use the standardized values <a href="https://drafts.csswg.org/css-sizing-3/#max-content"><code>max-content</code></a> and <a href="https://drafts.csswg.org/css-sizing-3/#min-content"><code>min-content</code></a> instead.</p>

<p>Support for CSS <code>composite-mode: darker</code> has been removed since <code>darker</code> is a non-<a href="https://drafts.fxtf.org/compositing-1/#compositemode">standard</a> value.</p>

<p>The <code>glyph-orientation-horizontal</code> and <code>glyph-orientation-vertical</code> CSS properties for SVG elements have been removed. Use <a href="https://drafts.csswg.org/css-writing-modes-3/#text-orientation"><code>text-orientation</code></a> instead, just like you would for HTML elements.</p>

<p>The <code>offsetParent</code>, <code>offsetTop</code>, <code>offsetLeft</code>, <code>offsetWidth</code>, and <code>offsetHeight</code> properties on <code>SVGElement</code> instances are now deprecated and will be removed in an upcoming release. Per the spec, <a href="https://drafts.csswg.org/cssom-view/#extensions-to-the-htmlelement-interface">these properties should only exist on <code>HTMLElement</code>s</a>. For <code>SVGElement</code>s, you can use <code>getBoundingClientRect()</code> instead.</p>

<p>The <code>getTransformToElement</code> method on <code>SVGGraphicsElement</code> instances has been removed, <a href="https://html.spec.whatwg.org/multipage/embedded-content.html#svg-0">matching the spec</a>.</p>

<p>The <code>SVGPathSeg</code> and <code>SVGPathSegList</code> 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 href="https://github.com/progers/pathseg">a polyfill is available for them</a>.</p>

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

<p>The non-standard <code>item()</code> method on <a href="https://html.spec.whatwg.org/#texttracklist"><code>TextTrackList</code></a> and <a href="https://html.spec.whatwg.org/#texttrackcuelist"><code>TextTrackCueList</code></a> has been removed. Use <code>tracks[index]</code> instead of <code>tracks.item(index)</code>.</p>

<p>Following the recommendation in <a href="https://tools.ietf.org/html/rfc7465" title="Prohibiting RC4 Cipher Suites">RFC 7465</a>, support for the RC4 cipher has finally been removed. HTTPS connections that rely on RC4 exclusively <a href="https://en.wikipedia.org/wiki/RC4#Security">cannot be considered secure anymore</a> and will therefore fail from now on.</p>

<h2 id="whats-next">What’s next?</h2>

<p>If you’re interested in experimenting with features that are in the pipeline for future versions of Opera, we recommend following <a href="https://www.opera.com/developer">our Opera Developer stream</a>.</p>
]]></content></entry><entry><id>https://dev.opera.com/articles/offline-with-upup-service-workers/</id><link type="text/html" rel="alternate" href="https://dev.opera.com/articles/offline-with-upup-service-workers/"/><title>Building Offline Sites with ServiceWorkers and UpUp</title><published>2016-01-19T00:00:00+00:00</published><updated>2016-01-19T00:00:00+00:00</updated><author><name>Tal Ater</name></author><content type="html" xml:base="https://dev.opera.com/"><![CDATA[<figure block="figure" mod="right" style="margin-left:20px">
	<img elem="media" src="/articles/offline-with-upup-service-workers/upup-phone-anim.gif" alt="Offline content demo" />
</figure>

<p>We are living in an increasingly mobile world. We rely on our phones to keep us connected wherever we go, and to provide us with the information we need to get through our day.</p>

<p>But connectivity hasn’t quite caught up with our dependence on it yet.</p>

<p>Every day we find ourselves without a working internet connection. Even in countries with near-perfect coverage, we lose connectivity when stepping into the elevator, or taking the subway. We have areas in our house that never seem to have a solid connection… and don’t even get me started about travel. The minute we leave our comfortable homes and offices, whether we’re boarding a plane, or just driving from town to town, we are at the mercy of the cell towers.</p>

<p>Now think of your users, and their dependence on the information you provide them. Are you running a travel site offering online hotel bookings? What would your users do if they just landed in Tokyo, without a local data plan, but they needed to access your site in order to find their hotel’s address? Does your store have a website? What would your users do if they were riding the elevator down to the parking lot while trying to find out your store’s opening hours?</p>

<p>Luckily we are living in very exciting times for web development. New technologies are coming out every day, unleashing new possibilities, and changing our perception of what is and isn’t possible in the browser. Two of the most important technologies to come out in recent years — service workers and the CacheStorage API — allow us an amazing level of control over the user’s browsing experience — even when their internet connection fails.</p>

<h2 id="taking-control-of-the-offline-experience">Taking control of the offline experience</h2>

<p>One library to provide an easy solution for the connectivity problem is called <a href="https://www.talater.com/upup/">UpUp</a>. <em>(Editor’s note: Tal is the developer of the UpUp library.)</em></p>

<p>UpUp allows you to define exactly what you want to show your users when they are offline, while handling all of the logic of intercepting requests, detecting when they fail, returning the right content from cache, managing that cache, and generally dealing with all the headaches of cross-browser compatibility.</p>

<p>The content you show your users can be as simple as one page (e.g. your business’ info, address, etc.), all the way to fully customized offline experiences with data customized for each user (e.g. a travel site’s user could browse his bookings, and get details on each booking, even while offline).</p>

<p>The best part of all, UpUp lets you do all of this in just a few lines of code:</p>

<pre><code>&lt;script src="/upup.min.js"&gt;&lt;/script&gt;
&lt;script&gt;
	UpUp.start({
		'content-url': 'offline.html'
	});
&lt;/script&gt;
</code></pre>

<p>In this article we’ll first look at how you can use UpUp to add offline capabilities to your site in under 10 minutes. We will then dive deeper behind the scenes, and see how UpUp achieves all of this.</p>

<h2 id="minute-tutorial">10 minute tutorial</h2>

<p>Let’s begin with a simple site, and add offline features to it:</p>

<pre><code>&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
	&lt;meta charset="utf-8"&gt;
	&lt;title&gt;Lonely Globe Advisor&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
	&lt;h1&gt;Top Hotels in Rome&lt;/h1&gt;
	&lt;ol&gt;
		&lt;li&gt;Villa Domus — Via Piacenza 9, Rome, Italy&lt;/li&gt;
		&lt;li&gt;Hotel Trivelli — Piazza Barberini 11, Rome, Italy&lt;/li&gt;
	&lt;/ol&gt;
&lt;/body&gt;
&lt;/html&gt;
</code></pre>

<p>Our sample site, Lonely Globe Advisor, offers visitors a list of the top fictional hotels in Rome.</p>

<p>But what happens if our user just landed in Rome and doesn’t have a local data plan? She’ll be out of luck.</p>

<p>We can improve on this experience by loading UpUp, and telling it what content we want it to show the user if she is offline.</p>

<pre><code>&lt;h1&gt;Top Hotels in Rome&lt;/h1&gt;
&lt;ol&gt;
	&lt;li&gt;Villa Domus — Via Piacenza 9, Rome, Italy&lt;/li&gt;
	&lt;li&gt;Hotel Trivelli — Piazza Barberini 11, Rome, Italy&lt;/li&gt;
&lt;/ol&gt;
&lt;script src="/upup.min.js"&gt;&lt;/script&gt;
&lt;script&gt;
	UpUp.start({
		'content-url': '/offline.html'
	});
&lt;/script&gt;
</code></pre>

<p>With just this tiny bit of code, we’ve added an offline experience for our site, and allowed our users to see the best hotels in Rome… even when they can’t access the web.</p>

<p>Any user that visited our site in the past, and is now trying to access it again without an internet connection, will now see the content of <code>offline.html</code>. Make sure you create this file and place it in the location you defined under <code>content-url</code>.</p>

<p>The sample above just shows a simple html page. You can improve on your offline content by including stylesheets, images, or even videos in your <code>offline.html</code>. You just need to make sure to tell UpUp what files you’re using, and it will cache them so they are available for your users when they are offline.</p>

<pre><code>&lt;h1&gt;Top Hotels in Rome&lt;/h1&gt;
&lt;ol&gt;
	&lt;li&gt;Villa Domus — Via Piacenza 9, Rome, Italy&lt;/li&gt;
	&lt;li&gt;Hotel Trivelli — Piazza Barberini 11, Rome, Italy&lt;/li&gt;
&lt;/ol&gt;
&lt;script src="/upup.min.js"&gt;&lt;/script&gt;
&lt;script&gt;
	UpUp.start({
		'content-url': 'offline.html',
		'assets': [
			'css/bootstrap.min.css',
			'img/trivelli.jpg',
			'mov/intro.mp4'
		]
	});
&lt;/script&gt;
</code></pre>

<p>With just one command and a couple of settings, we can create rich offline experiences for our users. These can be as simple as the example above, or as robust as a full single page application using frameworks like AngularJS, with content customized for each user, videos and files the user can access while offline.</p>

<p>There’s a more <a href="https://www.talater.com/upup/getting-started-with-offline-first.html">detailed tutorial</a> available on the official site, as well as complete documentation of <a href="https://github.com/TalAter/UpUp/blob/master/docs/README.md">UpUp’s API</a>.</p>

<h2 id="how-does-it-work">How does it work?</h2>

<p>How does UpUp serve this content to our users if they aren’t connected to the internet?</p>

<h4 id="tldr">tl;dr</h4>

<p>UpUp uses a new type of script called a ServiceWorker. This script runs even when the user is offline, and wraps every request made to the server with a promise. If the server can’t be reached, that promise is broken. The script catches broken promises, checks in its cache to see what offline content you’ve chosen to show and returns that instead of an error.</p>

<h4 id="serviceworkers">ServiceWorkers</h4>

<p>In order to understand how this works, let’s first understand how ServiceWorkers work.</p>

<p>A ServiceWorker is a special type of script that any site can register in the user’s browser. Once registered, this script sits in a very interesting position between the browser windows and that site’s server.</p>

<figure block="figure">
	<img elem="media" src="/articles/offline-with-upup-service-workers/serviceworker-online.gif" alt="Request and response to server through a ServiceWorker" />
</figure>

<p>As you can see, while the ServiceWorker runs within the user’s browser, it isn’t attached to any one window. Instead it runs in the background, and can communicate with the windows in its scope (the site that registered it).</p>

<p>From this unique location in the browser, ServiceWorkers have the power to examine each request as it is sent from the user’s browser, decide what to do with it, and then send it to the server. The ServiceWorker can then examine the response as it is returned from the server, decide what to do with it, and then pass either the original or a modified response back to the user’s window.</p>

<p>In a way, you can think of a ServiceWorker as a local proxy server inside the user’s browser. A proxy written in JavaScript that has the power to change requests and their responses.</p>

<p>Now if you think about this flow, you can probably begin to see the many different possibilities this grants us as developers.</p>

<p>For example, you could have a templating engine written entirely inside a ServiceWorker. This ServiceWorker would intercept requests to the server for HTML, asking the server for JSON instead. It would then parse that JSON against a template it has stored within it, and finally return simple HTML as the response. This could save us from rendering the HTML on the server, save bandwidth in the responses, and save us from having to include the templating logic in every page of our site. In other words, the server returns simple JSON, and the web page receives simple HTML.</p>

<p>Another idea could be a ServiceWorker that redirects requests to video files to either SD or HD videos based on the user’s connection speed or settings — this could be done without requiring each page to hold the logic for making that decision, or involving the server in the decision, allowing us to use a server optimized for delivering static files.</p>

<h4 id="serviceworkers-and-upup">ServiceWorkers and UpUp</h4>

<p>UpUp uses the power of ServiceWorkers to provide a solution to the lost connectivity problem described above, and serve content to the user even when their connection is down.</p>

<p>Let’s follow what happens behind the scenes of UpUp.</p>

<p>We’ll begin by registering a ServiceWorker. Once registered, all requests from the browser to our server go through the ServiceWorker, where they are wrapped in a JavaScript promise, and pass on untouched to our server. If that promise is broken (ie. we did not receive a response from the server), the ServiceWorker catches that error before it is shown to the user. It will then check for the cached content we’ve decided to show the user, and return that as the response, instead of an error .</p>

<figure block="figure">
	<img elem="media" src="/articles/offline-with-upup-service-workers/serviceworker-offline.gif" alt="Request and response to server through a ServiceWorker falling back to cache" />
</figure>

<p>To the browser’s window, responses returned from the server or from the cache by the ServiceWorker look exactly the same.</p>

<h5 id="where-does-the-offline-content-come-from">Where does the offline content come from?</h5>

<p>The final piece of the puzzle is the new caching technology used by UpUp — CacheStorage. Note: don’t confuse this with the browser’s own cache, or with that <a href="http://alistapart.com/article/application-cache-is-a-douchebag">douchebag</a>, the Application Cache. This is something new and much more powerful.</p>

<p>When we first registered our ServiceWorker, we told it what content to store in cache for later (we defined this in the <code>content-url</code> and <code>assets</code> settings). The UpUp ServiceWorker script went ahead and fetched that content, and stored it using the CacheStorage interface.</p>

<p>This content will now be available for the ServiceWorker the next time the user is offline.</p>

<h2 id="important-serviceworkers-considerations">Important ServiceWorkers Considerations</h2>

<p>When using ServiceWorkers, there are a few things you need to always keep in mind.</p>

<h4 id="https-only">HTTPS Only</h4>

<p>To preserve the user’s security and privacy, ServiceWorkers can only detect requests over a secure connection.</p>

<p>During development you can use UpUp through localhost or file (e.g. both <code>http://localhost/</code> and <code>file:///Users/tal_ater/index.html</code> are OK), but to deploy it to production you’ll need to have HTTPS set up on your server.</p>

<h4 id="browser-support">Browser Support</h4>

<p>UpUp plays nicely with all browsers, progressively enhancing browsers that support ServiceWorkers, while leaving users with older browsers unaffected.</p>

<p>UpUp currently supports Opera (since version 27), Chrome (since version 40) and Firefox (since version 41). If your users are using a different browser, they simply won’t notice anything different.</p>

<h4 id="where-should-i-place-my-files">Where Should I Place My Files?</h4>

<p>For security reasons, the browser only lets UpUp’s ServiceWorker see network requests within its scope.</p>

<p>The scope that the ServiceWorker can affect is determined by where you’ve placed <code>upup.min.js</code> and <code>upup.sw.min.js</code>. For example, if you place it on <code>https://yoursite.com/js/upup.sw.min.js</code>, UpUp will only be able to show your offline content when users try to look at the /js/ directory.</p>

<p>This is why it’s important to place both files on the same server as your content, and not in a subdirectory. This should ideally be in the root of your site (e.g. <code>https://yoursite.com/upup.min.js</code>).</p>

<h2 id="whats-next">What’s Next?</h2>

<p>It’s hard not to be excited about all the new possibilities ServiceWorker opens up to us as developers.</p>

<p>Go ahead, and try UpUp on your own site, you can see it in action and find more details and tutorials on doing <a href="https://www.talater.com/upup/">Offline First with UpUp</a>.</p>

<p>If you’d like to dive deeper and play some more with ServiceWorkers, there’s a <a href="http://www.html5rocks.com/en/tutorials/service-worker/introduction/">great introduction</a> by Matt Gaunt. If you’d like a few other ideas of how to improve caching with ServiceWorkers, check out Jake Archibald’s <a href="https://jakearchibald.com/2014/offline-cookbook/">Offline Cookbook</a>.</p>
]]></content></entry><entry><id>https://dev.opera.com/blog/cssconf-jsconf-asia/</id><link type="text/html" rel="alternate" href="https://dev.opera.com/blog/cssconf-jsconf-asia/"/><title>CSSConf.asia &amp; JSConf.asia</title><published>2016-01-07T00:00:00+00:00</published><updated>2016-01-07T00:00:00+00:00</updated><author><name>Mathias Bynens</name></author><content type="html" xml:base="https://dev.opera.com/"><![CDATA[<p>In November 2015, my colleague <a href="https://twitter.com/p01">Mathieu</a> and I visited Singapore to attend <a href="http://2015.cssconf.asia/">CSSConf.asia</a> and <a href="http://2015.jsconf.asia/">JSConf.asia</a>. Here’s a summary of our presentations.</p>

<h2 id="making-real-time-audio-visual-demos">Making real-time audio-visual demos</h2>

<p>At JSConf.asia, Mathieu spoke about creative coding, bringing the <a href="https://en.wikipedia.org/wiki/Demoscene">demoscene</a> to the web, and crazy JavaScript optimization tricks. He then proceeded to code an audio-visual demo from scratch, live on stage, using nothing but web standards.</p>

<figure block="figure">
	<iframe elem="media" width="560" height="315" src="https://www.youtube.com/embed/16oLi1kvLHs" allowfullscreen=""></iframe>
</figure>

<h2 id="random-css-fun-facts">Random CSS fun facts</h2>

<p>I had the pleasure of presenting at CSSConf.asia, and used that opportunity to showcase a series of obscure CSS fun facts, such as CSS syntax gimmicks and quirks, weird tricks that involve CSS in one way or another, and security vulnerabilities that are enabled by (ab)using CSS in unexpected ways.</p>

<figure block="figure">
	<iframe elem="media" width="560" height="315" src="https://www.youtube.com/embed/KPL-mA77bDo" allowfullscreen=""></iframe>
</figure>

<p>In case you’re into that kind of stuff, there’s some terrible CSS puns at the end. (<a href="https://twitter.com/search?q=cssbandnames">#cssbandnames</a>, anyone?)</p>
]]></content></entry><entry><id>https://dev.opera.com/blog/opera-34/</id><link type="text/html" rel="alternate" href="https://dev.opera.com/blog/opera-34/"/><title>Opera 34 released</title><published>2015-12-08T00:00:00+00:00</published><updated>2015-12-08T00:00:00+00:00</updated><author><name>Mathias Bynens</name></author><content type="html" xml:base="https://dev.opera.com/"><![CDATA[<p>Opera 34 (based on Chromium 47) for <a href="https://www.opera.com/computer">Mac, Windows, and Linux</a> and <a href="https://www.opera.com/mobile/operabrowser/android">Android</a> is out! To find out what’s new for users, see our <a href="https://www.opera.com/blogs/desktop/2015/12/opera-34-technology-help/">Desktop</a> and <a href="https://www.opera.com/blogs/mobile/2015/12/force-enable-zoom-opera-34-for-android/">Mobile</a> blogs. Here’s what it means for web developers.</p>

<h2 id="arrayprototypeincludes"><code>Array.prototype.includes</code></h2>

<p>ES2016 (previously known as “ES7”) features <a href="https://tc39.github.io/Array.prototype.includes/">a new array method named <code>includes</code></a> that determines whether an array includes a given element.</p>

<pre><code>// Good ol’ ES5:
var isIncluded = someArray.indexOf(element) != -1;
// Shiny new ES2016:
const isIncluded = someArray.includes(element);
</code></pre>

<p>Compared to the old-school <code>indexOf</code> approach, <code>includes</code> handles <code>NaN</code> more elegantly:</p>

<pre><code>var array = [NaN];
array.indexOf(NaN) != -1;
// → false
array.includes(NaN);
// → true
</code></pre>

<p><code>includes</code> is also available for <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays#Typed_array_views">typed arrays</a> such as <code>Int16Array</code> or <code>Float64Array</code>.</p>

<h2 id="es6-rest-parameters">ES6 rest parameters</h2>

<p>The <a href="https://tc39.github.io/ecma262/#sec-function-definitions">ES6 rest parameters syntax</a> allows functions to have a variable number of arguments without using the <code>arguments</code> object. Unlike <code>arguments</code>, the rest argument is a proper array, meaning array methods can be called on it directly:</p>

<pre><code>// ES5:
function sort() {
	var sortedArgs = [].sort.call(arguments);
	return sortedArgs;
}

sort('z', 'y', 'x', 'a', 'c', 'b');
// → 'a', 'b', 'c', 'x', 'y', 'z'

// ES6:
function sort(...args) {
	var sortedArgs = args.sort();
	return sortedArgs;
}

sort('z', 'y', 'x', 'a', 'c', 'b');
// → 'a', 'b', 'c', 'x', 'y', 'z'
</code></pre>

<h2 id="navigatormediadevices"><code>navigator.mediaDevices</code></h2>

<p>The new <code>navigator.mediaDevices</code> API can be used to enumerate connected media devices and to retrieve their media streams. We recommend the following:</p>

<ul>
  <li>Use <code>navigator.mediaDevices.enumerateDevices()</code> instead of the non-standard  <code>MediaStreamTrack.getSources()</code> which doesn’t support audio output devices.</li>
  <li>Use <code>navigator.mediaDevices.getUserMedia()</code> instead of <code>navigator.getUserMedia()</code>.</li>
</ul>

<p>More info can be found <a href="https://developers.google.com/web/updates/2015/10/media-devices">on the Google Developers blog</a>, and hey — <a href="https://webrtc.github.io/samples/src/content/devices/input-output/">here’s a demo</a>.</p>

<h2 id="mouseeventprototypegetmodifierstate"><code>MouseEvent.prototype.getModifierState</code></h2>

<p>We now support <a href="https://w3c.github.io/uievents/#widl-MouseEvent-getModifierState">the <code>getModifierState</code> method on <code>MouseEvent</code> instances</a>. It returns information about which modifier keys were pressed at the time the event was fired. Previously, this method was only available on <code>KeyboardEvent</code> instances. This change matches the spec and makes these APIs more consistent. <a href="https://googlechrome.github.io/samples/mouseevent-get-modifier-state/">A demo is available.</a></p>

<h2 id="requestidlecallback"><code>requestIdleCallback</code></h2>

<p><a href="https://w3c.github.io/requestidlecallback/">The new <code>requestIdleCallback</code> API</a> allows scheduling a task to run when the browser is idle. This makes it possible to perform background work on the main event loop, without impacting latency-critical events such as animation and input response.</p>

<p>For more information, check out <a href="https://developers.google.com/web/updates/2015/08/using-requestidlecallback">the excellent tutorial on the Google Developers blog</a>.</p>

<h2 id="inputdevicecapabilities"><code>InputDeviceCapabilities</code></h2>

<p><a href="https://rbyers.github.io/InputDevice/">The new <code>InputDeviceCapabilities</code> API</a> provides details about the physical device responsible for generating an event. <code>InputDeviceCapabilities.prototype.firesTouchEvents</code> returns whether this device dispatches touch events. All types of <code>UIEvent</code> now have their own <code>sourceCapabilities</code> property which returns the <code>InputDeviceCapabilities</code> associated with the physical device responsible for them.</p>

<h2 id="fetch-api-requestinitreferrer">Fetch API: <code>RequestInit.referrer</code></h2>

<p><a href="https://github.com/google/Chrome.Docs/blob/master/m47/Request_Constructor_Additions.md">This feature</a> allows requests captured by service workers to match the original referrer.</p>

<p>By default, a captured request gets the service worker’s referrer (i.e. the service worker’s script URL), but with this feature the request keeps the original referrer.</p>

<h2 id="updated-default-fetch-api-request-flags-for-service-workers">Updated default Fetch API request flags for service workers</h2>

<p>The flags of request objects that are passed to the service worker’s Fetch Event handler for navigation requests have been changed. Previously, these were the defaults for <code>mode</code>, <code>credentials</code>, and <code>redirect</code>:</p>

<pre><code>{
	'mode': 'no-cors',
	'credentials': 'same-origin'
	'redirect': 'follow'
}
</code></pre>

<p>The new defaults (matching the spec) are:</p>

<pre><code>{
	'mode': 'same-origin',
	'credentials': 'include'
	'redirect': 'manual'
}
</code></pre>

<h2 id="cache-api-matchall">Cache API: <code>matchAll</code></h2>

<p><a href="https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#cache-matchall"><code>Cache.prototype.matchAll</code></a> is now supported. It greatly simplifies bulk searching of the cache, and <a href="https://developers.google.com/web/updates/2015/09/updates-to-cache-api#cachematchall-coming-to-chrome-47">allows you to get multiple matches</a>.</p>

<h2 id="removed-features">Removed features</h2>

<p><a href="http://www.w3.org/TR/SVG11/types.html#InterfaceSVGTests">The SVG 1.1 <code>hasExtension()</code> methods</a> on <code>SVGAnimationElement</code>, <code>SVGCursorElement</code>, <code>SVGGraphicsElement</code>, <code>SVGMaskElement</code>, and <code>SVGPatternElement</code> have been <a href="http://www.w3.org/TR/SVG2/types.html#InterfaceSVGTests">removed in SVG 2</a>. Now, they’re removed from Opera and Chrome as well. Don’t worry — these methods always returned <code>false</code> and were thus of no real use anyway.</p>

<p>The same goes for <a href="http://www.w3.org/TR/SVG11/struct.html#InterfaceSVGSVGElement">a few SVG 1.1 SVG element methods</a> — <a href="http://www.w3.org/TR/SVG2/struct.html#InterfaceSVGSVGElement">they no longer exist in SVG 2</a>. So long, <code>pixelUnitToMillimeterX</code>, <code>pixelUnitToMillimeterY</code>, <code>screenPixelToMillimeterX</code>, and <code>screenPixelToMillimeterY</code>, and thanks for all the pixels! (These properties didn’t do what their names suggested in the first place — all they did was return the constant <code>0.2645833194255829</code>.)</p>

<h2 id="improved-text-selection">Improved text selection</h2>

<p>Chromium no longer highlights the gaps between content when painting selections.</p>

<figure block="figure">
	<img elem="media" src="/blog/opera-34/selection.png" width="388" alt="" />
	<figcaption elem="caption">The new, much cleaner, text selection behavior. <a href="/blog/opera-34/selection.jpg">A before/after comparison is available, too.</a></figcaption>
</figure>

<h2 id="more-extension-apis">More extension APIs</h2>

<p>Opera 34 adds support for <a href="https://developer.chrome.com/extensions/desktopCapture">the <code>chrome.desktopCapture</code> API</a>, enabling extensions with screensharing capabilities.</p>

<h2 id="whats-next">What’s next?</h2>

<p>If you’re interested in experimenting with features that are in the pipeline for future versions of Opera, we recommend following <a href="https://www.opera.com/developer">our Opera Developer stream</a>.</p>
]]></content></entry><entry><id>https://dev.opera.com/blog/progressive-web-apps-future/</id><link type="text/html" rel="alternate" href="https://dev.opera.com/blog/progressive-web-apps-future/"/><title>Progressive Web Apps Are the Future</title><published>2015-11-19T00:00:00+00:00</published><updated>2015-11-19T00:00:00+00:00</updated><author><name>Andreas Bovens, Vadim Makeev</name></author><content type="html" xml:base="https://dev.opera.com/"><![CDATA[<p>The two-day Chrome Dev Summit at Google’s headquarters in Mountain View is a wrap! Vadim and I had a great time attending the summit, and this year, I even had the pleasure to share the stage with Alex Russell (thank you!) to speak about Progressive Web Apps, and specifically web manifests, which we’ve <a href="https://dev.opera.com/articles/installable-web-apps/">recently shipped</a> support for in Opera for Android. (Since this was first published, <a href="https://blog.mozilla.org/futurereleases/2015/11/17/extending-the-webs-capabilities-in-firefox-and-beyond/">Firefox announced plans</a> to support Progressive Web Apps, too!)</p>

<p>You can check out the full video of our talk below:</p>

<figure block="figure">
	<iframe elem="media" width="560" height="315" src="https://www.youtube.com/embed/MyQ8mtR9WxI" allowfullscreen=""></iframe>
</figure>

<p>“Progressive Web Apps” is an umbrella term for modern, performant web apps that cleverly take advantage of technologies like web manifest, push notifications, service worker, responsive web design, etc. to provide a top-tier experience on mobile.</p>

<p>The latest high-profile “progressive web app” example is of course the recently launched <a href="http://stories.flipkart.com/introducing-flipkart-lite/">Flipkart Lite website</a>, which was presented in a dedicated session at the summit.</p>

<p>And if you’re into little web games, also try adding this <a href="https://andreasbovens.github.io/inbox-attack/">Inbox Attack</a> demo to your home screen: it will lock to vertical orientation, and in Opera, the game will go full screen. I’ve even added vibration events to the buttons to make it more realistic :)</p>

<p>Here at Opera, we’re super excited about Progressive Web Apps and the role they will play in bridging the gap between web and native. We’re hard at work to further add installation prompting in Opera for Android, and support for push notifications and more is in the pipeline. Stay tuned, and if you’re curious to learn more, check out the <a href="https://www.youtube.com/playlist?list=PLNYkxOF6rcICcHeQY02XLvoGL34rZFWZn">other videos from the summit</a>. We want your site to be a progressive web  as well!</p>
]]></content></entry></feed>