November 30, 2022

Release Notes for Safari Technology Preview 159

Surfin’ Safari

Safari Technology Preview Release 159 is now available for download for macOS Monterey 12.3 or later and macOS Ventura. If you already have Safari Technology Preview installed, you can update in the Software Update pane of System Preferences on macOS Monterey, or System Settings under General → Software Update on macOS Ventura.

This release includes WebKit changes between: 256139@main…256265@main

Note: Shared Tab Groups and syncing for Tab Groups, Website Settings, and Web Extensions are not enabled in this release.



  • Changed to allow variables with the same name as the class in its static block (256311@main)


  • Fixed floating boxes overlapping their margin boxes (256183@main)
  • Fixed rendering artifacts when presenting a fullscreen video (256251@main)

November 30, 2022 09:47 PM

November 16, 2022

Release Notes for Safari Technology Preview 158

Surfin’ Safari

Safari Technology Preview Release 158 is now available for download for macOS Monterey 12.3 or later and macOS Ventura. If you already have Safari Technology Preview installed, you can update in the Software Update pane of System Preferences on macOS Monterey, or System Settings under General → Software Update on macOS Ventura.

This release includes WebKit changes between: 255892@main…256138@main

Note: Shared Tab Groups and syncing for Tab Groups, Website Settings, and Web Extensions are not enabled in this release.

Web Inspector

  • Added support for editing @-rules in the Styles sidebar of the Elements tab (256043@main)


  • Implemented CSS font-size-adjust property (255927@main)
  • Implemented font-variant-alternates functions, along with matching @font-feature-values at-rule (256002@main, 255677@main)
  • Implemented CSS property contain-intrinsic-size behind a flag (255971@main)
  • Changed to allow calc() with combined percentages and lengths for line-height (256095@main)
  • Changed to always use percentages for computed values of font-stretch, never keywords (256094@main)
  • Fixed font shorthand to not reject values that happen to have CSS-wide keywords as non-first identifiers in a font family name (255894@main)
  • Fixed font-style descriptor for @font-face to accept angle ranges in reverse order (255893@main)
  • Fixed font-style: oblique with calc() to allow out-of-range angles and clamp them for computed style (255925@main)
  • Fixed computed value CSS gradients to serialize colors in their computed form (256073@main)
  • Fixed text-shadow positioning on text with text-combine-upright (255892@main)
  • Fixed line-height to allow calc() with combined percentages and lengths (256095@main)


  • Changed to check for overflow content after trimming trailing content (256045@main)
  • Fixed a table cell overflowing its contents when it has inline children that change the writing-mode (255919@main)
  • Fixed elements with negative margins to not avoid floats when appropriate (256132@main)


  • Enabled AVIF image decoding for macOS Monterey and macOS Big Sur (255984@main)
  • Fixed “A MediaStreamTrack ended due to a capture failure” when selecting bluetooth headphones as audio input device (256091@main)


  • Accelerated Array.prototype.slice on DirectArguments (256027@main)
  • Accelerated Array.prototype.concat when applied to the self array (256040@main)


  • Enabled WebCodecs by default (256060@main)
  • Added WebCodecsVideoFrame initial support for serialisation and transfer (255949@main)
  • Changed to schedule dequeue event when the encoder queue size decreases (255962@main)
  • Changed to set VPx decoder frame type based on given parameter (255963@main)
  • Changed to prevent garbage collecting an encoder or decoder with content being processed (256007@main)
  • Exposed decoded video frames colorSpace (256068@main)
  • Exposed encoder color space in decoder config (256052@main)
  • Flushed before reconfiguring the encoder (255957@main)
  • Implemented pixel buffer conversion for video frames produced by libwebrtc VPX decoders (255958@main)


  • Aligned fetch header handling with fetch specification (256003@main)
  • Changed calling CSSStyleValue.parseAll() on a list-valued CSS property to split its value list (256070@main)
  • Changed CSSStyleValue.parse() to throw when passed an empty string as custom property value (256011@main)
  • Changed creating a shared worker connection to retry without providing a specific webprocess (255968@main)
  • Implemented input validation for CSSRGB constructor and setters (256024@main)
  • Optimized postMessage between two MessageChannel ports living in the same process (255948@main)

November 16, 2022 09:33 PM

November 07, 2022

Release Notes for Safari Technology Preview 157

Surfin’ Safari

Safari Technology Preview Release 157 is now available for download for macOS Monterey 12.3 or later and macOS Ventura. If you already have Safari Technology Preview installed, you can update in the Software Update pane of System Preferences on macOS Monterey, or System Settings under General → Software Update on macOS Ventura.

This release includes WebKit changes between: 255077@main…255891@main

Note: Shared Tab Groups and syncing for Tab Groups, Website Settings, and Web Extensions are not enabled in this release.

Web Inspector

  • Elements Tab
    • Added support for event breakpoints to be case-insensitive and regular expression matching (255196@main)
    • Fixed disabling inline breakpoints unexpectedly removing them (255292@main)
    • Fixed inline breakpoints appearing for minified resources before they are pretty-printed (255200@main)


  • Added support for font-synthesis longhand properties (255171@main)
  • Added support for last baseline alignment for CSS Grid (255455@main)
  • Added support for last baseline alignment for Flexbox containers (255383@main)
  • Added support for lh and rlh units (255540@main)
  • Added margin when computing the baseline position for tables (255357@main)
  • Changed outline to follow border-radius (255314@main, 255300@main)
  • Changed to treat rem and rlh as absolute units for font size (255594@main)
  • Changed to allow the font-variant-east-asian shorthand property in any position (255134@main)
  • Changed to only preserve a scroll snap target if there are targets for both axes (255493@main)
  • Changed CSS Keyframe name handling to not allow CSS-wide keywords (255640@main)
  • Changed to use min-intrinsic size to compute min-content size for non-replaced flex items (255858@main)
  • Fixed the display property value of a computed style to be "none" instead of "inline" for an <audio> element without controls (255528@main)
  • Fixed font-style: oblique to allow angles equal to 90deg or -90deg (255875@main)
  • Fixed font-weight to be clamped to 1 as a minimum (255873@main)
  • Fixed the left-aligned contentEditable caret instead of centered when the :before pseudo-element is used (255333@main)
  • Fixed CSS 3D transform by matrix3d() with translations to take page zoom into account (255416@main)
  • Unprefixed font-size: -webkit-xxx-large (255602@main)
  • Updated @font-palette-values override-colors order (255604@main)


  • Fixed flickering while scrolling when the keyboard scrolling spring damping animation doesn’t finish (255306@main, 255099@main)


  • Added support for class static initialization blocks (255173@main)
  • Changed the default style of Intl.DurationFormat from “digital” to “short” (255255@main)
  • Fixed Intl.NumberFormat ignoring maximumFractionDigits with compact notation for currency and decimal (255691@main)
  • Improved Object.entries runtime function performance (255470@main)
  • Updated useGrouping handling for Intl.NumberFormat (255275@main)


  • Added support for WebCodecs encoder bitrate related parameters (255476@main)
  • Added support for WebCodecs video encoder flush (255785@main)
  • Added support for WebCodecs Validate VideoFrameInit algorithm (255786@main)
  • Added support for WebCodecs VideoFrame allocationSize (255313@main)
  • Added support for WebCodecsVideoEncoder (255316@main, 255262@main)
  • Added support for WebCodecsVideoDecoder (255215@main, 255138@main)
  • Added support for WebCodecs VideoFrame copyTo (255429@main)
  • Added support for WebCodecsVideoDecoder with VPx backend (255138@main)
  • Added support for AVC H.264 WebCodecsVideoEncoder and WebCodecsVideoDecoder (255430@main, 255422@main)
  • Added support for GPU-based WebCodecsVideoDecoder flush (255388@main)
  • Added cropping support to WebCodecsVideoFrame copyTo (255716@main)
  • Added initial implementation to VideoFrame (255259@main)
  • Added support for RGBX and BGRX pixel formats (255390@main)
  • Added WebCodecs VideoFrame support for createImageBitmap (255776@main)
  • Ensured VPx WebCodecs encoders and decoders are created asynchronously (255478@main)
  • Ensured the bitrate and framerate are set for VPx encoders (255666@main)
  • Fixed canvas to be able to draw a WebCodecsVideoFrame (255720@main)
  • Validated width, height, x and y for I420 and NV12 video frames (255489@main)


  • Added support for CSSNumericValue.toSum() (255679@main)
  • Added support for CSSNumericValue.parse() (255791@main)
  • Added support for CSSTransformValue.toMatrix (255299@main)
  • Added support for EXT_provoking_vertex draft extension (255261@main)
  • Added support for the Sec-Fetch-Site header (255810@main)
  • Added support for cancel event support on <input type=file> (255394@main)
  • Added support for referrerpolicy in link headers (255354@main)
  • Added a log channel for IntersectionObserver (255197@main)
  • Added the class FilterTargetSwitcher (255802@main)
  • Changed to fire an error event when CSP blocks inline stylesheets (255744@main)
  • Changed to fire an error event when link preload fails synchronously (255740@main)
  • Fixed CSSPerspective.toMatrix() to throw an exception if its length is not compatible with a px unit (255876@main)
  • Fixed CSSTransformComponent.toMatrix() to flatten to two-dimenions if necessary (255290@main)
  • Fixed headers iteration to not happen on the cached headers list (255639@main)
  • Made onpointerlockchange and onpointerlockerror enumerable (255153@main)
  • Updated ResizeObserver and IntersectionObserver timing to match other browsers (255132@main)


  • Accept image/jpg for compatibility (255268@main)
  • Changed to enforce Low Power Mode and Optimize Video Streaming setting by tone mapping HDR video to SDR (255127@main)
  • Changed sizing of video element to use width and height HTML attributes to calculate a natural aspect ratio before the video file loads (255743@main)
  • Changed to switch to an alternate <source> element for AirPlay when necessary (255624@main)
  • Fixed the display able to go to sleep when the camera is on (255636@main)

Web Animations

  • Fixed Animation.commitStyles() triggering a mutation even when the styles are unchanged (255129@main)
  • Fixed updating timing to invalidate the effect (255863@main)
  • Updated to account for iterationComposite when blending (255834@main)


  • Added the display of a thumbnail of selected file for <input type=file> on macOS (255355@main)


  • Fixed accessibility for the <meter> and <progress> elements when -webkit-appearance: none or appearance: none is set (255836@main)
  • Fixed accessibility to not limit navigation when focus is explicitly moved outside of a modal (255665@main)
  • Fixed a bug causing VoiceOver to double-read list markers and not output braille for list items (255276@main)


  • Fixed Cross-Origin-Embedder-Policy incorrectly blocking scripts on a cache hit (255302@main)


  • Capped cookie lifetimes to 7 days for responses from third-party IP addresses (255849@main)
  • Omitted document.referrer for third-party requests while in ephemeral mode (255649@main)

Safari Web Extensions

  • Added support for the modifyHeaders action type in Declarative Net Request rules
  • Fixed Declarative Net Request rules not loading after an extension was turned off and then back on

November 07, 2022 09:42 PM

October 24, 2022

WebKit Features in Safari 16.1

Surfin’ Safari

Today, Safari 16 arrives for macOS Ventura and iPadOS 16. Numbered Safari 16.1, this release is also available for iOS 16, macOS Monterey, and macOS Big Sur.

To update to Safari 16.1 on macOS Monterey or macOS Big Sur, go to System Preferences → Software Update → More info. To update your Mac to macOS Ventura, go to System Settings → Software Update. To update to Safari 16.1 on iPad and iPhone, update iPadOS 16 and iOS 16 in Settings → General → Software Update.

Features that shipped in September’s Safari 16.0 include Container Queries, Subgrid, Web Inspector Extensions, Flexbox Inspector, Offset Path, Overscroll Behavior, Shared Workers, Shadow Realms, resolution media query, :has(:target), text-align-last, animation-composition, discrete animation, accessibility improvements for display: contents, improved VoiceOver performance, additional Apple Pay support, new Web Extension APIs, Manifest version 3 support, and much more. Safari 16.1 brings all of these features to iPadOS 16 and macOS Ventura.

Now let’s look at the new features and fixes arriving with Safari 16.1.

Web Push for macOS Ventura

a push notification on macOS

Safari 16.1 for macOS Ventura brings support for Web Push to Safari. Websites and web apps can now remotely send notifications using the same standards supported in other browsers — Push API and Notifications API, along with Service Workers — and deliver those notifications even when Safari isn’t running.

In Safari, users of your website or web app opt into notifications by first indicating interest through a user gesture — such as clicking a button. Then they’ll be prompted to give permission for your site or app to send notifications. Users can view and manage notifications in Notifications Center. And they can customize styles and turn notifications off per website in Notifications Settings.

If you’ve already implemented Web Push for your web app or website using industry best practices, it will automatically work in Safari. You do not need to be an Apple Developer Program member. However, if you’ve excluded Safari through browser detection, you’ll need to switch to feature detection to get it working. Web Push in Safari uses the same Apple Push Notification service that powers native push on all Apple devices. If you tightly manage push endpoints on your server, be sure to allow URLs from any subdomain of

To learn more, watch the WWDC session Meet Web Push for Safari (15 min video), or read the article Meet Web Push on

Animated AVIF

Safari 16.0 brought support for AVIF still images to iOS 16. Safari 16.1 adds support for AVIF animated image sequences. Now both still and moving images saved in the AVIF format are supported on iOS 16, iPadOS 16, and macOS Ventura.


In September, iOS 16 introduced passkeys. Now with Safari 16.1, passkeys are supported everywhere Safari 16 is supported — including iPadOS 16, macOS Monterey, macOS Big Sur, and macOS Ventura, as well as iOS 16. Passkeys provide users with an incredibly easy way to log in, while delivering a profound increase in security.

The technology that makes passkeys possible is defined in open standards from the FIDO Alliance and the W3C, including the WebAuthn standard, which already has widespread support in browsers. Passkeys are an industry-wide effort, and “passkeys” is a common noun, to be used by anyone. You can offer passkeys alongside your existing authentication options. First, teach your backend to store public keys and issue authentication challenges. Then, on your website or web app, offer passkeys to users by adopting the APIs for creating new passkeys and allowing users to sign in with their passkey. If your website or web app already supports using a platform authenticator with WebAuthn, there are a few things to note as you add support for passkeys. Make sure you aren’t limiting signing in to the device that saved the passkey; that is, don’t use a cookie to “remember” that a user set up a key on a particular device. Also, make sure the username fields in your existing sign-in forms are compatible with AutoFill by adopting “conditional mediation”. Finally, start to refer to passkeys, and treat them as a primary way to sign in.

To learn more, watch the WWDC22 session, Meet Passkeys (27 min video) or read Supporting passkeys.

New viewport sizes on iPadOS

Three Safari browser windows, layered over one another, floating in space. One tall and very narrow. One medium and square. One bigger and wide.

iPadOS 16 introduces an entirely new multitasking experience with Stage Manager. This means browser windows on iPadOS can be resized to many different viewport sizes and aspect ratios. Responsive web design techniques, including the use of CSS media queries and container queries, are key. There’s never been a single “tablet size” for layout, and now that’s more true than ever.

Hover on iPadOS with Apple Pencil

The new iPad Pro supports hover with Apple Pencil. In web browsers, users see hover states for links, animations, and more. Hover on iPadOS is yet another example of how structuring code using feature detection, instead of device or UA detection, helps future-proof websites and web apps.

Scroll to Text Fragment

Safari 16.1 adds support for Scroll to Text Fragment, making it possible to include a text directive for finding a text fragment as part of a URL. When a user navigates to a URL that includes such a directive, the browser scrolls the text fragment into view and marks it with a persistent highlight.

Screen capture improvements

screenshot of dialog message asking Allow to share your screen?

On macOS Ventura, Safari 16.1 adds support for capturing a specific Safari window with getDisplayMedia(). Calling getDisplayMedia in response to a user action will show the user a prompt asking for permission to allow the sharing of their screen or a specific window of an application, including Safari windows. The MediaStream provided by getDisplayMedia contains a video stream of the screen or window that can be recorded, or used as part of a WebRTC session.

And More

Safari 16.1 adds support for web-to-App Store advertising with SKAdNetwork. It also adds support for WebDriver Wheel input source and actions. Safari Web Inspector adds support for the color picker to pick a color from any pixel on the screen.

Fixes and Polish

Safari 16.1 also contains bug fixes and feature polish. Many of these fixes improve the Interop 2022 score for Safari. The test pass rate for Safari 16.1 is 93.3%. That’s calculated from 84.3 points of a possible 90. The remaining 10 points are joint “investigation projects”.


  • Fixed display:contents buttons failing to expose their accessible name.


  • Fixed dynamic viewport height units (dvh) not matching the actual viewport height.
  • Fixed scroll-snap properties set on <body> to stop propagating to the viewport.
  • Fixed logical viewport units to properly resolve for font-size.
  • Fixed containing blocks with a non-visible overflow incorrectly clipping position: fixed descendants.
  • Fixed table user-agent styles to use box-sizing: border-box.
  • Fixed <select> elements with contain: size.
  • Fixed handling layout and paint containment.
  • Fixed handling font-variant: normal and font-variant: none shorthands to reset font-variant-numeric and font-variant-alternates.
  • Fixed small caps handling to prevent synthesizing if any character in the font supports small caps.


  • Fixed the ignored CSS color property on <select> elements.
  • Fixed hiding icons on <input type="search"> when appearance: textfield is set.
  • Fixed applying the readonly attribute to the correct <input> types and <textarea> element.
  • Fixed the content width for <input type="search"> to not include decorations.
  • Fixed input type state changes to correctly handle missing or empty string value attributes.
  • Fixed form.submit() to submit a single form to multiple frames concurrently.
  • Fixed cloning a <textarea> to not set the initial selection at the end of the text content.
  • Fixed not firing a select event when setting a selection range results in no change to the selection.


  • Fixed some AVIF images not rendering because of their container format.


  • Fixed preventing background propagation on <html> with any containment.


  • Fixed COOP same-origin breaking forms after a back navigation.
  • Fixed script-src-elem CSP in Workers.


  • Fixed focus behavior for shadow DOM and the <dialog> element to align with specifications.


We love hearing from you. Send a tweet to @webkit, @jensimmons, or @jonathandavis to share your thoughts on Safari 16.1. If you run into any issues, we welcome your feedback on Safari UI, or your WebKit bug report about web technology or Web Inspector. Filing issues really does make a difference.

Download the latest Safari Technology Preview to stay at the forefront of the web platform and to use the latest Web Inspector features. You can also use the WebKit Feature Status page to watch for new information about the web features that interest you the most.

To learn more about what’s in Safari 16.1 for web developers, read the Safari 16.1 release notes.

October 24, 2022 05:42 PM

October 19, 2022

Release Notes for Safari Technology Preview 156

Surfin’ Safari

Safari Technology Preview Release 156 is now available for download for macOS Monterey 12.3 or later and macOS Ventura beta. If you already have Safari Technology Preview installed, you can update in the Software Update pane of System Preferences on macOS Monterey, or System Settings under General → Software Update on macOS Ventura.

This release includes WebKit changes between: 254352@main…255076@main

Note: Shared Tab Groups and syncing for Tab Groups, Website Settings, and Web Extensions are not enabled in this release.

Web Inspector

  • Elements Tab
    • Fixed Computed details sidebar panel scrolling back to the top when <style> is added to page (255001@main)
    • Fixed the DOM tree missing parts of the tree when inspecting iOS (254744@main)
    • Improved the visual hierarchy of the Layout details sidebar panel (254637@main)
  • Console Tab


  • Changed to not consider min- or max-sizes when computing width as flex base size (255002@main)
  • Changed to omit the integer value for grid-lines when it’s the default value (254821@main)
  • Changed to choose the closest snap target if neither are visible (254982@main)
  • Fixed focus to not take into account scroll margin for visibility check (254732@main)
  • Fixed text-align-last causing a table to take full space (254725@main)
  • Made resnap follow scroll snap target if necessary (254773@main)
  • Updated the named colors list to match CSS Color 4 (254840@main)


  • Added support for all rounding modes in Temporal (Behind the --useTemporal flag) (255068@main)
  • Accelerated baseline String#replace performance (254659@main, 254717@main)
  • Implemented Intl.DurationFormat (254791@main)
  • Implemented Temporal.PlainDate#{since, until} (Behind the --useTemporal flag) (254780@main)
  • Optimized String#substring (255030@main)


  • Changed to avoid line breaks before whitespace content when line-break: after-white-space is present (254826@main)
  • Fixed content placement when first-line style is present in non-quirks mode (255069@main)
  • Fixed <select> controls rendering for size=2 or size=3 (254698@main)
  • Fixed negative z-index layers from triggering unnecessary compositing of foreground layers (254746@main)


  • Adjusted buffering rate monitor to react faster (254781@main)
  • Implemented EncodedVideoChunk (254953@main)
  • Updated MediaSessionInfo media elements with a srcObject (254948@main)
  • Fixed returning animation from picture-in-picture to Element Fullscreen sometimes breaking (255041@main)

Web Animations

  • Fixed additive and accumulative color blending to yield intermediary out-of-bounds values (254850@main)


  • Ignored <option> element while building accessibility tree when <select> is hidden (254970@main)
  • Integrated ARIA element reflection in the Accessibility Tree (254905@main, 254985@main)
  • Implemented ARIA id-ref reflection for ElementInternals (254709@main)
  • Made custom element’s default ARIA id-ref work with shadow DOM (254762@main)


  • Enabled constructible and adoptable CSSStyleSheet objects (255067@main)
  • Enabled smooth keyboard scrolling by default (255031@main)
  • Added support for extended color animation interpolation (254960@main)
  • Added ImageBitmapRenderingContext support to OffscreenCanvas (254697@main)
  • Aligned the user-agent stylesheet for <abbr> and <acronym> with the HTML Spec (254710@main)
  • Consider Container Percentage Sizes When Determining Definite Cross Size (254758@main)
  • Convert HDR video frames to SDR when drawing to canvas (254973@main)
  • Changed to not suppress the click event on <textarea> resize (254843@main)
  • Changed to recompute transforms on SVG containers if the bounds changed during layout (255060@main)
  • Exposed the Notification API to dedicated workers (254805@main)
  • Fixed smooth keyboard scrolling to account for fixed content (254963@main)
  • Fixed to abort all loads when the document is navigating (254699@main)
  • Fixed to remove the initial about:blank-ness of the document (254747@main)
  • Fixed FetchEvent to not start its navigation preload response load if the preload was already used (254992@main)
  • Fixed Clear-Site-Data: "cache" HTTP header to clear the back-forward cache (254798@main)
  • Fixed calculation of direction for text form control elements with dir="auto" (254943@main)
  • Fixed mutating keyframes via CSSOM to not set disabled properties (254998@main)
  • Fixed strokeStyle changes not being applied for successive stroke line operations (254889@main)
  • Fixed elements with background-attachment: fixed to behave like background-attachment: scroll inside transformed elements (255055@main)
  • Fixed getBoundingClientRect() returning the wrong value for <tr>, <td> and its descendants for a vertical table (254918@main)
  • Fixed getComputedStyle() on a transform property to return the function list (254760@main)
  • Fixed click() for invisible <summary> elements to toggle the <details> element (255073@main)
  • Fixed percentage-based translations for SVG <text> (254656@main, 254777@main)
  • Fixed specified hue interpolation method for hues less than 0 or greater than 360 (254833@main)
  • Implemented import.meta.resolve() (254691@main)
  • Implemented importmaps (254987@main)
  • Implemented support for the Clear-Site-Data HTTP header (254745@main)
  • Made ElementInternals conditional on the form associated custom elements (254920@main)
  • Restricted transferSize, encodedBodySize, and decodedBodySize methods of PerformanceServerTiming and PerformanceResourceTiming to same-origin requests (254922@main)
  • Fixed SVG.currentScale to only set the page zoom for a standalone SVG (254787@main)
  • Prototyped declarative Shadow DOM (254964@main)
  • Prototyped streaming for declarative Shadow DOM (255020@main)

Safari Extensions

  • Fixed an issue where browser.tabs sometimes returned an incorrect URL for pinned tabs.

Bug Fixes

  • Fixed the Share Menu when sharing an image to show a preview of the image and a title (254976@main)

October 19, 2022 10:45 PM

October 15, 2022

WPE WebKit Blog: Success Story: Metrological

Igalia WebKit

Metrological: A Comcast Company WPE

WPE WebKit brought RDK (Reference Design Kit), a modern, performant web browser, to millions of screens. It enables operators to manage devices and easily customize their UIs and apps and provides analytics to improve the customer experience and drive business results.

Delivering a fast and memory-efficient browser for embbedded systems is a challenging task, so Igalia helped Metrological build a new full-screen browser engine which stripped away all unecessary toolkit elements.

With years of experience around WebKit platform integration, Igalia worked to produce a new WebKit port, WPE, which interfaced directly with Wayland and the graphics driver. Additionally, Igalia pushed forward the implementation of a multi-platform multi-threaded compositer, enabling better performance on low-end multicore processors. WPE is an official port of WebKit.

October 15, 2022 12:00 AM

October 05, 2022

Release Notes for Safari Technology Preview 155

Surfin’ Safari

Safari Technology Preview Release 155 is now available for download for macOS Monterey 12.3 or later and macOS Ventura beta. If you already have Safari Technology Preview installed, you can update in the Software Update pane of System Preferences on macOS Monterey, or System Settings under General → Software Update on macOS Ventura.

This release includes WebKit changes between: 254352@main…254623@main

Note: Shared Tab Groups and syncing for Tab Groups, Website Settings, and Web Extensions are not enabled in this release.

Web Inspector

  • Sources Tab
    • Changed URL breakpoints to also pause when an HTML attribute is set that triggers a load (254488@main)


  • Changed animation-* declarations in @keyframes to be a parse error (254468@main)
  • Enabled new perspective: 0 behavior of clamping to 1 (254420@main)
  • Fixed forced breaks in layout containment (254432@main)
  • Fixed contain: content on the body breaking scrolling (254506@main)
  • Fixed ::placeholder to not support writing-mode, direction, and text-orientation (254416@main)
  • Removed CSS display and float quirks on table and table cell elements (254475@main)


  • Fixed inline box decoration position when the content box is vertically shifted with text-underline-position: under in a vertical writing mode (254554@main, 254593@main)
  • Updated transforms on SVG shapes and groups when the root element size is changed (254538@main)
  • Stopped ignoring nowrap for table cells with nowrap="nowrap" and absolute widths (254505@main)


  • Disabled ShadowRealm for now (the --useShadowRealm flag can enable it) (254483@main)
  • Implemented Temporal.PlainDate[Time].{equals, add, subtract} (Behind the --useTemporal flag) (254366@main)
  • Implemented with and round methods for TemporalPlainDate[Time] (Behind the --useTemporal flag) (254565@main)
  • Optimized eval call in DFG / FTL compilers (254367@main)


  • Added support for WebVTT-based extended audio descriptions (254502@main)
  • Changed to round the SourceBuffer removal range (254472@main)
  • Fixed incorrect fullscreen video frame in some cases (254462@main)

Scroll to Text Fragment

  • Fixed Scroll To Text Fragment indicator to not show through popup layers (254494@main)
  • Fixed Scroll To Text Fragments to always be scrolled to the center of the frame (254477@main)
  • Fixed maintaining the Scroll to the Text Fragment until a user scroll happens (254403@main, 254507@main)
  • Fixed nodes with display: none to be considered invisible to search (254498@main)


  • Enabled the Reporting API by default (254520@main)
  • Implemented nested Dedicated Workers (254597@main)
  • Implemented no-quirks mode for media, plugin, and UA-inline documents (254526@main)
  • Added support for Cross-Origin-EmbedderPolicy (COEP) violation reporting (254466@main)
  • Added support for PermissionStatus.onchange in workers (254490@main)
  • Fixed the screen size of fullscreen video based on the aspect ratio (254528@main)
  • Fixed erroneous forgiving selectors to not be reported as supported with CSS.supports("selector(...)") (254489@main)
  • Fixed parsing of negative age values in CORS prefetch responses (254410@main)
  • Fixed handling text documents to comply with modern HTML specs (254389@main)
  • Incorrect image srcset candidate chosen for <img> cloned from <template> (254361@main)
  • Fixed lazy-loaded images sometimes not loading (254471@main)
  • Fixed navigating a cross-origin iframe to the same URL to not replace the current HistoryItem (254563@main)
  • Fixed element.removeAttribute("style") to not cause a style-src CSP violation message (254409@main)
  • Fixed text selection on flex and grid box items (254602@main)
  • Fixed wheel events to not stop macOS smooth keyboard scroll (254561@main)


  • Disallowed redirecting to data: or about: URLs (254619@main)


  • Fixed automation session terminating during navigation process swap (254386@main)

October 05, 2022 08:50 PM

October 03, 2022

Claudio Saavedra: Mon 2022/Oct/03

Igalia WebKit

The series on the WPE port by the WebKit team at Igalia grows, with several new articles that go deep into different areas of the engine:

These articles are an interesting read not only if you're working on WebKit, but also if you are curious on how a modern browser engine works and some of the moving parts beneath the surface. So go check them out!

On a related note, the WebKit team is always on the lookout for talent to join us. Experience with WebKit or browsers is not necessarily a must, as we know from experience that anyone with a strong C/C++ background and enough curiosity will be able to ramp up and start contributing soon enough. If these articles spark your curiosity, feel free to reach out to me to find out more or to apply directly!

October 03, 2022 11:28 AM

October 02, 2022

Manuel Rego: Igalia Web Platform team is hiring

Igalia WebKit

Igalia’s Web Platform team is looking for new members. In this blog post, I’ll explore the kinds of work our team does, plus a little about what working at Igalia is like.

If you’re interested in the position, please apply using the following form:

Working at Igalia

Igalia has more than two decades of experience working on free software, actively participating in open source communities, and contributing code to many upstream projects. We are now in a position that allows us to commit and own new features in many of those communities, while becoming a trusted partner that people know they can rely on.

That’s cool and all, but the best part is how we organize ourselves in a cooperative with a flat structure, where we all take part in the decisions that affect us, and (eventually) we all become co-owners of the company. Our model is based on strong values, and focused on building a new way to understand the IT industry and run a company. At Igalia, everyone gets paid the same, we all share responsibility for the company’s success and the rewards for our work.

At Igalia, we provide a remote-friendly, collaborative, and supportive environment, driven by principles of diversity and inclusion. There are currently over 120 Igalians from all over the world, and we have been a remote-friendly company for more than a decade.

Picture of a group of Igalians attending Igalia Summit in June 2022 Picture of a group of Igalians attending Igalia Summit in June 2022

About the Web Platform team

If I had to describe the work we do in the Web Platform team in one sentence, I’d say something like: implementing web platform features in the different open source browser engines. That’s quite a high level definition, so let’s go into some more specific examples of what we’ve done this year (though this is not an exhaustive list):

  • Shipped some features: :has() and inert in Chromium, CSS Containment and :focus-visible in WebKit.
  • Got MathML ready to ship in Chromium (hopefully shipping by the end of the year), and improved its interoperability in other rendering engines.
  • Worked on Interop 2022 in WebKit and Gecko: Cascade Layers, CSS Containment, Forms, etc.
  • Landed a variety of accessibility features and improvements: accessible name calculation, AOM (accessible actions and attribute reflection), Orca screen reader maintenance, etc.
  • Helped ship the Custom Highlight API in Chromium and implement the ::spelling-error and ::grammar-error pseudos.
  • Added support for Custom Protocol Handlers in Chromium.
  • Took over Firefox Reality development and released Wolvic, the open source WebXR browser.

“Implementing” the features is not the whole story though, as they usually involve a bunch of other work like proposals, specs, and tests. It’s really important to be able to navigate those situations, and seek consensus and agreement from the parties involved, so our team has a great deal of experience working on specs and participating in the relevant standards bodies.

Picture of some members of the Web Platform team during Igalia Summit in June 2022. From left to right: Brenna Brown, Rob Buis, Cathie Chen, Frédéric Wang, Valerie Young, Manuel Rego, Javier Fernández, Andreu Botella, Sergio Villar, Ziran Sun Picture of some members of the Web Platform team during Igalia Summit in June 2022. From left to right: Brenna Brown, Rob Buis, Cathie Chen, Frédéric Wang, Valerie Young, Manuel Rego, Javier Fernández, Andreu Botella, Sergio Villar, Ziran Sun

We meet twice a year at Igalia Summit. Not everyone can always make it to A Coruña (Galicia, Spain) in person, but we look forward to everyone visiting HQ eventually.

We have around 20 team members with a variety of backgrounds and locations, from Australia to Brazil to San Francisco and beyond. We collaborate with many others in the company, including some well known folks like Brian Kardell and Eric Meyer, who are always spreading the word about the great work we do.

Send your application

So if you’re interested in joining the Web Platform team at Igalia, please fill the form on our website.

Just in case you’re wondering about the interview process, you won’t be asked to do a live coding exercise or anything like that. The interviews are intended to allow both you and Igalia to get to know each other better.

If the Web Platform team doesn’t sound right for you, it might be worth checking out some of our other open positions.

Feel free to contact me if you have any questions about the position or Igalia as a whole.

October 02, 2022 10:00 PM

September 29, 2022

WPE WebKit Blog: WPE Networking Overview

Igalia WebKit

At the heart of any browser engine is networking: Connecting with services and other users. Unlike other engines, WebKit approaches this more abstractly by leaving a large portion of the networking up to individual ports. This includes network protocols such as HTTP, WebSockets, and WebRTC. The upside to this approach is a higher level of integration with the system-provided libraries and features so WebKit will behave similarly to other software on the platform often with more centralized configuration.

Due to this abstraction there are a few independent layers that make up the networking stack of WPE. In this post, I’ll break down what each layer accomplishes as well as give some insight into the codebase’s structure.

Networking Layers

WebKit Network Layers


Before we get into the libraries used for WPE, let’s discuss WebKit itself. Despite abstracting out a lot of the protocol handling, WebKit itself still needs to understand a lot of fundamentals of HTTP.

WebCore (discussed in WPE Overview) understands HTTP requests, headers, and cookies, as they are required to implement many higher-level features. What it does not do is the network operations, most parsing, or on-disk storage. In the codebase, these are represented by ResourceRequest and ResourceResponse objects, which map to general HTTP functionality.


A core part of modern web engine security is the multi-process model. In order to defend against exploits, each website runs in its own isolated process that does not have network access. In order to allow for network access, they must talk over IPC to a dedicated NetworkProcess, typically one per browser instance. The NetworkProcess receives a ResourceRequest, creates a NetworkDataTask with it to download the data, and responds with a ResourceResponse to the WebProcess which looks like this:

WebKit Network Flowchart


WPE implements the platform-specific versions of the classes above as ResourceRequestSoup and NetworkDataTaskSoup, primarily using a library called libsoup.

The libsoup library was originally created for the GNOME project’s email client and has since grown to be a very featureful HTTP implementation, now maintained by Igalia.

At a high level, the main task that libsoup does is manage connections and queued requests to websites and then efficiently streams the responses back to WPE. Properly implementing HTTP is a fairly large task, and this is a non-exhaustive list of features it implements: HTTP/1.1, HTTP/2, WebSockets, cookies, decompression, multiple authentication standards, HSTS, and HTTP proxies.

On its own, libsoup is really focused on the HTTP layer and uses the GLib library to implement many of its networking features in a portable way. This is where TCP, DNS, and TLS are handled. It is also directly used by WebKit for URI parsing and DNS pre-caching.

Using GLib also helps standardize behavior across modern Linux systems. It allows configuration of a global proxy resolver that WebKit, along with other applications, can use.


Another unique detail of our stack is that TLS is fully abstracted inside of GLib by a project called GLib-Networking. This project provides multiple implementations of TLS that can be chosen at runtime, including OpenSSL and gnutls on Linux. The benefit here is that clients can choose the implementation they prefer—whether for licensing, certification, or technical reasons.


Let’s go step by step to see some real world usage. If we call webkit_web_view_load_uri() for a new domain it will:

  1. Create a ResourceRequest in WebCore that represents an HTTP request with a few basic headers set.
    • ResourceRequestSoup will create its own internal representation for the request using soup_message_new_for_uri().
  2. This is passed to the NetworkProcess to load this request as a NetworkDataTask.
  3. NetworkDataTaskSoup will send/receive the request/response with soup_session_send() which queues the message to be sent.
  4. libsoup will connect to the host using GSocketClient which does a DNS lookup and TCP connection.
    • If this is a TLS connection GTlsClientConnection will use a library such as gnutls to do a TLS handshake.
  5. libsoup will write the HTTP request and read from the socket parsing the HTTP responses eventually returning the data to WebKit.
  6. WebKit receives this data, along with periodic updates about the state of the request, and sends it out of the NetworkProcess back to the main process as a ResourceResponse eventually loading the data in the WebProcess.


In conclusion, WebKit provides a very flexible abstraction for platforms, and WPE leverages mature system libraries to provide a portable implementation. It has many layers, but they are all well organized and suited to their tasks.

If you are working with WPE and are interested in collaborating, feel free to contact us. If you are interested in working with Igalia, you can apply here.

September 29, 2022 12:00 AM

September 27, 2022

Manuel Rego: TPAC 2022

Igalia WebKit

A few weeks ago the W3C arranged a new edition of TPAC, this time it was an hybrid event. I had the chance to attend onsite in Vancouver (Canada).

This is the second conference for me this year after the Web Engines Hackfest, and the first one travelling away. It was awesome to meet so many people in real life again, some of them for the first time face to face. Also it was great spending some days with the other igalians attending (Andreu Botella, Brian Kardell and Valerie Young).

This is my third TPAC and I’ve experienced an evolution since my first one back in 2016 in Lisbon. At that time Igalia started to be known in some specific groups, mostly ARIA and CSS Working Groups, but many people didn’t know us at all. However nowadays lots of people know us, Igalia is mentioned every now and then in conversations, in presentations, etc. When someone asks where you work and you reply Igalia, they only have good words about the work we do. “You should hire Igalia to implement that” is a sentence that we heard several times during the whole week. It’s clear how we’ve grown into the ecosystem and how we can have an important impact on the web platform evolution. These days many companies understand the benefits of contributing to the web platform bringing new priorities to the table. And Igalia is ready to help pushing some features forward on the different standard bodies and browser engines.

Igalia sponsored TPAC in bronze level and also the inclusion fund.

The rest of this blog post is about some brief highlights related to my participation on the event.

Web Developers Meetup

On Tuesday evening there was the developer meetup with 4 talks and some demos. The talks were very nice, recordings will be published soon but meanwhile you can check slides at the meetup website. It’s worth to highlight that Igalia is somehow involved in topics related to the four presentations, some of them are probably better known than others. But some examples so you can connect the dots:

Wolvic logo Wolvic logo

On top of the talks, Igalia was showing a demo of Wolvic, the open source browser for WebXR devices. A bunch of people asked questions and got interested on it, and everyone liked the stickers with the Wolvic logo.

Igalia also sponsored this meetup.


Lots of amazing things have been happening to CSS recently like :has() and Container Queries. But these folks are always thinking in the next steps and during the CSSWG meeting there were discussions about some new proposals:

  • CSS Anchoring: This is about positioning things like pop-ups relative to other elements. The goal is to simplify current situation so it can be done with some CSS lines instead of having to deal manually with some JavaScript code.
  • CSS Toggles: This is a proposal to properly add the toggle concept in CSS, similar to what people have been doing with the “Checkbox Hack”.

Picture of the CSSWG meeting by Rossen Atanassov Picture of the CSSWG meeting by Rossen Atanassov

On the breaks there were lots of informal discussions about the line-clamp property and how to unprefix it. There different proposals about how to address this issue, let’s hope there’s some sort of agreement and this can be implemented soon.

Accessibility and Shadow DOM

Shadow DOM is cool but also quite complex, and right now the accessibility story with Shadow DOM is mostly broken. The Accessibility Object Model (AOM) proposals aim to solve some of these issues.

At TPAC a bunch of folks interested on AOM arranged an informal meeting followed by a number of conversations around some of these topics. On one side, there’s the ARIA reflection proposal that is being worked on in different browsers, which will allow setting ARIA attributes via JavaScript. In addition, there were lots of discussions around Cross-root ARIA Delegation proposal, and its counterpart Cross-root ARIA Reflection, thinking about the best way to solve these kind of issues. We now have some kind of agreement on an initial proposal design that would need to be discussed with the different groups involved. Let’s hope we’re on the right path to find a proper solution to help making Shadow DOM more accessible.

Maps on the Web

This is one of those problems that don’t have a proper solution on the web platform. Igalia has been in conversations around this for a while, for example you can check this talk by Brian Kardell at a W3C workshop. This year Bocoup together with the Natural Resources Canada did a research on the topic, defining a long term roadmap to add support for maps on the Web.

There were a few sessions at TPAC about maps where Igalia participated. Things are still in a kind of early stage, but some of the features described on the roadmap are very interesting and have a broader scope than only maps (for example pan and zoom would be very useful for other more generic use cases too). Let’s see how all this evolves in the future.


And that’s all from my side after a really great week in the nice city of Vancouver. As usual in this kind of event, the most valuable part was meeting people and having lots of informal conversations all over the place. The hybrid setup was really nice, but still those face-to-face conversations are something different to what you can do attending remotely.

See you all in the next editions!

September 27, 2022 10:00 PM

September 21, 2022

Release Notes for Safari Technology Preview 154

Surfin’ Safari

Safari Technology Preview Release 154 is now available for download for macOS Monterey 12.3 or later and macOS Ventura beta. If you already have Safari Technology Preview installed, you can update in the Software Update pane of System Preferences on macOS Monterey, or System Settings under General → Software Update on macOS Ventura.

This release includes WebKit changes between: 253848@main…254351@main

Note: Shared Tab Groups and syncing for Tab Groups, Website Settings, and Web Extensions are not enabled in this release.

Web Inspector

  • Sources Tab
  • Elements Tab
    • Added “Scroll” labels in the element tree for scrollable elements (254061@main)
    • Added warnings in the Font details sidebar for synthesized boldness or obliqueness (254188@main)
    • Fixed DOM Tree to update when a top-level item in the DOM tree is added or removed (254062@main)
    • Prevented showing the Target in the Event badge popover (254018@main)
  • Timelines Tab
    • Fixed selecting timeline records from a coalesced record bar selecting the first record in the group, not the record nearest the cursor. (254056@main)
  • Settings
    • Added a setting to control whether nodes that are not rendered are de-emphasized (254022@main)



  • Fixed ShadowRealm test262 failures (253977@main)
  • Finished to and from methods for Temporal.PlainDate[Time] (Behind the --useTemporal flag) (253876@main)
  • Optimized Proxy [[Get]] operations (254092@main)
  • Optimized String#replace(String, String) (254156@main)
  • Optimizde String#replace with constant String via Boyer-Moore-Horspool search algorithm (254342@main)


  • Fixed incorrect bidi visual direction after forced line break (253872@main)
  • Fixed <div> with border-radius not getting repainted correctly when the bounds change (254041@main)
  • Fixed border-radius clipping of composited layers (254253@main)
  • Fixed updating transforms on table sections (254351@main)

Reporting API

  • Added support for generateTestReport in WebDriver (254122@main)
  • Hooked up to Content-Security-Policy 'report-to' directive (253966@main)
  • Refactored network send logic for Report-related code (254208@main)


  • Added support for COOP navigation violation reporting (254291@main)
  • Added support for ElementInternals.role, ariaLabel, and ariaRoleDescription (254278@main)
  • Added support for PermissionStatus.onchange (254193@main)
  • Added support for InputEvent.isComposing (254131@main)
  • Added ReferrerPolicy to the PolicyContainer (254003@main)
  • Added generation of IndexedDB object serializers (254196@main)
  • Enabled Scroll To Text Fragment by default (253855@main)
  • Enabled SKAttributionEnabled by default (254328@main)
  • Changed to not parse or scroll to text fragments in iframe URLs (254073@main)
  • Fixed memory usage scaling for Compression Streams to handle out-of-memory conditions (253930@main)
  • Fixed deleting a button element leaving the style inside the button element (254285@main)
  • Fixed matching fancy quotes and apostrophes for Scroll To Text Fragment fragments (254275@main)
  • Fixed link elements to be able to fire more than one load or error event (254290@main)
  • Fixed String.prototype.includes incorrectly returning false when the string is empty and the position is past end of string (254319@main)
  • Fixed opening the share sheet to not clear the text selection (254136@main)
  • Fixed <canvas> ConicGradient angle to start at the x-axis, not at the top (254038@main)
  • Fixed X-Frame-Options HTTP headers with an empty value being incorrectly ignored (254245@main)
  • Stopped painting a border for images with loading="lazy" before it loaded (253960@main)


  • Implemented WebVTT-based audio descriptions with text-to-speech (253931@main, 254266@main)
  • Implemented the ARIA 1.3 mark role, which provides parity with the <mark> tag (254008@main)


  • Fixed AudioWorklet scripts to inherit their owner document’s referrer policy (254306@main)
  • Fixed canPlayType for WebM VP8 on older Macs without VP9 (254013@main)
  • Fixed WebM files that fail to play (254219@main)
  • Fixed WebVTT styles not getting applied with in-band tracks (254109@main)

Intelligent Tracking Prevention

  • Updated to wait longer before deleting website data for domains where a user interacted with a Web Push notification (254048@main)

September 21, 2022 08:00 PM

September 12, 2022

WebKit Features in Safari 16.0

Surfin’ Safari

Today, we are excited to announce the release of Safari 16.0 for iOS 16, macOS Monterey and macOS Big Sur. This release contains quite a few new web technologies that web developers can use to make their sites and web apps even better.

To update to Safari 16.0 on macOS Monterey and macOS Big Sur, go to System Preferences → Software Update → More info. To update to Safari 16.0 on iOS, install iOS 16. Safari 16 for macOS Ventura and iPadOS 16 are coming this October, and will include Web Push on macOS Ventura.

a word cloud of everything that shipped in Safari this year, including what's in Safari 16

We announced many details about what’s in Safari 16 in our article, News from WWDC22: WebKit Features in Safari 16 Beta, and the WWDC22 session, What’s new in Safari and WebKit (32 min video). But that’s not all. In the months since WWDC, we’ve added even more.

New since Safari 16 Beta 1

Safari for iOS 16 includes support for still images compressed using the AVIF format. Developed by the Alliance for Open Media, AVIF is an alternative to image formats like JPEG, PNG, GIF, or WebP. It offers multiple color spaces, lossless and lossy compression, and more. Support for AVIF will also come to macOS Ventura and iPadOS in October.

WebKit now fully supports the resolution media query. This media query provides a way for web developers to conditionally apply CSS based on the pixel density of a screen. For example: @media (min-resolution: 326dpi) { }.

WebKit now supports text-align-last, a CSS property that sets how the last line of a text block is aligned. For instance, a paragraph could have text-align: center applied to most its lines, while the last line of that paragraph is aligned right with text-align-last: right.

The :has() pseudo-class in WebKit now supports :target. The CSS :target pseudo-class selects an element when that element has an id that matches a fragment in the URL. For example, if a user clicks on a link that takes them to, and an element on that page has the ID #chapter2, then the :target pseudo-class will select that element. In Safari 16, :has(:target) opens up new possibilities when using URLs with fragments. For an in-depth look at :has, read Using :has() as a CSS Parent Selector and much more.


Safari on iOS 16 adds support for passkeys. They provide users with an incredibly easy way to log in, while delivering a profound increase in security.

To sign in with a passkey, fill in your username (or email, depending on the site) and tap the button. Your device authenticates that it’s you, and you’re in.

The technology that makes passkeys possible is defined in open standards from the FIDO Alliance and the W3C, including the WebAuthn standard, which already has widespread support in browsers. Passkeys are an industry-wide effort, and “passkeys” is a common noun, to be used by anyone. You can offer passkeys alongside your existing authentication options. First, teach your backend to store public keys and issue authentication challenges. Then, on your website or web app, offer passkeys to users by adopting the APIs for creating new passkeys and allowing users to sign in with their passkey.

If your website or web app already supports using a platform authenticator with WebAuthn, there are a few things to note as you add support for passkeys. Make sure you aren’t limiting signing in to the device that saved the passkey; that is, don’t use a cookie to “remember” that a user set up a key on a particular device. Also, make sure the username fields in your existing sign-in forms are compatible with AutoFill by adopting “conditional mediation”. Finally, start to refer to passkeys, and treat them as a primary way to sign in.

To learn more, watch the WWDC22 session, Meet Passkeys (27 min video) or read Supporting passkeys. In October, support for passkeys will come to macOS Monterey and macOS Big Sur, as well as macOS Ventura and iPadOS.

Apple Pay

Safari 16 adds Apple Pay support for Merchant Tokens, a more efficient way to support recurring payments, and support for multi-merchant payments, a way to pay multiple merchants of record in one transaction. Safari 16 also supports Order Tracking to enable merchants on the web to provide detailed order and shipping information in Wallet. Apple Pay can now be used in all WKWebView.

Web Inspector Extensions

Safari 16 brings support for Web Inspector Extensions, enabling you to enhance Safari’s built-in web developer tools. Download these extensions on macOS by going to Safari > Safari Extensions and looking for Web Inspector Extensions in the App Store. Search for developer tools from your favorite third-party developer services, test suites, and frameworks — including Angular DevTools, which recently announced support. If you’d like to learn how to make such extensions, watch the WWDC22 session, Create Safari Web Inspector Extensions (18 min video).

Safari 16 includes even more for Safari Web Extensions, including the ability to sync which extensions are enabled across iOS, iPadOS, and macOS. Safari 16 supports both manifest version 2 and manifest version 3. Watch What’s new in Safari Web Extensions from WWDC22 to learn about the differences, and how to upgrade your extension. Web Extensions in Safari 16 also add support for declarativeNetRequestWithHostAccess permission and browser.runtime.getFrameID.

Container Queries

Similar to Media Queries, Container Queries allow you to adjust the layout or styling of a particular item on your web page based on the size of its container rather than the size of the viewport. Safari 16 supports size queries and container query units. “Size queries” are what web developers imagine when they talk about Container Queries — the opportunity to write CSS that only applies if a container is a certain size. Container Query Units are similar to Viewport Units, but they specify a length relative to the dimensions of a query container instead of the viewport. These include cqw, cqh, cqi, cqb, cqmin, and cqmax.


CSS Grid revolutionized what’s possible in layout design on the web. Subgrid takes Grid to another level, providing an easy way to put grandchildren of a grid container on that grid. It makes it possible to line up items across complex layouts without being constrained by the HTML structure. And Safari’s Grid Inspector lets you turn on the overlays for as many grids as you want — which is especially helpful when coding subgrid.

Web Inspector

Following last year’s addition of Grid Inspector, Safari 16.0 adds Flexbox Inspector. It pairs perfectly with the addition of Alignment Editor in Safari 15.4.

a screenshot of the Flexbox Inspector in action, drawing lines around the container, around each item, and marking gaps and free spaceOverlays for Flexbox containers make it easier to visualize the effects your CSS.

Safari’s Flexbox Inspector visually distinguishes between excess free space and Flex gaps. It also shows the boundaries of items, revealing how they are distributed both on the main axis and the cross axis of your Flexbox containers. The toggleable “Order Numbers” option show the layout order of elements in the container, which can be helpful when using the order property. And just like our overlays for Grid last year, you can simultaneously show as many Flexbox overlays as you want, without any impact on scrolling performance. A single checkbox turns them all on.

In the Timelines Tab there are additional links to reference documentation, and a new experimental Screenshots timeline that captures screenshots of the viewport when content changes are painted.

The Elements Tab now supports showing Container Queries in the Styles sidebar.

The Sources Tab brings new improvements including allowing local overrides for requests to use regular expression matches in the redirect URL and local overrides for responses now being able to be mapped to a file on disk.

The Network Tab includes a new proxy indicator, and provides a way to entirely block network requests.

Accessibility Improvements

Safari 16 introduces a re-architecture of WebKit’s accessibility support on macOS. By adding Isolated Tree Mode, WebKit reduces VoiceOver hangs by offloading accessibility work to a secondary thread, improving performance and increasing responsiveness. This change allows WebKit to service more accessibility requests from clients like VoiceOver in less time than before. On some complex webpages, we’ve measured twice the number of accessibility requests served in twenty-five percent less time. Safari 16 also greatly improves accessibility support for elements with display:contents by ensuring they are properly represented in the accessibility tree.

Animation Improvements

WebKit now supports CSS Offset Path (also known as Motion Path), providing web developers the ability to animate objects along a custom path of any shape. The offset-path property lets you define a geometrical path along which to animate. The offset-anchor, offset-distance, offset-position, and offset-rotate properties give you additional abilities to refine the exact movement of the object being animated. While the offset property acts as a shorthand for combining these properties.

In Safari 16, you can now animate track sizes in CSS Grid, dynamically changing the size of rows and columns.

Safari 16 also adds support for composite operations, resolving how an element’s animation impacts its underlying property values. And it adds support for discrete animation to thirty-nine CSS properties.

Overscroll Behavior

CSS Overscroll Behavior determines what happens when a user scrolls and reaches the boundary of a scrolling area. It’s useful when you want to stop scroll chaining — when a user scrolls inside a box and hits the end, you now have control over stopping or allowing scrolling on the rest of the page.

Shared Workers

WebKit now supports Shared Workers. It’s similar to Service Workers, running JavaScript in the background, but its lifetime is slightly different. Your Shared Worker runs as long as the user has any tab open to your domain. All the tabs open to the same domain can share the same Shared Worker.

Additional Features

Safari 16 adds support for Shadow Realms, <form>.requestSubmit(), the showPicker() method for HTML input elements, and the worker-src Content Security Policy directive.

Fixes and Polish

Safari 16.0 also contains quite a few bug fixes and feature polish.


  • Fixed gradient color interpolation with alpha.
  • Removed most non-standard CSS appearance values.
  • Polished the implementation of the :has() pseudo-class, updated to match the evolving web standard.
  • Polished the implementation of Cascade Layers.


  • Fixed firing the load event after a form is submitted with a "_blank" target.
  • Fixed contenteditable anchors getting stuck with an :active state.
  • Fixed changing the value for stepUp() and stepDown() with out-of-range values.
  • Fixed using min as the default value when min is greater than max for <input type="range">.
  • Fixed making value updates visible for <input type="email">.
  • Fixed making sure :active is removed on keyup event for radio inputs.
  • Fixed applyStep() behavior to align with specifications.
  • Fixed the select() method returns to align with specifications.
  • Fixed form data generated by <input type="image"> when a value attribute is present.
  • Fixed the FormData object to not include an entry for the submit button used to submit the form.
  • Fixed returning an empty string for invalid floating-point numbers that end with a ".".
  • Fixed selection range after the type attribute of an <input> changes.
  • Fixed selection range to be limited by the length of the current value.
  • Fixed the user-agent stylesheet to include table { text-indent: initial } to align with specifications.
  • Fixed the user-agent stylesheet to include box-sizing: border-box for <input type="color">.
  • Fixed the line-height declaration to use !important for the placeholder of an input.


  • Fixed blocking image content in object elements.
  • Fixed incorrect CORP/COEP check in 304 responses.
  • Fixed mixing strict-dynamic and unsafe-inline policies.
  • Fixed script-src-elem policies in Workers.
  • Fixed incorrect blocked-uri for inline scripts and strict-dynamic policies.

WebGL 2

  • Fixed handling AllowShared TypedArray.

Web Inspector

  • Fixed breakpoints not triggering, breakpoints occurring at incorrect locations in scripts, and incorrect error/stack trace line/column numbers when inspecting minified sources with multi-line strings.
  • Fixed importing Timelines sometimes not scrolling.
  • Fixed importing Audits sometimes crashing.
  • Fixed CSS autocomplete to suggest the most commonly-used property, not the alphabetical one.

Web Driver

  • Fixed pointerMove actions to correctly fire mouse events.
  • Fixed rapid session creation and deletion leading to timeouts in session creation.

Safari Web Extensions

  • Fixed incorrect counts being returned from getBytesInUse.
  • Extensions that request the unlimitedStorage permission no longer also need the storage permission.
  • Updated the maximum number of static rulesets to 50 and the maximum number of enabled static rulesets to 10.
  • Service workers are no longer returned from extension.getBackgroundPage and extension.getViews


We love hearing from you. Send a tweet to @webkit, @jensimmons, or @jonathandavis to share your thoughts on Safari 16. If you run into any issues, we welcome your feedback on Safari UI, or your WebKit bug report about web technology or Web Inspector. Filing issues really does make a difference.

Download the latest Safari Technology Preview to stay at the forefront of the web platform and to use the latest Web Inspector features. You can also use the WebKit Feature Status page to watch for new information about the web features that interest you the most.

To learn more about what’s in Safari 16 for web developers, read the Safari 16 Release Notes.

September 12, 2022 05:45 PM

Introducing JetStream 2.1

Surfin’ Safari

JetStream 2 is a JavaScript benchmark suite that runs 64 subtests. We recently discovered that the benchmark score of JetStream 2 may be influenced by pause times between individual subtests because of second order effects, like CPU ramping. Network latency is one source of such pause times. As a result, depending on the speed of one’s network, JetStream 2’s benchmark score can vary. This is undesirable since the goal of JetStream 2 is to measure JavaScript performance, not the second order effects of network latency.

We’re introducing JetStream 2.1 which runs the same subtests as JetStream 2. However, JetStream 2.1 updates the benchmark driver to pre-fetch network resources into Blobs, and create URLs from them. The subtests will now load resources from these blob URLs instead.

With this change, we measured JetStream 2.1’s benchmark scores on both Chrome and Safari to be more stable and is less perturbed by pause times due to network latency. Scores produced from JetStream 2.1 are not comparable to other versions of any JetStream benchmark.

September 12, 2022 04:50 PM

September 07, 2022

Release Notes for Safari Technology Preview 153

Surfin’ Safari

Safari Technology Preview Release 153 is now available for download for macOS Monterey 12.3 or later and macOS Ventura beta. If you already have Safari Technology Preview installed, you can update in the Software Update pane of System Preferences on macOS Monterey, or System Settings under General → Software Update on macOS Ventura.

This release includes WebKit changes between: 253169@main…253847@main

Note: Shared Tab Groups and syncing for Tab Groups, Website Settings, and Web Extensions are not enabled in this release.

Web Inspector

  • Sources Tab
  • Elements Tab
    • Added a way to control what badges are shown in the main DOM tree (253579@main)
    • Added Event badges for nodes that directly have event listeners in the main DOM tree (253727@main)
    • Changed the Computed panel to no longer show the Variables section when the selected element has no CSS variables (253562@main)
    • Changed the Computed panel to sort prefixed properties below non-prefixed properties (253789@main)
    • Changed the Computed panel to only show inline swatches that actually preview the value (253214@main)
  • Network Tab
    • Fixed highlighting only the initiated resources when a row is hovered (253476@main)


  • Added support for background images on ::first-line (253553@main)
  • Added right-to-left direction support for text-overflow: ellipsis (253689@main)
  • Implemented forced-colors media query (253290@main)
  • Fixed text-decoration location for superscripts when the text string contains both superscript and regular text (253406@main)
  • Fixed handling of layout and paint containment with internal ruby boxes (253354@main)
  • Fixed :has(:lang(~)) invalidation with dynamic changes (253764@main)
  • Fixed @supports to not work if “not”, “or”, or “and” isn’t follow by a space (253194@main)
  • Fixed handling of font-variant: normal and font-variant: none shorthand (253731@main)
  • Fixed behavior of cursor: auto over links (253685@main)
  • Fixed color-scheme to not propagate to the viewport background if set on the <body> (253565@main)
  • Fixed tiled layer flicker when an animation ends (253549@main)
  • Fixed the transferred min and max sizes to be constrained by defined sizes (253262@main)
  • Fixed pseudo-elements not treated as ASCII case-insensitive (253631@main)
  • Fixed the title of non-CSS stylesheets to be not preferred (253632@main)
  • Fixed input[type=search] to hide icons when appearance: textfield is set (253691@main)
  • Included aspect-ratio when calculating inline min-content size and add min-content block computation (253740@main)
  • Renamed initial value of color-scheme from auto to normal (253659@main)
  • Used align-content when calculating the static position of absolutely-positioned flexbox children (253389@main)
  • Used logical top, bottom, and height when computing the available height for an out-of-flow block (253312@main)


  • Implemented import-assertion and JSON module (253234@main)
  • Implemented Temporal.PlainDateTime to the extent of the current PlainDate implementation (Behind the --useTemporal flag) (253623@main)
  • Fixed not generating import.meta object if it is not referenced (253636@main)
  • Optimized async and await and microtask queue (253651@main)
  • Optimized Promise.all (253716@main)
  • Added support for WebAssembly GC recursion groups (253491@main)


  • Changed to not generate text runs for empty text content (253569@main)
  • Fixed text-overflow: ellipsis to change the text content to render (253607@main)
  • Fixed text-overflow: ellipsis to not affect geometries (253650@main)
  • Fixed underline thickness to align with device pixels (253182@main)
  • Stopped propagating scroll-snap style from <body> to viewport (253430@main)

Screen Capture

  • Changed to reject the getDisplayMedia prompt if the system picker times out (253260@main)


  • Included explicit !important min, max properties, and explicit width and height for full-screen elements (253790@main)
  • Fixed MediaRecorder.stop() firing an additional dataavailable event with bytes after MediaRecorder.pause() (253529@main)
  • Fixed audio pitch changes on enabling or disabling the mic capture (253673@main)
  • Fixed screen recording in a background tab working for only about a minute (253769@main)


  • Stopped applying the buffer offset twice in getBufferSubData (253175@main)


  • Implemented the Imperative Slot API (253187@main, 253198@main, 253199@main, 253202@main, 253266@main, 253320@main, 253359@main, 253365@main, 253392@main, 253396@main, 253402@main)
  • Implemented full search for text directives for Scroll to Text Fragment spec (253383@main)
  • Added Set-Cookie as a forbidden header name (253325@main)
  • Added generic media query parser and evaluator (253298@main)
  • Added support to the Permissions API for dedicated workers (253447@main)
  • Added support to the Permissions API for Service Workers and Shared Workers (253752@main)
  • Added way to get parent inline box to the inline iterator (253304@main)
  • Added box-sizing: border-box to table in the User-Agent stylesheet (253581@main)
  • Fixed blob URLs with a fragment from opaque origins cannot be loaded (253498@main)
  • Fixed ignored charset of blobs (253458@main)
  • Fixed composited canvas element to update the layer configuration after creating a WebGL context (253231@main)
  • Fixed position elements should layout relative to transformed container (253809@main)
  • Fixed Navigator.share() rejecting with the wrong exception when called multiple times (253419@main)
  • Fixed iframe srcdoc with a quirky doctype to use no-quirks mode (253326@main)
  • Fixed input[type=search] preferred content width to not include decorations (253595@main)
  • Fixed Permissions.query to return “prompt“ for opaque origins (253785@main)
  • Fixed scheduling a navigation to a Blob URL to keep the URL alive until the navigation actually occurs (253435@main)
  • Fixed forms with a disabled submit button from being posted with the Enter key (253228@main)
  • Fixed the HTML parser to ignore starting <head> tags in the “in head noscript” state (253489@main)
  • Fixed the HTML parser’s foster-parenting algorithm to not require foster parents to be elements (253504@main)
  • Fixed the HTML parser’s adoption agency algorithm to not reverse the order of nodes (253505@main)
  • Fixed an issue where data-x-2="" is not included in the dataset if it’s the only data attribute (253625@main)


  • Added support for the ARIA 1.3 property aria-description (253184@main)
  • Fixed updating accessibility objects role after a dynamic contenteditable change (253630@main)


  • Added support for Wheel input source and actions (253578@main)
  • Added support for “Get Computed Role” and “Get Computed Label” commands (253732@main)
  • Fixed automation hanging indefinitely when dismissing alerts

September 07, 2022 08:19 PM

August 31, 2022

WebKit on GitHub!

Surfin’ Safari

On June 23rd, the WebKit project froze its Subversion tree and transitioned management and interaction with our source code to git on GitHub.

WebKit project GitHub page

Why git?

git’s distributed nature makes it easy for not just multiple developers, but multiple organizations to collaborate on a single project. git’s local record of changes makes moving commits between branches or reverting changes simple and quick. git’s author and committer model does a good job representing the complex ways a large software project like WebKit writes and manages code. git’s local record of commit messages, along with git log’s ability to limit commit history to certain parts of the repository, mean large projects no longer require antiquated ChangeLog files be checked in with each commit.

In addition to git’s strengths, its ubiquity in software engineering meant that most new contributors to the WebKit project found themselves preferring to work from git-svn mirrors of the WebKit project already, so transitioning our project to exclusively git worked well with existing tools and workflows. It also means that the WebKit team will have many options for tools and services which integrate well with git.

Why GitHub?

The WebKit project is interested in contributions and feedback from developers around the world. GitHub has a very large community of developers, especially web developers, with whom the WebKit project works closely with to improve the engine that brings those developer’s creations into the hands of users around the world. We also found that GitHub’s API let us build out advanced pre-commit and post-commit automation with relatively minor modification to our existing infrastructure, and provides a modern and secure platform to review and provide feedback on new code changes.

Maintaining Order

One drawback of git is that git hashes are not naturally ordered. The WebKit team has found that the ability to easily reason about the order of commits in our repository is crucial for our zero-tolerance performance regression policy. We’ve decided to use what we’re calling “commit identifiers” in workflows that require bisection.

On the main branch, commit identifiers are a count of the number of ancestors a commit has. On a branch off of main, commit identifiers are the number of ancestors on main combined with the number of ancestors on the branch. Commit identifiers can be computed with git rev-list --count <ref> on main and git rev-list --count main..<ref> on a branch.

The WebKit team has developed a few simple tools to work with commit identifiers, most notably Tools/Scripts/git-webkit (which offers git commands compatible with identifiers) and (a simple web service for translating between different commit representations). All of our commits embed their commit identifier inside their commit message via a link. We’ve outlined in detail how commit identifiers work on the Source Control page on the GitHub wiki.

You Can Contribute!

We always welcome new contributors to the project. Get started by checking out WebKit from GitHub today! Consult our “Getting Started” documentation for information on building, testing and contributing improvements to the project. The WebKit Team is also available on Slack at #WebKit, and we’re always ready to help folks get involved with the project on the webkit-dev mailing list.

August 31, 2022 07:15 PM

July 28, 2022

WPE WebKit Blog: WPE QA and tooling

Igalia WebKit

In the previous posts, my colleagues Claudio and Miguel wrote respectively about the major components of the project and, specifically, the graphics architecture of WPE. Today, you’ll see our efforts to improve the quality of both WPE and the experience of working and using it. While the previous entries in this blog post series about WPE aren’t necessarily required in order to read this one, we recommend you to starting with the first post in the series.

Automated testing

Testing is an essential part of the WebKit project, primarily due to the large number of use cases covered by HTML/CSS/Javascript specifications and the need for the project to work correctly in a wide range of configurations.

As an official port of WebKit, WPE uses the former’s testing infrastructure, based on BuildBot. There are two primary servers, one working as an early warning system by testing the patches before they’re committed to the main repository, and another for more extensive testing after accepting the incoming changes. screenshot

Currently, the WPE testing bots target debug and release configurations using the Flatpak SDK (more on it later in this article) on 64bit Intel-based Linux Debian systems. We have plans of adding bots running on Raspberry Pi boards in the future. Alongside nightly testing, we keep builder bots covering the Ubuntu LTS/Debian versions we support. After August 14th, 2022, the earliest supported versions will be Ubuntu 20.04 LTS and Debian 11 (Bullseye).

Test suites

Initially, the WPE builder bots build WPE in both release and debug configurations and feed the built packages into the tester bots, which run some test suites according to their configuration, each suite focused in one aspect of the project:

  • Layout tests: The main suite tests whether WebKit correctly renders web pages and its implementation of web APIs. This suite comprises both WebKit’s test cases and the imported tests from Web Platform Test. At the time of writing, it runs over 50,000 test cases.
  • API Tests: This suite tests the API provided to developers by WebKit and its ports. For example, this step tests the WPE API used in Cog.
  • Javascriptcore tests: Covers the JavascriptCore engine, running WebKit’s tests alongside test262, the reference test suite for JS/ECMAScript implementations.
  • WebDriver: Tests from Selenium and W3C WebDriver APIs for browser automation.
  • Other small suites: Tests for WebKit’s tooling components.

Due to a large number of tests and the fast development of both WebKit and the specifications—it’s not uncommon to have dozens of daily commits touching dozens of tests—it’s hard to keep the testing bots green.

For example, while we try to make the tests work on all platforms, many old layout tests use the -expected.txt scheme, where the render tree is printed in a textual format with the text sized in pixels for every node. While this works fine in most cases, many tests have minor differences between the expected result in the Mac platform and the WPE/GTK platform. One of the causes is the font rendering particularities of each port.

Thankfully, this situation improved significantly since the beginning of the project. Among the efforts, many tests are now using a “reference” HTML file, which are HTML files that render to the same expected result as the test case, so both the test case and the reference will use the same font rendering scheme and can be compared pixel by pixel.

Building and running WPE

This section focuses on the experience of building and running WPE in a regular Linux x86–64 system. In a future post, we’ll cover building for and running on embedded devices.

Checking out the code

Recently, WebKit moved to GitHub, so you can clone it directly from there:

$ mkdir ~/dev
$ git clone

Note: Due to the size of the project history, you might want to use --depth=1 to clone a single revision, followed by git pull --unshallow from inside the cloned repository to fetch the history if needed.

There’s more information in WebKit’s GitHub wiki about setting up the git checkout for contributing code back to WebKit. It’ll set up some git hooks to do some tasks required by the project, like formatting the commit message and automatically linking the pull request to the Bugzilla issue.

All commands in the following sections are run from inside the cloned repository.

Updating the dependencies (aka The WebKit Flatpak SDK)

Like most complex software projects, WebKit has a reasonably extensive list of dependencies. Keeping a reference set of their versions frozen during development is desirable to make it easier to reproduce bugs and test results. In older times, WPE and WebKitGTK used JHBuild to freeze a set of dependencies. While this worked for a long time, it did not cover all dependencies. Sometimes, there could be minor differences in the layout tests between the reference test bots and the developer machine due to some dependency resolved by the host system outside JHBuild.

To improve reproducibility, since 2020, WPE and WebKitGTK have been using an SDK based on Flatpak (kudos to my colleagues Thibault Saunier and Philippe Normand), with a much more extensive dependency coverage and isolation from the host system. Alongside the dependencies, it ships some tools like rr and supports tools like clangd. Almost all bots enable this SDK, the exception being the LTS/Stable bots; as in the latter, we want to build with the already available packages in each distribution.

$ ./Tools/Scripts/update-webkit-flatpak

The command will set up the local flatpak repository at ./WebKitBuild/UserFlatpak with the downloaded SDK and create some bundled icecc toolchains. This enables distributed builds in local networks…


Once the SDK download finishes, you can use the helper script ./Tools/Scripts/build-webkit, which wraps the cmake command with some pre-set options commonly used in normal development, like enabling developer-only features usually disabled in regular builds. Manually invoking cmake is possible, although usually only when you want more control over the build. To build WPE in release mode, use:

$ ./Tools/Scripts/build-webkit --release --wpe

Optionally, you can pass it multiple arguments to be fed directly to make or cmake with the switches --makeargs=... and --cmakeargs=..., respectively. For example, --makeargs="-j8" will limit make to 8 parallel jobs and --cmakeargs="-DENABLE_GAMEPAD=1" will enable gamepad support (requires libmanette, bundled in the SDK).

The first build might take a while (up to almost one hour in a regular laptop). Fortunately, the SDK uses ccache to avoid recompiling the same object files, so subsequent builds without significant changes usually are faster. For more info on speeding the build, check the wiki.

Running the browser (Cog)

To run Cog, the reference WPE browser, you need a Wayland server, which is common in most Linux systems nowadays.

$ ./Tools/Scripts/run-minibrowser --wpe --release
Cog with GTK4 shell screenshot

Running some tests

To run the API tests, which reside in Tools/TestWebKitAPI/Tests/, you can use the following command:

$ ./Tools/Scripts/run-wpe-tests --release --display-server=headless

Other test suites:

  • Layout tests: ./Tools/Scripts/run-wpe-tests
  • JSC tests: ./Tools/Scripts/run-javascriptcore-tests
  • WebDriver: ./Tools/Scripts/run-webdriver-tests

As stated when we described the test suites, the main challenge in testing is keeping up with the fast pace of development, as it’s not uncommon to have some revisions updating hundreds of tests.

Contributing code to WPE

After hacking locally, you can submit your changes following the workflow listed in the WebKit wiki.

Testing WPE in the wild

If you don’t want to build your WPE build or image, there are some options to get a taste of WPE listed on our website, including:

Some of these options, like the prebuilt images and the Balena blocks, will be the subject of future blog posts in this series.

Final thoughts

With this, we conclude this brief overview of WPE automated testing and the main tools we use in our daily work with WPE. In future posts in this area we’ll go deeper in other subjects like testing on embedded boards and debugging practices.

If this post got you interested in collaborating with WPE development, or you are in need of a web engine to run on your embedded device, feel free to contact us. We’ll be pleased to help!

We also have open positions at the WebKit team at Igalia. If you’re motivated by this field and you’re interested in developing your career around it, you can apply here!

July 28, 2022 12:00 AM

July 20, 2022

Víctor Jáquez: Gamepad in WPEWebkit

Igalia WebKit

This is the brief story of the Gamepad implementation in WPEWebKit.

It started with an early development done by Eugene Mutavchi (kudos!). Later, by the end of 2021, I retook those patches and dicussed them with my fellow igalian Adrián, and we decided to come with a slightly different approach.

Before going into the details, let’s quickly review the WPE architecture:

  1. cog library — it’s a shell library that simplifies the task of writing a WPE browser from the scratch, by providing common functionality and helper APIs.
  2. WebKit library — that’s the web engine that, given an URI and other following inputs, returns, among other ouputs, graphic buffers with the page rendered.
  3. WPE library — it’s the API that bridges cog (1) (or whatever other browser application) and WebKit (2).
  4. WPE backend — it’s main duty is to provide graphic buffers to WebKit, buffers supported by the hardware, the operating system, windowing system, etc.

Eugene’s implementation has code in WebKit (implementing the gamepad support for WPE port); code in WPE library with an API to communicate WebKit’s gamepad and WPE backend, which provided a custom implementation of gamepad, reading directly the event in the Linux device. Almost everything was there, but there were some issues:

  • WPE backend is mainly designed as a set of protocols, similar to Wayland, to deal with graphic buffers or audio buffers, but not for input events. Cog library is the place where input events are handled and injected to WebKit, such as keyboard.
  • The gamepad handling in a WPE backend was ad-hoc and low level, reading directly the events from Linux devices. This approach is problematic since there are plenty gamepads in the market and each has its own axis and buttons, so remapping them to the standard map is required. To overcome this issue and many others, there’s a GNOME library: libmanette, which is already used by WebKitGTK port.

Today’s status of the gamepad support is that it works but it’s not yet fully upstreamed.

  • merged ">">libwpe pull request.
  • cog pull request — there are two implementations: none and libmanette. None is just a dummy implementation which will ignore any request for a gamepad provider; it’s provided if libmanette is not available or if available libwpe hasn’t gamepad support.
  • WebKit pull request.

To prove you all that it works my exhibit A is this video, where I play asteroids in a RasberryPi 4 64 bits:

The image was done with buildroot, using its master branch (from a week ago) with a bunch of modifications, such as adding libmanette, a kernel patch for my gamepad device, kernel 5.15.55 and its corresponding firmware, etc.

By vjaquez at July 20, 2022 10:08 AM

July 19, 2022

Manuel Rego: Some highlights of the Web Engines Hackfest 2022

Igalia WebKit

Last month Igalia arranged a new edition of the Web Engines Hackfest in A Coruña (Galicia, Spain), where brought together more than 70 people working on the web platform during 2 days, with lots of discussions and conversations around different features.

This was my first onsite event since “before times”, it was amazing seeing people for real after such a long time, meeting again some old colleagues and also a bunch of people for the first time. Being an organizer of the event meant that they were very busy days for me, but it looks like people were happy with the result and enjoyed the event quite a lot.

This is a brief post about my personal highlights during the event.


During the hackfest we had an afternoon with 5 talks, the talks were live streamed on YouTube and people could follow them remotely and also ask questions through the event matrix channel.

Leo Balter's Talk

Leo Balter’s Talk

  • Leo Balter talked about how Salesforce participates on the web platform as partner, working with browsers and web standards.
    I really liked this talk, because it explains how companies that use the web platform, can collaborate and have a direct impact on the evolution of the web. And there are many ways to do that: reporting bugs that affect your company, explaining use cases that are important for you and the things you miss from the platform, providing feedback about different features, looking for partners to fix outstanding issues or add support for new stuff, etc.
    Igalia has been showing during the last decade that there’s a way to have an impact on the web platform outside of the big companies and browser vendors. Thanks to our position on the different communities, we can help companies to push features they’re interested in and that would benefit the entire web platform in the future.
  • Dominik Röttsches gave a talk about COLRv1 fonts giving details on Chromium implementation and the different open-source software components involved.
    This new font format allows to do really amazing things and Dominik showed how to create a Galician emoji font with popular things like Tower of Hercules or Polbo á feira. With some early demos on variable COLRv1 and the beginnings of the first Galician emoji font…
  • Daniel Minor explained the work done in Gecko and SpiderMonkey to refactor the internationalization system.
    Very interesting talk with lots of information and details about internationalization, going deep on text segmentation and how it works on different languages, and also introducing the ICU4X project.
  • Ada Rose Cannon did a great introduction to WebXR and Augmented Reality.
    Despite not being onsite, this was an awesome talk and the video was actually a very immersive experience. Ada explained many concepts and features around WebXR and Augmented Reality with a bunch of cool examples and demos.
  • Thomas Steiner talked about Project Fugu APIs that have been implemented in Chromium.
    Using the Web Engines Hackfest logo as example, he explained different new capabilities that Project Fugu is adding to the web through a real application called SVGcode.

It was a great set of talks, and you can now watch them all on YouTube. We hope you enjoy them if you haven’t the chance to watch them yet.

CSS & Interop 2022

On the CSS breakout session we talked about all the new big features that are arriving to browsers these days. Container Queries and :has being probably the most notable examples, features that people have been requesting since the early days and that are shipping into browsers this year.

Apart from that, we talked about the Interop 2022 effort. How the target areas to improve interoperability are defined, and how much it implies the work in some of them.

MathML & Fonts

Frédéric Wang did a nice presentation about MathML and all the work that has been done in the recent years. The feature is close to shipping in Chromium (modulo finding some solution regarding printing or waiting for LayoutNG to be ready to print), that will be a huge step forward for MathML becoming it a feature supported in the major browser engines.

Related to the MathML work there were some discussion around fonts, particularly OpenType MATH fonts, you can read Fred’s post for more details. There are some good news regarding this topic, new macOS version includes STIX Two Math installed by default, and there are ongoing conversations to get some OpenType MATH font by default in Android too.

MathML Breakout Session MathML Breakout Session

Accessibility & AOM

Valerie Young, who has recently started acting as co-chair of the ARIA Working Group, was leading a session around accessibility where we talked about ARIA and related things like AOM.

The Accessibility Object Model (AOM) is an effort that involves a lot of different things. In this session we talked about ARIA Attribute Reflection and the issues making accessible custom elements that use Shadow DOM, and that proposals like Cross-root ARIA Delegation are trying to solve.

Accessibility Breakout Session Accessibility Breakout Session


To close this post I’d like to say thank you to everyone that participated in the Web Engines Hackfest, without your presence this event wouldn’t make any sense. Also I’d like to thank the speakers for the great talks and the time devoted to work on them for this event. As usual big thanks to the sponsors Arm, Google and Igalia to make this event possible once more. And thanks again to Igalia for letting me be part of the event organization.

Web Engines Hackfest 2022 Sponsors - Host & Organizer: Igalia. Gold Sponsors: Arm, Google and Igalia. Other Sponsors: Arm (Lunch sponsor) Web Engines Hackfest 2022 Sponsors

July 19, 2022 10:00 PM

July 15, 2022

WPE WebKit Blog: WPE Graphics architecture

Igalia WebKit

Following the previous post in the series about WPE where we talked about the WPE components, this post will explain briefly the WPE graphics architecture, and how the engine is able to render HTML content into the display. If you haven’t read the previous entries in this blog post series about WPE, we recommend you to start with the first post in the series for an introduction, and then come back to this.

DOM + CSS = RenderTree

As the document is parsed, it will begin building the DOM tree and load-blocking CSS resources. At some point, possibly before the entire DOM tree is built, it’s time to draw things on the screen. The first step to render the content of a page is to perform what’s called the attachment, which is merging the DOM tree with the CSS rules, in order to create the RenderTree. This RenderTree is a collection of RenderObjects, structured into a tree, and each of these RenderObjects represent the elements in the DOM tree that have visual output. RenderObjects have the capability to render the associated DOM tree node into a surface by using the GraphicsContext class (in the case of WPE, this GraphicsContext uses Cairo to perform the rendering).

Once the RenderTree is created, the layout is performed, ensuring that each of the RenderObjects have their proper size and position set.

Going from source content to displayed content

It would be possible to render the content of the web page just traversing this RenderTree and painting each of the RenderObjects, but there would be problems when rendering elements that overlap each other, because the order of the elements in the RenderTree doesn’t necessarily match the order in which they must be painted in order to get the appropriate result. For example, an element with a big z-index value should be painted last, no matter its position in the RenderTree.

This is an example of how some HTML content is translated into the RenderTree (there are some RenderObjects missing here that are not relevant for the explanation).

RenderTree generated from example HTML


In order to ensure that the elements of the RenderTree are rendered in the appropriate order, the concept of RenderLayer is added. A RenderLayer represents a layer in the document containing some elements that have to be rendered at the same depth (even though this is not exactly the case, you can think of each RenderLayer as a group of RenderObjects that are at a certain z-index). Each RenderObject is associated to a RenderLayer either directly or indirectly via an ancestor RenderObject.

RenderLayers are grouped into a tree, which is called the RenderLayer tree, and RenderLayer children are sorted into two lists: those that are below the RenderLayer, and those that are above. With this we have a structure that has grouped all the RenderObjects that have to be rendered together: they will be on top of the content that has been rendered by the RenderLayers below this one, and below the content rendered by the RenderLayers over this one.

There are several conditions that can decide whether a RenderLayer is needed for some element, it doesn’t necessarily needs to be due to the usage of z-index. It can be required due to transparency, CSS filters, overflow, transformations, and so on.

Continuing with the example, these are RenderLayers that we would get for that HTML code:

RenderLayer tree generated from example HTML

We can see that there are four RenderLayers:

  • The root one, corresponding to the RenderView element. This is mandatory.
  • Another one corresponding to the first RenderBlock.
  • One corresponding to the RenderVideo element, because video elements always get their own RenderLayer.
  • One corresponding to the transformed RenderBlock.

RenderLayers have a paint method that is able to paint all the RenderObjects associated to the layer into a GraphicsContext (as mentioned, WPE uses Cairo for this). As in the previous case, it’s possible to paint the content of the page at this point just by traversing the RenderLayer tree and requesting the RenderLayers to paint their content, but in this case the result will be the correct one. Actually this is what WebKitGTK does when it’s run with accelerated compositing disabled.

Layer composition

While with the previous step we are already able to render the page contents, this approach is not very efficient, especially when the page contains animations, elements with transparency, etc. This is because in order to paint a single pixel, all the RenderLayers need to be traversed, and those that are contributing to that pixel need to be repainted (totally or partially), even if the content of those RenderLayers hasn’t changed. For example, think about an animation that’s moving an element. For each frame of that animation, the animated element needs to be repainted, but the area that was covered by the animated element in the last frame needs to be repainted as well. The same happens if there’s a translucent element on top of other content. If the translucent element changes, it needs to be repainted, but the content below the translucent element needs to be repainted as well because the blend needs to be performed again.

This would be much more efficient if the content that doesn’t change was somehow separated from the content that’s changing, and we could render those two types of content separately. This is where the composition stage comes into action.

The idea here is that we’re going to paint the RenderLayer contents into intermediate buffers, and then compose those buffers one on top of the other to get the final result. This last step is what we call composition. And it fixes the problems we mentioned with animations of transparency: animations don’t require repainting several RenderLayers. Actually moving an element just means painting one buffer with an offset during the composition. And for transparency, we just need to perform the new blending of the two buffers during the composition, but the RenderLayers of the content below the translucent element don’t need to be repainted.

Once we have the RenderLayer tree, we could just paint each RenderLayer in its own buffer in order to perform the composition. But this would be a waste of memory, as not every RenderLayer needs a buffer. We introduce here a new component, the GraphicsLayer.

GraphicsLayers are a structure used to group those RenderLayers that will render into the same buffer, and it will also contain all the information required to perform the composition of these buffers. A RenderLayer may have a GraphicsLayer associated to it if it requires its own buffer to render. Otherwise, it will render into an ancestor’s buffer (specifically, the first ancestor that has a GraphicsLayer). As usual, GraphicsLayers are structured into a tree.

This is how the example code would be translated into GraphicsLayers.

GraphicsLayer tree generated from example HTML

We can see that we have now three GraphicsLayers:

  • The root one, which is mandatory. It belongs to the RenderView element, but the first RenderBlock will render into this GraphicsLayer's buffer as well.
  • The one for the RenderVideo element, as videos are updated independently from the rest of the content.
  • The one for the transformed element, as the transformed elements are updated independently from the rest of the content.

With this structure, now we can render the intermediate buffers of the RenderView and the transformed RenderBlock, and we don’t need to update them any more. For each frame, those buffers will be composited together with the RenderVideo buffer. This RenderVideo will be updating its buffer whenever a new video frame arrives, but it won’t affect the content of the other GraphicsLayers.

So now we have successfully separated the content that is changing and needs to be updated from the content that remains constant and doesn’t need to be repainted anymore, just composited.

Accelerated compositing and threaded accelerated compositing

There’s something else that be done in order to increase the rendering performance, and it’s using the GPU to perform the composition. The GPU is highly optimized to perform operations like the buffer composition that we need to do, as well as handle 3D transforms, blending, etc. We just need to upload the buffers into textures and let the GPU handle the required operations. WPE does this though the usage of the EGL and GLES2 graphics APIs. In order to perform the composition, EGL is used to create a GLES2 EGLContext. Using that context, the intermediate buffers are uploaded to textures, and then those textures are positioned and composited according to their appropriate positions. This leverages the GPU for the composition work, leaving the CPU free to perform other tasks.

This is why this step is called accelerated compositing.

But there’s more.

Until this point, all the steps that are needed to render the content of the page are performed in the main thread. This means that while the main thread is rendering and compositing, it’s not able to perform other tasks, like run JS code.

WPE improves this by using a parallel thread whose only mission is to perform the composition. You can think of it as a thread that runs a loop that composites the incoming buffers using the GPU when there’s content to render. This is what we call threaded accelerated compositing.

This is specially useful when there’s a video or an animation running on the page:

  • If there’s a video running in the page, in the non-threaded case, for each video frame the main thread would need to get the frame and perform the composition with the rest of the page content. In the threaded case, the video element delivers the frames directly to the compositor thread, and requests a composition to be done, without the main thread being involved at all.

  • If there’s an animation, in the non-threaded case, for each frame of the animation the main thread would need to calculate the animation step and then perform the composition of the animated element with the rest of the page content. In the threaded case, the animation is passed to the compositor thread, and the animation steps are calculated on that thread, triggering a composition when needed. The main thread doesn’t need to do anything besides starting the animation.

It would take another post to explain in detail how the threaded accelerated composition is implemented on WPE, but if you’re curious about it, know that WPE uses an specialization of the GraphicsLayer called CoordinatedGraphicsLayer in order to implement this. You can use that as an starting point.

So this is the whole process that’s performed in WPE in order to display the content of a page. We hope it’s useful!


At Igalia we’re constantly evolving and improving WPE, and have ongoing efforts to improve the graphics architecture as well. Besides small optimizations and refactors here and there, the most important goals that we have are:

  • Add a GPU process. Currently the EGL and GLES2 operations are performed in the web process. As there can be several web processes running when several pages are open, this means the browser can be using a lot of EGL contexts in total, which is a waste of memory. Also, all these processes could potentially be affected by errors, leaks, etc., in the code that handles the GPU operations. The idea is to centralize all the GPU operations into a single process, the GPU one, so all the web processes will issue paint requests to the GPU process instead of painting their content themselves. This will reduce the memory usage and improve the software’s robustness.

  • Remove CPU rasterization and paint all the content with GLES2. Using the CPU to paint the layer contents with cairo is expensive, especially in platforms with slow CPUs, as embedded devices sometimes do. Our goal here is to completely remove the cairo rasterization and use GLES2 calls to render the 2D primitives. This will greatly improve the rendering performance.

  • Use ANGLE to perform WebGL operations. WPE currently implements the WebGL 1.0 specification through direct calls to GLES2 methods. We are changing this in order to perform the operations using ANGLE, which will allow WPE to support the WebGL 2.0 specification as well.

But what about the backends?

In the previous post there was a mention of backends that are used to integrate with the underlying platform. How is this relevant to the graphics architecture?

Backends have several missions when it comes to communicate with the platform, but regarding graphics, they have two functions to achieve:

  • Provide a platform dependent surface that WPE will render to. This can be a normal buffer, a Wayland buffer, a native window, or whatever, as long as the system EGL implementation allows creating an EGLContext to render to it.

  • Process WPE indications that a new frame has been rendered, performing whatever tasks are necessary to take that frame to the display. Also notify WPE when that frame was been displayed.

The most common example of this is a Wayland backend, which provides a buffer to WPE for rendering. When WPE has finished rendering the content, it notifies the backend, which sends the buffer to the Wayland compositor, and notifies back to WPE when the frame has been displayed.

So, whatever platform you want to run WPE on, you need to have a backend providing at least these capabilities.

Final thoughts

This was a brief overview of how WPE rendering works, and also what are the major improvements we’re trying to achieve at Igalia. We’re constantly putting in a lot of work to keep WPE the best web engine available for embedded devices.

If this post got you interested in collaborating with WPE development, or you are in need of a web engine to run on your embedded device, feel free to contact us. We’ll be pleased to help!

We also have open positions at the WebKit team at Igalia. If you’re motivated by this field and you’re interested in developing your career around it, you can apply here!

July 15, 2022 12:00 AM

July 01, 2022

Claudio Saavedra: Fri 2022/Jul/01

Igalia WebKit

I wrote a technical overview of the WebKit WPE project for the WPE WebKit blog, for those interested in WPE as a potential solution to the problem of browsers in embedded devices.

This article begins a series of technical writeups on the architecture of WPE, and we hope to publish during the rest of the year further articles breaking down different components of WebKit, including graphics and other subsystems, that will surely be of great help for those interested in getting more familiar with WebKit and its internals.

July 01, 2022 10:39 AM

WPE WebKit Blog: An overview of the WPE WebKit project

Igalia WebKit

In the previous post in this series, we explained that WPE is a WebKit port optimized for embedded devices. In this post, we’ll dive into a more technical overview of the different components of WPE, WebKit, and how they all fit together. If you’re still wondering what a web engine is or how WPE came to be, we recommend you to go back to the first post in the series and then come back here.

WebKit architecture in a nutshell

To understand what makes WPE special, we first need to have a basic understanding of the architecture of WebKit itself, and how it ties together a given architecture/platform and a user-facing web browser.

WebKit, the engine, is split into different components that encapsulate its different parts. At the heart of it is WebCore. As the name suggests, this contains the core features of the engine (rendering, layout, platform access, HTML and DOM support, the graphics layer, etc). However, some of these ultimately depend heavily on the OS and underlying software platform in order to function. For example: how do we actually do any I/O on different platforms? How do we render onscreen? What’s the underlying multimedia platform and how does it decode media and play it?

WebCore handles the multitude of potential answers to these questions by abstracting the implementation of each component and allowing port developers to fill the gaps for each supported platforms. For example, for rendering on Mac, Cocoa APIs implement the graphics APIs needed. On Linux, this can be done through different implementations via Wayland, Vulkan, etc. For networking I/O on Mac, the networking APIs in the Foundation framework are used. On Linux, libsoup fills that gap, and so on.

On the opposite side, for browser implementors to be able to write a browser using WebKit, an API is needed. WebKit, after all, is a library. WebKit ports, besides providing the platform support described above, also provide APIs that suit the target environments: The Apple ports provide Objective-C APIs (which are then used to write Safari and the iOS browsers, for instance), while the GTK+ port provides a GObject-based APIs for Linux (that are used in Epiphany, the GNOME browser, and other GNOME applications that rely on WebKit to render HTML). All of these APIs are built on top of an internal, middle-man, C API that is meant to make it easy for each port to provide a high-level API for browser developers.

With all this in place, it would seem that it shouldn’t be so difficult for any vendor trying to reuse WebKit in a new platform to support new hardware and implement a browser, right? All that you need to do is:

  • Implement backends that integrate with your hardware platform: for multimedia, IO, OS support, networking, graphics, etc.
  • Write an API that you can use to plug the engine into your browser.
  • Maintain the changes needed off-tree, that is, outside the source code tree of WebKit.
  • Keep your implementation up-to-date with the many changes that happen in the WebKit codebase on a daily basis, so that you can update WebKit regularly and take advantage of the many bug fixes, improvements, and new features that land on WebKit continuously.

Does that sound easy? No, it’s not easy at all! In fact, implementation of ports in this fashion is strongly discouraged and vendors who have tried this approach in the past have had to do a huge effort just to play catch-up with the fast-paced development of WebKit. This is where WPE comes to the rescue.

Simplifying browsers development in the diverse embedded world

To simplify the task of porting WebKit to different platforms, Igalia started working on a platform-agnostic, Linux-based, and full-featured port of WebKit. This port relies on existing and mature platform backends for everything that can be easily reused across platforms: multimedia, networking, and I/O, which are already present in-tree and are used by Linux ports, like the GTK one. For the areas that are most likely to require hardware-specific support (that is, graphics and input), WPE abstracts the implementation so that it can be more easily provided out of tree, allowing implementors to avoid having to deal with the WebKit internals more than what’s strictly needed.

Additionally, WPE provides a high-level API that can be used to implement actual browsers. This API is very similar to the WebKitGTK API, making it easy for developers already familiar with the latter to start working with WPE. The cog library also serves as a wrapper around WPE to make it easier still. Once WPE was mature enough, it was accepted by Apple as an official WebKit port, meaning that the port lives now in-tree and takes immediate advantage of the many improvements that land on the WebKit repository on a daily basis.

How does WPE integrate with WebKit?

A diagram of the WPE WebKit architecture

The WPE port has several components. Some are in-tree (that is, are a part of WebKit itself), while others are out-of-tree. Let’s examine those components and how they relate to each other, from top to bottom:

  • The Cog library. While not an integral part of WPE, libcog is a shell library that simplifies the task of writing a WPE browser from the scratch, by providing common functionality and helper APIs. This component also includes the cog browser, a simple WPE browser built on top of libcog that can be used as a reference or a starting point for the development of a new browser for a specific use case.
  • The WPE WebKit API: the entry point for browser developers to the WebKit engine, provides a comprehensive GObject/C API. The cog library uses this API extensively and we recommend relying on it, but for more specific needs and more fine-tuning of the engine, working directly with the WebKit API can be often necessary. The API is stable and easy to use, especially, and for those familiar with the GTK/GNOME platform.
  • WPE’s WebCore implementation: This part, internal to WebKit, implements an abstraction of the graphics and input layers of WebKit. This implementation relies on the libwpe library to provide the functionality required in an abstract way. Thanks to the architecture of WPE, implementors don’t need to bother with the complexities of WebCore and WebKit internals.
  • The libwpe library. This is an out-of-tree library that provides the API required by the WPE port in a generic way to implement the graphical and input backends. Specific functionality for a concrete platform is not provided, but the library relies on the existence of a backend implementation, as is described next.
  • Finally, a WPE backend implementation. This is where all the platform-specific code lives. Backends are loadable modules that can be chosen depending on the underlying hardware. These should provide access to graphics and input depending on the specific architecture, platform, and operating system requirements. As a reference, WPEBackend-fdo is a backend, which uses Wayland and technologies, and is supported for several architectures, including NXP and Broadcom chipsets, like the Raspberry Pi, and also regular PC architectures, easing testing and development.

An implementor interested in building a browser in a new architecture only needs to focus on the development of the last component – a WPE backend. Having a backend, starting the development of a WebKit-powered browser is already much easier than it ever was!

For a more detailed description of the architecture of WPE and WebKit, check this article on the architecture of WPE.

OK, sounds interesting, how do I get my hands dirty?

If you have made it this far, you should give WPE a try!

We have listed several on the exploring WPE page. From there, you will see that depending on how interested you are in the project, your background, and what you’d like to do with it, there are different ways!

It can be as easy as installing WPE directly from the most popular Linux distributions or downloading and flashing prebuilt images for the Raspberry Pi. There are easy and flexible options like Flatpak or Balena, which you can dig into to learn more. If you want to build WPE yourself, you can use Yocto and if you’d like to contribute—that’s very welcome!

Happy hacking!

July 01, 2022 12:00 AM

June 29, 2022

Patrick Griffis: WebExtension Support in Epiphany

Igalia WebKit

I’m excited to help bring WebExtensions to Epiphany (GNOME Web) thanks to investment from my employer Igalia. In this post, I’ll go over a summary of how extensions work and give details on what Epiphany supports.

Web browsers have supported extensions in some form for decades. They allow the creation of features that would otherwise be part of a browser but can be authored and experimented with more easily. They’ve helped develop and popularize ideas like ad blocking, password management, and reader modes. Sometimes, as in very popular cases like these, browsers themselves then begin trying to apply lessons upstream.

Toward universal support

For most of this history, web extensions have used incompatible browser-specific APIs. This began to change in 2015 with Firefox adopting an API similar to Chrome’s. In 2020, Safari also followed suit. We now have the foundations of an ecosystem-wide solution.

“The foundations of” is an important thing to understand: There are still plenty of existing extensions built with browser-specific APIs and this doesn’t magically make them all portable. It does, however, provide a way towards making portable extensions. In some cases, existing extensions might just need some porting. In other cases, they may utilize features that aren’t entirely universal yet (or, may never be).

Bringing Extensions to Epiphany

With version 43.alpha Epiphany users can begin to take advantage of some of the same powerful and portable extensions described above. Note that there are quite a few APIs that power this and with this release we’ve covered a meaningful segment of them but not all (details below). Over time our API coverage and interoperability will continue to grow.

What WebExtensions can do: Technical Details

At a high level, WebExtensions allow a private privileged web page to run in the browser. This is an invisible Background Page that has access to a browser JavaScript API. This API, given permission, can interact with browser tabs, cookies, downloads, bookmarks, and more.

Along with the invisible background page, it gives a few options to show a UI to the user. One such method is a Browser Action which is shown as a button in the browser’s toolbar that can popup an HTML view for the user to interact with. Another is an Options Page dedicated to configuring the extension.

Lastly, an extension can inject JavaScript directly into any website it has permissions to via Content Scripts. These scripts are given full access to the DOM of any web page they run in. However content scripts don’t have access to the majority of the browser API but, along with the above pages, it has the ability to send and receive custom JSON messages to all pages within an extension.

Example usage

For a real-world example, I use Bitwarden as my password manager which I’ll simplify how it roughly functions. Firstly there is a Background Page that does account management for your user. It has a Popup that the user can trigger to interface with your account, passwords, and options. Finally, it also injects Content Scripts into every website you open.

The Content Script can detect all input fields and then wait for a message to autofill information into them. The Popup can request the details of the active tab and, upon you selecting an account, send a message to the Content Script to fill this information. This flow does function in Epiphany now but there are still some issues to iron out for Bitwarden.

Epiphany’s current support

Epiphany 43.alpha supports the basic structure described above. We are currently modeling our behavior after Firefox’s ManifestV2 API which includes compatibility with Chrome extensions where possible. Supporting ManifestV3 is planned alongside V2 in the future.

As of today, we support the majority of:

  • alarms - Scheduling of events to trigger at specific dates or times.
  • commands - Keyboard shortcuts.
  • cookies - Management and querying of browser cookies.
  • downloads - Ability to start and manage downloads.
  • menus - Creation of context menu items.
  • notifications - Ability to show desktop notifications.
  • storage - Storage of extension private settings.
  • tabs - Control and monitoring of browser tabs, including creating, closing, etc.
  • windows - Control and monitoring of browser windows.

A notable missing API is webRequest which is commonly used by blocking extensions such as uBlock Origin or Privacy Badger. I would like to implement this API at some point however it requires WebKitGTK improvements.

For specific API details please see Epiphany’s documentation.

What this means today is that users of Epiphany can write powerful extensions using a well-documented and commonly used format and API. What this does not mean is that most extensions for other browsers will just work out of the box, at least not yet. Cross-browser extensions are possible but they will have to only require the subset of APIs and behaviors Epiphany currently supports.

How to install extensions

This support is still considered experimental so do understand this may lead to crashes or other unwanted behavior. Also please report issues you find to Epiphany rather than to extensions.

You can install the development release and test it like so:

flatpak remote-add --if-not-exists gnome-nightly
flatpak install gnome-nightly org.gnome.Epiphany.Devel
flatpak run --command=gsettings org.gnome.Epiphany.Devel set org.gnome.Epiphany.web:/org/gnome/epiphany/web/ enable-webextensions true

You will now see Extensions in Epiphany’s menu and if you run it from the terminal it will print out any message logged by extensions for debugging. You can download extensions most easily from Mozilla’s website.

June 29, 2022 04:00 AM

June 20, 2022

Frédéric Wang: Update on OpenType MATH fonts

Igalia WebKit

I mentioned in a previous post that Igalia organized the Web Engines Hackfest 2022 last week. As usual, fonts were one of the topic discussed. Dominik Röttsches presented COLRv1 color vector fonts in Chrome and OSS (transcript) and we also settled a breakout session on Tuesday morning. Because one issue raised was the availability of OpenType MATH fonts on operating systems, I believe it’s worth giving an update on the latest status…

There are only a few fonts with an OpenType MATH table. Such fonts can be used for math layout e.g. modern TeX engines to render LaTeX, Microsoft Office to render OMML or Web engines to render MathML. Three of such fonts are interesting to consider, so I’m providing a quick overview together with screenshots generated by XeTeX from the LaTeX formula $${\sqrt{\sum_{n=1}^\infty {\frac{10}{n^4}}}} = {\int_0^\infty \frac{2x dx}{e^x-1}} = \frac{\pi^2}{3} \in {\mathbb R}$$:

Recently, Igalia has been in touch with Myles C. Maxfield who has helped with internal discussion at Apple regarding inclusion of STIX Two Math in the list of fonts on macOS. Last week he came back to us announcing it’s now the case on all the betas of macOS 13 Ventura 🎉 ! I just tested it this morning and indeed STIX Two Math is now showing up as expected in the Font Book. Here is the rendering of the last slide of my hackfest presentation in Safari 16.0:

Screenshot of a math formula rendered with STIX Two Math by Safari

Obviously, this is a good news for Chromium and Firefox too. For the former, we are preparing our MathML intent-to-ship and having decent rendering on macOS by default is important. As for the latter, we could in the future finally get rid of hardcoded tables to support the deprecated STIXGeneral set.

Another interesting platform to consider for Chromium is Android. Last week, there has been new activity on the Noto fonts bug and answers seem more encouraging now… So let’s hope we can get a proper math font on Android soon!

Finally, I’m not exactly sure about the situation on Linux and it may be different for the various distributions. STIX and Latin Modern should generally be available as system packages that can be easily installed. It would be nicer if they were pre-installed by default though…

June 20, 2022 12:00 AM