March 31, 2025

Igalia WebKit Team: WebKit Igalia Periodical #19

Igalia WebKit

Update on what happened in WebKit in the week from March 24 to March 31.

Cross-Port šŸ±

Multimedia šŸŽ„

GStreamer-based multimedia support for WebKit, including (but not limited to) playback, capture, WebAudio, WebCodecs, and WebRTC.

ManagedMediaSource was enabled in WPE WebKit and WebKitGTK.

JavaScriptCore šŸŸ

The built-in JavaScript/ECMAScript engine for WebKit, also known as JSC or SquirrelFish.

The JSC jitless Wasm tests now work again on ARMv7.

Doing a 32-bit build on ARM64 hardware now works with GCC 11.x as well.

Graphics šŸ–¼ļø

Landed a change that improves the painting of tile fragments in the compositor if damage propagation is enabled and if the tiles sizes are bigger than 256x256. In those cases, less GPU is utilized when damage allows.

The GTK and WPE ports no longer use DisplayList to serialize the painting commands and replay them in worker threads, but SkPictureRecorder/SkPicture from Skia. Some parts of the WebCore painting system, especially font rendering, are not thread-safe yet, and our current cross-thread use of DisplayList makes it harder to improve the current architecture without breaking GTK and WPE ports. This motivated the search for an alternative implementation.

Community & Events šŸ¤

Sysprof is now able to filter samples by marks. This allows for statistically relevant data on what's running when a specific mark is ongoing, and as a consequence, allows for better data analysis. You can read more here.

Thatā€™s all for this week!

By Unknown at March 31, 2025 07:58 PM

WebKit Features in Safari 18.4

Surfin’ Safari

Safari 18.4 is here! It includes 84 new features, including a completely new declarative mechanism for sending Web Push notifications, lots of CSS including a brand-new shape() function, P3 & translucency for the HTML color picker, media formats with more robust support for recording, new Web APIs including modern popover manipulation, new JavaScript features like Iterators, a faster way to jump to device viewport presets in Responsive Design Mode, new Web Extension API, improvements to WKWebView, and enhancements across Networking, Storage, and Connection Securityā€”plus much more.

A lot of our focus this winter has been on improving the quality and polish of existing web platform features, with a goal of greatly improving compatibility. WebKit for Safari 18.4 includes 184 resolved issues and 13 deprecations of older technology.

If youā€™ve struggled with support for something in WebKit or Safari in the past, please test again with WebKit for Safari 18.4. You can always file an issue about WebKit at bugs.webkit.org. Or, if the issue involves technology deeper in the stack, file feedback with a sysdiagnose to provide information on how the operating system itself is being impacted. If you run into a website that isnā€™t working as expected, please file a report at webcompat.com and our team will take a look. Filing issues really does make a difference. You can always ping our web evangelists: Jen Simmons on Bluesky / Mastodon, Saron Yitbarek on BlueSky, or Jon Davis on Bluesky / Mastodon.

Hereā€™s a tour of whatā€™s new with WebKit in Safari 18.4.

Declarative Web Push

Reaching users through push notifications is a powerful and important part of any modern computing platform. In 2013, Safari 7 on OS X 10.9 Mavericks added Safari Push, giving sites the ability to send push notifications across the web for the very first time. We learned a lot about how websites used this capability, and how users responded to it.

Other browsers were also eager to add push notifications to the web. The development of the Service Worker API coincided with the development of Push API, Notifications API, and RFC 8030. All four were combined into what we now call Web Push. Chrome first supported these standards in 2015 and Firefox in 2016.

The Safari team at Apple continued to refine Safari Push over the years, learning more about power usage, privacy, and its potential for abuse. The WebKit team at Apple watched the deployment of Web Push standards closely, then made deliberate decisions in implementing those standards in a privacy and power preserving way. That implementation shipped Web Push for Safari 16.1 on macOS followed by support for web apps on iOS and iPadOS 16.4.

The Web Push standards have required a Service Worker since the beginning, much like how web apps require Service Workers in Chromium browsers. Compared to the original Safari Push, which used a declarative model, requiring a Service Worker introduces added complexity for web developers. It also demands more from the system ā€” consuming additional battery and CPU resources ā€” and opens the door to potential misuse. Much like how web apps created from within Safari have never required a Service Worker on iOS, iPadOS, or macOS, we wanted the web platform to have push notifications that can also be declarative, displaying instantly without requiring a Service Worker.

Over the last several years weā€™ve been working on a new technology for push notifications on the web ā€” Declarative Web Push. Learn all about how we designed and implemented it in Meet Declarative Web Push.

Declarative Web Push is now available on iOS and iPadOS 18.4 for web apps added to the Home Screen.

CSS

Shape function

For complex graphical effects like clipping an image or video to a shape, authors often fall back on CSS masking so that they can ensure that the mask adapts to the size and aspect ratio of the content being masked. Using the clip-path property was problematic, because the only way to specify a complex shape was with the path() function, which takes an SVG-style path, and the values in these paths donā€™t have units; they are just treated as CSS pixels. It was impossible to specify a path that was responsive to the element being clipped.

The CSS shape() function, new in WebKit for Safari 18.4, addresses these shortcomings. The shape() function is a new member in the family of CSS basic shapes, and provides a way to describe an SVG-style path as a list of path commands which use CSS units. For example, to create this simple shape:

Solid blue baseball diamond shape

We can use this style:

clip-path: shape(from right center,
line to bottom center,
arc to top center of 50% 50% cw,
line to right center);

Details styling

WebKit for Safari 18.4 adds several improvements to the experience of using <details> and <summary> elements, continuing a slow march to significantly improve this feature. If you steered away from it in the past because of limitations, you should try it again. Web standards have evolved in recent years, and all browsers have been improving support as part of Interop 2025.

First, there is new support for the::details-content pseudo-element. You can use this pseudo-element to select just the content that appears when the details element is open, so you can style it independently.

Try this demo out in a browser with support.

This also means you can animate the height of this container for the first time, solving a long-standing problem that previously required JavaScript or an extra container around the content.

And WebKit for Safari 18.4 reimplements the <details> and </details><summary> disclosure triangle as a list item. This means you can now easily change the character used like this: summary { list-style: "+ "; } and further customize its styling using the::marker pseudo-element.

These changes modernize <details> and <summary>, making it possible to use this HTML instead of building custom controls from scratch using JavaScript. Itā€™s faster and easier for you, and ensures your results have the proper semantics and full support for users of assistive technologies.

Sideways writing modes

Writing modes in CSS provide support for a wide variety of layout directions for written languages. At its core, the writing-mode property switches the text flow in the inline direction between a horizontal or vertical layout, as well as determining in which the direction in blocks stack. Safari has had support for writing-mode: horizontal-tb, vertical-rl, and vertical-lr since 2011 (prefixed until March 2017). Now, WebKit for Safari 18.4 adds support for writing-mode: sideways-rl and writing-mode: sideways-lr.

The sideways writing modes are very similar to vertical writing modes, but not the same. They were intended to be used for text thatā€™s normally laid out horizontally to be instead displayed vertically as a graphic design effect. Note in the demo below the difference between how CJK characters are rendered in sideways-* vs vertical-*. When the intention is to layout out typical horizontal text sideways, using sideways-rl instead of vertical-rl ensures punctuation and other direction-neutral characters are typeset correctly for the purpose at hand. It also handles the baseline of the text differently. Using sideways-lr instead of vertical-lr creates an entirely different result. Dig into this example to see more, including toggling to see the differences in text wrapping.

Try this demo in a browser with support.

Text auto space

WebKit for Safari 18.4 adds support for the brand new text-autospace property, which automatically introduces extra space to provide visual breathing room when transitioning between scripts. In the distant past, Chinese and Japanese were written in a purely native writing system derived from ancient Chinese Han characters. But in modern typesetting, they liberally mix in Western numbers and letters. When set solid, the boundary between the traditional characters and the new foreign characters feels cramped, and so modern typesetting convention has adopted a practice of inserting a little bit of extra space at these boundaries. With the text-autospace property, the browser automatically inserts this extra space whenever it detects a script transition.

The options for values include:

  • ideograph-alpha creates extra spacing between runs of CJK and non-CJK letters.
  • ideograph-numeric creates extra spacing between runs of CJK and non-CJK numerals.
  • normal does both ideograph-alpha and ideograph-numeric at the same time.
  • no-autospace inserts no space at all.

Try this demo in a browser with support.

WebKit defaults to text-autospace: no-autospace to match the current default behavior of older (currently all) browsers. The CSS specification calls for browsers to switch the default to text-autospace: normal ā€” automatically applying better spacing to all CJK content on the web, no matter when the website was created.

We have not yet switched to the new default behavior. Use text-autospace In Safari 18.4 to opt your content into the new spacing, and test it out. If you have thoughts about the implementation, file an issue at bugs.webkit.org. We want to ensure our implementation is well tested before changing the default.

View Transitions

Last December, Safari 18.2 added support for view-transition-name: auto, allowing you to avoid individually naming potentially hundreds of different content items if you are applying transitions to the content on a single page. With auto , the id is first checked to be identical across the transition, then if the id isnā€™t present, the elements are checked directly to be identical across the transition.

In WebKit for Safari 18.4, weā€™re adding support for view-transition-name: match-element, which only checks the elements to be identical across the transition. This can only be used for single-page view transitions, whereas auto can be used for multi-page view transitions through matching the id attribute.

And more CSS updates

Thereā€™s also added support for several more CSS features in WebKit for Safari 18.4:

  • gradients with only one stop
  • fallbacks inside attr(), for example ā€” attr(data-count, "0")
  • unicode-bidi text rendering UA rules (except for ruby elements)

And the non-standard CSSUnknownRule interface has been removed.

HTML

Now, WebKit for Safari 18.4 enhances <input type="color" /> to support alpha and colorspace attributes. This means you can offer users the chance to choose a color from the Display P3 colorspace, and/or to adjust the opacity of their choice. You can also use any supported CSS color syntax inside the value attribute of the <input type="color" /> control and it will be properly converted as per the colorspace attribute.

The color picker showcasing the opacity and color wheel

And the WebKit team worked with the WHATWG community to standardize these color picker enhancements in the HTML standard.

WebKit for Safari 18.4 adds iOS support for thewebkitdirectory attribute on <input type="file" /> elements. When a file input with the attribute is invoked, the document picker is immediately displayed with non-directory items grayed out. From this document picker, a directory can be uploaded by navigating into the target directory and pressing ā€œOpenā€.

Support for the composite attribute on an <img> element has been removed in WebKit for Safari 18.4. It was originally added in April 2004 to support composite operations on images (combining two images for creating an effect) in the context of the now discontinued Dashboard macOS feature. This attribute is not necessary anymore and can be safely removed.

Web Inspector

Responsive Design Mode in Safari 18.4 allows you to select from a list of device viewport size presets to quickly test the layout of your web page. Presets can be rotated for portrait and landscape orientations. Viewport size presets offer a good approximation of how your web page will be affected by viewport sizes, but they donā€™t represent exact layout, rendering, and behavior as experienced on an actual device. For example, the page layout on a device might be influenced by the browser address bar or the on-screen keyboard. To get high fidelity previews, use the Open with Simulator menu to check the webpage on a device simulator.

Screenshot of the top section of webkit.org viewed in Responsive Design Mode

If you use JSContexts in your macOS, iOS, iPadOS, visionOS, watchOS or tvOS app, you can use Safari Web Inspector to debug them. Sometimes, you need to automatically inspect and pause script execution in a JSContext before it has a chance to run so you can set breakpoints and manually step through the code. Prior to Safari 18.4, you could only configure these options for the entire device which could lead to interruptions as JSContexts from other apps would also be automatically inspected. Starting in Safari 18.4, you can configure automatic inspection and pausing of JSContexts just for your app.

The new Inspect Apps and Devices menu item in the Develop menu opens a window with a list of all connected devices and currently running apps that have inspectable content, such as webpages, service workers, JSContexts, WKWebViews, and web extension background pages. Next to each app in the list, there is a triple-dot menu which reveals options to configure automatic inspection and pausing of JSContexts just for that app. The settings apply to any new JSContext created by that app. If the JSContext you want to automatically inspect is created at app launch, youā€™ll need to restart the app to see the effect.

Screenshot of the Apps and Devices Inspection menu showing devices on the left panel and apps in the primary panel

You can use a Request Local Override to add or change headers for requests matching a URL without modifying any of the other data by ticking the checkbox for ā€œInclude original request data” in the Local Override configuration popover. Any new or changed headers will augment the request headers. Starting in Safari 18.4, you can select the “passthrough” option for the Method selector to apply the override for any HTTP method.

Screenshot of thethe Sources panel in Web Inspector open to the Local Overrides section and towing the Request Override form for webkit.org

The User Agent string overrides list now includes Android options. You can apply an override for the currently open page using the User Agent submenu from the Safari Develop menu. When remotely-inspecting a web page on a connected device or simulator, you can find User Agent string overrides in the Device Settings popover.

The console.screenshot method from the Web Inspector Console API now supports providing a DOMRect as an argument to capture a screenshot of a precise area of the web page.

You can grab a DOMRect from an existing DOM node:

console.screenshot(document.querySelector("#testNode").getBoundingClientRect())

Or you can define a DOMRect with custom values:

console.screenshot(new DOMRect(0, 0, 800, 600))

Web Inspector now supports the ignoreList field from the official source map specification. Tools that generate source maps can use this field to identify sources that can be ignored, for example framework code or bundler-generated code, to ease the cognitive burden for developers when debugging their own code.

The Cookie table view in the Storage tab can now be configured to show a column with the cookie partition key for partitioned cookies.

Media

WebKit for Safari 18.4 adds support for Image Capture API. It provides a way to enable the capture of images or photos from a camera or other photographic device through MediaStream Image Capture API.

As part of our efforts to improve web compatibility, MediaRecorder in WebKit for Safari 18.4 now supports creating WebM files using the Opus audio codec and either VP8 or VP9 for video. Additionally, it can now create ISOBMFF (fragmented MP4) files, which can be easily used with Media Source Extensionsā€™ SourceBuffer. MediaRecorder can also generate high-quality, lossless audio tracks in ALAC or PCM formats. And weā€™ve added support for video tracks in H264, HEVC, and AV1 (for devices with AV1 hardware support).

WebKit for Safari 18.4 rounds out our support for media formats by adding Ogg container support for both Opus and Vorbis audio on macOS Sequoia 15.4, iOS 15.4, iPadOS 15.4, and visionOS 2.4.

WebRTC

WebKit for Safari 18.4 adds WebRTC support for the MediaSession capture mute API:

  • Web pages can detect in a central place whether user muted/unmuted camera/microphone/screenshare capture via specific actions
  • Web pages can ask capture to be muted/unmuted via dedicated methods. Unmuting requires user activation and will not trigger a user prompt if muting was done by the web page.

WebKit for Safari 18.4 adds speaker selection API on macOS:

  • Speakers can be enumerated once microphone access is granted
  • Audio rendered with HTMLMediaElement can be routed to specific speakers via setSinkId.

SVG

There are a few updates to SVG in WebKit for Safari 18.4.

Thereā€™s new support for the lh and ch units inside of SVG. Note that support for the ch does not include support for upright vertical character width.

SVGImageElement.prototype.decode() is now supported to help you avoid an empty image while waiting to download and decoding an SVG image.

And WebKit for Safari 18.4 removes support for the SVG 1.1 kerning property, and the SVGDocument alias to XMLDocument.

Web API

The Screen Wake Lock API now also works in Home Screen Web Apps on iOS and iPadOS 18.4. This allows you to prevent a device from dimming and locking the screen. Itā€™s especially great for use cases like recipe apps, when the user is still reading but not touching the screen.

The dialog.requestClose() method is new with WebKit for Safari 18.4. Use it to request to close a <dialog>. It differs from the other methods by firing a cancel event before firing the close event and closing the dialog.

WebKit for Safari 18.4 adds an option to set an invoker for popover from an imperative API with the showPopover() and togglePopover() methods. For example:

element.showPopover({ source: document.querySelector("#menu-button") })

The Cookie Store API is a new asynchronous API in WebKit for Safari 18.4 for managing cookies and getting notifications about changes. Due to privacy concerns, this new API exposes only the ā€œnameā€ and ā€œvalueā€ properties of cookiesā€”just like document.cookie. The change event is implemented for windows, but not yet for service workers due to ambiguities in the specification.

Compression Streams now supports compressing and decompressing data using the Brotli format. This may offer significant improvements in both performance and compression size based on the specific data compared to Deflate. Authors only need to update the CompressionStreams constructor to brotli to take advantage of the new feature.

WebKit for Safari 18.4 adds support for X25519 for Web Cryptography which allows access to deriveBits, deriveKey, exportKey, generateKey, and importKey in the SubtleCrypto interface. This offers better security and less reliance on external libraries to get the benefits of secure curves.

Key generation, import and export support for CryptoKeyOKP(x25519/ed25519) is now supported with a CryptoKit implementation, allowing use of Curve25519 in cryptography.

New control of the focusing process is available in WebKit for Safari 18.4 with support for element.focus({ focusVisible: true }). This allows developers to programmatically control the visible focus indicator of an element, to force it to be visible or prevent it from being visible instead of relying exclusively on the User Agent.

WebKit for Safari 18.4 adds support for the PublicKeyCredential.parseCreationOptionsFromJSON() , PublicKeyCredential.parseRequestOptionsFromJSON(), and PublicKeyCredential.toJSON() methods. This provides web developers an easy way to serialize Web Authentication requests and responses objects between client and server.

WebKit for Safari 18.4 adds support for Scroll To Text Fragment feature detection with document.fragmentDirective. This lets you test whether or not text fragments are supported in your browser by checking for existence of the object.

WebKit for Safari 18.4 removes support for built-in wheel event handling for <input type="number" />. Its behavior did not match the equivalent control on Apple platformā€™s and was confusing to end users. Web developers frequently sought to disable it, or would enable it inadvertently.

JavaScript

Iterators

WebKit for Safari 18.4 adds support for several new features from the Iterator Helpers proposal. When interacting with large sets of data it might not be possible to fit all your data in memory at once, such as in an Array. With iterator helpers, data is handled lazily so it doesn’t all have to be in memory at the same time.

As an example, Around the World in Eighty Days is a French novel by Jules Verne. The hero, Phileas Fogg, makes a bet that he can navigate around the world in no more than 80 days. These are the cities Phileas Fogg will go through:

function* cities() {
yield "London (UK)";
yield "Suez (Egypt)";
yield "Bombay (India)";
yield "Calcutta (India)";
yield "Victoria (Hong-Kong)";
yield "Singapore (Singapore)";
yield "Yokohama (Japan)";
yield "San Francisco (USA)";
yield "New-York (USA)";
yield "London (UK)";
// If Phileas went to every city in the world this list would be very long.
}

We can make an iterator out of the cities generator function by calling it. For other iterable data structures such as Map, Set, and Array we can use Iterator.from.

let citiesIter = cities();

let otherCitiesIter = Iterator.from(["London (UK)", "Suez (Egypt)", "Bombay (India)"]);

To iterate through an iterator, we can call next():

citiesIter.next(); // < {value: "London (UK)", done: false}
citiesIter.next(); // < {value: "Suez (Egypt)", done: false}
citiesIter.next(); // < {value: "Bombay (India)", done: false} // etc. 

As we can see we can iterate through the cities, one by one. If we want to restart the iterator from the beginning, we just need to create a new one:

citiesIter = cities(); 

Let’s create functions that will check if a city is in India or France:

isCityInIndia = (x) => x.includes("India");
isCityInFrance = (x) => x.includes("France");

The method iterator.some() will check if some elements in the iterator meet a certain criteria:

citiesIter.some(isCityInIndia);

It will return true as some of the cities are in India.

Letā€™s make a new iterator again and check for cities in France:

citiesIter.some(isCityInFrance);

As expected, it returns false as none of the cities are in France.

The method Iterator.every() checks if all elements in the iterator meet the specified criteria.

citiesIter.every(isCityInIndia);

It will return false. Indeed. Not all cities from the iterator are in India.

The method Iterator.filter() returns a new iterator whose elements match our criteria.

citiesIter.filter(isCityInIndia);
// Iterator.from(["Bombay (India)", "Calcutta (India)"]);

One of the nicest parts of iterator helpers is that you can compose them. Letā€™s say we want to know how many places Phileas visited in India on his journey. We can use the reduce function on our filtered iterator to get our answer.

cities().filter(isCityInIndia).reduce((count, city) => count + 1, 0);
// 2

The method Iterator.map() applies the function for each elements returned by the iterator when .next() is called.

citiesIter = cities();
// here we create a function modifying the element returned by `next()`.
travelDone = (x); "Travel to " + x + ": done!";
let citiesDone = citiesIter.map(travelDone);
citiesDone.next();
// {value: "Travel to London (UK): done!", done: false}
citiesDone.next();
// {value: "Travel to Suez (Egypt): done!", done: false}
// etc.

These are a couple of examples of the new methods which have been added to Safari. Take your time to discover others: some(), every(), find(), map(), filter(), take(), drop(), flatMap() , toArray(), forEach(), reduce().

JSON Parsing

WebKit improves parsing performance using SIMDe in JSON for fast scanning of strings in JSON.parse, plus fast scanning and copying of strings in JSON.stringify. SIMD (Single Instruction, Multiple Data) is practical when handling computations on a large set of data, where each data element receives the same instruction.

Improved Error detection

WebKit for Safari 18.4 supports Error.isError to identify a ā€œrealā€ native error in a world where Symbol.toStringTag means there isnā€™t a reliable way to test the internal slot for Error instances. It makes it possible to normalize error objects instead of relying on only strings.

try {
  throw "Oops; this is not an Error object. Just a string.";
} catch (e) {
  // test if it's not an error
  if (!Error.isError(e)) {
    // make it a real error
    e = new Error(e);
  }
  console.error(e.message);
}

And more

WebKit also allows for programs using spin-wait loops to give the CPU a hint that itā€™s waiting on a value and still spinning by implementing Atomics.pause.

Canvas

WebKit adds un-prefixed letterSpacing and wordSpacing for CanvasRenderingContext2D in Safari 18.4. This enables you to specify the spacing between words and letters when drawing text in a 2D canvas, without a -webkit prefix.

And support has been removed for three antiquated technologies to improve interoperability and compatibility:

  • webKitBackingStorePixelRatio
  • the prefixed webkitImageSmoothingEnabled ā€” use the standard imageSmoothingEnabled property instead
  • the non-standard legacy alias of Canvas Compositing including setAlpha and setCompositeOperation

Editing

WebKit for Safari 18.4 adds support for ClipboardItem.supports(). When a web application needs to place content in the clipboard of the operating system, it is useful to know in advance if the format is supported by the clipboard. By default, browsers support text/plain, text/html and image/png .

  • This gives the ability to check if other formats are supported. It will send back false when the format is not supported and avoid an error message.
  • It also adds text/uri-list which is a supported format by Safari, useful when sharing list of URLs.

It also improves interoperability by sending TypeError for a new ClipboardItem() with an empty Array.

Also, WebKit for Safari 18.4 fixes document.execCommand("copy") so that it can be triggered even if there is not any text selected.

Loading

With Safari 18.4, WebKit now supports noopener-allow-popups in Cross-Origin-Opener-Policy (COOP). This disconnects the relationship between the opener and the document loaded with its policy, but still allows the document to open other documents if their COOP policy allows it.

WebAssembly

WebKit for Safari 18.4 supports running Wasm when Just-In-Time compilation (JIT) is disabled. That means Safari can still run Wasm in environments where JIT compilation has been turned off to boost system security.

Thereā€™s also support for the new Wasm Exception specification. Exception handling allows code to break control flow when an exception is thrown. The new specification provides both a mechanism for Wasm code to handle JavaScript exceptions, and to throw its own exceptions. This new specification supersedes the legacy proposal, which WebKit supported since Safari 15.2 and will continue to support for compatibility.

WebKit for Safari 18.4 adds support for relaxed_laneselect SIMD instructions which means that when the mask is all its bits set or unset, it will behave like a bitwise select SIMD instruction. Otherwise, if the mask has a different value, the implementation can then use the backing architecture to pick the relaxed instructionā€™s behavior.

Web Extensions

Browser Web Extension APIs

WebKit on iOS 18.4, iPadOS 18.4, visionOS 2.4, and macOS Sequoia 15.4 adds support for integrating web extensions into WebKit-based browsers with a set of straightforward Swift and Objective-C APIs. With the new WKWebExtension, WKWebExtensionContext, and WKWebExtensionController classes, browsers can incorporate web extensions that empower users to customize their browsing experience. Integrating web extensions into WebKit enables all WebKit-based browsers to align on a unified implementation, ensuring they all benefit from continuous improvements and fixes in support of the evolving web extensions standard.

Temporary Extension Installation

New in Safari 18.4 on macOS, you can temporarily install a web extension from disk. This provides a convenient way to develop your extension and test compatibility without building an Xcode project. When loading a temporary extension, youā€™ll have access to most Safari Web Extension functionality. When youā€™re ready to test out nativeMessaging, or prepare your extension for distribution, you can create a new Xcode project using the Safari Web Extension Converter.

Developer ID-Signed and Notarized Safari Web Extensions

Safari 18.4 on macOS now supports Safari Web Extensions that have been Developer ID-signed and notarized. Notarization is an additional step after signing your app and extension with your Developer ID. Appleā€™s notarization service automatically checks for malicious content and code-signing issues. Once notarized, your app and extension is ready for distribution and use in Safari.

Reliable Document Identification

Safari 18.4 adds support for documentId in webRequest, webNavigation, tabs, and scripting APIs, ensuring extensions can reliably track documents when sending messages, injecting scripts, or processing requests. Unlike frameId, which stays the same when a new document loads in the same frame, documentId updates with each navigation, helping extensions avoid interacting with the wrong content.

Efficient Storage Key Retrieval

Safari 18.4 introduces getKeys() in extension storage, allowing developers to retrieve stored keys without fetching their associated values. This improves performance for extensions that manage large sets of structured data, such as those that store user preferences, session data, or categorized content. By retrieving only the keys, extensions can efficiently determine what data is available before deciding which values to load, reducing unnecessary data transfers.

Improved Localization Support

Support for i18n.getSystemUILanguage() and i18n.getPreferredSystemLanguages() in Safari 18.4 provides extensions with access to the userā€™s system language settings. Unlike i18n.getUILanguage(), which returns the browserā€™s interface language, these APIs allow extensions to align with system-wide language preferences. This is particularly useful for extensions that format dates, numbers, and other locale-specific content according to the userā€™s preferred regional settings, even when the browserā€™s locale differs.

Expanded Subframe Injection

Safari 18.4 adds support for match_about_blank and match_origin_as_fallback in extension manifests, as well as matchOriginAsFallback in scripting for dynamically registered content scripts. These properties allow scripts and styles to run in additional frames such as about:blank, data:, and blob: URLs by matching based on the origin of the parent frame rather than the frameā€™s own URL, making it possible to target frames with opaque origins. Host permissions for the parent frameā€™s origin are still required.

WKWebView

In this release, we brought more platform parity across our APIs. On iOS, itā€™s now possible for API clients to customize the upload flow for file inputs using the WKUIDelegate/webView(_:runOpenPanelWith:initiatedByFrame:) delegate method.

We also now expose the buttonNumber and modifierFlags properties of WKNavigationAction on iOS and visionOS.

Lastly, visionOS 2.4 brings Apple Intelligence features like summarization, text compose, rewriting, and proofreading into WebKit client experiences on visionOS with support for Writing Tools. This includes their respective APIs, WKWebView.isWritingToolsActive and WKWebViewConfiguration.writingToolsBehavior.

Networking

WebKit for Safari 18.4 on macOS Sequoia 15.4, iOS 18.4, and visionOS 2.4 introduce support for opt-in partitioned cookies, known as CHIPS. Partitioned cookies allow third-party content on a web page to create and access cookies on that specific site without allowing cross-site tracking. CHIPS is an important technology for web sites that still require access to cookies in a third-party context (e.g., an iframe), and it is an important step toward helping sites finish their migration away from relying on unpartitioned, cross-site cookies.

For example, if https://siteA.example creates an iframe and loads https://siteB.example in it, and the webpage from https://siteB.example creates a partitioned cookie, then that cookie is only accessible to siteB.example on a webpage from siteA.example. Note that WebKit is using a different partitioning boundary for CHIPS compared with its other storage areas (e.g., localstorage). WebKit is aligning with the other browser engines by partitioning cookies by site, as compared to by origin. This means that if both https://news.siteA.example and https://mail.siteA.example embed an iframe from https://chat.siteB.example, then https://chat.siteB.example will have access to the same cookie on both web pages because https://news.siteA.example and https://mail.siteA.example are subdomains of the same site: https://siteA.example.

Partitioned cookies with CHIPS require that the website explicitly sets a new attribute on the cookie. This explicit attribute ensures that WebKit and the website have a shared understanding that the cookie will be only accessible on a particular site. The new attribute is named Partitioned, and it is used in a similar manner to the Secure or HTTPOnly attributes. As with other cookie attributes, the Partitioned attribute is only used when the cookie is set, and it is not accessible afterward.

As an example, if you want to set a partitioned cookie using the HTTP Set-Cookie header, that could look like:

Set-Cookie: TestCookie=12345; SameSite=None; Secure; Partitioned

Note, this cookie includes the SameSite=None and Secure attributes. These attributes are required for a Partitioned cookie, and the cookie will be blocked if those attributes are not set. This means that the cookie much be created and accessed from a secure webpage (e.g., https) and the cookie will be sent in all go your cross-site requests to your server. You can read more about these attributes on the linked pages.

Similar to setting a partitioned cookie with the HTTP header, you can set it using JavaScript, as well. For example, JavaScript could create the same cookie as above:

document.cookie = "TestCookie=12345; SameSite=None; Secure; Partitioned";

And document.cookie will return "TestCookie=12345".

Note, cross-site tracking domains may not be allowed to use partitioned cookies.

If you require access to both partitioned third-party cookies and unpartitioned third-party cookies, then you can continue using the Storage Access API with document.requestStorageAccess() to request access to the unpartitioned cookies.

Storage

WebKit for Safari 18.4 adds support for clearing partitioned cookies using the Clear-Site-Data HTTP header. Support for clearing first party cookies using the Clear-Site-Data was introduced in Safari 17.0. Now, with the introduction of CHIPS, described above, this HTTP header has different behavior depending on which server sends it. If the header is received in the response that was sent by the first party site (e.g., the main web page), then WebKit will clear only unpartitioned cookies for that domain. If the HTTP header is received in a response that was sent by a cross-site iframe, then WebKit will clear only partitioned cookies for the particular site on which the iframe is loaded.

Connection Security

For years, the lock icon in Safari indicated that the connection is secure ā€” that the site is using HTTPS. With more than 87% of all connections made over HTTPS now, secure connections are ubiquitous. The new norm. Meanwhile, the presence of the lock could be creating a false sense of trustworthiness, if users instead believe itā€™s there to signal the website is trustworthy. With this in mind, we removed the lock icon from the Smart Search field for HTTPS connection in Safari 18.4.

For users who would like the ability to learn more about connection security, weā€™re introducing a new option. On macOS, go to Safari menu; Connection Security Details. And on iOS, iPadOS, and visionOS, youā€™ll find the information in Page menu; more; Connection Security Details.

This view lets users confirm the connection is secure, and for the first time on iOS, iPadOS, and visionOS, view certificate information such as CA issuer and expiration date.

Three devices showing three different screens. The first shows the Page Menu and shows options for Page Actions, Tab Actions, and Website Settings for Apple.com. The second screen shows the Connection Security Details options and displays that your connection with apple.com is secure and shows the certificate. The third screen show the three certificates for apple.com.

In the EU, Connection Security Details indicate connections made using an EU Qualified Web Authentication (QWAC) certificate providing an indicator for enhanced trust and security for online interactions on iOS 18.4, iPadOS 18.4, macOS Sequoia 15.4, and in visionOS 2.4.

Additionally, WebKit for Safari 18.4 changes 3DES cipher to show a warning to users that itā€™s a legacy TLS (Transport Layer Security). Tap here to see such a warning.

Security

WebKit for Safari 18.4 adds support for CSP Hash Reporting keywords: report-sha256, report-sha384 and report-sha512. And it removes support for Clear-Site-Data: for executionContexts since Safari was the most only browser with support.

WebKit for Safari 18.4 now enables a user to set a PIN for a security key when itā€™s required during registration.

Resolved Issues

In addition to new features, WebKit for Safari 18.4 includes work to polish existing features.

Browser

  • Fixed an issue where sites would log out automatically after a brief time. (99829958)

CSS

  • Fixed table border-color to be currentColor by default. (48382483)
  • Fixed combining CSS clip-path with any property that creates a new stacking context makes <img> element disappear. (86091397)
  • Fixed resize to not be applied to generated content. (121348638)
  • Fixed contain: size breaking object-fit. (131866042)
  • Fixed: Dropped layout containment from container-type. (132549134)
  • Fixed handling all of the CSS properties in specifications that should cause a UI widget to devolve to a primitive appearance. (134273374)
  • Fixed scrollIntoView alignment to always be honored. (135484284)
  • Fixed:background-clip: border-area to do nothing on the root. (135972986)
  • Fixed vertical-rl writing mode inter-character ruby text being significantly smaller than over ruby text. (135973587)
  • Fixed CSS cursor to not eagerly evaluate calc() values. (136103471)
  • Fixed flex shorthand to not eagerly evaluate calc(). (136103475)
  • Fixed -webkit-perspective to not eagerly evaluate calc(). (136103493)
  • Fixed @property initial-value descriptor to prevent containing var(--foo). (136103499)
  • Fixed delaying the evaluation of calc() for raw font consumers so that each caller can choose the correct behavior. (136103500)
  • Fixed grid to not eagerly evaluate calc() for repetitions value. (136103503)
  • Fixed counter-increment, counter-set, and counter-reset to not eagerly evaluate calc(). (136103519)
  • Fixed CSS nested declarations inside a @scope to behave like :where(:scope). (136856371)
  • Fixed: Updated the shape() function to match the proposed syntax. (138126105)
  • Fixed same-document view transitions performance on pages with many elements. (138966650)
  • Fixed an issue where radial gradients with two color stops at 100% failed to extend the last color. (139369366)
  • Fixed @scope start and end to be a classic (non-forgiving) selector list. (139471866)
  • Fixed updating the base background color where the root has color set explicitly when switching to light or dark modes. (139917332)
  • Fixed performance of querySelectorAll() with :has() descendant selectors. (140093151)
  • Fixed the unicode-bidi default for the <bdo> element. (140662417)
  • Fixed broken revert-layer when logical group CSS properties are explicitly inherited. (140819138)
  • Fixed border-spacing to use the shortest possible serialization (“0px” vs “0px 0px”). (141920587)
  • Fixed subsequent nested styles getting ignored after an incorrect nested selector. (142187930)
  • Fixed font-variant-caps: all-small-caps causing incorrect box-sizing in flex inline context. (142212550)
  • Fixed ensuring the correct logic is run for over-constrained cases when the absolute positioned box is a writing-mode root. (142214631)
  • Fixed animation-name set from the view transitions dynamic UA stylesheet having extra quotes. (142298840)
  • Fixed the serialization and parsing of animation-name strings. (142318879)
  • Fixed text-box-trim accumulation failing when updating the CSS dynamically. (142386761)
  • Fixed text-emphasis to not paint emphasis marks on punctuations. (142387538)
  • Fixed sizing and positioning issues when a popover changes CSS position upon opening. (142491219)
  • Fixed Page Zoom (āŒ˜+ and āŒ˜-) to work with calc() used with font-size on macOS. (142736427) (FB16287129)
  • Fixed scroll-padding and scroll-margin to be strongly typed CSS/Style values. (142830546)
  • Fixed View Transitions to stop running when the user navigates with a swipe. (142844150)
  • Fixed top-level and nesting selector to have zero specificity matching a recent specification update. (143765827)

Editing

  • Fixed document.execCommand("copy") only triggering if there is a selection. (27792460)
  • Fixed an issue where iCloud Notes pasted text copied from a plain text document in Safari as raw markup. (124788252)
  • Fixed highlighting correctly a large text selection that ends with a common phrase. (135973065)
  • Fixed copying a link to a common term in an article to highlight the correct part of the page. (135973186)
  • Fixed missing SecureContext in the ClipboardItem interface. (137197266)
  • Fixed Hebrew text pasted from Safari getting aligned left. (139029945)
  • Fixed setting selection to not set focus unless there is an existing selection. (139075809)
  • Fixed sometimes being unable to select text for non-editable content. (143296175)
  • Fixed missing selection handles after selecting text across multiple lines. (143720155)

Forms

  • Fixed <textarea> to handle switching direction. (73475239)
  • Fixed setting a datetime-local input to a large value cause a crash. (135733092)
  • Fixed <datalist> dropdown keyboard interactions to align with platform conventions. (143012287)
  • Fixed: Disabled all Writing Tools app menu items, except ā€œComposeā€, for empty editable content. (143332082)

Home Screen Web Apps

  • Fixed Screen Wake Lock API for Home Screen Web Apps. (108573133)

HTML

  • Implemented <details> and <summary> disclosure triangle as a list item. (95148788)

Images

  • Fixed broken WebP images in lockdown mode. (144224372)

JavaScript

  • Fixed Array destructuring assignment to close the iterator if an evaluation throws an exception. (121960887)
  • Fixed: Updated Intl.DurationFormat#resolvedOptions to the latest specification. (136276429)
  • Fixed Iterator Helpers methods to not iterate an array. (136303997)
  • Fixed Iterator.prototype.reduce() not properly forwarding the return() call to the underlying iterator. (137181340)
  • Fixed Set.prototype methods to invoke keys() without arguments. (137395979)
  • Fixed Array.from(), Array.fromAsync(), and TypedArray.from() to invoke document.all passed as a mapper. (137490201)
  • Fixed Intl.DurationFormat to have a value limit to match the specification. (137885273)
  • Fixed a rounding error for Intl.DurationFormat. (138261569)
  • Fixed calendar canonicalization logic in DateTimeFormat. (141792829)
  • Fixed broken output for Intl.DurationFormat digital style when hoursDisplay is "auto". (141969050)
  • Fixed Intl.DurationFormat to print a negative sign for minutes after hidden hours. (142119353)
  • Fixed Array.prototype.toReversed to fill holes with undefined. (142197604)
  • Fixed: Increased the matchLimit for regular expressions, allowing complex matches on longer strings. (143202375)

Media

  • Fixed handling an empty srcAttr in Media Element. (132042925)
  • Fixed getUserMedia video track getSettings() returning a stale value for torch and whiteBalanceMode constraints. (137870391)
  • Fixed the space key not pausing a video in fullscreen by making the video mouse focusable. (138037616)
  • Fixed an issue where playback doesn’t always resume after a seek. (140097993)
  • Fixed playing video generating non-monotonic ‘timeupdate’ events. (142275184) (FB16222910)
  • Fixed websites calling play() during a seek() is allowed by the specification so that the play event is fired even if the seek hasn’t completed. (142517488)
  • Fixed seek not completing for WebM under some circumstances. (143372794)
  • Fixed MediaRecorderPrivateEncoder writing frames out of order. (143956063)

Networking

  • Fixed optimistically upgraded navigations to set a timeout based on current network conditions. (135972599)

PDF

  • Fixed switching a PDF from continuous to discrete mode displaying the page(s) that are at the top of the window, even when barely visible. (137608841)
  • Fixed the “Previous Page” context menu option not navigating to previous page in 2-up continuous mode. (139817364)
  • Fixed main frame PDFs served with a CSP sandbox header not loading. (141166987)

Rendering

  • Fixed computing the baseline for replaced elements with an intrinsic ratio but no intrinsic size as flex items. (74279029)
  • Fixed flickering caused by extra resize events dispatched when rotating from landscape to portrait on iOS. (93767145)
  • Fixed adding out-of-flow objects under the inline in a continuation chain, when possible. (102421379)
  • Fixed mix-blend-mode to work for large resolution fixed or stick elements. (104686540)
  • Fixed the missing table collapsed border for <thead>, <tbody>, and <tfoot> elements in the wrong order. (110430887)
  • Fixed handling inline-box trailing content. (112409103)
  • Fixed <input type="range"> taking up space even with width: 0 applied. (113402515)
  • Fixed the Spotify media player disappearing when rotating to landscape mode on iOS. (123870311)
  • Fixed textarea elements to reserve space for overlay scrollbars. (129597865)
  • Fixed grid layout animation performance by caching intrinsic logical heights during the first row sizing pass, improving efficiency and preventing invalidation issues with complex grid configurations. (135791322)
  • Fixed Grid item which is an image with specified sizes failing to update when the src changes. (135972911)
  • Fixed nested inlines’ vertical alignment when line-fit-edge is set. (136036997)
  • Fixed the consistency of table layout with <td width="100%">. (136090741)
  • Fixed repainting to be more consistent for text-underline-position. (136095297)
  • Fixed floats not clearing in the WordPress Classic Editor sidebar layout. (136362683)
  • Fixed handling of out-of-flow children in MathML layout functions to be consistent. (136683070)
  • Fixed a repeating background-image sized to the content-box failing to fill the viewport in an iframe. (136725820)
  • Fixed consistently triggering a reflow when needed for table DOM manipulations. (137300794)
  • Fixed scriptlevel multipler for font-size in MathML. (137671252)
  • Fixed inline marquees to allow them to shrink when adjacent to float(s). (137766071)
  • Fixed a flex container with no flex item to not run flex layout. (137884128)
  • Fixed support for CSS width and height properties on MathML elements. (138174295)
  • Fixed Inline content incorrectly positioning around right-to-left and/or vertical shape-outside floats. (139076129)
  • Fixed incorrectly overlapping when a float has shape-outside: inset. (139133291)
  • Fixed right-to-left content failing with a shape-outside float. (139198865)
  • Fixed incorrectly overlapping a float that has shape-outside: ellipse in vertical mode. (139208636)
  • Fixed incorrectly overlapping a float that has shape-outside: polygon in right-to-left. (139215719)
  • Fixed outside list-style-position quirk to only be applicable in quirks mode. (140602985)
  • Fixed: Updated line box dimensions. (141167251)
  • Fixed incorrect horizontal writing mode state when nested in a vertical block container. (141543326)
  • Fixed baseline calculation few cases for tables with empty rows. (142046863)
  • Fixed to refuse to break inside replaced content. (142224455)
  • Fixed absolute positioned child with percent to include containing block padding. (142321535)
  • Fixed computing an out-of-flow box width correctly when it is inside an inline continuation. (142417374)
  • Fixed a border not showing when a linear gradient and a border radius are set. (142617573)
  • Fixed relative-positioned input elements in scroll areas not rendering outlines. (142995142)
  • Fixed tabbing out of a popover causing a hang in certain cases. (143145544)
  • Fixed setting up inline continuations correctly when not inserting a new child. (143388080)
  • Fixed adding a margin-top to a <rt> also adds a bottom margin. (143720832)

Scrolling

  • Fixed changes to the “scrolling” attribute on an iframe element already in the DOM to take effect. (98911472)

Service Workers

  • Fixed handling the case of busy looping service workers in a process containing web pages. (138626537)
  • Fixed an unexpected failure when serving a redirected response from cache for a navigation loaded via service worker navigation preload. (146113615)

Storage

  • Fixed the Storage Access API to consider AllExceptPartitioned as not currently having cookie access, ensuring sites can request access to first-party cookie. (143508260)

SVG

  • Fixed not propagating the bounding box for empty text to ancestors. (115217040)
  • Fixed SVG masks not working as a mask-image. (127327715)
  • Fixed a bug in case of reference elements (e.g., textPath) unable to notify the referring element (e.g, text) about their availability. (135509733)
  • Fixed SVGUseElement to prevent sniffing the content type when loading an external document. (135972621)
  • Fixed vertical writing modes to se the correct bounding rect. (135973175)
  • Fixed: Updated getTotalLength() with the web specification to throw an exception when non-renderable and the path is empty. (136719548)
  • Fixed SVG quadratic curve getting incorrectly clipped at tile boundaries. (139904014)
  • Fixed dynamically updating the transform attribute. (140761655)
  • Fixed synthesizing a viewBox in <img> only for the document element <svg>. (141733733)
  • Fixed SVGElement.prototype.ownerSVGElement on the outermost <svg> in foreignObject. (143625675)

Tables

  • Fixed table row direction to be determined by the table’s direction, not the section. (99343532)
  • Fixed missing behavior for rowspan="0" on HTML tables where 0 means span over all the remaining rows. (133910430)
  • Fixed Table Root to also account for fill-available in a fixed table layout. (137297914)
  • Fixed table section and row background to not be treated as opaque. (142588505)

Text

  • Fixed an issue where a thick underline would not show on short content. (64705955)
  • Fixed: The changes for GB18030-2022 now properly impact GBK as well, as required by the Encoding Standard. (136368583)
  • Fixed automatically hyphenating text only when a language specified. (136826305)
  • Fixed the boundary style calculation when text-spacing: text-autospace is applied. (137153961)
  • Fixed displaying OpenType-SVG color fonts. (137496217) (FB15426148)

Web API

  • Fixed: Aligned some MIME type handling in EME with the MIME Sniffing standard. (114311586)
  • Fixed window.history.replaceState('', '', '') having no effect on macOS. (117782346)
  • Fixed MutationObserver to observe style attribute changes when resizing the element. (120109181)
  • Fixed: Updated selectorText handling to align with the specification for CSSPageRule. (125588212)
  • Fixed Gamepad rumble issue where sending two sequential playEffect() requests prevents reset() from working as expected. (126589062) (FB13733668)
  • Fixed matching emoji in an element’s id attribute from a <link rel=expect> with an href that uses percent-encoded syntax. (134531921)
  • Fixed the onrejectionhandled and onunhandledrejection event handler attributes to work correctly on body and frameset elements. (135401362)
  • Fixed render blocking for <link> to not match elements that are on a ‘stack of open elements’ for the parser. (135846827)
  • Fixed Distraction Control unexpectedly hiding out-of-flow elements that overlap with a hidden element. (136358918)
  • Fixed CSSOM setSelectorText(string) to prepend the implicit selector. (136791222)
  • Fixed HTMLElement.prototype.requestPointerLock to return a Promise. (139854530)
  • Fixed innerText behavior for <details> and <summary>. (140172890)
  • Fixed the HTML parser phone number handling to better account for MathML. (141632782)
  • Fixed Range.getClientRects to take surrogate pairs into account. (142098484)
  • Fixed tokenization of the rel attribute of the link element and Link header. (142600096)

Web Authentication

  • Fixed .catch() for conditional mediation not getting passed the abort reason that was thrown. (112178073)

Web Extensions

  • Fixed CORS for Web Extension pages to respect granted per-site permissions.

    Developers will need to add a browser.permissions.request({origins: []}) call before doing any fetch() that is blocked by CORS. (102912898)

  • Fixed an issue causing content blockers to not hide content in about:blank frames. (134273470)
  • Fixed a slowdown in applying rulesets and dynamic rules in declarativeNetRequest. (136394861) (FB15196130)
  • Fixed clicking the “Clear Storageā€¦” button in Safari Extensions Settings. (137533628)
  • Fixed storage.onChanged returning undefined as the areaName. (138086765)
  • Fixed the tabs field missing from the result returned by windows.create. (138529797)
  • Fixed es-419 support in Web Extensions. (138857112)
  • Fixed the webRequest.onBeforeRequest event missing the requestBody. (140338580) (FB15911234)
  • Fixed blurry extension icons. (142070967) (FB16171862)
  • Fixed not picking the “zh” locale when “zh-Hant” is preferred. (142602243) (FB16271745)
  • Fixed webRequest event listeners to honor extraInfoSpec for better performace. (142907168)
  • Fixed web extension resources to be treated as UTF-8 by default. (143079179)

Web Inspector

  • Fixed ensuring that all of the Desktop Sites on iPad site-specific hacks are disabled when the site-specific hacks setting is turned off in Web Inspector. (50035167)
  • Fixed style rules to stay editable after being modified by CSSOM in JavaScript. (124650808)
  • Fixed glitches when trying to edit a style from a stylesheet that has an @import statement. (131756178)
  • Fixed error cases to match new source map specification. (137934436)
  • Fixed the overview icon to be inverted dark mode in the Graphics tab. (140602803)
  • Fixed recorded WebGL objects not getting highlighted correctly in the Graphics tab. (140625113)

WebAssembly

  • Fixed Wasm legacy catch_all instruction to correctly catch thrown JS primitives. (135972897)

WebDriver

  • Fixed a crash that could occur when simulating drag events with the right mouse button. (137068514)

WebRTC

  • Fixed MediaSession.setMicrophoneActive(true) prompting repeatedly if the microphone was muted by the user-agent once. (135941062)
  • Fixed setCameraActive to not unmute microphone if the user-agent previously muted both camera and microphone. (136221456)
  • Fixed AirPods unmuting to not unmute the camera if website muted the camera. (137065964)
  • Fixed voice search to not re-prompt for camera or microphone permission after a page-initiated same origin navigation. (138122655)

WKWebView

  • Fixed calling WKWebView.evaluateJavaScript in an async context when nothing is returned by JS. (139618495) (FB15755273)

Updating to Safari 18.4

Safari 18.4 is available on iOS 18.4, iPadOS 18.4, macOS Sequoia 15.4, macOS Sonoma, macOS Ventura, and in visionOS 2.4. To get the latest version of Safari on iPhone, iPad or Apple Vision Pro, go to Settings; General; Software Update, and tap to update.

If you are running macOS Sonoma or macOS Ventura, you can update Safari by itself, without updating macOS. Go to ļ£æ; System Settings; General; Software Update and click ā€œMore infoā€¦ā€ under Updates Available.

Feedback

We love hearing from you. To share your thoughts, find our web evangelist online: Jen Simmons on Bluesky / Mastodon, Saron Yitbarek on BlueSky, and Jon Davis on Bluesky / Mastodon. You can follow WebKit on LinkedIn. If you run into any issues, we welcome your feedback on Safari UI (learn more about filing Feedback), or your WebKit bug report about web technologies or Web Inspector. If you run into a website that isnā€™t working as expected, please file a report at webcompat.com. Filing issues really does make a difference.

Download the latest Safari Technology Preview on macOS to stay at the forefront of the web platform and to use the latest Web Inspector features.

You can also find this information in the Safari 18.4 release notes.

March 31, 2025 07:00 PM

March 28, 2025

Item Flow, Part 1: A new unified concept for layout

Surfin’ Safari

CSS Grid and Flexbox brought incredible layout tools to the web, but they donā€™t yet do everything a designer might want. One of those things is a popular layout pattern called ā€œmasonryā€ or ā€œwaterfall,ā€ which currently still requires a Javascript library to accomplish.

Masonry layouts in CSS feature was first proposed by Mozilla and implemented in Firefox behind a flag in 2020. From the beginning, thereā€™s been a hot debate about this mechanism. The WebKit team at Apple picked up where Mozilla left off, implemented the drafted spec, and landed it in Safari Technology Preview 163. This reinvigorated the conversation. By October 2024, there were two competing ideas being debated ā€” to ā€œJust Use Gridā€ or to create a whole ā€œNew Masonry Layoutā€. We wrote extensively about these ideas in a previous article on this website.

A lot has happened since October. Now, a third path forward is emerging ā€” a path that would mean the CSS Working Group doesnā€™t choose either ā€œJust Use Gridā€ or ā€œNew Masonry Layoutā€. It merges ideas from both with a completely-new idea to create a unified system of Item Flow properties. This article explains what Item Flow is, and its impact on both Flexbox and Grid. In Part 2, another article will more fully explain the implications for the future of masonry-style layouts.

The three options for CSS Masonry.

But first, why is a third possibility called Item Flow emerging at all? Why not just pick between the ā€œJust Use Gridā€ and ā€œNew Masonry Layoutā€ options? Well, back in October, the folks working on masonry asked the W3C Technical Architecture Group (TAG) to weigh in on the debate. The TAG had a lengthy response, but one of the most interesting parts was this:

Overall, we think masonry, grid, and wrapping-flexbox should be incorporated into a unified set of properties. Chromeā€™s [New Masonry Layout] proposal splits apart property sets too eagerly, but even the WebKit [originally Mozilla | Just Use Grid] proposal seems to miss a chance to develop more-general properties.

Wow. Incorporate Flexbox, Grid and Masonry into a unified set of properties? What would that even look like?

The suggestion isnā€™t to combine all of Flexbox with all of Grid ā€” but rather to create a new set of properties and values to ā€œreplaceā€ specifically the flex-flow and grid-auto-flow properties. (You will always be able to use the older syntax if you prefer.) Think how originally the Alignment properties and thegap property were defined to work only in one layout system, and then later got modified and extended to work in multiple layout contexts.

Several of us here at Apple got together and started figuring out how a such unified system for layout *-flow could work. We decided to tentatively name the shorthand item-flow. Itā€™d be the main property from which the longhands and values follow. Together, the new rules would all control the direction of flow, how items wrap, how items pack, whether or not thereā€™s ā€œslackā€ in the layout, and more.

As we worked through the details, we started to get excited. Suddenly new features for Flexbox and Grid that people have wanted for years had an obvious home. Things seemed to click together elegantly. New capabilities emerged:

  • Flexbox could gain a way to do dense packing
  • Grid could gain the ability to turn off wrapping
  • Masonry layouts could now be triggered with a value for item-flow
  • and moreā€¦

In this article, we want to describe Item Flow to you, the people who make websites and web apps, to see what you think. So, letā€™s go on a journey to imagine what this future would be likeā€¦

Combining Flexbox and Grid

Flexbox has flex-flow. Itā€™s a shorthand for these two longhands:

  • flex-direction: row | row-reverse | column | column-reverse;
  • flex-wrap: nowrap | wrap | wrap-reverse;

Flex-direction determines which direction the content flows, while flex-wrap determines whether or not to wrap content.

CSS Grid has grid-auto-flow.

  • grid-auto-flow: row | column | dense;

It determines the direction in which the content flows, and whether or not dense packing is used, all in one property. It has no longhands.

So how shall we unify these capabilities? We proposed calling the new shorthand item-flow, with four new longhands:

  • item-direction
  • item-wrap
  • item-pack
  • item-slack

(Itā€™s important to note all of these are brand new, baby fresh ideas. They will get discussed at length and changed before they become reality in browsers. To make this article readable, we are glossing over the current debates and presenting just one name for each property/value, not listing the all the variations proposed at the CSSWG.)

Item Direction

The item-direction property would determine how content flows. Should content flow in rows or columns? In the normal direction or reversed? This would work just like flex-direction and the corresponding part of grid-auto-flow.

item-direction: row | column | row-reverse | column-reverse

This is pretty straightforward to understand because it works just like we expect from years of working with Flexbox and Grid. There is a debate about what ā€œrowā€ and ā€œcolumnā€ mean for masonry-style layouts ā€” weā€™ll get into that in our next article, Item Flow ā€“ Part 2: next steps for Masonry.

Item Wrap

The item-wrap property would determine whether or not content will wrap, and if so, in which direction. The new default would be auto ā€” which resolves to nowrap in Flexbox and wrap in Grid, matching the current initial values.

This is familiar territory, but creating a new property gives us the opportunity to clean up the values and make them more sensical. We could add a new reverse keyword, so that [ nowrap | wrap ] is one choice, while [ normal | reverse ] is a second, separate choice, improving on how this currently works in Flexbox. (We could also keep wrap-reverse around for the sake of supporting legacy habits.) This would give us:

item-wrap: auto | nowrap | wrap | normal | reverse

But CSS Grid hasnā€™t had a concept of nowrap before! So what would that be?!? Hereā€™s one ideaā€¦

With Flexbox, there are many use cases for laying out your items in one line, one row, without any wrapping. Perhaps itā€™s a navigation bar, where each item is a phrase of a different length. The amount of space for each item is determined by the size of that item ā€” you get flexible boxes.

What if you want to lay out all your content in one row, but, instead, for each item to get the same amount of space ā€” for every item to be 1fr wide? Since the size of the columns is extrinsically determined, CSS Grid is the right tool for this job. But because Grid wraps by default, developers often hack Flexbox instead, not realizing they can get the desired effect today with grid-auto-flow: column.

In a future with Item Flow, itā€™d be very obvious how to use nowrap to tell Grid to fit everything on one line.

.container {
  display: grid;
  grid-auto-columns: 1fr;
  item-wrap: nowrap;
}

Now, if there are nine items, we get nine columns. If there are five items, we get five columns, like this:

A grid of five columns, filled with five items, all in just one row.

Item Pack

The item-pack property would let us switch between different kinds of packing.

Dense packing

In Grid, we currently have the ability to switch to a mode of dense packing, with grid-auto-flow: dense. In the new integrated system, this same capability would be available with item-pack: normal | dense ā€” adding an explicit value for switching back to not-dense for the first time.

Flexbox currently has no concept of dense packing. So what feature could we add to it here?

.container {
  display: flex;
  item-pack: dense;
}

Two ideas have been debated so far:

  1. Dense packing could mean Flexbox will attempt to cram one more item on the row (or column) before starting a new row. It would shrink the items on the row just enough, instead of leaving extra space and growing them.
  2. Or, to behave like Grid, dense packing could mean Flexbox will look back to previous spots in the layout and place smaller items in any available space.

To understand what these option means, letā€™s review how Flexbox currently works, and then take a look at what dense could do.

Today, when Flexbox starts to lay out content, fills up a row with the items that fit in the available space. When it runs out of space, it wraps (if wrapping is allowed), and fills up the next rowā€¦ until all the items have a home. And then, it distributes all the extra space according to the flex and Alignment properties. (See these two steps on the left & right of the illustration.)

A diagram of the two stages of Flexbox laying out ā€” the current way it works.

With the first idea listed above, dense packing in Flexbox could instead shrink items just enough to be able to fit one more item on the row, shrinking each item instead of distributing extra space.

A similar diagram, with the changes if Idea 1 is chosen. Instead of being stretched, more items are on each line, shrunk to fit.

With the second idea, to behave more like Grid dense packing, Flexbox could instead rearrange the order of items and back-fill smaller spaces with smaller items. In this case, item 6 and 10 end up out of the normal order, placed on previous rows.

A similar diagram, with the changes if Idea 2 is chosen. Item 6 & 10 are reordered to be visually earlier in the layout.

This second idea would cause smaller items to pile up on the right (on the end edge). Because of this, some folks have wondered if this would be at all useful in practice.

What do you want ā€œdenseā€ to mean for Flexbox? Do you like the first or second idea more ā€” or do you have a third?

Balanced packing

The item-pack property could also allow for new kinds of packing that donā€™t yet exist. For example, we could invent item-pack: balance.

Currently, Flexbox places items on each line without any regard to whatā€™s happening on the other lines. This can often end up with a very few number of items on the last line.

A diagram of how Flexbox layouts works today. Five items are on the first row, and only one item is in the second row, stretched to span across the whole.

A new balance value could tell the browser to instead balance the items in some fashion, similar to text-wrap: balance, ensuring the last line doesnā€™t stand out as weird.

.container {
  display: flex;
  item-pack: balance;
}
Now instead, three items are on the first row of the layout, and three items are on the second row. This looks better.

This could be incredibly useful and solve a long-standing frustration with Flexbox.

Collapsed packing

The item-pack property could also give us a new home for the trigger for masonry-style layouts. This is a change from the previous Masonry proposals:

Proposal Trigger for masonry layouts
Just Use Grid grid-template-rows: collapse
New Masonry Layout display: masonry
the Item Pack approach item-pack: collapse

Going in this direction means we might not use either of the triggers for masonry layouts from Just Use Grid or New Masonry Layouts. We could abandon both in favor of this new trigger.

Weā€™ll write more about how collapsed item packing could work for masonry layouts in our next article, Item Flow ā€“ Part 2: next steps for Masonry.

Item slack

The item-slack property would allow you to control just how picky the layout engine is when determining where to put the next item.

For masonry-style layouts, this would be the new name for the property previously discussed as grid-slack or masonry-slack. A default slack of 1em means, ā€œhey, when you are looking to see which column has an empty space closest to the top (as you decide where to put the next item), donā€™t worry about it if the difference is 1em or less. Just consider those tied.ā€

For Flexbox, this could set a point to switch from loose packing to cramming in extra item ā€” which is currently set to zero. A value of 1em would mean, if itā€™s within 1em of fitting, cram it in, otherwise wrap to the next line. This idea could integrate with the first idea for Flexbox dense packing (described above), or replace it entirely.

Maybe -slack is not the best name. You can suggest other words in the CSSWG issue. Perhaps item-tolerance would be better, for example ā€” or threshold, strictness, adjust, sensitivity.

The Overall Plan

Put all of these ideas together, and you get this matrix.

A table showing the list of properties, values, and what they do. Everything here is described in this article.

In case itā€™s not clear, web developers will be able to use the longhands or the shorthand as desired. You could, for example, define a Flexbox context with:

.container {
  display: flex;
  item-direction: column;
  item-wrap: nowrap;
}

Or get the exact same result with:

.container {
  display: flex;
  item-flow: column nowrap;
}

Of course, this whole idea for Item Flow is still a work in progress. Big changes can still be made. The names are temporary. This articleā€™s description of how works is just the first draft. There are many conversations and many decisions to be had.

What do you think?

We would love to hear what you think about Item Flow.

  • Is this a good idea to combine flex-flow and grid-auto-flow into a unified system?
  • As a developer would you use the new syntax to accomplish the things you do today with flex-flow and grid-auto-flow?
    • item-direction: row | column | row-reverse | column-reverse
    • item-wrap: auto | nowrap | wrap | normal | reverse
    • item-pack: normal | dense
  • What other ideas might you have for combining existing functionality in Flexbox and Grid into a unified system?
  • Are you excited about the possibilities of adding new capabilities to Grid and Flexbox? Which ones have the most potential to help you do your work, and unlock new designs?
    • No wrapping for Grid with: item-wrap: nowrap
    • Dense packing for Flexbox with: item-pack: dense
    • Balanced wrapping for Flexbox with: item-pack: balance
    • Adjusting when content is crammed/not in Flexbox with: item-slack: <length-percentage>
  • What other new ideas might you want to add in this unified system?

Weā€™d love to hear what you think. Find Jen Simmons on Bluesky or Mastodon to share your feedback. Or even better, publish your thoughts in a blog post and share the link. Explore examples. Explain ideas. And let us know if you like this direction. While the CSS Working Group has resolved to pursue Item Flow, thereā€™s still plenty of time to go in another direction if need be once we hear from web developers.

Stay tuned for Item Flow ā€“ Part 2: next steps for Masonry to learn more about how all this affects the plans for masonry layouts, and to learn more about the specific debates about how item-flow syntax could work.

March 28, 2025 11:00 PM

March 27, 2025

Meet Declarative Web Push

Surfin’ Safari

Web Push notifications are a powerful and important part of the web platform.

As someoneā€™s very famous uncle once said, with great power comes great responsibility. When we added Web Push to WebKit we knew it was imperative to maintain peopleā€™s expectations of power efficiency and privacy.

We took a deliberate approach to maintain those expectations when implementing Web Push for Safari on macOS, for web apps saved to the Home Screen on iOS and iPadOS, and web apps on Mac. We knew running extra code to display notifications could impact battery life. We knew that Web Pushā€™s reliance on service worker JavaScript was at odds with our broad approach to user privacy on the web. We learned that the protections we felt necessary for user privacy challenged assumptions web developers had about Web Push in other browsers. So we challenged ourselves to propose something better for end users, web developers, and browsers.

Declarative Web Push allows web developers to request a Web Push subscription and display user visible notifications without requiring an installed service worker. Service worker JavaScript can optionally change the contents of an incoming notification. Unlike with original Web Push, there is no penalty for service workers failing to display a notification; the declarative push message itself is used as a fallback in case the optional JavaScript processing step fails.

Declarative Web Push is more energy efficient and more private by design. It is easier for you, the web developer to use. And itā€™s backwards compatible with existing Web Push notifications.

Keep reading for our thinking on the challenges that result from how Web Push works today. Or jump straight to how to use Declarative Web Push. You can test it out in iOS and iPadOS 18.4.

The status quo

Existing Web Push notifications were designed with a JavaScript-first mindset. Instead of a remote push directly describing a user visible notification, the more abstract concept of a ā€œpush messageā€ is handled by the websiteā€™s service worker JavaScript.

The website first needs to have a service worker registered. It can then use that ServiceWorkerRegistration to create a PushSubscription, which gives the website the information it needs to remotely send a push message to the browser.

To give users direct control, WebKit requires you as the developer to always show a notification; no silent push messages are allowed. Therefore we require push subscriptions to set the userVisibleOnly flag to true. While this can be frustrating, the original Web Push design made this necessary to protect user privacy and battery life.

Once a push message is received on the device, the browser makes sure there is an instance of the service worker JavaScript and then dispatches a PushEvent to it. The code handling that event inspects the data in the push message, using it to make a call to ServiceWorkerRegistration.showNotification(...) to display the user visible notification.

While some popular JavaScript libraries abstract away some of these complexities, thereā€™s a lot of code involved, and a lot can subtly go wrong.

Challenge 1 ā€” Silent push protection

Recall that WebKit requires the userVisibleOnly flag be set to true when registering for a push subscription. The JavaScript in a ServiceWorkerā€™s PushEvent handler has the responsibility of showing that user visible notification. Allowing websites to remotely wake up a device for silent background work is a privacy violation and expends energy. So if an event handler doesnā€™t show the user visible notification for any reason we revoke its push subscription

Unfortunately bugs in a service worker script, networking conditions, or local device conditions all might prevent a timely call to showNotification. These scenarios might not always be the fault of the script author and can be difficult to debug. It would be better if there were technical enforcement of the userVisibleOnly promise and therefore the silent push penalty box could be ignored.

Challenge 2 ā€” Tracking data

Weā€™ve blogged about it before and weā€™ll blog about it again; Privacy is a fundamental human right.

Since the first version of Safari weā€™ve focused on privacy. WebKit goes above and beyond the privacy protections required by web standards. As the web platform evolved, so did our strategies to protect user privacy. This now includes active blocking and removal of website data, like with Intelligent Tracking Prevention (shortened as ITP).

ITP deletes all website data for websites you havenā€™t visited in a while. This includes service worker registrations. While this can be frustrating to web developers, itā€™s key to protecting user privacy. Itā€™s a hard tradeoff we make intentionally given how committed we are to protecting users.

When we implemented Web Push that created a dilemma. Since creating and using a push subscription is inherently tied to having a service worker, ITP removing a service worker registration would render the push subscription useless. Since having strong anti-tracking prevention features seems to be fundamentally at odds with the JavaScript-driven nature of existing Web Push, wouldnā€™t it be better if Web Push notifications could be delivered without any JavaScript?

So what does Declarative Web Push look like in practice?

How to use Declarative Web Push

To use any flavor of Web Push you first use a PushManager to acquire a push subscription. Web Push on Appleā€™s platforms uses the same Apple Push Notification service that powers native push on all Apple devices. You do not need to be a member of the Apple Developer Program to use it.

The only PushManager available with original Web Push is ServiceWorkerRegistration.pushManager.
Declarative Web Push also exposes window.pushManager to support subscription management without requiring a service worker.

const subscription = await window.pushManager.subscribe({
    userVisibleOnly: true,
    applicationServerKey: arrayForPublicKey
});

If you do also have a registered service worker scoped to the root level of your website domain, it shares the same push subscription as the window object. But the removal of that service worker registration will not affect the associated push subscription.

Sending a push message to that push subscription works exactly as before. For a notification to be handled declaratively the contents of the push message must match the declarative standard JSON format. This standardized format guarantees that the browser has enough information to display a user-visible notification without any JavaScript.

{
    "web_push": 8030,
    "notification": {
        "title": "Webkit.org ā€” Meet Declarative Web Push",
        "lang": "en-US",
        "dir": "ltr",
        "body": "Send push notifications without JavaScript or service worker!",
        "navigate": "https://webkit.org/blog/16535/meet-declarative-web-push/",
        "silent": false,
        "app_badge": "1"
    }
}

The top level "web_push" value is an homage to RFC 8030 – Generic Event Delivery Using HTTP Push. This is the magic value that opts the rest of your push message into declarative parsing.

The "notification" value is a dictionary that describes the user visible notification to the browser. Like when you create a notification programmatically in JavaScript, a non-empty "title" value is required. Most of the optional members of the NotificationOptions dictionary can also be specified.

So far weā€™ve mostly discussed the automatic display of a notification without JavaScript. Something useful needs to happen without JavaScript when a user activates a declarative notification. Thatā€™s where the required "navigate" value comes in. It describes a URL that will be navigated to by the browser upon activation.

Finally, if the web app supports running in an app-like mode that supports the Badging API, such as Home Screen web apps on iOS, the declarative message can include an updated application badge.

A note on backwards compatibility

In practice, a vast majority of Web Push messages are already JSON. They describe a user visible notification to be displayed. The service worker JavaScript handling those push messages simply parses the JSON to display the notification programatically. But the format of those JSON messages varies on a per-website basis.

Most applications will find it straightforward to send the declarative standard JSON in their push messages and rewrite their service workerā€™s PushEvent handler to display it. Once those two steps are taken, those Web Push messages become backwards compatible with browsers that do not yet support Declarative Web Push.

If your push message arrives to a newer browser, itā€™s handled declaratively by the browser. If it arrives to an older browser, itā€™s handled imperatively by JavaScript as it always had been.

Always standardizing on the declarative standard JSON has the nice side effect of introducing consistency across all projects, further reducing maintenance burden for prolific web developers.

What if I canā€™t send the notification description through the internet?

All apps ā€” no matter their platform ā€” might not be able to send the visible content of a notification through push services. How a notification should display often relies on application state local to the userā€™s device. Maybe the user has used the app in ways the server is not aware of yet, requiring an update to the notification. Or maybe the app is for secure communication and decryption keys for the notification payload only exist within the app on the device.

In these cases, code is needed to process the incoming push message to display something meaningful.

Native iOS apps that run into these edge cases have a tool call UNNotificationServiceExtension which allows a small snippet of application code to run in response to an incoming push notification. The incoming notification always has enough content to display a user visible ā€œfallback notificationā€, but the appā€™s notification service extension is given a short amount of time to consult the appā€™s local data storage and propose a new, more meaningful notification.

If thereā€™s a bug in the notification extension, or the required data is not available, or some other unforeseen scenario causes it to fail to show a different notification in time, the original ā€œfallback contentā€ is displayed instead.

For web apps with Declarative Web Push, service worker JavaScript fills the same role. When a Declarative Web Push message arrives and a service worker is installed, a push event is dispatched to it like before.

PushEvent now has the context of the ā€œproposed notificationā€ from the Declarative Web Push message. If the event handler displays a replacement notification properly, the proposed notification is ignored. If the event handler fails to display a replacement notification in time, the fallback is used.

Because there is always a user visible notification ā€” therefore a privacy breaking silent push remains impossible ā€” browsers donā€™t have to apply their ā€œsilent push penaltiesā€ to Declarative Web Push messages.

iOS also supports offloading unused native apps which frees up the storage used by the application code while leaving minimal application functionality in place. In this scenario, the UNNotificationServiceExtension code is gone but unmodified notifications can still be displayed for the application.

This is quite similar to how Declarative Web Push notifications work on iOS after the websiteā€™s service worker JavaScript has been removed either by the user or by ITP. The modification of an incoming push message is no longer possible but the unmodified notification can still be displayed.

Standards work

Weā€™re excited about Declarative Web Push and want it supported everywhere.

Around the time we published our WebKit Declarative Web Push explainer, we also approached the other browser vendors and interested parties about it at TPAC 2023 and raised an issue against the Push API to discuss it. While standards bodies will always nit pick on the details, the overall goal of the proposal was well met.

In 2024, we actively made proposals to the various specs involved, making changes to our implementation as well reasoned feedback came in:

We feel the feature has a good enough foundation for us to ship it and for web developers to start experimenting with it. We foresee future enhancements enabled by this solid foundation. And we hope it ends up widely available soon.

We encourage you to reach out to us on WebKitā€™s Slack or our issue tracker to share your experiences working with this great new feature.

March 27, 2025 05:00 PM

March 24, 2025

Igalia WebKit Team: WebKit Igalia Periodical #18

Igalia WebKit

Update on what happened in WebKit in the week from March 17 to March 24.

Cross-Port šŸ±

Limited the amount data stored for certain elements of WebKitWebViewSessionState. This results in memory savings, and avoids oddly large objects which resulted in web view state being restored slowly.

Multimedia šŸŽ„

GStreamer-based multimedia support for WebKit, including (but not limited to) playback, capture, WebAudio, WebCodecs, and WebRTC.

Reduced parsing overhead in incoming WebRTC video streams by reducing excessive tag events at startup and by avoiding the plugging of parser elements for already-parsed streams.

JavaScriptCore šŸŸ

The built-in JavaScript/ECMAScript engine for WebKit, also known as JSC or SquirrelFish.

Fixed an integer overflow when using wasm/gc on 32-bits.

Graphics šŸ–¼ļø

Landed a change that fixes a few scenarios where the damage was not generated on layer property changes.

Releases šŸ“¦ļø

WebKitGTK 2.48.0 and WPE WebKit 2.48.0 have been released. While they may not look as exciting as the 2.46 series, which introduced the use of Skia for painting, they nevertheless includes half a year of improvements. This development cycle focused on reworking internals, which brings modest performance improvements for all kinds of devices, but most importantly cleanups which will enable further improvements going forward.

For those who need longer to integrate newer releases, which we know can be a longer process for embedded device distrihytos, we have also published WPE WebKit 2.46.7 with a few stability and security fixes.

Accompanying these releases there is security advisory WSA-2025-0002 (GTK, WPE), which covers the solved security issues. Crucially, all three contain the fix for an issue known to be exploited in the wild, and therefore we strongly encourage updating.

As usual, bug reports are always welcome at the WebKit Bugzilla.

libsoup 3.6.5 has been released with bug fixes and security improvements.

Thatā€™s all for this week!

By Unknown at March 24, 2025 07:50 PM

March 18, 2025

Manuel Rego

Igalia WebKit

Two new nice additions by Igalia on the last Safari Technology Preview.

March 18, 2025 12:00 AM

March 17, 2025

Igalia WebKit Team: WebKit Igalia Periodical #17

Igalia WebKit

Update on what happened in WebKit in the week from March 10 to March 17.

Cross-Port šŸ±

Web Platform šŸŒ

Updated button activation behaviour and type property reflection with command and commandfor. Also aligned popovertarget behaviour with latest specification.

Fixed reflection of command IDL property.

Implemented the trusted-types-eval keyword for the script-src CSP directive.

Implemented accessibility handling for command buttons.

Enabled command and commandfor in preview.

JavaScriptCore šŸŸ

The built-in JavaScript/ECMAScript engine for WebKit, also known as JSC or SquirrelFish.

Fixed an integer overflow in JSC (only happens on 32-bit systems with lots of RAM).

Graphics šŸ–¼ļø

Fixed theming issues in WPE/WebKitGTK with vertical writing-modes.

Thatā€™s all for this week!

By Unknown at March 17, 2025 08:31 PM

Release Notes for Safari Technology PreviewĀ 215

Surfin’ Safari

Safari Technology Preview Release 215 is now available for download for macOS Sequoia and macOS Sonoma. If you already have Safari Technology Preview installed, you can update it in System Settings under General ā†’ Software Update.

This release includes WebKit changes between: 290457@main…291467@main.

CSS

New Features

  • Added support for Scroll Driven Animations. (290471@main) (144887859)
  • Added support for text-wrap-style: pretty. (291092@main) (145577976)
  • Added support for CSS Anchor Positioning. (291214@main) (145681750)

JavaScript

Resolved Issues

  • Fixed processing of an alternation of strings (290982@main) (145222010)

Networking

Resolved Issues

  • Fixed using WebSocket in a WebWorker causing the entire Worker to freeze. (290802@main) (145149784)

Scrolling

Resolved Issues

  • Fixed autoscrolling for smooth scrolling while selecting text. (290497@main) (144900491)

Text

Resolved Issues

  • Fixed generating scroll to text fragments around text that contains newlines. (290761@main) (137109344)
  • Fixed generating text fragments when the selected text starts and ends in different blocks. (290748@main) (137761701)
  • Fixed Copy Link to Highlight not working when selecting text that is its own block and when that text exists higher up in the document. (290683@main) (144392379)
  • Fixed selections that start or end in white space not creating text fragments. (291146@main) (145614181)

Web API

New Features

  • Added support for Trusted Types. (291409@main) (130065736)
  • Added support for the File System WritableStream API. (291399@main) (145875384)

Resolved Issues

  • Fixed fullscreen to use a single queue for event dispatching. (290898@main) (145372389)

Web Extensions

Resolved Issues

  • Fixed a bug where the runtime.MessageSender origin parameter would be lowercased, differing from the result returned from runtime.getURL. (291118@main) (140291738)

March 17, 2025 07:10 PM

March 10, 2025

Igalia WebKit Team: WebKit Igalia Periodical #16

Igalia WebKit

Update on what happened in WebKit in the week from March 3 to March 10.

Cross-Port šŸ±

Web Platform šŸŒ

Forced styling to field-sizing: fixed when an input element is auto filled, and added support for changing field-sizing dynamically.

Fixed an issue where the imperative popover APIs didn't take into account the source parameter for focus behavior.

Multimedia šŸŽ„

GStreamer-based multimedia support for WebKit, including (but not limited to) playback, capture, WebAudio, WebCodecs, and WebRTC.

Fixed YouTube breakage on videos with advertisements. The fix prevents scrolling to the comments section when the videos are fullscreened, but having working video playback was considered more important for now.

Graphics šŸ–¼ļø

Fixed re-layout issues for form controls with the experimental field-sizing implementation.

Landed a change that improves the quality of damage rectangles and reduces the amount of painting done in the compositor in some simple scenarios.

Introduce a hybrid threaded rendering mode, scheduling tasks to both the CPU and GPU worker pools. By default we use CPU-affine rendering on WPE, and GPU-affine rendering on the GTK port, saturating the CPU/GPU worker pool first, before switching to the GPU/CPU.

Infrastructure šŸ—ļø

We have recently enabled automatic nightly runs of WPT tests with WPE for the Web Platform Tests (WPT) dashboard. If you click on the ā€œEditā€ button at the wpt.fyi dashboard now there is the option to select WPE.

For example, one may compare the results for WPE to other browsers or examine the differences between the WPE and GTK ports.

These nightly runs happen now daily on the TaskCluster CI sponsored by Mozilla (Thanks to James Graham!). If you want to run WPT tests with WPE WebKit locally, there are instructions at the WPT documentation.

Thatā€™s all for this week!

By Unknown at March 10, 2025 10:59 PM

March 03, 2025

Igalia WebKit Team: WebKit Igalia Periodical #15

Igalia WebKit

Update on what happened in WebKit in the week from February 19 to March 3.

Cross-Port šŸ±

Web Platform šŸŒ

Implemented support for setting returnValue for <dialog> with Invoker Commands.

After fixing an issue with Trusted Types when doing attribute mutation within the default callback, and implementing performance improvements for Trusted Types enforcement, the Trusted Types implementation is now considered stable and has been enabled by default.

Multimedia šŸŽ„

GStreamer-based multimedia support for WebKit, including (but not limited to) playback, capture, WebAudio, WebCodecs, and WebRTC.

Landed one fix which, along with previous patches, solved the webKitMediaSrcStreamFlush() crash reported in bug #260455.

Unfortunately, in some pages where the crash previously occurred, now a different blank video bug has been revealed. The cause of this bug is known, but fixing it would cause performance regressions in pages with many video elements. Work is ongoing to find a better solution for both.

The initial support of MP4-muxed WebVTT in-band text tracks is about to be merged, which will bring this MSE feature to the ports using GStreamer. Text tracks for the macOS port of WebKit only landed two weeks ago and we expect there will be issues to iron out in WebKit ports, multiplatform code and even potentially in spec workā€”we are already aware of a few potential ones.

Note that out-of band text-tracks are well supported in MSE across browsers and commonly used. On the other hand, no browsers currently ship with in-band text track support in MSE at this point.

Support for MediaStreamTrack.configurationchange events was added, along with related improvements in the GStreamer PipeWire plugin. This will allow WebRTC applications to seamlessly handle default audio/video capture changes.

Graphics šŸ–¼ļø

Continued improving the support for handling graphics damage:

  • Added support for validating damage rectangles in Layout Tests.

  • Landed a change that adds layout tests covering the damage propagation feature.

  • Landed a change that fixes damage rectangles on layer resize operations.

  • Landed a change that improves damage rectangles produced by scrolling so that they are clipped to the parent container.

The number of threads used for painting with the GPU has been slightly tweaked, which brings a measurable performance improvement in all kinds of devices with four or mores processor cores.

Releases šŸ“¦ļø

The stable branch for the upcoming 2.48.x stable release series of the GTK and WPE ports has been created. The first preview releases from this branch are WebKitGTK 2.47.90 and WPE WebKit 2.47.90. People willing to report issues and help with stabilization are encouraged to test them and report issues in Bugzilla.

Community & Events šŸ¤

Published a blog post that presents an opinionated approach to the work with textual logs obtained from WebKit and GStreamer.

Thatā€™s all for this week!

By Unknown at March 03, 2025 02:15 PM

February 27, 2025

Release Notes for Safari Technology PreviewĀ 214

Surfin’ Safari

Safari Technology Preview Release 214 is now available for download for macOS Sequoia and macOS Sonoma. If you already have Safari Technology Preview installed, you can update it in System Settings under General ā†’ Software Update.

This release includes WebKit changes between: 289652@main…290517@main.

Browser

New Features

  • Added support for data: URL favicons. (290395@main) (143967312)

CSS

New Features

  • Added support for overflow-block and overflow-inline. (290109@main) (70579028)

Resolved Issues

  • Fixed cursor: pointer not appearing on an <area> element used in conjunction with an <img usemap="..."> element. (290169@main) (74483873)
  • Fixed the behavior of cursor over live text with user-select: none. (289793@main) (99708616)
  • Fixed an issue wrapping an SVG at the end of a line when using text-wrap: balance. (289963@main) (141532036)
  • Fixed the computed value of a float with absolute positioning to be none when there is no box. (290061@main) (144045558)
  • Fixed: Updated contrast-color() to remove the max parameter. (290210@main) (144611470)

JavaScript

New Features

  • Added support for Regular Expression Pattern Modifiers. (290485@main) (131580854)

Media

New Features

  • Added support for MediaSource prefers DecompressionSession by default. (289924@main) (142761051)

  • Added support for WebCodecs AudioDecoder by default. (289723@main) (144059448)

  • Added support for ALAC and PCM audio in MediaRecorder. (289781@main) (144145333)

Resolved Issues

  • Fixed picture-in-picture to exit when the video element is removed. (290216@main) (123869436)
  • Fixed seeking or scrubbing not always seeking to the time requested. (289836@main) (142275903) (FB16223006)

Networking

New Features

  • Blocked partitioned cookies for known tracking domains. (289849@main) (144184516)

Rendering

Resolved Issues

  • Fixed a disappearing stretched image in a vertical flexbox layout. (289903@main) (135897530)
  • Fixed the caret positioning in sideways-lr writing mode. (290387@main) (144117372)

Web API

Resolved Issues

  • Fixed update scoped custom element registry implementation to match the web standard changes. (290096@main) (144456850)

Web Inspector

Deprecations

  • Removed support for inspecting WebSQL in Web Inspector. (289854@main) (143596276)
  • Removed support for inspecting ApplicationCache. (289820@main) (143596399)

February 27, 2025 11:16 PM

February 26, 2025

Pawel Lampe: Working with WebKit and GStreamer logs in Emacs.

Igalia WebKit

WebKit has grown into a massive codebase throughout the years. To make developersā€™ lives easier, it offers various subsystems and integrations. One such subsystem is a logging subsystem that offers the recording of textual logs describing an execution of the internal engine parts.

The logging subsystem in WebKit (as in any computer system), is usually used for both debugging and educational purposes. As WebKit is a widely-used piece of software that runs on everything ranging from desktop-class devices up to low-end embedded devices, itā€™s not uncommon that logging is sometimes the only way for debugging when various limiting factors come into play. Such limiting factors donā€™t have to be only technical - it may also be that the software runs on some restricted systems and direct debugging is not allowed.

Requirements for efficient work with textual logs #

Regardless of the reasons why logging is used, once the set of logs is produced, one can work with it according to the particular need. From my experience, efficient work with textual logs requires a tool with the following capabilities:

  1. Ability to search for a particular substring or regular expression.
  2. Ability to filter text lines according to the substring or regular expressions.
  3. Ability to highlight particular substrings.
  4. Ability to mark certain lines for separate examination (with extra notes if possible).
  5. Ability to save and restore the current state of work.

While all text editors should be able to provide requirement 1, requirements 2-5 are usually more tricky and text editors wonā€™t support them out of the box. Fortunately, any modern extensible text editor should be able to support requirements 2-5 after some extra configuration.

Setting up Emacs to work with logs #

Throughout the following sections, I use Emacs, the classic ā€œextensible, customizable, free/libre text editorā€, to showcase how it can be set up and used to meet the above criteria and to make work with logs a gentle experience.

Emacs, just like any other text editor, provides the support for requirement 1 from the previous section out of the box.

loccur - the minor mode for text filtering #

To support requirement 2, it requires some extra mode. My recommendation for that is loccur - the minor mode that acts just like a classic grep *nix utility yet directly in the editor. The benefit of that mode (over e.g. occur) is that it works in-place. Therefore itā€™s very ergonomic and - as Iā€™ll show later - it works well in conjunction with bookmarking mode.

Installation of loccur is very simple and can be done from within the built-in package manager:

M-x package-install RET loccur RET

With loccur installed, one can immediately start using it by calling M-x loccur RET <regex> RET. The figure below depicts the example of filtering: loccur - the minor mode for text filtering.

highlight-symbol - the package with utility functions for text highlighting #

To support requirement 3, Emacs also requires the installation of extra module. In that case my recommendation is highlight-symbol that is a simple set of functions that enables basic text fragment highlighting on the fly.

Installation of this module is also very simple and boils down to:

M-x package-install RET highlight-symbol RET

With the above, itā€™s very easy to get results like in the figure below: highlight-symbol - the package with utility functions for text highlighting. just by moving the cursor around and using C-c h to toggle the highlight of the text at the current cursor position.

bm - the package with utility functions for buffer lines bookmarking #

Finally, to support requirements 4 and 5, Emacs requires one last extra package. This time my recommendation is bm that is quite a powerful set of utilities for text bookmarking.

In this case, installation is also very simple and is all about:

M-x package-install RET bm RET

In a nutshell, the bm package brings some visual capabilities like in the figure below: bm - the package with utility functions for buffer lines bookmarking as well as non-visual capabilities that will be discussed in further sections.

The final configuration #

Once all the necessary modules are installed, itā€™s worth to spend some time on configuration. With just a few simple tweaks itā€™s possible to make the work with logs simple and easily reproducible.

To not influence other workflows, I recommend attaching as much configuration as possible to any major mode and setting that mode as a default for files with certain extensions. The configuration below uses a major mode called text-mode as the one for working with logs and associates all the files with a suffix .log with it. Moreover, the most critical commands of the modes installed in the previous sections are binded to the key shortcuts. The one last thing is to enable truncating the lines ((set-default 'truncate-lines t)) and highlighting the line that the cursor is currently at ((hl-line-mode 1)).

(add-to-list 'auto-mode-alist '("\\.log\\'" . text-mode))
(add-hook 'text-mode-hook
(lambda ()
(define-key text-mode-map (kbd "C-c t") 'bm-toggle)
(define-key text-mode-map (kbd "C-c n") 'bm-next)
(define-key text-mode-map (kbd "C-c p") 'bm-previous)
(define-key text-mode-map (kbd "C-c h") 'highlight-symbol)
(define-key text-mode-map (kbd "C-c C-c") 'highlight-symbol-next)
(set-default 'truncate-lines t)
(hl-line-mode 1)
))

WebKit logs case study #

To show what the workflow of Emacs is with the above configuration and modules, some logs are required first. Itā€™s very easy to get some logs out of WebKit, so Iā€™ll additionally get some GStreamer logs as well. For that, Iā€™ll build a WebKit GTK port from the latest revision of WebKit repository. To make the build process easier, Iā€™ll use the WebKit container SDK.

Hereā€™s the build command:

./Tools/Scripts/build-webkit --gtk --debug --cmakeargs="-DENABLE_JOURNALD_LOG=OFF"

The above command disables the ENABLE_JOURNALD_LOG build option so that logs are printed to stderr. This will result in the WebKit and GStreamer logs being bundled together as intended.

Once the build is ready, one can run any URL to get the logs. Iā€™ve chosen a YouTube conformance tests suite from 2021 and selected test case ā€œ39. PlaybackRateChangeā€ to get some interesting entries from multimedia-related subsystems:

export GST_DEBUG_NO_COLOR=1
export GST_DEBUG=4,webkit*:7
export WEBKIT_DEBUG=Layout,Media=debug,Events=debug
export URL='https://ytlr-cert.appspot.com/2021/main.html'
./Tools/Scripts/run-minibrowser --gtk --debug --features=+LogsPageMessagesToSystemConsole "${URL}" &> log.log

The commands above reveal some interesting aspects of how to get certain logs. First of all, the commands above specify a few environment variables:

  • GST_DEBUG=4,webkit*:7 - to enable GStreamer logs of level INFO (for all categories) and of level TRACE for the webkit* categories
  • GST_DEBUG_NO_COLOR=1 - to disable coloring of GStreamer logs
  • WEBKIT_DEBUG=Layout,Media=debug,Events=debug - to enable WebKit logs for a few interesting channels.

Moreover, the runtime preference LogsPageMessagesToSystemConsole is enabled to log console output logged by JavaScript code.

The workflow #

Once the logs are collected, one can open them using Emacs and start making sense out of them by gradually exploring the flow of execution. In the below exercise, I intend to understand what happened from the multimedia perspective during the execution of the test case ā€œ39. PlaybackRateChangeā€.

The first step is usually to find the most critical lines that mark more/less the area in the file where the interesting things happen. In that case I propose using M-x loccur RET CONSOLE LOG RET to check what the console logs printed by the application itself are. Once some lines are filtered, one can use bm-toggle command (C-c t) to mark some lines for later examination (highlighted as orange): Effect of filtering and marking some console logs.

For practicing purposes I propose exiting the filtered view M-x loccur RET and trying again to see what events the browser was dispatching e.g. using M-x loccur RET on node node 0x7535d70700b0 VIDEO RET: Effect of filtering and marking some video node events.

In general, the combination of loccur and substring/regexp searches should be very convenient to quickly explore various types of logs along with marking them for later. In case of very important log lines, one can additionally use bm-bookmark-annotate command to add extra notes for later.

Once some interesting log lines are marked, the most basic thing to do is to jump between them using bm-previous (C-c n) and bm-next (C-c p). However, the true power of bm mode comes with the use of M-x bm-show RET to get the view containing only the lines marked with bm-toggle (originally highlighted orange): Effect of invoking bm-show.

This view is especially useful as it shows only the lines deliberately marked using bm-toggle and allows one to quickly jump to them in the original file. Moreover, the lines are displayed in the order they appear in the original file. Therefore itā€™s very easy to see the unified flow of the system and start making sense out of the data presented. Whatā€™s even more interesting, the view contains also the line numbers from the original file as well as manually added annotations if any. The line numbers are especially useful as they may be used for resuming the work after ending the Emacs session - which Iā€™ll describe further in this section.

When the *bm-bookmarks* view is rendered, the only problem left is that the lines are hard to read as they are displayed using a single color. To overcome that problem one can use the macros from the highlight-symbol package using the C-c h shortcut defined in the configuration. The result of highlighting some strings is depicted in the figure below: Highlighting strings in bm-show.

With some colors added, itā€™s much easier to read the logs and focus on essential parts.

Saving and resuming the session #

On some rare occasions it may happen that itā€™s necessary to close the Emacs session yet the work with certain log file is not done and needs to be resumed later. For that, the simple trick is to open the current set of bookmarks with M-x bm-show RET and then save that buffer to the file. Personally, I just create a file with the same name as log file yet with .bm prefix - so for log.log itā€™s log.log.bm.

Once the session is resumed, it is enough to open both log.log and log.log.bm files side by side and create a simple ad-hoc macro to use line numbers from log.log.bm to mark them again in the log.log file: Resuming the session

As shown in the above gif, within a few seconds all the marks are applied in the buffer with log.log file and the work can resume from that point i.e. one can jump around using bm, add new marks etc.

Summary #

Although the above approach may not be ideal for everybody, I find it fairly ergonomic, smooth, and covering all the requirements I identified earlier. Iā€™m certain that editors other than Emacs can be set up to allow the same or very similar flow, yet any particular configurations are left for the reader to explore.

February 26, 2025 12:00 AM

February 19, 2025

Manuel Rego: Announcing the Web Engines Hackfest 2025

Igalia WebKit

Igalia is arranging the twelfth annual Web Engines Hackfest, which will be held on Monday 2nd June through Wednesday 4th June. As usual, this is a hybrid event, at Palexco in A CoruƱa (Galicia, Spain) as well as remotely.

Registration is now open:

Picture of sunset in A CoruƱa from June 2024 at Riazor beach where the whole OrzƔn bay can be seen.
Sunset in A CoruƱa from Riazor beach (June 2024)

The Web Engines Hackfest is an event where folks working on various parts of the web platform gather for a few days to share knowledge and discuss a variety of topics. These topics include web standards, browser engines, JavaScript engines, and all the related technology around them. Last year, we had eight talks (watch them on YouTube) and 15 breakout sessions (read them on GitHub).

A wide range of experts with a diverse set of profiles and skills attend each year, so if you are working on the web platform, this event is a great opportunity to chat with people that are both developing the standards and working on the implementations. Weā€™re really grateful for all the people that regularly join us for this event; you are the ones that make this event something useful and interesting for everyone! šŸ™

Really enjoying Web Engines Hackfest by @igalia once again. Recommended for everyone interested in web technology.

— Anne van Kesteren (@annevk@hachyderm.io) June 05, 2024

The breakout sessions are probably the most interesting part of the event. Many different topics are discussed there, from high-level issues like how to build a new feature for the web platform, to lower-level efforts like the new WebKit SDK container. Together with the hallway discussions and impromptu meetings, the Web Engines Hackfest is an invaluable experience.

Talk by Stephanie Stimac about Sustainable Futures in the Web Engines Hackfest 2024

Big shout-out to Igalia for organising the Web Engines Hackfest every year since 2014, as well as the original WebKitGTK+ Hackfest starting in 2009. The event has grown and weā€™re now close to 100 onsite participants with representation from all major browser vendors. If your organization is interested in helping make this event possible, please contact us regarding our sponsorship options.

See you all in June!

February 19, 2025 07:55 AM

February 18, 2025

Igalia WebKit Team: WebKit Igalia Periodical #14

Igalia WebKit

Update on what happened in WebKit in the week from February 11 to February 18.

Cross-Port šŸ±

Multimedia šŸŽ„

GStreamer-based multimedia support for WebKit, including (but not limited to) playback, capture, WebAudio, WebCodecs, and WebRTC.

Several multimedia-related optimizations landed this week, memory allocations were reduced in the video rendering code path and in the MediaStreamAudioDestinationNode implementation.

On the WebRTC fronts, the GstWebRTC backend has gained support for stats rate limiting support and the send/receive buffer sizes were adjusted.

The GStreamer video frame converter, used to show video frames in the canvas or WebGL, has been fixed to use the right GL context and now supports DMA-BUF video frames, too.

Added support to the eotf additional MIME type parameter when checking for supported multimedia content types. This is required by some streaming sites like YouTube TV.

The GStreamer-based WebCodecs AudioData::copyTo() is now spec compliant, handling all possible format conversions defined in the WebCodecs specification.

Infrastructure šŸ—ļø

The WebKit ports that use CMake as their build systemā€”as is the case for the GTK and WPE onesā€”now enable C++ library assertions by default, when building against GNU libstdc++ or LLVM's libc++. This adds lightweight runtime checks to a number of C++ library facilities, mostly aimed at detecting out-of-bounds memory access, and does not have a measurable performance impact on typical browsing workloads.

A number of Linux distributions were already enabling these assertions as part of their security hardening efforts (e.g. Fedora or Gentoo) and they do help finding actual bugs. As a matter of fact, a number of issues were fixed before all the WebKit API and layout tests with the assertions enabled and the patch could be merged! Going forward, this will prevent accidentally introducing bugs new due to wrong usage of the C++ standard library.

Thatā€™s all for this week!

By Unknown at February 18, 2025 11:34 AM

February 12, 2025

Release Notes for Safari Technology PreviewĀ 213

Surfin’ Safari

Safari Technology Preview Release 213 is now available for download for macOS Sequoia and macOS Sonoma. If you already have Safari Technology Preview installed, you can update it in System Settings under General ā†’ Software Update.

This release includes WebKit changes between: 288458@main…289651@main.

CSS

New Features

  • Implemented unicode-bidi text rendering UA rules (except for ruby elements). (288511@main) (142191490)
  • Added support for gradients with only one stop. (289469@main) (142796999)

Resolved Issues

  • Fixed contain: size breaking object-fit. (289287@main) (131866042)
  • Fixed broken revert-layer when logical group CSS properties are explicitly inherited. (289183@main) (140819138)
  • Fixed subsequent nested styles getting ignored after an incorrect nested selector. (289429@main) (142187930)
  • Fixed font-variant-caps: all-small-caps causing incorrect box-sizing in flex inline context. (289486@main) (142212550)
  • Fixed ensuring the correct logic is run for over-constrained cases when the absolute positioned box is a writing-mode root. (288797@main) (142214631)
  • Fixed text-box-trim accumulation failing when updating the CSS dynamically. (288480@main) (142386761)
  • Fixed text-emphasis to not paint emphasis marks on punctuations. (288476@main) (142387538)
  • Fixed sizing and positioning issues when a popover changes CSS position upon opening. (288655@main) (142491219)
  • Fixed view transitions to stop running when the user navigates with a swipe. (288956@main) (142844150)

Editing

Resolved Issues

  • Fixed document.execCommand("copy") only triggering if there is a selection. (288559@main) (27792460)
  • Fixed Hebrew text pasted from Safari getting aligned left. (289323@main) (139029945)
  • Fixed setting selection to not set focus unless there is an existing selection. (288555@main) (139075809)

Forms

Resolved Issues

  • Fixed <datalist> dropdown keyboard interactions to align with platform conventions. (289067@main) (143012287)
  • Fixed: Disabled all Writing Tools app menu items, except “Compose”, for empty editable content. (289243@main) (143332082)

HTML

Deprecations

  • Removed the composite attribute on an <img> element. (289071@main) (143109250)

JavaScript

Resolved Issues

  • Fixed: Increased the matchLimit for regular expressions, allowing complex matches on longer strings. (289319@main) (143202375)

Media

New Features

  • Enabled MediaSource prefers DecompressionSession by default. (289924@main) (142761051)
  • Enabled WebCodec’s AudioEncoder and AudioDecoder by default. (288965@main) (142916087)

Resolved Issues

  • Fixed handling an empty srcAttr in Media Element. (289432@main) (132042925)
  • Fixed the space key not pausing a video in fullscreen by making the video mouse focusable. (289220@main) (138037616)
  • Fixed playing video generating non-monotonic ‘timeupdate’ events. (288722@main) (142275184) (FB16222910)
  • Fixed websites calling play() during a seek() is allowed by the specification so that the play event is fired even if the seek hasn’t completed. (288577@main) (142517488)
  • Fixed seek not completing for WebM under some circumstances. (143372794)
  • Fixed MediaRecorderPrivateEncoder writing frames out of order. (289643@main) (143956063)

Networking

Deprecations

  • Changed 3DES cipher to show a warning to users that it is a legacy TLS cipher. (288742@main) (138948491)

PDF

Resolved Issues

  • Fixed switching a PDF from continuous to discrete mode displaying the page(s) that are at the top of the window, even when barely visible. (289212@main) (137608841)
  • Fixed the “Previous Page” context menu option not navigating to previous page in 2-up continuous mode. (289337@main) (139817364)

Rendering

Resolved Issues

  • Fixed adding out-of-flow objects under the inline in a continuation chain, when possible. (289451@main) (102421379)
  • Fixed the missing table collapsed border for <thead>, <tbody>, and <tfoot> elements in the wrong order. (289434@main) (110430887)
  • Fixed <input type="range"> taking up space even with width: 0 applied. (289184@main) (113402515)
  • Fixed absolute positioned child with percent to include containing block padding. (288460@main) (142321535)
  • Fixed a border not showing when a linear gradient and a border radius are set. (289101@main) (142617573)
  • Fixed relative-positioned input elements in scroll areas not rendering outlines. (289154@main) (142995142)
  • Fixed tabbing out of a popover causing a hang in certain cases. (289277@main) (143145544)

Storage

Resolved Issues

  • Fixed the Storage Access API to consider AllExceptPartitioned as not currently having cookie access, ensuring sites can request access to first-party cookie. (289450@main) (143508260)

SVG

New Features

  • Added support for the ch length type for character width, but does not include support for upright vertical character width. (288558@main) (142463263)

Resolved Issues

  • Fixed not propagating bbox for empty text to ancestors. (289394@main) (115217040)
  • Fixed dynamically updating the transform attribute. (289022@main) (140761655)
  • Fixed SVGElement.prototype.ownerSVGElement on the outermost <svg> in foreignObject. (289388@main) (143625675)

Tables

Resolved Issues

  • Fixed missing behavior for rowspan="0" on HTML tables where 0 means span over all the remaining rows. (288746@main) (133910430)
  • Fixed table section and row background to not be treated as opaque. (289047@main) (142588505)

Text

Resolved Issues

  • Fixed displaying OpenType-SVG color fonts. (288980@main) (137496217) (FB15426148)

Web Animations

Resolved Issues

  • Fixed computing the time offset as needed when applying accelerated actions. (288652@main) (142604875)

Web API

New Features

  • Added support for the URLPattern API. (288942@main) (142967833)

Resolved Issues

  • Fixed: Aligned some MIME type handling in EME with the MIME Sniffing standard. (288916@main) (114311586)
  • Fixed: Updated selectorText handling to align with the specification for CSSPageRule. (289428@main) (125588212)
  • Fixed matching emoji in an element’s id attribute from a <link rel=expect> with an href that uses percent-encoded syntax. (289174@main) (134531921)
  • Fixed render blocking for <link> to not match elements that are on a ‘stack of open elements’ for the parser. (289020@main) (135846827)
  • Fixed Distraction Control unexpectedly hiding out-of-flow elements that overlap with a hidden element. (288593@main) (136358918)
  • Fixed the HTML parser phone number handling to better account for MathML. (288706@main) (141632782)

Deprecations

  • Removed wheel event handling for <input type="number"> to match platform conventions. (289285@main) (99318505)

Web Extensions

Resolved Issues

  • Fixed the tabs field missing from the result returned by windows.create. (288949@main) (138529797)
  • Fixed the webRequest.onBeforeRequest event missing the requestBody. (288813@main) (140338580) (FB15911234)
  • Fixed blurry extension icons. (288529@main) (142070967) (FB16171862)
  • Fixed not picking the “zh” locale when “zh-Hant” is preferred. (288974@main) (142602243) (FB16271745)
  • Fixed webRequest event listeners to honor extraInfoSpec for better performace. (288938@main) (142907168)
  • Fixed web extension resources to be treated as UTF-8 by default. (289086@main) (143079179)

Web Inspector

Resolved Issues

  • Fixed style rules to stay editable after being modified by CSSOM in JavaScript. (288948@main) (124650808)

WebRTC

Resolved Issues

  • Fixed switching from speaker to receiver does not work the first time, but only the second time. (289006@main) (141685006)

February 12, 2025 10:10 PM

Announcing Interop 2025

Surfin’ Safari

Exciting news for web developers, designers, and browser enthusiasts alike ā€” Interop 2025 is here, continuing the mission of improving cross-browser interoperability. For the fourth year in a row, we are pleased to collaborate with Bocoup, Igalia, Google, Microsoft, and Mozilla to smooth out inconsistencies between browsers. The result? A more reliable, user-friendly web experience for everyone.

The WebKit team is proud to have ended Interop 2024 with 98% of tests passing in Safari 18.2 and 99% passing in Safari Technology Preview. In fact, itā€™s very exciting to see all four participating preview browsers reach 99.

Scores from Interop 2024 dashboard ā€” Chrome, 98; Edge, 97; Firefox, 99; Safari 98Scores from Interop 2024 dashboard ā€” Chrome Canary, 99; Edge Dev, 99; Firefox Nightly, 99; Safari Technology Preview 99

Overall interoperability reached 97% for Interop 2024 ā€” the highest test pass-rate ever! This means long-time features like Accessibility, Custom Properties, font-size-adjust, IndexDB, URLs, scrollbar styling, Text Direction now work the same way in every browser. And new features like CSS Nesting, Declarative Shadow DOM, popover, Relative Color Syntax, and text-wrap: balance are starting their lives with excellent interoperability.

Introducing Interop 2025

Standards are most impactful when theyā€™re broadly supported and Interop 2025 will continue to push the web forward by promoting consistent adoption of standards that let developers build cutting-edge websites. Safari has already implemented many of the standards included in Interop 2025, including View Transitions in Safari 18.0 and Safari 18.2, and the @scope rule shipped in Safari 17.4. Weā€™re excited that these technologies are being included as focus areas in Interop 2025, ensuring they get implemented across all browsers with strong interoperability.

We will also be focused on adding support for the following features over the course of the year: Anchor positioning, Navigation API, URLPattern, scrollend events, Core Web Vitals, two Wasm features, two new Storage Access API methods, and removing Mutation Events. Together, these eight areas make up over 40% of the overall score. We believe these are features you are asking for and care about and are excited to work on them. Increasing support over the course of the year is what the Interop Project is all about, and year after year our ending scores prove our commitment to leadership in providing the latest and most important web standards.

This yearā€™s Interop 2025 runs automated tests for 19 focus areas:

Investigations

In addition to the focus areas, the Interop Project includes several investigation areas. These are projects where teams gather to assess the current state of testing infrastructure and sort through issues that are blocking progress. For instance, two years ago accessibility could not be an Interop focus area, because there just wasnā€™t enough test coverage in the WPT test suite. So Apple led a project to create over 1,100 subtests. Accessibility then became a focus area for Interop 2024, where it reached almost perfect interoperability.

There are five investigations for Interop 2025. We are especially excited about another Accessibility investigation to create even more accessibility tests. A new WebVTT investigation will look to improve the text tracks that are synchronized to videos, used most often for closed captioning. And a new Privacy investigation will dive into what privacy-related standardized features need tests, develop automated tests or document manual tests, and improve interoperability of privacy protections.

Focus Areas for 2025

Interop 2025 contains a lot, with nineteen focus areas. Just two areas are being carried over from Interop 2024. The other seventeen are brand new.

Anchor Positioning

Have you ever wanted to position one element relative to another elementā€™s position and size, rather than relying solely on the elementā€™s own dimensions or static placement within the page? Thatā€™s what Anchor Positioning is all about. This CSS feature allows elements like tooltips or dropdowns to be anchored to specific parts of other elements. Whether it’s a tooltip that follows a button or a callout that stays in place even when the page scrolls, this feature makes complex layouts simpler and more predictable.

Anchor Positioning is currently a work-in-progress in WebKit, available in Safari Technology Preview behind a feature flag. You can test it by turning on support. Once the implementation is close to complete, it will be marked as preview, turning it on by default in Safari Technology Preview, where the tests in the Anchor Positioning focus area will begin to pass.

Backdrop-filter

Next up,backdrop-filter lets you apply graphical effects like blur or color shifts to the background area behind an element. Imagine a frosted glass effect on a page where the content behind an overlay is blurred without affecting the content itself. This can add depth to designs and make interfaces feel modern and sleek. This year, the goal is to ensure this property works smoothly across all browsers, making those stunning effects a reliable part of your CSS toolkit.

See whatā€™s possible with backdrop filter in this demo. Use the dropdown to switch filters.

In Safari 18.0, we updated our implementation to the latest spec, but thereā€™s more work to do to reach full interoperability.

Core Web Vitals

The performance of your website is key to providing a fantastic user experience, and we know itā€™s top-of-mind as you write code. Weā€™ve heard your requests for cross-browser support of the popular Core Web Vitals, and we are excited to have them on the agenda for 2025. The focus areas includes:

  • Largest Contentful Paint (LCP)
  • Interaction to Next Paint (INP)

Having these metrics available in all browsers allows you to track how quickly and smoothly users can interact with a page, no matter which platform they are on.

<details> Element

This simple but powerful HTML element lets you create expandable content sections ā€” think of those collapsible menus or FAQs. In 2025, the goal is to enhance support for the <details> and<summary> elements, and improve their interaction with other features of the Web platform. This means:

  • improving how pseudo-elements like ::marker and ::details-content work
  • adding better interactivity with content-visibility
  • making the find-in-page search interact with the element more intuitively

Itā€™s all about improving user interaction with these controls.

This focus area also includes the hidden=until-found HTML attribute, which can be used on any element. This causes the content in the element with this attribute to be hidden until a fragment link to the content is activated or find in page reaches the content ā€” then the content is revealed.

Layout: Flexbox & Grid

The Layout focus area is being carried over from Interop 2024 to ensure even more interoperability for Flexbox, Grid, Subgrid. These layout systems have been a game-changer for web design.

Modules: JSON and Import Attributes

Modern JavaScript is all about modularity, and in 2025, Modules are getting a little extra love. This includes allowing you to import JSON files directly into your scripts. And refining import attributes (like type:"json") to ensure they work seamlessly, reducing the need for custom parsing logic.

Navigation API

The Navigation API is a powerful tool for managing meaningful user state within web applications, making it easier for developers to control, intercept, and modify browser navigation events. This API is designed to enhance the way websites and web apps manage navigation, enabling more control over how users move between pages or states within a single page application.

The team at Igalia has been hard at work implementing Navigation API in WebKit. You can test it in Safari Technology Preview by turning on the feature flag. Once itā€™s enabled in Safari Technology Preview by default, the tests in the Navigation API focus area will begin to pass.

Pointer and Mouse Events

Handling user input with pointer and mouse events is essential for building interactive web experiences. While pointer events provide a unified model for all input types (mouse, touch, stylus), there are still some differences in how these events are handled across browsers.

Last year, Safari made a solid 47% improvement to Pointer and Mouse Events, rising from passing 41% of the WPT automated tests included in Interop 2024 to passing 88% ā€” but weā€™re not stopping there. Interop 2025 adds even more tests to this focus area, encouraging all browsers to keep making progress towards interoperability.

Remove Mutation Events

Those old, deprecated mutation events (like DOMNodeInserted) were handy back in the day but have long since been replaced by the more efficient MutationObserver API. In 2025, the goal is to fully phase out support for mutation events in favor of the newer, better approach. This will improve performance and reduce potential issues for developers relying on DOM mutation tracking.

@scope

For developers working with complex CSS rules, @scope offers the ability to apply a set of styles within a specific subtree of the DOM. Think of it as a more efficient way to apply styles to certain areas of your page, avoiding global overrides. This year, the focus is on ensuring that @scope works consistently and correctly across all browsers.

<article id="my-component">
  <style>
    @scope {
      h1 { font-size: 4rem; }
    }
  </style>
  <h1>This is 4rem text.</h1>
</article>

<h1>This will not be styled by the CSS above.</h1>

We shipped support for CSS Scoping in Safari 17.4.

scrollend Event

The scrollend event fires when a user finishes scrolling a document or an element. Itā€™s a helpful tool for triggering actions or animations only after a scroll has completed, improving performance.

This feature is not in Safari yet. We are happy for it to be part of Interop 2025 to ensure both Firefox and Safari implement support.

Storage Access API

Keeping user data private is one of our core values. It shapes how we approach the web. We were pleased to introduce the Storage Access API in 2018 to provide a way for embedded cross-site content to authenticate users who are already logged in to their first-party services, while maintaining user privacy by not using third-party cookies.

Over the last seven years, the Storage Access API has continued to evolve as other browsers implemented support. Interop 2025 brings focus to the latest changes to the web standard ā€” specifically two methods:

  • the document.requestStorageAccess() method, which allows iframe content to request storing and reading cookies and other site data
  • the document.hasStorageAccess() method, which checks if such access is granted

We look forward to implementing these two methods in Safari, and gaining stronger interoperability for Storage Access API across browsers ā€” providing tools for you to create elegant experiences while maintaining user privacy.

Text Decoration

Text decoration is a great example of the power of the Interop Project. The ability to underline text on the web has existed since HTML 1.1 with the original <u> element. Today you can use CSS to create underlines, strikethroughs and overlines, and adjust how they look. However, small differences across browsers leave traps that developers can fall into, writing code that you might well expect will work everywhere, but just doesnā€™t. This focus area will ensure interoperability for:

URLPattern

With the URLPattern API, you can define and match patterns against URLs or URL components. This makes handling URL routing and parsing easier, especially for modern web applications.

View Transitions

View Transitions are all about animating the change between different states of a page or the content on the page. Itā€™s great for creating smooth, dynamic user experiences where elements transition between states (like navigating between pages or opening and closing a modal). While View Transitions is a powerful and complex API, Interop 2025 focuses on:

  • Same-document View Transitions
  • View Transitions Classes

We shipped support for same-document View transitions in Safari 18.0 and support for View Transition classes in Safari 18.2.

WebAssembly

WebAssembly enables developers to deploy code written in a number of programming languages at near-native speed in the browser. With that in mind, one of the core weaknesses of Wasm today is interaction with the DOM. To that end, Interop 2025 focuses on enhancing:

  • integration of Resizable Buffers
  • improving JS string built-ins to make working with WebAssembly even smoother and more efficient

Web Compat

Web compatibility refers to whether a website works as intended in a particular browser. The tests in this focus area were selected based on evidence that differences between browsers have caused real-world problems for web developers or end users. This year, the work focuses on web compatibility issues with:

WebRTC

WebRTC (Web Real-Time Communication) enables direct peer-to-peer communication between web browsers, mobile apps, and devices. It allows for real-time audio, video, and data sharing directly within the browser, without the need for external plugins or software. WebRTC is especially useful for video conferencing tools and live-streaming applications. This year, Interop 2025 focuses on:

  • RTCRtpScriptTransform, which allows scripts to modify the media stream, and which is commonly used to implement end-to-end encryption in WebRTC applications.
  • Make RTCDataChannels transferable to workers to enable off-main-thread processing of data.

Writing Modes

CSS Writing Modes define the layout direction of text for different languages and designs. At its core, writing-mode switches the inline direction between horizontal and vertical. Writing modes have been supported in browsers for years, but Interop 2025 includes two newer aspects:

  • writing-mode: sideways-lr and sideways-rl allow for text thatā€™s normally laid out horizontally to be instead displayed vertically as a graph design effect. Using sideways-rl instead of vertical-rl ensures punctuation and other direction-neutral characters are typeset correctly, while using sideways-lr instead of vertical-lr creates an entirely different result
  • overflow-inline and overflow-block provide a logical replacement for overflow-x and overflow-y

Investigation Efforts Look Ahead

The Interop Focus Areas improve interoperability through automated testing of specific, high-priority features, but not everything the Interop Project wants to help improve can be tested across browsers using automated tests. When this happens, Investigation projects are launched to see what kind of work can be done to improve interoperability, often including by improving the testing infrastructure and writing more tests. Here are the Interop 2025 Investigations:

Accessibility Testing

Continuing from last year, the Accessibility Testing investigation aims to broaden the testing surface of accessibility features of the web platform. This will ensure that accessibility features are reliable and consistent, helping developers create more inclusive web experiences.

Gaming Testing

With excitement about gaming on the web, the Gaming investigation focuses on improving the automated test coverage of the Gamepad API.

Mobile Testing

The advent of mobile devices brought the web to billions of people. Continuing from 2024, the Mobile Testing Investigation is finishing the creation the infrastructure necessary so WPT tests can run correctly on mobile devices. This will open up the possibilities for mobile-specific Interop Focus Areas, as well as other testing and interoperability efforts in the future.

Privacy Testing

Privacy is more important than ever, but the web doesnā€™t yet have a good automated test suite for testing privacy protections across browsers. This Privacy investigation will set out to fix that by identifying possibilities for tests of existing web standards, writing tests, and documenting what else is needed.

WebVTT

The WebVTT investigation will address the challenges in ensuring consistent behavior for captions and subtitles across browsers. By improving how WebVTT works with the <track> element and enhancing the VTTCue API, the team will ensure that captions are reliable, dynamic, and accessible across all web platforms.

A More Interoperable Web

Interop 2025 is all about making the web work better for everyone. Whether itā€™s ensuring that your CSS behaves the same across browsers or improving privacy with Storage Access API, this yearā€™s focus areas are all about creating a more reliable, efficient, and seamless web. With continued collaboration from the browser community and the contributions of developers around the world, Interop 2025 will help ensure that the web remains a powerful, user-friendly platform for years to come. Get ready for smoother, more consistent experiences ahead!

February 12, 2025 06:30 PM

February 11, 2025

Igalia WebKit Team: WebKit Igalia Periodical #13

Igalia WebKit

Update on what happened in WebKit in the week from February 3 to February 11.

Cross-Port šŸ±

Fixed an assertion crash in the remote Web Inspector when its resources contain an UTF-8 ā€œnon-breaking spaceā€ character.

Multimedia šŸŽ„

GStreamer-based multimedia support for WebKit, including (but not limited to) playback, capture, WebAudio, WebCodecs, and WebRTC.

Media playback now supports choosing the output audio device on a per element basis, using the setSinkId() API. This also added the support needed for enumerating audio outputs, which is needed by Web applications to obtain the identifiers of the available devices. Typical usage includes allowing the user to choose the audio output used in WebRTC-based conference calls.

For now feature flags ExposeSpeakers, ExposeSpeakersWithoutMicrophone, and PerElementSpeakerSelection need to be enabled for testing.

Set proper playbin flags which are needed to properly use OpenMax on the RaspberryPi.

Graphics šŸ–¼ļø

Landed a change that adds a visualization for damage rectangles, controlled by the WEBKIT_SHOW_DAMAGE environment variable. This highlights areas damaged during rendering of every frameā€”as long as damage propagation is enabled.

Screenshot of a web page showing the ā€œPoster Circleā€ CSS transforms demo, with red rectangles overlapping the areas that have been last re-rendered

Releases šŸ“¦ļø

Stable releases of WebKitGTK 2.46.6 and WPE WebKit 2.46.6 are now available. These come along with the first security advisory of the year (WSA-2025-0001: GTK, WPE): they contain mainly security fixes, and everybody is advised to update.

The unstable release train continues as well, with WebKitGTK 2.47.4 and WPE WebKit 2.47.4 available for testing. These are snapshots of the current development status, and while expected to work there may be rough edgesā€”if you encounter any issue, reports at the WebKit Bugzilla are always welcome.

The recently released libwpe 1.16.1 accidentally introduced an ABI break, which has been corrected in libwpe 1.16.2. There are no other changes, and the latter should be preferred.

Thatā€™s all for this week!

By Unknown at February 11, 2025 10:43 AM

February 10, 2025

Manuel Rego: Solving Cross-root ARIA Issues in Shadow DOM

Igalia WebKit

This blog post is to announce that Igalia has gotten a grant from NLnet Foundation to work on solving cross-root ARIA issues in Shadow DOM. My colleague Alice Boxhall, which has been working on sorting out this issue since several years ago, together with support form other igalians is doing the work related to this grant.

The Problem #

Shadow DOM has some issues that prevent it to be used in some situations if you want to have an accessible application. This has been identified by the Web Components Working Group as one of the top priority issues that need to be sorted out.

Briefly speaking, there are mainly two different problems when you want to reference elements for ARIA attributes cross shadow root boundaries.

First issue is that you cannot reference things outside the Shadow DOM. Imagine you have a custom element (#customButton) which contains a native button in its Shadow DOM, and you want to associate the internal button with a label (#label) which is outside in the light DOM.

<label id="label">Label</label>
<custom-button id="customButton">
<template shadowrootmode="open">
<div>foo</div>
<button aria-labelledby="label">Button</button>
<div>bar</div>
</template>
</custom-button>

And the second problem is that you cannot reference things inside a Shadow DOM from the outside. Imagine the opposite situation where you have a custom label (#customLabel) with a native label in its Shadow DOM that you want to reference from a button (#button) in the light DOM.

<custom-label id="customLabel">
<template shadowrootmode="open">
<div>foo</div>
<label>Label</label>
<div>bar</div>
</template>
</custom-label>
<button id="button" aria-labelledby="customLabel">Button</button>

This is a huge issue for web components because they cannot use Shadow DOM, as they would like due to its encapsulation properties, if they want to provide an accessible experience to users. For that reason many of the web components libraries donā€™t use yet Shadow DOM and have to rely on workarounds or custom polyfills.

If you want to know more on the problem, Alice goes deep on the topic in her blog post How Shadow DOM and accessibility are in conflict.

Prior Art #

The Accessibility Object Model (AOM) effort was started several years ago aiming to solve several issues including the one described before, that had a wider scope and tried to solve many different things including the problems described in this blog post. At that time Alice was at Google and Alex Surkov at Mozilla, both were part of this effort. Coincidentally, they are now at Igalia, which together with Joanmarie Diggs and Valerie Young create a dream team of accessibility experts in our company.

Even when the full problem hasnā€™t been sorted out yet, there has been some progress with the Element Reflection feature which allows ARIA relationship attributes to be reflected as element references. Whit this users can specify them without the need to assign globally unique ID attributes to each element. This feature has been implemented in Chromium and WebKit by Igalia. So instead of doing something like:

<button id="button" aria-describedby="description">Button</button>
<div id="description">Description of the button.</div>

You could specify it like:

<button id="button">Button</button>
<div id="description">Description of the button.</div>
<script>
button.ariaDescribedByElements = [description];
</script>

Coming back to Shadow DOM, this feature also enables authors to specify ARIA relationships pointing to things outside the Shadow DOM (the first kind of problem described in the previous section), however it doesnā€™t allow to reference elements inside another Shadow DOM (the second problem). Anyway letā€™s see an example of how this will solve the first issue:

<label id="label">Label</label>
<custom-button id="customButton"></custom-button>
<script>
const shadowRoot = customButton.attachShadow({mode: "open"});

const foo = document.createElement("div");
foo.textContent = "foo";
shadowRoot.appendChild(foo);

const button = document.createElement("button");
button.textContent = "Button";
/* Here is where we reference the outer label from the button inside the Shadow DOM. */
button.ariaLabelledByElements = [label];
shadowRoot.appendChild(button);

const bar = document.createElement("div");
bar.textContent = "bar";
shadowRoot.appendChild(bar);
</script>

Apart from Element Reflection, which only solves part of the issues, there have been other ideas about how to solve these problems. Initially Cross-root ARIA Delegation proposal by Leo Balter at Salesforce. A different one called Cross-root ARIA Reflection by Westbrook Johnson at Adobe. And finally the Reference Target for Cross-root ARIA proposal by Ben Howell at Microsoft.

Again if you want to learn more about the different nuances of the previous proposals you can revisit Aliceā€™s blog post.

The Proposed Solution: Reference Target #

At this point this is the most promising proposal is the Reference Target one. This proposal allows the web authors to use Shadow DOM and still donā€™t break the accessibility of their web applications. The proposal is still in flux and itā€™s currently being prototyped in Chromium and WebKit. Anyway as an example this is the kind of API shape that would solve the second problem described in the initial section, where we reference a label (#actualLabel) inside the Shadow DOM from a button (#button) in the light DOM.

<custom-label id="customLabel">
<template shadowrootmode="open"
shadowrootreferencetarget="actualLabel">

<div>foo</div>
<label id="actualLabel">Label</label>
<div>bar</div>
</template>
</custom-label>
<button id="button" aria-labelledby="customLabel">Button</button>

The Grant #

As part of this grant weā€™ll work on all the process to get the Reference Target proposal ready to be shipped in the web rendering engines. Some of the tasks that will be done during this project include work in different fronts:

  • Proposal: Help with the work on the proposal identifying issues, missing bits, design solutions, providing improvements, keeping it up to date as the project evolves.
  • Specification: Write the specification text, discuss and review it with the appropriate working groups, improved it based on gathered feedback and implementation experience, resolve issues identified in the standards bodies.
  • Implementation: Prototype implementation in WebKit to verify the proposal, upstream changes to WebKit, fix bugs on the implementation, adapt it to spec modifications.
  • Testing: Analyze current WPT tests, add new ones to increase coverage, validate implementations, keep them up-to-date as things evolve.
  • Outreach: Blog posts explaining the evolution of the project and participation in events with other standards folks to have the proper discussions to move the proposal and specification forward.

NLnet Foundation logo

Weā€™re really grateful that NLnet has trusted us to this project, and we really hope this will allow to fix an outstanding accessibility issue in the web platform that has been around for too many time already. At the same point itā€™s a bit sad, that the European Union through the NGI funds is the one sponsoring this project, when it will have a very important impact for several big fishes that are part of the Web Components WG.

If you want to follow the evolution of this project, Iā€™d suggest you to follow Aliceā€™s blog where sheā€™ll be updating us about the progress of the different tasks.

February 10, 2025 12:00 AM

February 03, 2025

Igalia WebKit Team: WebKit Igalia Periodical #12

Igalia WebKit

Update on what happened in WebKit in the week from January 27 to February 3.

Cross-Port šŸ±

The documentation now has a section on how to use the Web Inspector remotely. This makes information on this topic easier to find, as it was previously scattered around a few different locations.

Jamie continues her Coding Experience work around bringing WebExtensions to the WebKitGTK port. A good part of this involves porting functionality from Objective-C, which only the Apple WebKit ports would use, into C++ code that all ports may use. The latest in this saga was WebExtensionStorageSQLiteStore.

Web Platform šŸŒ

The experimental support for Invoker Commands has been updated to match latest spec changes.

WPE and WebKitGTK now have support for the Cookie Store API.

Implemented experimental support for the CloseWatcher API.

Multimedia šŸŽ„

GStreamer-based multimedia support for WebKit, including (but not limited to) playback, capture, WebAudio, WebCodecs, and WebRTC.

The GStreamer WebRTC backend can now recycle inactive senders and support for inactive receivers was also improved. With these changes, support for screen sharing over WebRTC is now more reliable.

On the playback front, a bug on the silent video automatic pause optimization was fixed, the root case for certain VP9 videos appearing as empty sometimes was found out to be in GStreamer, and there is effort ongoing to solve racy crashes when flushing MSE streams.

WebKitGTK šŸ–„ļø

Support for WebDriver BiDi has been enabled in WebKitGTK as an experimental feature.

Thatā€™s all for this week!

By Unknown at February 03, 2025 10:33 PM

January 30, 2025

Vivienne Watermeier: Debugging GStreamer applications using Nushell

Igalia WebKit

Nushell is a new shell (get it?) in development since 2019. Where other shells like bash and zsh treat all data as raw text, nu instead provides a type system for all data flowing through its pipelines, with many commands inspired by functional languages to manipulate that data. The examples on their homepage and in the README.md demonstrate this well, and I recommend taking a quick look if youā€™re not familiar with the language.

I have been getting familiar with Nu for a few months now, and found it a lot more approachable and user-friendly than traditional shells, and particularly helpful for exploring logs.

Where to find documentation #

I wonā€™t go over all the commands I use in detail, so if anything is ever unclear, have a look at the Command Reference. The most relevant categories for our use case are probably Strings and Filters. From inside nushell, you can also use help some_cmd or some_cmd --help, or help commands for a full table of commands that can be manipulated and searched like any other table in nu. And for debugging a pipeline, describe is a very useful command that describes the type of its input.

Set-up for analyzing GStreamer logs #

First of all, we need some custom commands to parse the raw logs into a nu table. Luckily, nushell provides a parse command for exacly this use case, and we can define this regex to use with it:

let gst_regex: ([
  '(?<time>[0-9.:]+) +'
  '(?<pid>\w+) +'
  '(?<thread>\w+) +'
  '(?<level>\w+) +'
  '(?<category>[\w-]+) +'
  '(?<file>[\w.-]+)?:'
  '(?<line>\w+):'
  '(?<function>[\w()~-]+)?:'
  '(?<object><[^>]*>)? +'
  '(?<msg>.*)$'
] | str join)

(I use a simple pipeline here to split the string over multiple lines for better readability, it just concatenates the list elements.)

Lets run a simple pipeline to get some logs to play around with:
GST_DEBUG=*:DEBUG GST_DEBUG_FILE=sample.log gst-launch-1.0 videotestsrc ! videoconvert ! autovideosink

For parsing the file, we need to be careful to remove any ansi escapes, and split the input into lines. On top of that, we will also store the result to a variable for ease of use:
let gst_log = open sample.log | ansi strip | lines | parse --regex $gst_regex

You can also define a custom command for this, which would look something like:

def "from gst logs" []: string -> table {
  $in | ansi strip | lines | parse --regex ([
    '(?<time>[0-9.:]+) +'
    '(?<pid>\w+) +'
    '(?<thread>\w+) +'
    '(?<level>\w+) +'
    '(?<category>[\w-]+) +'
    '(?<file>[\w.-]+)?:'
    '(?<line>\w+):'
    '(?<function>[\w()~-]+)?:'
    '(?<object><[^>]*>)? +'
    '(?<msg>.*)$'
  ] | str join)
}

Define it directly on the command line, or place it in your configuration files. Either way, use the command like this:
let gst_log = open sample.log | from gst logs

Some basic commands for working with the parsed data #

If you take a look at a few lines of the table, it should look something like this:
$gst_log | skip 10 | take 10

ā•­ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā•®
ā”‚  # ā”‚        time        ā”‚  pid  ā”‚   thread   ā”‚ level  ā”‚      category       ā”‚      file      ā”‚ line  ā”‚           function           ā”‚   object    ā”‚                      msg                      ā”‚
ā”œā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤
ā”‚  0 ā”‚ 0:00:00.003607288  ā”‚ 5161  ā”‚ 0x1ceba80  ā”‚ DEBUG  ā”‚ GST_ELEMENT_PADS    ā”‚ gstelement.c   ā”‚ 315   ā”‚ gst_element_base_class_init  ā”‚             ā”‚ type GstBin : factory (nil)                   ā”‚
ā”‚  1 ā”‚ 0:00:00.003927025  ā”‚ 5161  ā”‚ 0x1ceba80  ā”‚ INFO   ā”‚ GST_INIT            ā”‚ gstcontext.c   ā”‚ 86    ā”‚ _priv_gst_context_initialize ā”‚             ā”‚ init contexts                                 ā”‚
ā”‚  2 ā”‚ 0:00:00.004117399  ā”‚ 5161  ā”‚ 0x1ceba80  ā”‚ INFO   ā”‚ GST_PLUGIN_LOADING  ā”‚ gstplugin.c    ā”‚ 328   ā”‚ _priv_gst_plugin_initialize  ā”‚             ā”‚ registering 0 static plugins                  ā”‚
ā”‚  3 ā”‚ 0:00:00.004164980  ā”‚ 5161  ā”‚ 0x1ceba80  ā”‚ DEBUG  ā”‚ GST_REGISTRY        ā”‚ gstregistry.c  ā”‚ 592   ā”‚ gst_registry_add_feature     ā”‚ <registry0> ā”‚ adding feature 0x1d08c70 (bin)                ā”‚
ā”‚  4 ā”‚ 0:00:00.004176720  ā”‚ 5161  ā”‚ 0x1ceba80  ā”‚ DEBUG  ā”‚ GST_REFCOUNTING     ā”‚ gstobject.c    ā”‚ 710   ā”‚ gst_object_set_parent        ā”‚ <bin>       ā”‚ set parent (ref and sink)                     ā”‚
ā”‚  5 ā”‚ 0:00:00.004197201  ā”‚ 5161  ā”‚ 0x1ceba80  ā”‚ DEBUG  ā”‚ GST_ELEMENT_PADS    ā”‚ gstelement.c   ā”‚ 315   ā”‚ gst_element_base_class_init  ā”‚             ā”‚ type GstPipeline : factory 0x1d09310          ā”‚
ā”‚  6 ā”‚ 0:00:00.004243022  ā”‚ 5161  ā”‚ 0x1ceba80  ā”‚ DEBUG  ā”‚ GST_REGISTRY        ā”‚ gstregistry.c  ā”‚ 592   ā”‚ gst_registry_add_feature     ā”‚ <registry0> ā”‚ adding feature 0x1d09310 (pipeline)           ā”‚
ā”‚  7 ā”‚ 0:00:00.004254252  ā”‚ 5161  ā”‚ 0x1ceba80  ā”‚ DEBUG  ā”‚ GST_REFCOUNTING     ā”‚ gstobject.c    ā”‚ 710   ā”‚ gst_object_set_parent        ā”‚ <pipeline>  ā”‚ set parent (ref and sink)                     ā”‚
ā”‚  8 ā”‚ 0:00:00.004265272  ā”‚ 5161  ā”‚ 0x1ceba80  ā”‚ INFO   ā”‚ GST_PLUGIN_LOADING  ā”‚ gstplugin.c    ā”‚ 236   ā”‚ gst_plugin_register_static   ā”‚             ā”‚ registered static plugin "staticelements"     ā”‚
ā”‚  9 ā”‚ 0:00:00.004276813  ā”‚ 5161  ā”‚ 0x1ceba80  ā”‚ DEBUG  ā”‚ GST_REGISTRY        ā”‚ gstregistry.c  ā”‚ 476   ā”‚ gst_registry_add_plugin      ā”‚ <registry0> ā”‚ adding plugin 0x1d084d0 for filename "(NULL)" ā”‚
ā•°ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā•Æ

skip and take do exactly what it says on the tin - removing the first N rows, and showing only the first N rows, respectively. I use them here to keep the examples short.


To ignore columns, use reject:
$gst_log | skip 10 | take 5 | reject time pid thread

ā•­ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā•®
ā”‚ # ā”‚ level ā”‚      category      ā”‚     file      ā”‚ line ā”‚           function           ā”‚   object    ā”‚              msg               ā”‚
ā”œā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤
ā”‚ 0 ā”‚ DEBUG ā”‚ GST_ELEMENT_PADS   ā”‚ gstelement.c  ā”‚ 315  ā”‚ gst_element_base_class_init  ā”‚             ā”‚ type GstBin : factory (nil)    ā”‚
ā”‚ 1 ā”‚ INFO  ā”‚ GST_INIT           ā”‚ gstcontext.c  ā”‚ 86   ā”‚ _priv_gst_context_initialize ā”‚             ā”‚ init contexts                  ā”‚
ā”‚ 2 ā”‚ INFO  ā”‚ GST_PLUGIN_LOADING ā”‚ gstplugin.c   ā”‚ 328  ā”‚ _priv_gst_plugin_initialize  ā”‚             ā”‚ registering 0 static plugins   ā”‚
ā”‚ 3 ā”‚ DEBUG ā”‚ GST_REGISTRY       ā”‚ gstregistry.c ā”‚ 592  ā”‚ gst_registry_add_feature     ā”‚ <registry0> ā”‚ adding feature 0x1d08c70 (bin) ā”‚
ā”‚ 4 ā”‚ DEBUG ā”‚ GST_REFCOUNTING    ā”‚ gstobject.c   ā”‚ 710  ā”‚ gst_object_set_parent        ā”‚ <bin>       ā”‚ set parent (ref and sink)      ā”‚
ā•°ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā•Æ

Or its counterpart, select, which is also useful for reordering columns:
$gst_log | skip 10 | take 5 | select msg category level

ā•­ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā•®
ā”‚ # ā”‚              msg               ā”‚      category      ā”‚ level ā”‚
ā”œā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤
ā”‚ 0 ā”‚ type GstBin : factory (nil)    ā”‚ GST_ELEMENT_PADS   ā”‚ DEBUG ā”‚
ā”‚ 1 ā”‚ init contexts                  ā”‚ GST_INIT           ā”‚ INFO  ā”‚
ā”‚ 2 ā”‚ registering 0 static plugins   ā”‚ GST_PLUGIN_LOADING ā”‚ INFO  ā”‚
ā”‚ 3 ā”‚ adding feature 0x1d08c70 (bin) ā”‚ GST_REGISTRY       ā”‚ DEBUG ā”‚
ā”‚ 4 ā”‚ set parent (ref and sink)      ā”‚ GST_REFCOUNTING    ā”‚ DEBUG ā”‚
ā•°ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā•Æ

Meanwhile, get returns a single column as a list, which can for example be used with uniq to get a list of all objects in the log:
$gst_log | get object | uniq | take 5

ā•­ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā•®
ā”‚ 0 ā”‚              ā”‚
ā”‚ 1 ā”‚ <registry0>  ā”‚
ā”‚ 2 ā”‚ <bin>        ā”‚
ā”‚ 3 ā”‚ <pipeline>   ā”‚
ā”‚ 4 ā”‚ <capsfilter> ā”‚
ā•°ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā•Æ

Filtering rows by different criteria works really well with where.
$gst_log | where thread in ['0x7f467c000b90' '0x232fefa0'] and category == GST_STATES | take 5

ā•­ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā•®
ā”‚  # ā”‚        time        ā”‚  pid  ā”‚     thread      ā”‚ level  ā”‚  category   ā”‚   file   ā”‚ line ā”‚       function        ā”‚      object      ā”‚                            msg                            ā”‚
ā”œā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤
ā”‚  0 ā”‚ 0:00:01.318390245  ā”‚ 5158  ā”‚ 0x7f467c000b90  ā”‚ DEBUG  ā”‚ GST_STATES  ā”‚ gstbin.c ā”‚ 1957 ā”‚ bin_element_is_sink   ā”‚ <autovideosink0> ā”‚ child autovideosink0-actual-sink-xvimage is sink          ā”‚
ā”‚  1 ā”‚ 0:00:01.318523898  ā”‚ 5158  ā”‚ 0x7f467c000b90  ā”‚ DEBUG  ā”‚ GST_STATES  ā”‚ gstbin.c ā”‚ 1957 ā”‚ bin_element_is_sink   ā”‚ <pipeline0>      ā”‚ child autovideosink0 is sink                              ā”‚
ā”‚  2 ā”‚ 0:00:01.318558109  ā”‚ 5158  ā”‚ 0x7f467c000b90  ā”‚ DEBUG  ā”‚ GST_STATES  ā”‚ gstbin.c ā”‚ 1957 ā”‚ bin_element_is_sink   ā”‚ <pipeline0>      ā”‚ child videoconvert0 is not sink                           ā”‚
ā”‚  3 ā”‚ 0:00:01.318569169  ā”‚ 5158  ā”‚ 0x7f467c000b90  ā”‚ DEBUG  ā”‚ GST_STATES  ā”‚ gstbin.c ā”‚ 1957 ā”‚ bin_element_is_sink   ā”‚ <pipeline0>      ā”‚ child videotestsrc0 is not sink                           ā”‚
ā”‚  4 ā”‚ 0:00:01.338298058  ā”‚ 5158  ā”‚ 0x7f467c000b90  ā”‚ INFO   ā”‚ GST_STATES  ā”‚ gstbin.c ā”‚ 3408 ā”‚ bin_handle_async_done ā”‚ <autovideosink0> ā”‚ committing state from READY to PAUSED, old pending PAUSED ā”‚
ā•°ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā•Æ

It provides special shorthands called row conditions - have a look at the reference for more examples.


Of course, get and where can also be combined:
$gst_log | get category | uniq | where $it starts-with GST | take 5

ā•­ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā•®
ā”‚ 0 ā”‚ GST_REGISTRY       ā”‚
ā”‚ 1 ā”‚ GST_INIT           ā”‚
ā”‚ 2 ā”‚ GST_MEMORY         ā”‚
ā”‚ 3 ā”‚ GST_ELEMENT_PADS   ā”‚
ā”‚ 4 ā”‚ GST_PLUGIN_LOADING ā”‚
ā•°ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā•Æ

And if you need to merge multiple logs, I recommend using sort-by time. This could look like
let gst_log = (open sample.log) + (open other.log) | from gst logs | sort-by time

Interactively exploring logs #

While there are many other useful commands, there is one more command I find incredbly useful: explore. It is essentially the nushell equivalent to less, and while it is still quite rough around the edges, Iā€™ve been using it all the time, mostly for its interactive REPL.

First, just pipe the parsed log into explore:
$gst_log | explore

Now, using the :try command opens its REPL. Enter any pipeline at the top, and you will be able to explore its output below: Example of using the explore command and its REPL. The top of the window shows the current command, with the resulting data underneath as a table.

Switch between the command line and the pager using Tab, and while focused on the pager, search forwards or backwards using / and ?, or enter :help for explanations. Also have a look at the documentation on explore in the Nushell Book.

January 30, 2025 12:00 AM

January 27, 2025

WebKit Features in Safari 18.3

Surfin’ Safari

Today marks the arrival of Safari 18.3. This release is focused on improving the quality of features with 23 bug fixes and 1 depreciation, plus 1 new feature. Safari 18.3 is available on iOS 18.3, iPadOS 18.3, visionOS 2.3, macOS Sequoia 15.3, macOS Sonoma and macOS Ventura.

Genmoji in WKWebView

macOS Sequoia 15.3 now supports Genmoji in Messages, Mail, Notes, and more. With this, WKWebView on macOS now supports the NSAdaptiveImageGlyph API, via the supportsAdaptiveImageGlyph property on WKWebViewConfiguration, making it possible to support adaptive image glyphs in your Mac app. Learn more by watching Bring expression to your app with Genmoji from WWDC24.

Bug Fixes and more

Accessibility

  • Fixed VoiceOver to not announce the content of <script> elements inside containers with display: contents.

CSS

  • Fixed the ::view-transition pseudo-element to create a stacking context.
  • Fixed an issue where SVG text was not displayed in a content-visibility: auto subtree.
  • Fixed :not(:has(...)) invalidation.
  • Fixed the default background-origin to border-box for the border-area in shorthand.
  • Fixed text-box not working correctly on buttons.

Editing

  • Fixed duplicated and offset highlights in iCloud Notes.
  • Fixed getRangeAt(0) returning the same JavaScript object even after selection changes.
  • Fixed the inability to tap to place the cursor at end of the line if last word was autocorrected.
  • Fixed the drag preview remaining after dragging multiple items and then cancelling the drag.

Media

  • Fixed an incorrect aspect ratio for WebM files with non-1:1 source pixels and a sample-aspect-ratio setting.

Rendering

  • Fixed dynamically changing scrollbar-width causing horizontal scrollbars to be painted incorrectly.
  • Fixed <img> element with height: min-content getting stretched vertically.
  • Improved view-transitions performance by only rasterizing on-screen snapshots.

Scrolling

  • Fixed scrollbar appearance when changing to light or dark appearance.

Security

  • Removed support for Clear-Site-Data: "executionContexts".

SVG

  • Fixed SVG paths getting clipped at tile boundaries.

Web API

  • Fixed touching or clicking outside of the popover not closing it on iOS or iPadOS.
  • Fixed coalesced and predicted events of a given pointer event to have the same pointer identifier as their parent.

Web Extensions

  • Fixed an issue where the permissions alert would still appear after clicking the extension icon, even though the user had granted the extension access to all sites.
  • Fixed browser.tabs.create ignoring the pinned and openerTabId attributes, also occurring with browser.tabs.duplicate on iOS.

Web Inspector

  • Fixed the DOM tree view in the Elements tab reducing deeply-nested nodes to one character wide.
  • Improved the reliability of safaridriver connecting to remote devices, especially immediately after toggling the ā€œRemote Automationā€ setting.

WebAssembly

  • Fixed memory leaks in WebAssembly Table objects for JSWebAssemblyInstance to improve resource management in WebAssembly instances. This change enhances the stability and performance of WebAssembly in Safari by ensuring proper lifecycle management of internal Table references. No action is required by web developers, but you may notice reduced memory usage in applications that create and manage WebAssembly instances extensively.

WKWebView

  • Fixed an issue where entering full screen in WKWebView on iOS could fail, even with isElementFullscreenEnabled enabled.

Updating to Safari 18.3

Safari 18.3 is available on iOS 18.3, iPadOS 18.3, macOS Sequoia 15.3, macOS Sonoma, macOS Ventura, and in visionOS 2.3. If you are running macOS Sonoma or macOS Ventura, you can update Safari by itself, without updating macOS. Go to ļ£æ > System Settings > General > Software Update and click ā€œMore infoā€¦ā€ under Updates Available. To get the latest version of Safari on iPhone, iPad or Apple Vision Pro, go to Settings > General > Software Update, and tap to update.

Feedback

We love hearing from you. To share your thoughts, find Jen Simmons on Bluesky / Mastodon and Jon Davis on Bluesky / Mastodon. You can follow WebKit on LinkedIn. If you run into any issues, we welcome your feedback on Safari UI (learn more about filing Feedback), or your WebKit bug report about web technologies or Web Inspector. If you run into a website that isnā€™t working as expected, please file a report at webcompat.com. Filing issues really does make a difference.

Download the latest Safari Technology Preview on macOS to stay at the forefront of the web platform and to use the latest Web Inspector features.

You can also find this information in the Safari 18.3 release notes.

January 27, 2025 07:00 PM

Igalia WebKit Team: WebKit Igalia Periodical #11

Igalia WebKit

Update on what happened in WebKit in the week from January 20 to January 27.

Cross-Port šŸ±

GLib 2.70 will be required starting with the upcoming 2.48 stable releases. This made it possible to remove some code that is no longer needed.

Fixed unlimited memory consumption in case of playing regular video playback and using web inspector.

Speed up reading of large messages sent by the web inspector.

Web Platform šŸŒ

Implemented support for dialog.requestClose().

Multimedia šŸŽ„

GStreamer-based multimedia support for WebKit, including (but not limited to) playback, capture, WebAudio, WebCodecs, and WebRTC.

Fixed the assertion error "pipeline and player states are not synchronized" related to muted video playback in the presence of scroll. Work is ongoing regarding other bugs reproduced with the same video, some of them related to scroll and some likely indepedent.

Fixed lost initial audio samples played using WebAudio on 32-bit Raspberry Pi devices, by preventing the OpenMAX subsystem to enter standby mode.

Graphics šŸ–¼ļø

Landed a change that fixes damage propagation of 3D-transformed layers.

Fixed a regression visiting any web page making use of accelerated ImageBuffers (e.g. canvas) when CPU rendering is used. We were unconditionally creating OpenGL fences, even in CPU rendering mode, and tried to wait for completion in a worker thread, that had no OpenGL context (due to CPU rendering). This is an illegal operation in EGL and fired an assertion, crashing the WebProcess.

Releases šŸ“¦ļø

Despite the work on the WPE Platform API, we continue to maintain the ā€œclassicā€ stack based on libwpe. Thus, we have released libwpe 1.16.1 with the smallā€”but importantā€”addition of support for representing analog button inputs for devices capable of reporting varying amounts of pressure.

Thatā€™s all for this week!

By Unknown at January 27, 2025 05:56 PM

January 24, 2025

Release Notes for Safari Technology PreviewĀ 212

Surfin’ Safari

Safari Technology Preview Release 212 is now available for download for macOS Sequoia and macOS Sonoma. If you already have Safari Technology Preview installed, you can update it in System Settings under General ā†’ Software Update.

This release includes WebKit changes between: 287863@main…288540@main.

Authentication

New Features

  • Added support for setting a pin on a security key when a registration requires it. (288259@main) (122660610)

Canvas

Deprecations

  • Removed non-standard legacy alias of Canvas Compositing including setAlpha and setCompositeOperation. (287871@main) (141510218)

CSS

New Features

  • Added support for view-transition-name: match-element. (288102@main) (138932551)

Resolved Issues

  • Fixed CSSPageRule to derive from CSSGroupingRule. (288443@main) (69847560)
  • Fixed animation-name set from the view transitions dynamic UA stylesheet having extra quotes. (288417@main) (142298840)
  • Fixed the serialization and parsing of animation-name strings. (288404@main) (142318879)

Deprecations

  • Removed the non-standard CSSUnknownRule interface. (288453@main) (142380626)

Forms

Resolved Issues

  • Fixed the hover state getting lost when moving from a checkbox input to the parent label. (288449@main) (107220591)

JavaScript

New Features

  • Added support for an in-place interpreter for Wasm. (288385@main) (113768719)
  • Updated JSON.parse to provide the reviver function access to the input source text and extended JSON.stringify behavior to support object placeholders. (288223@main) (131579181)

Resolved Issues

  • Fixed calendar canonicalization logic in DateTimeFormat. (288143@main) (141792829)
  • Fixed broken output for Intl.DurationFormat digital style when hoursDisplay is "auto". (288277@main) (141969050)
  • Fixed Intl.DurationFormat to print a negative sign for minutes after hidden hours. (288317@main) (142119353)
  • Fixed Array.prototype.toReversed to fill holes with undefined. (288339@main) (142197604)

Loading

Resolved Issues

  • Fixed javascript: URL navigation to another browsing context created from window.open not checking the source’s Content Security Policy. (137941234)

Networking

New Features

  • Added support for cookiesā€™ Partitioned attribute (opt-in partitioned cookies). (288413@main) (142317056)

PDF

Resolved Issues

  • Fixed main frame PDFs served with a CSP sandbox header not loading. (288060@main) (141166987)

Rendering

Resolved Issues

  • Fixed handling inline-box trailing content. (288082@main) (112409103)
  • Fixed grid layout animation performance by caching intrinsic logical heights during the first row sizing pass, improving efficiency and preventing invalidation issues with complex grid configurations. (287890@main) (135791322)
  • Fixed incorrect horizontal writing mode state when nested in a vertical block container. (287877@main) (141543326)
  • Fixed baseline calculation few cases for tables with empty rows. (288314@main) (142046863)
  • Fixed to refuse to break inside replaced content. (288354@main) (142224455)

SVG

New Features

  • Added support for the lh length type. (288448@main) (142068343)

Resolved Issues

  • Fixed synthesizing a viewBox in <img> only for the document element <svg>. (288134@main) (141733733)

Deprecations

  • Removed SVGDocument alias to XMLDocument. (288135@main) (123121696)

Text

Resolved Issues

  • Fixed bold synthesis to be less aggressive. (288130@main) (138047199)

Web API

New Features

  • Added support for element.focus({ focusVisible: true }). (287959@main) (97021844)

Web Inspector

New Features

  • Exposed cookie Partition Key in Web Inspector. (288103@main) (136293236)

January 24, 2025 12:33 AM

January 20, 2025

Igalia WebKit Team: WebKit Igalia Periodical #10

Igalia WebKit

Update on what happened in WebKit in the week from January 13 to January 20.

Cross-Port šŸ±

JavaScriptCore šŸŸ

The built-in JavaScript/ECMAScript engine for WebKit, also known as JSC or SquirrelFish.

The JavaScriptCore GLib API has gained support for creating Promise objects. This allows integrating asynchronous functionality more ergonomically when interfacing between native code and JavaScript.

Graphics šŸ–¼ļø

Elements with outlines inside scrolling containers now render their outlines properly.

Landed a change that adds multiple fixes to the damage propagation functionality in scenarios such as:

  • Layers with custom transforms.

  • Pages with custom viewport scale.

  • Dynamic layer size changes.

  • Scrollbar layers.

Landed a change that improves damage propagation in terms of animations handling.

Landed a change that prevents any kind of damage propagation when the feature is disabled at runtime using its corresponding flag. Before that, even though the functionality was runtime-disabled some memory usage and unneeded calculations were being done.

WPE WebKit šŸ“Ÿ

WPE Platform API šŸ§©

New, modern platform API that supersedes usage of libwpe and WPE backends.

Drag gesture threshold, and key repeat delay/interval are now handled through the WPESettings API instead of using hardcoded values. While defaults typically work well, being able to tweak them for certain setups without rebuilding WPE is a welcome addition.

Sylvia has also improved the WPE Platform DRM/KMS backend to pick the default output device scaling factor using WPESettings.

Infrastructure šŸ—ļø

libsoup has been added to Google's OSS-Fuzz program to help find security issues.

Thatā€™s all for this week!

By Unknown at January 20, 2025 10:32 PM

January 14, 2025

The success of Interop 2024!

Surfin’ Safari

With close of 2024 came the end of another year of the Interop project ā€” the annual collaboration between browser engine teams to improve the interoperability of web technology by collectively focusing on fixing bugs and improving features in specific areas.

In 2024, there were 17 such focus areas: Accessibility, CSS Nesting, Custom Properties, Declarative Shadow DOM, font-size-adjust, HTTPS URLs for WebSocket, IndexedDB, Layout, Pointer and Mouse Events, popover, Relative Color Syntax, requestVideoFrameCallback, Scrollbar Styling, @starting-style & transition-behavior, Text Directionality, text-wrap: balance and URL.

Each focus area was represented by a set of automated Web Platform Tests (WPT). Test results were continuously posted to the Interop dashboard throughout the year.

Interop 2024 progress, January through December

At the beginning of 2024, 46% of tests simultaneously passed in all four participating browsers ā€” seen on this graph as the ā€œInteropā€ score, represented by the bottom line:

The graph of progress across 2024, Chrome, Edge, Firefox, Safari, and overall interoperability. Go to https://wpt.fyi/interop-2024 for full details.
Test results in ā€œstableā€ browsers ā€” those released to everyday users.

By end of December, 95% of tests passed in Chrome 131, Edge 131, Firefox 133 and Safari 18.2 at the same time. Reaching 95% interoperability is an incredible result! Itā€™s the best the Interop project has done so far ā€” by a lot.

End-of-the-year results over time

Comparing year over year, you can see just how successful Interop 2024 has been. In past years, the final interop score reached 83ā€“87%.

The final interoperability score for each year, for each browser play overall score.
Results of Interop Project over the years, as seen in released browsers. (*The project was originally named ā€œCompat 2021ā€ and did not involve people from the Safari or Firefox teams in the first year.)

The WebKit team is proud to have ended 2024 with 98% of tests passing in Safari 18.2 and 99% passing in Safari Technology Preview. In fact, itā€™s exciting to see all four participating preview browsers reach 99.

Final Interop 2024 scores ā€” Chrome Canary, 99; Edge Dev, 99; Firefox Nightly, 99; Safari Technology Preview, 99

Impact of Interop 2024

So what exactly did Interop 2024 improve? Thereā€™s a lot. You can read all the details in our article from the beginning of the year, The web just gets better with Interop 2024. A few standouts were especially meaningful to the WebKit team.

URL has been an Interop focus area since 2023. URLs are one of the most fundamental parts of the web. Without them, you wouldnā€™t be reading this. The WHATWG URL standard details exactly how URLs are supposed to work, but less than 80% of the tests of the standard passed in all browsers. Weā€™re extremely happy with the progress made in 2024 by Chrome, Edge and Firefox, raising the overall interop score to 94.5%, finally putting full interoperability of this crucial building block in sight. Web developers can now use all matter of custom URL schemes and be assured they work identically across the board.

Itā€™s also particularly exciting to see strong improvements in the interoperability of Accessibility technology. Led by Appleā€™s accessibility team, Interop 2023 took on an Accessibility Investigation project and wrote almost 1500 new interoperable accessibility tests in the last two years. For Interop 2024, over 1000 accessibility tests were chosen for an Accessibility Focus Area, and now all but two of those pass in all preview browsers, reaching 99.7% interop. The Accessibility Testing Investigation continues into 2025, if youā€™re interested in contributing!

Thefont-size-adjust property first shipped sixteen years ago in Firefox, but the original design was missing key features to make it easy to use or compatible with every language (from-font and two value syntax). The CSS Working Group later updated the web standard. Safari shipped the full set of features in 2023, and Firefox updated their implementation at the same time. Now finally the mature version font-size-adjust works in all browser engines making it very easy to get all the fonts used in a string of text to be the same visual size. Learn how and when to use it in this chapter of Whatā€™s new in CSS from WWDC23.

Pointer and mouse events wins the award for most improved ā€” passing just 31.9% of tests at the beginning of 2024, and now passing 87.2% in preview browsers. If youā€™ve ever struggled writing code with pointer and mouse events, try again! Other focus areas also improved long-standing interoperability problems with existing technologies, including HTTPS URLs for WebSocket, IndexedDB, Layout (Grid, Subgrid and Flexbox), requestVideoFrameCallback, Scrollbar styling, and Text Directionality (dir).

And several focus areas ensured that new features start their life with strong interoperability, including CSS Nesting, Custom Properties (@property), Declarative Shadow DOM, Popover, Relative Color Syntax, text-wrap: balance, @starting-style and transition-behavior.

Interop 2025

Planning for Interop 2025 is currently underway. Stay tuned for more about whatā€™s next.

January 14, 2025 04:00 PM

January 13, 2025

Igalia WebKit Team: WebKit Igalia Periodical #9

Igalia WebKit

Update on what happened in WebKit in the week from December 31, 2024 to January 13, 2025.

Cross-Port šŸ±

Web Platform šŸŒ

Landed a fix to the experimental Trusted Types implementation for certain event handler content attributes not being protected even though they are sinks.

Landed a fix to experimental Trusted Types implementation where the SVGScriptElement.className property was being protected even though it's not a sink.

Multimedia šŸŽ„

GStreamer-based multimedia support for WebKit, including (but not limited to) playback, capture, WebAudio, WebCodecs, and WebRTC.

Support for the H.264 ā€œconstrained-highā€ and ā€œhighā€ profiles was improved in the GStreamer WebRTC backend.

The GStreamer WebRTC backend now has basic support for network conditions simulation, that will be useful to improve error recovery and packet loss coping mechanisms.

JavaScriptCore šŸŸ

The built-in JavaScript/ECMAScript engine for WebKit, also known as JSC or SquirrelFish.

JSC got a fix for a tricky garbage-collection issue.

Graphics šŸ–¼ļø

Landed a change that enables testing the "damage propagation" functionality. This is a first step in a series of fixes and improvements that should stabilize that feature.

Damage propagation passes extra information that describes the viewport areas that have visually changed since the last frame across different graphics subsystems. This allows the WebKit compositor and the system compositor to reduce the amount of painting being done thus reducing usage of resources (CPU, GPU, and memory bus). This is especially helpful on constrained, embedded platforms.

WebKitGTK šŸ–„ļø

A patch landed to add metadata (title and creation/modification date) to PDF documents generated for printing.

The ā€œsuspendedā€ toplevel state is now handled in GTK port to pause rendering when web views are fully obscured.

Jamie Murphy is doing a Coding Experience focused on adding support for WebExtensions. After porting a number of Objective-C classes to C++, to allow using them in all WebKit ports, she has recently made the code build on Linux, and started adding new public API to expose the functionality to GTK applications that embed web views. There is still plenty of work to do, but this is great progress nevertheless.

WPE WebKit šŸ“Ÿ

Sylvia Li, who is also doing a Coding Experience, has updated WPEView so it will pick its default configuration values using the recently added WPESettings API.

Thatā€™s all for this week!

By Unknown at January 13, 2025 01:36 PM

December 30, 2024

Igalia WebKit Team: WebKit Igalia Periodical #8

Igalia WebKit

Update on what happened in WebKit in the week from December 23 to December 30.

Community & Events šŸ¤

Published an article on CSS Anchor Positioning. It discusses the current status of the support across browsers, Igalia's contributions to the WebKit's implementation, and the predictions for the future.

Thatā€™s all for this week!

By Unknown at December 30, 2024 04:39 PM

December 27, 2024

Pawel Lampe: Contributing to CSS Anchor Positioning in WebKit.

Igalia WebKit

CSS Anchor Positioning is a novel CSS specification module that allows positioned elements to size and position themselves relative to one or more anchor elements anywhere on the web page. In simpler terms, it is a new web platform API that simplifies advanced relative-positioning scenarios such as tooltips, menus, popups, etc.

CSS Anchor Positioning in practice #

To better understand the true power it brings, letā€™s consider a non-trivial layout presented in Figure 1:

Non-trivial layout.

In the past, creating a context menu with position: fixed and positioned relative to the button required doing positioning-related calculations manually. The more complex the layout, the more complex the situation. For example, if the table in the above example was in a scrollable container, the position of the context menu would have to be updated manually on every scroll event.

With the CSS Anchor Positioning the solution to the above problem becomes trivial and requires 2 parts:

  • The <button> element must be marked as an anchor element by adding anchor-name: --some-name.
  • The context menu element must position itself using the anchor() function: left: anchor(--some-name right); top: anchor(--some-name bottom).

The above is enough for the web engine to understand that the context menu elementā€™s left and top must be positioned to the anchor elementā€™s right and bottom. With that, the web engine can carry out the job under the hood, so the result is as in Figure 2:

Non-trivial layout with anchor-positioned context menu.

As the above demonstrates, even with a few simple API pieces, itā€™s now possible to address very complex scenarios in a very elegant fashion from the web developerā€™s perspective. Moreover, CSS Anchor Positioning offers even more than that. There are numerous articles with great examples such as this MDN article, this css-tricks article, or this chrome blog post, but the long story short is that both positioning and sizing elements relative to anchors are now very simple.

Implementation status across web engines #

The first draft of the specification was published in early 2023, which in the web engines field is not so long time ago. Therefore - as one can imagine - not all the major web engines support it yet. The first (and so far the only) web engine to support CSS Anchor Positioning was Chromium (see the introduction blog post) - thus the information on caniuse.com. However, despite the information visible on the WPT results page, the other web engines are currently implementing it (see the meta bug for Gecko and bug list for WebKit). The lack of progress on the WPT results page is due to the feature not being enabled by default yet in those cases.

Implementation status in WebKit #

From the commits visible publicly, one can deduce that the work on CSS Anchor Positioning in WebKit has been started by Apple early 2024. The implementation was initiated by adding a core part - support for anchor-name, position-anchor, and anchor(). Those 2 properties and function are enough to start using the feature in real-world scenarios as well as more sophisticated WPT tests.

The work on the above had been finished by the end of Q3 2024, and then - in Q4 2024 - the work significantly intensified. A parsing/computing support has been added for numerous properties and functions and moreover, a lot of new functionalities and bug fixes landed afterwards. One could expect some more things to land by the end of the year even if thereā€™s not much time left.

Overall, the implementation is in progress and is far from being done, but can already be tested in many real-world scenarios. This can be done using custom WebKit builds (across various OSes) or using Safari Technology Preview on Mac. The precondition for testing is, however, that the runtime preference called CSSAnchorPositioning is enabled.

My contributions #

Since the CSS Anchor Positioning in WebKit is still work in progress, and since the demand for the set of features this module brings is high, Iā€™ve been privileged to contribute a little to the implementation myself. My work so far has been focused around the parts of API that allow creating menu-like elements becoming visible on demand.

The first challenge with the above was to fix various problems related to toggling visibility status such as:

The obvious first step towards addressing the above was to isolate elegant scenarios to reproduce the above. In the process, Iā€™ve created some test cases, and added them to WPT. With tests in place, Iā€™ve imported them into WebKitā€™s source tree and proceeded with actual bug fixing. The result was the fix for the above crash, and the fix for the layout being broken. With that in place, the visibility of menu-like elements can be changed without any problems now.

The second challenge was about the missing features allowing automatic alignment to the anchor. In a nutshell, to get the alignment like in the Figure 3:

Non-trivial layout with centered anchor-positioned context menu.

there are 2 possibilities:

At first, I wasnā€™t aware of the anchor-center and hence Iā€™ve started initial work towards supporting position-area. Once I became aware, however, Iā€™ve switched my focus to implementing anchor-center and left the above for Apple to continue - not to block them. Until now, both the initial and core parts of anchor-center implementation have landed. It means, the basic support is in place.

Despite anchor-center layout tests passing, Iā€™ve already discovered some problems such as:

and I anticipate more problems may appear once the testing intensifies.

To address the above, Iā€™ll be focusing on adding extra WPT coverage along with fixing the problems one by one. The key is to make sure that at the end of the day, all the unexpected problems are covered with WPT test cases. This way, other web engines will also benefit.

The future #

With WebKitā€™s implementation of CSS Anchor Positioning in its current shape, the work can be very much parallel. Assuming that Apple will keep working on that at the same pace as they did for the past few months, I wouldnā€™t be surprised if CSS Anchor Positioning would be pretty much done by the end of 2025. If the implementation in Gecko doesnā€™t stall, I think one can also expect a lot of activity around testing in the WPT. With that, the quality of implementation across the web engines should improve, and eventually (perhaps in 2026?) the CSS Anchor Positioning should reach the state of full interoperability.

December 27, 2024 12:00 AM

December 23, 2024

Igalia WebKit Team: WebKit Igalia Periodical #7

Igalia WebKit

Update on what happened in WebKit in the week from December 16 to December 23.

Cross-Port šŸ±

Improved logging in WebDriver service executables, using the same infrastructure as the browser (e.g. journald logging and different levels).

Added support for the first WebDriver-BiDi event in WebKit: monitoring console messages.

JavaScriptCore šŸŸ

The built-in JavaScript/ECMAScript engine for WebKit, also known as JSC or SquirrelFish.

JavaScriptCore got a fix for a wasm test that was flaky on 32-bits. We also submitted a new PR to fix handling of Air (Air is an intermediate representation) Args with offsets that are not directly addressable in the O0 register allocator.

Graphics šŸ–¼ļø

Since the switch to Skia we have been closely following upstream changes, and making small contributions when needed. After adding support for OpenType-SVG fonts the build with Clang was broken, and needed a fix to allow building Skia in C++ 23 mode (as we do in WebKit). The Skia update for this week resulting in a fix to avoid SK_NO_SANITIZE("cfi") when using GCC.

Releases šŸ“¦ļø

Stable releases of WebKitGTK 2.46.5 and WPE WebKit 2.46.5 are now available. While they include some minor fixes, these are focused on patches for security issues, and come accompanied with a new security advisory (WSA-2024-0008: GTK, WPE). As usual, it is recommended to stay up to date, and fresh packages have been already making their way to mainstream Linux distributions.

Thatā€™s all for this week!

By Unknown at December 23, 2024 04:03 PM

December 16, 2024

Igalia WebKit Team: WebKit Igalia Periodical #6

Igalia WebKit

Update on what happened in WebKit in the week from December 9 to December 16.

Cross-Port šŸ±

Web Platform šŸŒ

Shipped the X25519 algorithm of the WebCrypto API for the Mac, GTK+ and WPE ports.

Fixed corner case invoker issue with popover inside invoker, matching the updated spec.

Form controls have long standing interoperability issues and <textarea> is no exception. This patch fixes space being reserved for scrollbars despite overlay scrollbars being enabled. This brings WebKit in line with Firefox's behaviour.

Implemented improvements to the popover API to allow imperative invokers relationships, this brings the JavaScript APIs inline with the declarative popovertarget attribute.

Implemented the CanvasRenderingContext2D letterSpacing/wordSpacing support.

Multimedia šŸŽ„

GStreamer-based multimedia support for WebKit, including (but not limited to) playback, capture, WebAudio, WebCodecs, and WebRTC.

Due to on-going work on improving memory usage in WebRTC use-cases, several patches landed in WebKit (1, 2,3) and GStreamer (4). Another related task is under review in libnice.

Several WebCodecs GStreamer backend fixes landed, mostly related with Opus and LPCM decoding support.

JavaScriptCore šŸŸ

The built-in JavaScript/ECMAScript engine for WebKit, also known as JSC or SquirrelFish.

JavaScriptCore now has Wasm tail call support on ARMv7.

Graphics šŸ–¼ļø

OpenType color fonts with SVG outlines stopped working with the transition from Cairo to Skia. This was unintentional, and support for this kind of fonts has been re-enabled for Skia.

Building the OpenType-SVG support required building Skia's SVG module, which uses Expat as its XML parser. Packagers will need to add it as a build dependency, or configure the compilation passing -DUSE_SKIA_OPENTYPE_SVG=OFF, which disables the feature.

Thatā€™s all for this week!

By Unknown at December 16, 2024 01:33 PM

December 10, 2024

Igalia WebKit Team: WebKit Igalia Periodical #5

Igalia WebKit

Update on what happened in WebKit in the week from December 3 to December 10.

Web Platform šŸŒ

Improved interoperability somewhat by including font-weight in the CanvasRenderingContext2D.font serialization.

Graphics šŸ–¼ļø

Support for cross-thread transfer of accelerated ImageBitmap objects landed upstream for the GTK and WPE ports. It improves performance of applications that use worker threads and pass accelerated ImageBitmap objects (with ownership) around.

Thatā€™s all for this week!

By Unknown at December 10, 2024 10:05 PM

December 09, 2024

Vivienne Watermeier: How I set up my IDE for the WebKit container SDK

Igalia WebKit

This is based on this previous blog post by Alicia, and I recommend taking a look - many things mentioned in it are still useful here.
Example of symbol documentation in Helix. The screenshot shows the entire window, with a outlined popup below the cursor, showing documentation. Reading a symbolā€™s documentation in a popup

The most straight-forward option would have been to just install another instance of my IDE inside the container. However, I use NixOSĀ +Ā Home Manager to manage and configure my packages declaratively, so the Ubuntu-based container environment would be a quite frustrating difference:

  1. Package versions will be lagging behind, and sooner or later I will have to deal with differences with configuration, features, or bugs. For example, at time of writing, neovim is packaged in Debian 24.10 at version 0.9.5, while nixpkgs ships 0.10.2. (To be fair, Flathub and Snapcraft would be up-to-date as well, but I have my gripes with those too.)

  2. Either way, I now have a new set of configurations to manage and keep in sync with their canonical versions on the host system.

  3. Any other tools I donā€™t install in the container, I wonā€™t have access to - for example, for running commands from inside my IDE.

Overall, this will waste time and disk space better used for other things. So, after trying out a few different approaches, a clangd wrapper script that bridges the disconnect between my host system and the container was the first satisfying solution I found.

Conveniently, this fits well with my approach of writing wrappers around wkdev scripts to expose as much functionality as possible to my host system, to avoid manually entering the container - in effect abstracting it out of sight.

Step 1: Wrapper script #

This is roughly the script I currently use. I personally prefer nushell, but I will go into details below so you can write your own version in whatever language you prefer.

The idea is to start clangd inside the container, and use socat to expose its stdin/out to the IDE over TCP. That is to avoid this podman issue I ran into if I tried using stdin.

#!/usr/bin/env -S nu --stdin

def main [
  --name (-n): string = "wkdev-sdk"
  --show-config
] {
  # picking a random port for the connection avoids colliding with itself in case an earlier instance of this script is still around
  let port = random int 2000..5000 
  let workdir = $"/host(pwd)"

  # the container SDK mounts your home directory to `/host/home/...`,
  # so as long as the WebKit checkout is somewhere within your $HOME,
  # mapping paths is as easy as just prepending `/host`
  let mappings_table = ["Source" "WebKitBuild/GTK/Debug" "WebKitBuild/GTK/Release"]
    | each {|path| {host: $"($env.WEBKIT_DIR)/($path)" container: $"/host($env.WEBKIT_DIR)/($path)"}}

  let mappings = $mappings_table
    | each {|it| $"($it.host)=($it.container)" }
    | str join ","

  let podman_args = [
    exec
    --detach
    --user
    1000:100
    $name
  ]

  let clangd_args = [
    $"--path-mappings=($mappings)"
    --header-insertion=never  # clangd has the tendency to insert unnecessary includes, so I prefer to just disable the feature.
    --limit-results=5000      # The default limit for reference search results is too low for WebKit
    --background-index
    --enable-config           # Enable reading .clangd file
    -j 8
  ]

  # Show results of above configuration when called with --show-config, particularly helpful for debugging
  if $show_config {
    {
      port: $port
      work_dir: $workdir
      mappings: $mappings_table
      podman_args: $podman_args
      clangd_args: $clangd_args
    }
  } else {
    # ensure that the container is running
    podman start $name | ignore

    # container side
    ( podman ...$podman_args /usr/bin/env $'--chdir=($workdir)' socat 
      $"tcp-l:($port),fork"
      $"exec:'clangd ($clangd_args | str join (char space))'"
    ) | ignore

    # host side
    nc localhost $port
  }
}

Step 2: IDE setup #

IDE setup is largely the same as it would usually be, aside from pointing the clangd path at our wrapper script instead. I use helix, where I just need to add a .helix/languages.toml to the WebKit checkout directory:

[language-server.clangd]
command = "/path/to/clangd_wrapper"

In VS Code, you need the clangd extension, then you can enter the absolute path to the script under File > Preferences > Settings > Extensions/clangd > Clangd: Path, ideally in the Workspace tab so the setting only applies to WebKit.

Step 3: clangd setup #

Clangd will require two things to be set up at the root of your WebKit checkout:

First, create a compile_commands.json symlink for the build you will use, for example to WebKitBuild/GTK/Debug/compile_commands.json.

Secondly, a .clangd (which is what we needed the --enable-config flag for) at the root of the WebKit checkout:

If:
PathMatch: "(/host/home/vivienne/dev/work/metro/wk/up)?Source/.*\\.h"
PathExclude: "(/host/home/vivienne/dev/work/metro/wk/up)?Source/ThirdParty/.*"

CompileFlags:
Add: [-include, config.h]

I created both files manually, but as of [cmake] Auto-complete via clangd auto-setup, there seem to be new scripts to help with setting up and updating both files. (Thanks Alicia!) I havenā€™t tried it so far, but I recommend you take a look yourself.

Conclusion #

Example of using the symbol picker in Helix in a WebKit header file - there is a big popup across the entire window, showing results of a fuzzy search on the left, and a snippet of the selected item on the right Searching for a field using the symbol picker

Overall, Iā€™m very satisfied with the results, so far everything is working like I expected it to. Finally having a working language server brought me the usual benefits - I mostly got rid of the manual compile-fix cycles that introduced so much friction and waiting times, and trivial mistakes and typos are much less of a headache now. But the biggest improvement, to me, is Goto definition/references and the symbol picker, making it easier to grasp how things interact. Much better than using grep over and over!

As I was fighting clangd/podman, I also came across some other options that I didnā€™t try, but might be interesting to look at:

  1. VSCode dev containers
    Probably the most polished option, though it is exclusive to VSCode - from what I understand, the extension isnā€™t even available to forks for licensing reasons.

  2. Distant
    Its main purpose is to act as a tool for working remotely, but I donā€™t see why it couldnā€™t be used with a container. It is still in alpha, and so far only has support in Neovim. I canā€™t tell how well it would play with LSP, but it might be worth a shot if you already use Neovim.

December 09, 2024 12:00 AM