WebExtensions

Browser Extensions

  • Chrome, Opera, (Edge)
  • Firefox
    • Overlay (restart required)
    • Bootstrapped
    • SDK
    • WebExtensions
  • Others?

Agenda

  • File structure
  • JavaScript APIs
  • Future

FileS Anatomy

  • Extension metadata
  • Permissions
  • Static content
    • CSP
    • Content scripts
    • UI features
    • web-acessible resources

manifest.json

{
    "manifest_version": 2,
    "name": "Hello World",
    "version": "1.0.0",
    "description": "Not sure yet, but will be useful.",
    "icons": {
        "48": "icons/icon-48.png"
    },
    "content_scripts": [
        {
            "matches": ["*://*.example.com/*"],
            "js": ["content.js"]
        }
    ],
    "applications": {
        "gecko": {
            "id": "borderify@example.com",
            "strict_min_version": "48.0"
        }
    },
    "options_ui": {
        "page": "settings.html"
    },
    "permissions": [
        "cookies",
        "activeTab"
    ]
}

Packaging

  • Zipped up
  • manifest.json file in the ZIP root
  • Renamed to .XPI once signed for Firefox
  • Renamed to .CRX once signed for Chrome

CC-BY-NC-SA: ShockWatchWiki

  • Load unsigned extensions
    • Raw extension folder
    • Packaged
  • Debug running extension's background page
  • Can reload local extensions when they change
  • Command-line tool
  • Signing
  • Installing temporarily
  • Linting

Webpage

  • All the DOM APIs
    • Except for alert()

  • Special globals for extension specific things
  • Background page just for the extension
  • Content-scripts get a subset of APIs

chrome Namespace

  • Promisified APIs
  • Firefox-specific API expansions

Events

browser.api.onEvent.addListener((...eventDetails) => {
    // handle event
}, {
    // filter options
    url: [ "https://example.com" ]
});

Messaging

// Send a message and listen for a reply
browser.runtime.sendMessage("WebExtensions are ok.", (response) => {
    console.log(response);
});

// Somewhere else:
const listener = (message, sender, reply) => {
    if(message == "WebExtensions are ok.") {
        reply("WebExtensions rock!");
    }
};

browser.runtime.onMessage.addListener(listener);

console.log(browser.runtime.onMessage.hasListener(listener));

// Console
true
"WebExtensions rock!"

Callbacks

const callback = (result) => {
    if (browser.extension.lastError) {
        console.error(browser.extension.lastError);
    } else {
        console.log(result);
    }
};

browser.cookies.set({
    url: "https://developer.mozilla.org/"
}, logCookie);

// or thanks to promises

browser.cookies.set({
    url: "https://developer.mozilla.org/"
}).then((result) => {
    console.log(result);
}, (error) => {
    console.error(error);
});

Future

Potential APIs

  • logins
  • webRTC controls
  • proxy
  • devtool APIs
  • API experiments

Extension

WebExtension

Old Extension

Cross Browser Standard

Firefox

Opera

Edge

Discussion

Image sources