Dunfey · Hotel WWDC as data, est. 1983
Front desk everything
Years
Topics

2022 Safari & Web

WWDC22 · 23 min · Safari & Web

What’s new in Safari Web Extensions

Learn how you can use the latest improvements to Safari Web Extensions to create even better experiences for people browsing the web. We’ll show you how to upgrade to manifest version 3, adopt the latest APIs for Web Extensions, and sync extensions across devices.

Watch at developer.apple.com ↗

Transcript all transcripts

Code shown on screen · 18 snippets

Executing script on webpages json · at 2:43 ↗
// Manifest version 2
browser.tabs.executeScript(1, {
  frameId: 1,
  code: "document.body.style.background = 'blue';"
});
scripting.executeScript API javascript · at 3:00 ↗
// Manifest version 3
function changeBackgroundColor(color) {
  document.body.style.background = color;
};

browser.scripting.executeScript({
  target: { tabId: 1, frameIds: [ 1 ] },
  func: changeBackgroundColor,
  args: [ "blue" ]
});
tabs.executeScript file javascript · at 4:02 ↗
// Manifest version 2
browser.tabs.executeScript({ 1,
  file: "file.js"
});
scripting.executeScript API files javascript · at 4:09 ↗
// Manifest version 3
browser.scripting.executeScript({
  target: { tabId: 1 },
  files: [ "file.js", "file2.js" ]
});
scripting.insertCSS javascript · at 4:15 ↗
// Add styling
browser.scripting.insertCSS({
  target: { tabId: 1, frameIds: [ 1, 2, 3 ] },
  files: [ "file.css", "file2.css" ]
});
scripting.removeCSS javascript · at 4:21 ↗
// Remove styling
browser.scripting.removeCSS({
  target: { tabId: 1, frameIds: [ 1, 2, 3 ] },
  files: [ "file.css", "file2.css" ]
});
Manifest version 3 web_accessible_resources json · at 5:08 ↗
// Manifest version 3
"web_accessible_resources": [
    {
      "resources": [ "pie.png" ],
      "matches": [ "*://*.apple.com/*" ]
    },
    {
      "resources": [ "cookie.png" ],
      "matches": [ "*://*.webkit.org/*" ]
    }
]
Manifest version 3 action json · at 5:42 ↗
// Manifest version 3
"action": {
  "default_icon": {
    "16": "Images/icon16.png"
  },
  "default_title": "defaultTitle"
}
Manifest version 2 content_security_policy json · at 5:57 ↗
// Manifest version 2

"content_security_policy" : "script-src 'unsafe-eval' https://*apple.com 'self'"
Manifest version 3 content_security_policy json · at 6:08 ↗
// Manifest version 3

"content_security_policy" : { "extension_pages" : "script-src 'unsafe-eval' 'self'" }
Specifying a ruleset json · at 10:31 ↗
// manifest.json

"permissions": [ "declarativeNetRequest" ],

"declarative_net_request": {
  "rule_resources": [
    {
      "id": "my_ruleset",
      "enabled": true,
      "path": "rules.json"
    }
  ]
}
updateSessionRules javascript · at 11:44 ↗
// Rules that won't persist

browser.declarativeNetRequest.updateSessionRules({ addRules: [ rule ] });

// Rules that will persist

browser.declarativeNetRequest.updateDynamicRules({ addRules: [ rule ] });
externally connectable javascript · at 14:33 ↗
// In the webpage
let extensionID = "com.apple.Sea-Creator.Extension (GJT7Q2TVD9)";

browser.runtime.sendMessage(extensionID, { greeting: "Hello!" },
 function(response) {
    console.log("Received response from the background page:");
    console.log(response.farewell);
});
Message from webpage to extension (in the webpage) javascript · at 15:00 ↗
// In the webpage
let extensionID = "com.apple.Sea-Creator.Extension (GJT7Q2TVD9)";

browser.runtime.sendMessage(extensionID, { greeting: "Hello!" },
 function(response) {
    console.log("Received response from the background page:");
    console.log(response.farewell);
});
Message from webpage to extension (in the background page) swift · at 15:33 ↗
// In the background page
browser.runtime.onMessageExternal.addListener(function(message, sender, sendResponse) {
    console.log("Received message from the sender:");
    console.log(message.greeting);
    sendResponse({ farewell: "Goodbye!" });
});
Determining the correct identifier swift · at 16:17 ↗
// Determining the correct identifier

function determineExtensionID(extensionID) {
  return new Promise((resolve) => {
    try {
      browser.runtime.sendMessage(extensionID, { action: 'determineID' }, function(response) {
        if (response)
          resolve({ extensionID: extensionID, isInstalled: true, response: response });
        else 
          resolve({ extensionID: extensionID, isInstalled: false });
      });
    }
  });
};
background.js javascript · at 17:09 ↗
// background.js

browser.runtime.onMessageExternal.addListener(function(message, sender, sendResponse) {
  if (message.action == "determineID") {
    sendResponse({ "Installed" });
  }
});
Unlimited storage json · at 18:07 ↗
// manifest.json

"permissions": [ "storage", "unlimitedStorage" ]

Resources