WWDC Quick Look 💓 By SwiftGGTeam
Create Safari Web Inspector Extensions

Create Safari Web Inspector Extensions

Watch original video

Highlight

Devin Rousso from the WebKit team walks through how to create an extension for Safari’s Web Inspector. The Web Inspector extension is built on the cross-browser Web Extensions standard and the DevTools API, allowing developers to add custom tabs to Web Inspector.


Core Content

Web Inspector is Safari’s main tool for debugging web pages. It has built-in tabs such as Elements and can also cover common network, DOM, style and script debugging tasks.

The problem is that real projects often have narrower requirements. You may want to debug a JavaScript framework, or you may just want to centrally display the Open Graph metadata in a web page. Such tools are too specific to be plugged directly into a general-purpose debugger.

(00:47) Safari 16’s Web Inspector extensions give an entry. Developers can add their own tabs in Web Inspector based on cross-browser Web Extensions and DevTools API.

This session uses the Open Graph extension as an example. It reads the title, description, and image used for link previews in the web page and displays them in a custom tab in Web Inspector.

Detailed Content

Start with Safari Extension App

(02:00) Web Inspector extension and Safari Web Extension follow the same distribution method: distributed through apps in the App Store. New projects can be created using Xcode’s Safari Extension App template.

If you already have a web extension for other browsers, you can use the conversion tool included with Xcode. The command mentioned in session issafari-web-extension-converter, the input containsmanifest.jsonAfter the extension directory, it will generate an app project that can be built and run.

Concept example:

safari-web-extension-converter ./MyExtension

Key points:

  • Line 1 calls the conversion tool that comes with Xcode. -./MyExtensionPoint to the directory where the web extension already exists.
  • This directory needs to containmanifest.json, because manifest is the root configuration file of extension.

Declare devtools background page in manifest

(03:06) The structure of the Web Inspector extension is very similar to that of the ordinary Safari Web Extension, with manifests, icons, pages, scripts, and styles. The difference is that it also requires a dedicated devtools background page.

This page is responsible for the behind-the-scenes logic of the Web Inspector extension. It accesses the DevTools API and creates custom tabs that appear in the Web Inspector.

Concept example:

{
  "devtools_page": "devtools_background.html"
}

Key points:

  • Line 2 declares the devtools background page in the manifest. -devtools_background.htmlCreated when Web Inspector is opened.
  • If ordinary background pages, content scripts and popups are not used, they can be deleted from the project and manifest to reduce the extension’s running surface.

Each Web Inspector has its own instance

(03:43) The devtools background page only serves one Web Inspector window. If the user inspects multiple pages at the same time, each Web Inspector will have its own instance of the devtools background page.

This affects state management. Extensions cannot default to treating the state of a tab page as global state. Each inspected page may correspond to a separate set of devtools background page and devtools tab page.

Create Web Inspector tab

(06:54) The core task of devtools background page is to create a custom tab page in Web Inspector. The example in session uses three parameters: tab name, icon path, and tab page HTML.

Concept example:

browser.devtools.panels.create(
  browser.i18n.getMessage("extensionName"),
  "images/logo.svg",
  "devtools_tab.html"
);

Key points:

  • Line 1 calls the DevTools panels create API to create a new Web Inspector tab.
  • Line 2 passesbrowser.i18n.getMessage()Read the localized extension name to avoid hard-coding the UI copy.
  • Line 3 passes in the label icon path. session recommends using SVG vector graphics so that the icons remain clear when users zoom in and out of the interface.
  • Line 4 specifies the HTML page that is actually displayed to the user.

(07:02) Devin Rousso recommends almost always creating a tab page. The reason is straightforward: If an extension requires permissions, Safari can display the permission prompt inside Web Inspector, and users can complete authorization while seeing the location of the tool.

Execute JavaScript in the inspected page

(11:45) A common task of the Web Inspector extension is to extract data from the inspected page. Safari 16 offersdevtools.inspectedWindow.eval(), which automatically locates the page being inspected by the Web Inspector that the current extension belongs to.

Official code snippet:

// Evaluating scripts inside the inspected page

let result = await browser.devtools.inspectedWindow.eval("foo.bar()");

Key points:

  • Line 3 callsbrowser.devtools.inspectedWindow.eval().
  • The passed in string will be executed in the checked page. -awaitWaiting for the execution result to return, the extension can thenresultRender to its own devtools tab page.
  • The API will automatically associate with the page corresponding to the current Web Inspector, which is suitable for users to inspect multiple pages at the same time.

###Specify frame execution code

(12:27) By default,eval()The expression will be executed in the main frame of the page being checked. If the page has multiple subframes, the extension can be passedframeURLSpecify the target frame.

Official code snippet:

// Evaluating scripts inside a frame in the inspected page

let result = await browser.devtools.inspectedWindow.eval("foo.bar()", {
    frameURL: "http://example.com/",
});

Key points:

  • Line 3 still usesbrowser.devtools.inspectedWindow.eval().
  • The second parameter is the options object.
  • line 4frameURLSpecifies the frame in which to execute the expression.
  • This option is only required if you need to extract data from subframes; the Open Graph example only reads the main frame.

Open Graph extended data flow

(13:05) The example extension replaces the placeholder “Hello World” with real tab HTML, CSS, and JavaScript. CSS uses root levelcolor-scheme, to match the tab’s appearance to the Web Inspector’s.

(14:09) The core logic is to pass a piece of JavaScript toinspectedWindow.eval(). This script queries the DOM of the inspected page and reads common Open Graph metadata: title, description, image, and the currentdocumentready state.

Concept example:

let result = await browser.devtools.inspectedWindow.eval(`
  ({
    title: document.querySelector('meta[property="og:title"]')?.content,
    description: document.querySelector('meta[property="og:description"]')?.content,
    image: document.querySelector('meta[property="og:image"]')?.content,
    readyState: document.readyState,
  })
`);

Key points:

  • Line 1 passesinspectedWindow.eval()Send the script to the page being checked.
  • Line 3 readsog:titlemetadata.
  • Line 4 readsog:descriptionmetadata.
  • Line 5 readsog:imagemetadata.
  • Line 6document.readyStateReturned together, the extension can use this to determine whether the page is ready.
  • Got it on line 8resultCan be used to update the corresponding HTML elements in the devtools tab page.

(15:00) The example also listensdevtools.network.onNavigated. When the inspected page is navigated, the extension re-reads the Open Graph data to ensure that the information displayed in Web Inspector is the current page.

Concept example:

browser.devtools.network.onNavigated.addListener(() => {
  refreshOpenGraphMetadata();
});

Key points:

  • Line 1 registers the page navigation listener. -onNavigatedFrom the DevTools network API.
  • Line 2 rereads the data of the inspected page after navigation.
  • This writing method is suitable for users to continuously switch pages while Web Inspector remains open.

User experience details

(15:57) The session finally gives three practical suggestions.

First, create the devtools tab page from the devtools background page. This way the permission prompt will appear inside Web Inspector and the user won’t have to jump elsewhere to authorize.

Second, give priority to usingactiveTabpermission instead of requesting specific host permissions. In this way, the access scope of the Web Inspector extension is more concentrated and only acts on the currently inspected page.

Third, use CSScolor-schemeOr the web extension devtools theme APIs match the Web Inspector theme. Debugging tools are often left open for long periods of time, and visual consistency has a direct impact on readability.

Core Takeaways

1. Make a frame status check tab

  • What to do: Make a Web Inspector tab for the internal front-end framework that displays current routing, page status, and key store data.
  • Why it’s worth doing: session shows how to useinspectedWindow.eval()Read the data of the checked page and display the results in the devtools tab page.
  • How ​​to start: First create the devtools background page and then use itbrowser.devtools.panels.create()Add a tab page, pass in tab pagebrowser.devtools.inspectedWindow.eval()Call the debugging entry function in the page.

2. Make an SEO and social sharing checker

  • What: Read Open Graph, Twitter Card, canonical URL and page title, giving missing items directly in Web Inspector.
  • Why it’s worth doing: The Open Graph example has covered the path of reading meta tags, processing ready state, and rendering results.
  • How ​​to start: Fromdocument.querySelector()Read the target meta tag; if the page is not ready, try again after a short delay; used during navigationbrowser.devtools.network.onNavigatedRefresh results.

3. Make an iframe content positioning tool

  • What to do: List the sub-frames in the page and allow developers to select a frame to execute the check script.
  • Why it’s worth doing: session clearly demonstratesframeURLOption, suitable for extracting target data from multi-frame pages.
  • How ​​to start: First collect the frame URL in the main frame, and then use the URL selected by the user asbrowser.devtools.inspectedWindow.eval()offrameURLparameter.

4. Make a project standard audit tool

  • What to do: Check whether the page complies with team specifications, such as whether it has the specified data attribute, whether it loads debug tags, and whether it outputs necessary buried fields.
  • Why it’s worth doing: The Web Inspector extension is suitable for individual or team workflows. The beginning of the session specifically mentions that it can cover scenarios where general developer tools are not suitable for built-in scenarios.
  • How ​​to start: Write the specification check as a JavaScript expression that is executed on the page, and then return the results to the devtools tab page, displaying the passed and failed items in a list.
  • What’s new in Safari Web Extensions — Continue to learn about Manifest V3, Safari Web Extensions API updates, and cross-device synchronization.
  • Meet Web Push for Safari — Learn about another set of web standards-based capabilities in Safari: Push API, Notifications API, and Service Worker.
  • Meet Safari Web Extensions — Understand the basis of this session from the creation, conversion, and distribution process of Safari Web Extension.
  • Meet CKTool JS — Refer to another WWDC 2022 session on using JavaScript as a developer automation tool.

Comments

GitHub Issues · utterances