{"id":8686,"date":"2019-06-13T08:00:43","date_gmt":"2019-06-13T15:00:43","guid":{"rendered":"http:\/\/blog.mozilla.org\/addons\/?p=8686"},"modified":"2019-06-12T12:02:02","modified_gmt":"2019-06-12T19:02:02","slug":"extensions-in-firefox-68","status":"publish","type":"post","link":"https:\/\/blog.mozilla.org\/addons\/2019\/06\/13\/extensions-in-firefox-68\/","title":{"rendered":"Extensions in Firefox 68"},"content":{"rendered":"<p>In Firefox 68, we are introducing a new API and some enhancements to webRequest and private browsing. We&#8217;ve also fixed a few issues in order to improve compatibility and resolve issues developers were having with Firefox.<\/p>\n<h1>Captivating Add-ons<\/h1>\n<p>At airports and caf\u00e9s you may have seen Firefox asking you to log in to the network before you can access the internet. In Firefox 68, you can make use of this information in an extension. The new captive portal API will assist you in making sure your add-on works gracefully when locked behind a captive portal.<\/p>\n<p>For example, you could hold off your requests until network access is available again. If you have been using other techniques for detecting captive portals, we encourage you to switch to this API so your extension uses the same logic as Firefox.<\/p>\n<p>Here is an example of how to use this API:<\/p>\n<pre style=\"color: #000000; background: #eee;\"><span style=\"color: #808030;\">(<\/span>async <span style=\"color: #800000; font-weight: bold;\">function<\/span><span style=\"color: #808030;\">(<\/span><span style=\"color: #808030;\">)<\/span> <span style=\"color: #800080;\">{<\/span>\r\n  <span style=\"color: #696969;\">\/\/ The current portal state, one of `unknown`, `not_captive`, `unlocked_portal`, `locked_portal`.<\/span>\r\n  <span style=\"color: #800000; font-weight: bold;\">let<\/span> state <span style=\"color: #808030;\">=<\/span> await browser<span style=\"color: #808030;\">.<\/span>captivePortal<span style=\"color: #808030;\">.<\/span>getState<span style=\"color: #808030;\">(<\/span><span style=\"color: #808030;\">)<\/span><span style=\"color: #800080;\">;<\/span>\r\n\r\n  <span style=\"color: #696969;\">\/\/ Get the duration since the captive portal state was last checked<\/span>\r\n  <span style=\"color: #800000; font-weight: bold;\">let<\/span> lastChecked <span style=\"color: #808030;\">=<\/span> await browser<span style=\"color: #808030;\">.<\/span>captivePortal<span style=\"color: #808030;\">.<\/span>getLastChecked<span style=\"color: #808030;\">(<\/span><span style=\"color: #808030;\">)<\/span><span style=\"color: #800080;\">;<\/span>\r\n\r\n  console<span style=\"color: #808030;\">.<\/span><span style=\"color: #800000; font-weight: bold;\">log<\/span><span style=\"color: #808030;\">(<\/span><span style=\"color: #800000;\">`<\/span><span style=\"color: #0000e6;\">The captive portal has been <\/span><span style=\"color: #800000;\">${<\/span><span style=\"color: #797997;\">state<\/span><span style=\"color: #800000;\">}<\/span><span style=\"color: #0000e6;\"> since at least <\/span><span style=\"color: #800000;\">${<\/span><span style=\"color: #797997;\">lastChecked<\/span><span style=\"color: #800000;\">}<\/span><span style=\"color: #0000e6;\"> milliseconds<\/span><span style=\"color: #800000;\">`<\/span><span style=\"color: #808030;\">)<\/span><span style=\"color: #800080;\">;<\/span>\r\n\r\n  browser<span style=\"color: #808030;\">.<\/span>captivePortal<span style=\"color: #808030;\">.<\/span>onStateChanged<span style=\"color: #808030;\">.<\/span>addListener<span style=\"color: #808030;\">(<\/span><span style=\"color: #808030;\">(<\/span>details<span style=\"color: #808030;\">)<\/span> <span style=\"color: #808030;\">=<\/span><span style=\"color: #808030;\">&gt;<\/span> <span style=\"color: #800080;\">{<\/span>\r\n    console<span style=\"color: #808030;\">.<\/span><span style=\"color: #800000; font-weight: bold;\">log<\/span><span style=\"color: #808030;\">(<\/span><span style=\"color: #800000;\">\"<\/span><span style=\"color: #0000e6;\">Captive portal state is: <\/span><span style=\"color: #800000;\">\"<\/span> <span style=\"color: #808030;\">+<\/span> details<span style=\"color: #808030;\">.<\/span>state<span style=\"color: #808030;\">)<\/span><span style=\"color: #800080;\">;<\/span>\r\n  <span style=\"color: #800080;\">}<\/span><span style=\"color: #808030;\">)<\/span><span style=\"color: #800080;\">;<\/span>\r\n\r\n  browser<span style=\"color: #808030;\">.<\/span>captivePortal<span style=\"color: #808030;\">.<\/span>onConnectivityAvailable<span style=\"color: #808030;\">.<\/span>addListener<span style=\"color: #808030;\">(<\/span><span style=\"color: #808030;\">(<\/span>status<span style=\"color: #808030;\">)<\/span> <span style=\"color: #808030;\">=<\/span><span style=\"color: #808030;\">&gt;<\/span> <span style=\"color: #800080;\">{<\/span>\r\n    <span style=\"color: #696969;\">\/\/ status can be \"captive\" in an (unlocked) captive portal, or \"clear\" if we are in the open<\/span>\r\n    console<span style=\"color: #808030;\">.<\/span><span style=\"color: #800000; font-weight: bold;\">log<\/span><span style=\"color: #808030;\">(<\/span><span style=\"color: #800000;\">\"<\/span><span style=\"color: #0000e6;\">Internet connectivity is available: <\/span><span style=\"color: #800000;\">\"<\/span> <span style=\"color: #808030;\">+<\/span> status<span style=\"color: #808030;\">)<\/span><span style=\"color: #800080;\">;<\/span>\r\n  <span style=\"color: #800080;\">}<\/span><span style=\"color: #808030;\">)<\/span><span style=\"color: #800080;\">;<\/span>\r\n<span style=\"color: #800080;\">}<\/span><span style=\"color: #808030;\">)<\/span><span style=\"color: #808030;\">(<\/span><span style=\"color: #808030;\">)<\/span><span style=\"color: #800080;\">;<\/span>\r\n<\/pre>\n<p>Note: if you use this API, be sure to add the captivePortal permission to your manifest.<\/p>\n<h1>Private and contained<\/h1>\n<p>We\u2019ve made a few additions to the <a href=\"https:\/\/developer.mozilla.org\/docs\/Mozilla\/Add-ons\/WebExtensions\/API\/webRequest\" target=\"_blank\" rel=\"noopener noreferrer\">webRequest API<\/a> to better support private browsing mode. You can now limit your webRequests to only include requests from private browsing mode. If instead you are interested in both types of requests it is now possible to differentiate them in the webRequest listener.<\/p>\n<p>To improve the integration of containers, we\u2019ve also added the container ID (cookieStoreId) to the webRequest listener.<\/p>\n<h1>Proxy new and proxy old<\/h1>\n<p>The two additional fields mentioned in the previous section are also available in the details object passed to the <a href=\"https:\/\/developer.mozilla.org\/docs\/Mozilla\/Add-ons\/WebExtensions\/API\/proxy\/onRequest\" target=\"_blank\" rel=\"noopener noreferrer\">proxy.onRequest<\/a> listener.<\/p>\n<p>At the same time, we\u2019d like to make you aware that we are deprecating the <code>proxy.register<\/code>, <code>proxy.unregister<\/code> and <code>proxy.onProxyError<\/code> APIs. As an alternative, you can use the <a href=\"https:\/\/developer.mozilla.org\/docs\/Mozilla\/Add-ons\/WebExtensions\/API\/proxy\/onRequest\" target=\"_blank\" rel=\"noopener noreferrer\">proxy.onRequest<\/a> API to determine how requests will be handled, and <a href=\"https:\/\/developer.mozilla.org\/docs\/Mozilla\/Add-ons\/WebExtensions\/API\/proxy\/onError\" target=\"_blank\" rel=\"noopener noreferrer\">proxy.onError<\/a> to handle failures. If your extension is using these APIs you will see a warning in the console. These APIs will ultimately be removed in Firefox 71, to be released on December 10th, 2019.<\/p>\n<h1>Timing is everything<\/h1>\n<p>We\u2019ve changed the timing of <a href=\"https:\/\/developer.mozilla.org\/docs\/Mozilla\/Add-ons\/WebExtensions\/API\/tabs\/duplicate\" target=\"_blank\" rel=\"noopener noreferrer\">tabs.duplicate<\/a> for better compatibility with Chrome. The promise is now resolved immediately, before the duplicated tab finished loading. If you have been relying on this promise for a completed duplicated tab in Firefox, please adjust your code and make use of the <a href=\"https:\/\/developer.mozilla.org\/docs\/Mozilla\/Add-ons\/WebExtensions\/API\/tabs\/onUpdated\" target=\"_blank\" rel=\"noopener noreferrer\">tabs.onUpdated<\/a> listener.<\/p>\n<h1>Miscellaneous<\/h1>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li>Since extensions cannot add bookmarks to the root folder, we\u2019ve improved the error message you get when you try.<\/li>\n<li>If you&#8217;ve been trying to remove indexedDB data via <code>browser.browsingData.remove({}, { indexedDB: true });<\/code> and it failed in some cases, we\u2019ve fixed this on our end now.<\/li>\n<li>Removing cookies for IPv6 addresses has been fixed.<\/li>\n<li>Fixes an issue when setting cookies with an IP address in the domain field, along with the url field being set.<\/li>\n<li>Hard-to-debug performance issues using webRequest.onBeforeRequest with requestBody during large uploads have been solved.<\/li>\n<li>An issue with <a href=\"https:\/\/developer.mozilla.org\/docs\/Mozilla\/Add-ons\/WebExtensions\/API\/identity\/launchWebAuthFlow\" target=\"_blank\" rel=\"noopener noreferrer\">identity.launchWebAuthFlow<\/a> hanging after authentication has been resolved.<\/li>\n<li><a href=\"https:\/\/developer.mozilla.org\/docs\/Mozilla\/Add-ons\/WebExtensions\/API\/storage\/onChanged\" target=\"_blank\" rel=\"noopener noreferrer\">storage.onChanged<\/a> is now fired when values are removed.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h1>Thank You<\/h1>\n<p>We&#8217;ve had a great amount of support from the community. I&#8217;d like to thank everyone who has taken part, but especially our volunteer contributors Jan Henning, Myeongjun Go, <a href=\"https:\/\/mozillians.org\/u\/Oriol\/\" target=\"_blank\" rel=\"noopener noreferrer\">Oriol Brufau<\/a>, <a href=\"https:\/\/mozillians.org\/u\/ariasuni\/\" target=\"_blank\" rel=\"noopener noreferrer\">M\u00e9lanie Chauvel<\/a>, violet.bugreport and <a href=\"https:\/\/mozillians.org\/fr\/u\/Piro\/\" target=\"_blank\" rel=\"noopener noreferrer\">Piro<\/a>. If you are interested in contributing to the WebExtensions ecosystem, please take a look at our <a href=\"https:\/\/wiki.mozilla.org\/Add-ons\/Contribute\" target=\"_blank\" rel=\"noopener noreferrer\">wiki<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In Firefox 68, we are introducing a new API and some enhancements to webRequest and private browsing. We&#8217;ve also fixed a few issues in order to improve compatibility and resolve &hellip; <a class=\"go\" href=\"https:\/\/blog.mozilla.org\/addons\/2019\/06\/13\/extensions-in-firefox-68\/\">Read more<\/a><\/p>\n","protected":false},"author":333,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[44,227,278886],"tags":[278873,304462,278875,278871],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v22.5 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Extensions in Firefox 68 - Mozilla Add-ons Community Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/blog.mozilla.org\/addons\/2019\/06\/13\/extensions-in-firefox-68\/\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Philipp Kewisch\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"3 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/blog.mozilla.org\/addons\/2019\/06\/13\/extensions-in-firefox-68\/\",\"url\":\"https:\/\/blog.mozilla.org\/addons\/2019\/06\/13\/extensions-in-firefox-68\/\",\"name\":\"Extensions in Firefox 68 - Mozilla Add-ons Community Blog\",\"isPartOf\":{\"@id\":\"https:\/\/blog.mozilla.org\/addons\/#website\"},\"datePublished\":\"2019-06-13T15:00:43+00:00\",\"dateModified\":\"2019-06-12T19:02:02+00:00\",\"author\":{\"@id\":\"https:\/\/blog.mozilla.org\/addons\/#\/schema\/person\/86ecef4a5de728e6d3ffe72a25077a94\"},\"breadcrumb\":{\"@id\":\"https:\/\/blog.mozilla.org\/addons\/2019\/06\/13\/extensions-in-firefox-68\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/blog.mozilla.org\/addons\/2019\/06\/13\/extensions-in-firefox-68\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/blog.mozilla.org\/addons\/2019\/06\/13\/extensions-in-firefox-68\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/blog.mozilla.org\/addons\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Extensions in Firefox 68\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/blog.mozilla.org\/addons\/#website\",\"url\":\"https:\/\/blog.mozilla.org\/addons\/\",\"name\":\"Mozilla Add-ons Community Blog\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/blog.mozilla.org\/addons\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/blog.mozilla.org\/addons\/#\/schema\/person\/86ecef4a5de728e6d3ffe72a25077a94\",\"name\":\"Philipp Kewisch\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/blog.mozilla.org\/addons\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/c2d92d64a4b77306c45df1c9be647621?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/c2d92d64a4b77306c45df1c9be647621?s=96&d=mm&r=g\",\"caption\":\"Philipp Kewisch\"},\"description\":\"Twitter: @pkewisch\",\"sameAs\":[\"https:\/\/twitter.com\/pkewisch\",\"https:\/\/x.com\/pkewisch\"],\"url\":\"https:\/\/blog.mozilla.org\/addons\/author\/calendar\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Extensions in Firefox 68 - Mozilla Add-ons Community Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/blog.mozilla.org\/addons\/2019\/06\/13\/extensions-in-firefox-68\/","twitter_misc":{"Written by":"Philipp Kewisch","Est. reading time":"3 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/blog.mozilla.org\/addons\/2019\/06\/13\/extensions-in-firefox-68\/","url":"https:\/\/blog.mozilla.org\/addons\/2019\/06\/13\/extensions-in-firefox-68\/","name":"Extensions in Firefox 68 - Mozilla Add-ons Community Blog","isPartOf":{"@id":"https:\/\/blog.mozilla.org\/addons\/#website"},"datePublished":"2019-06-13T15:00:43+00:00","dateModified":"2019-06-12T19:02:02+00:00","author":{"@id":"https:\/\/blog.mozilla.org\/addons\/#\/schema\/person\/86ecef4a5de728e6d3ffe72a25077a94"},"breadcrumb":{"@id":"https:\/\/blog.mozilla.org\/addons\/2019\/06\/13\/extensions-in-firefox-68\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/blog.mozilla.org\/addons\/2019\/06\/13\/extensions-in-firefox-68\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/blog.mozilla.org\/addons\/2019\/06\/13\/extensions-in-firefox-68\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/blog.mozilla.org\/addons\/"},{"@type":"ListItem","position":2,"name":"Extensions in Firefox 68"}]},{"@type":"WebSite","@id":"https:\/\/blog.mozilla.org\/addons\/#website","url":"https:\/\/blog.mozilla.org\/addons\/","name":"Mozilla Add-ons Community Blog","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/blog.mozilla.org\/addons\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/blog.mozilla.org\/addons\/#\/schema\/person\/86ecef4a5de728e6d3ffe72a25077a94","name":"Philipp Kewisch","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/blog.mozilla.org\/addons\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/c2d92d64a4b77306c45df1c9be647621?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/c2d92d64a4b77306c45df1c9be647621?s=96&d=mm&r=g","caption":"Philipp Kewisch"},"description":"Twitter: @pkewisch","sameAs":["https:\/\/twitter.com\/pkewisch","https:\/\/x.com\/pkewisch"],"url":"https:\/\/blog.mozilla.org\/addons\/author\/calendar\/"}]}},"_links":{"self":[{"href":"https:\/\/blog.mozilla.org\/addons\/wp-json\/wp\/v2\/posts\/8686"}],"collection":[{"href":"https:\/\/blog.mozilla.org\/addons\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.mozilla.org\/addons\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.mozilla.org\/addons\/wp-json\/wp\/v2\/users\/333"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.mozilla.org\/addons\/wp-json\/wp\/v2\/comments?post=8686"}],"version-history":[{"count":0,"href":"https:\/\/blog.mozilla.org\/addons\/wp-json\/wp\/v2\/posts\/8686\/revisions"}],"wp:attachment":[{"href":"https:\/\/blog.mozilla.org\/addons\/wp-json\/wp\/v2\/media?parent=8686"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.mozilla.org\/addons\/wp-json\/wp\/v2\/categories?post=8686"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.mozilla.org\/addons\/wp-json\/wp\/v2\/tags?post=8686"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}