October 07, 2024

Release Notes for Safari Technology Preview 205

Surfin’ Safari

Safari Technology Preview Release 205 is now available for download for macOS Sequoia beta 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: 283688@main…284049@main.

HTML

Resolved Issues

  • Fixed adding an unexpected download failure when no placeholder URL is provided. (284157@main) (136378962)

JavaScript

New Features

  • Added support for Math.sumPrecise. (283774@main) (131580043)

  • Added support for Iterator.prototype.reduce. (283697@main) (136064316)

Resolved Issues

  • Fixed: Updated Intl.DurationFormat#resolvedOptions to the latest specification. (283901@main) (136276429)
  • Fixed Iterator Helpers methods to not iterate an array. (283933@main) (136303997)

Lockdown Mode

New Features

  • Enabled Lockdown Mode Safe Fonts to try parsing web fonts with a safe font parser in Lockdown Mode. While the safe parser is enabled the list of allowed fonts won’t be used. (283951@main) (125621507)

SVG

Deprecations

  • Removed the SVG 1.1 kerning property. (283718@main) (116965514)

Tables

Resolved Issues

  • Fixed table row direction to be determined by the table’s direction, not the section. (283875@main) (99343532)

Text

Resolved Issues

  • Fixed: The changes for GB18030-2022 now properly impact GBK as well, as required by the Encoding Standard. (283987@main) (136368583)

Web API

Resolved Issues

  • Fixed the onrejectionhandled and onunhandledrejection event handler attributes to work correctly on body and frameset elements. (283698@main) (135401362)

Web Driver

Resolved Issues

  • Fixed chorded mouse interactions by ensuring input dispatch logic correctly interprets successive mousepress or mouserelease actions with different button values. (283790@main) (128669517)

Web Extensions

Resolved Issues

  • Fixed an issue to restore lost Safari Web Extension data. (136159837)

WebAssembly

New Features

  • Added support for the new Wasm Exception Specification. (283954@main) (131409318)

October 07, 2024 11:00 PM

WPE WebKit Blog: WPE WebKit 2.46 highlights

Igalia WebKit

A couple of weeks ago, the WPE WebKit team released version 2.46. This is an important milestone for the project as, for the first time in a stable series, the Skia backend takes over rendering. Skia brings significant improvements to the graphics stack, so we are very happy for this release. The list of changes goes beyond graphics, and it’s not short of awesome, so let’s have a look to what’s new!

Cairo is out, Skia is in

We announced some time ago that a new rendering backend with Skia was on the works and that it would eventually replace Cairo. 2.46 the first release series where Skia is used, bringing important improvements in rendering and performance.

While Skia can use a GPU for rendering, our testing with common embedded SoCs has shown that the way WPE WebKit works may result in slightly worse performance in some cases than letting Skia use the CPU. Hence, for the 2.46 releases the latter is the default, while development continues to improve GPU usage on low-powered devices with the ultimate goal of making accelerated rendering the default choice in all cases.

The Cairo backend is still present and will be selected automatically at build time for big-endian architectures, where Skia is not yet supported. We plan to remove support for Cairo in the near future, and this approach allows us to ship the new renderer while solving the remaining issues. At any rate, the Cairo renderer is no longer receiving active development.

It is important to notice that it is recommended to build WPE with Clang instead of GCC. This comes from upstream Skia; see their supported and preferred compilers page for details.

Graphics stack revamped

Tha switch to Skia has made possible a significant number of changes and improvements in the WebKit graphics stack. These changes relate to accelerated canvas, accelerated CSS filters, color spaces, and more. Carlos García has written extensively about these changes in his blog, we recommend reading his article for more details.

Trace point profiling with sysprof

Sysprof is a profiling and performance analysis tool for Linux. Thanks to integration with libsysprof-capture, it is now possible to use Sysprof to record trace points to do profiling and performance analysis of WebKit internals. This is a major improvement that will allow us to more effectively analyze the code paths that are more performance-sensitive and find ways to optimize them. It will also allow vendors to profile their specific hardware configurations and specific use-cases as well.

For a more in-depth presentation of the integration with Sysprof, please read Georges Stavacras’ blog post on the topic.

API changes

Additions

  • webkit_settings_apply_from_key_file() allows applying WebKit settings directly from a key file
  • The console message API, which had been previously deprecated, has been brought to the current API
  • WebKitAutomationSession::will-close signal, which allows clients to perform cleanup tasks before an automation session is closed
  • enable-2d-canvas-acceleration WebSetting can be used to control 2D-canvas acceleration in Skia-enabled builds
  • webkit_web_view_toggle_inspector() shows or hides the web inspector for a given webview (only available with the WPE platform API)

Deprecations

  • WebKitWebView::insecure-content-detected signal.
  • WebKitWebContext:use-system-appearance-for-scrollbars property.
  • webkit_web_context_set_use_system_appearance_for_scrollbars() and webkit_web_context_get_use_system_appearance_for_scrollbars().

GStreamer customizations

Compile-time platform-specific GStreamer customizations are now done at runtime, using the WEBKIT_GST_QUIRKS and WEBKIT_GST_HOLE_PUNCH_QUIRK environment variables. Setting their value to help will return a help message with the possible values to stderr. A list of the removed CMake defines:

  • USE_GSTREAMER_NATIVE_VIDEO
  • USE_GSTREAMER_NATIVE_AUDIO
  • USE_GSTREAMER_TEXT_SINK
  • USE_GSTREAMER_HOLEPUNCH
  • USE_WPEWEBKIT_PLATFORM_WESTEROS
  • USE_WPEWEBKIT_PLATFORM_BCM_NEXUS
  • USE_WPEWEBKIT_PLATFORM_AMLOGIC
  • USE_WPEWEBKIT_PLATFORM_RPI
  • USE_WPEWEBKIT_PLATFORM_BROADCOM
  • USE_WESTEROS_SINK

Web Platform changes

The changes to supported Web Platform features between releases of WebKit are always substantial, and for that reason listing all of those changes here would be a major endeavour. The following is an incomplete list of some of the features that have been enabled, removed, and marked in preview state since 2.44, in no particular order:

  • CSS Container/Style Queries
  • CSS text-wrap-style
  • CSS background-clip: border-area
  • CSS text-underline-position: left|right
  • CSS scrollbar-width
  • CSS View Transitions
  • CSS Grid Masonry layout (preview)
  • CSS ::target-text pseudo element
  • WebCrypto X25519 algorithm (preview)
  • AppCache support has been removed
  • New Promise.try() method
  • New Observable methods, like .map() and .filter()

Other noteworthy changes

  • Suport for the WebP image format is now always enabled.
  • WebDriver clients may now connect to an already running process, instead of always needing to spawn a new one.
  • The gst-libav AAC decoders are now disabled due to outstanding bugs. Distributors are encouraged to use the GStreamer FDK AAC decoder (part of gst-plugins-bad) instead.

And much more!

WebKit evolves and changes a lot between major stable releases. Listing all changes would not be possible. There are countless bug fixes, performance improvements, new web features supported, and so on. We recommend checking the release notes and the git log for more details.

The WPE WebKit team is already working on the 2.48 release, schedule for early next year. Until then!

October 07, 2024 12:00 AM

September 30, 2024

Release Notes for Safari Technology Preview 204

Surfin’ Safari

Safari Technology Preview Release 204 is now available for download for macOS Sequoia beta 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: 283043@main…283691@main.

Accessibility

Resolved Issues

  • Fixed VoiceOver focus to activate PDF form fields when it lands on them. (283281@main) (134522935)

CSS

New Features

  • Added support for cross-document view-transitions. (283320@main) (133994557)
  • Added preview support for line-clamp. (283233@main) (135369594)

Resolved Issues

  • Fixed text-decoration-thickness to work in buttons. (283212@main) (118320835)
  • Fixed skipping view transitions on hidden pages. (283084@main) (125017653)
  • Fixed contrast between ButtonFace and ButtonText system colors in dark mode. (283284@main) (131996608)

Forms

Resolved Issues

  • Fixed HTMLSelectElement.prototype.add with optgroup elements. (283080@main) (120553757)

JavaScript

Resolved Issues

  • Fixed: Improved the TypeError message when a WeakMap constructor takes an iterable that yields invalid entry. (283199@main) (135333331)
  • Fixed incorrect SyntaxError when destructuring let. (283217@main) (135353378)

Deprecations

  • Removed obsoleted methods for Temporal.PlainTime and Temporal.PlainDateTime to align with specification changes. (283315@main) (135509670)

Service Workers

Resolved Issues

  • Fixed Service Workers to support focusing a page that is being loaded. (283263@main) (135337772)

Web API

New Features

  • Added support for the Cookie Store API. (283654@main) (135969444)

Resolved Issues

  • Fixed scrollIntoView(...) for SVG elements. (283157@main) (135265918)

Web Driver

Resolved Issues

  • Fixed Web Driver to use pointer origin rather than viewport origin for state location resolution. (283186@main) (128668986)

Web Extensions

New Features

Resolved Issues

  • Fixed blob URL downloads failing to trigger from an extension. (283220@main) (78929424)
  • Fixed including the extension’s icon in the commands menu item and prevented customization using System Settings. (283229@main) (135360504)

Web Inspector

Resolved Issues

  • Fixed an issue where multi-line content in the Console prompt was not scrollable. (283412@main) (131756916)

September 30, 2024 10:04 PM

September 27, 2024

Carlos García Campos: Graphics improvements in WebKitGTK and WPEWebKit 2.46

Igalia WebKit

WebKitGTK and WPEWebKit recently released a new stable version 2.46. This version includes important changes in the graphics implementation.

Skia

The most important change in 2.46 is the introduction of Skia to replace Cairo as the 2D graphics renderer. Skia supports rendering using the GPU, which is now the default, but we also use it for CPU rendering using the same threaded rendering model we had with Cairo. The architecture hasn’t changed much for GPU rendering: we use the same tiled rendering approach, but buffers for dirty regions are rendered in the main thread as textures. The compositor waits for textures to be ready using fences and copies them directly to the compositor texture. This was the simplest approach that already resulted in much better performance, specially in the desktop with more powerful GPUs. In embedded systems, where GPUs are not so powerful, it’s still better to use the CPU with several rendering threads in most of the cases. It’s still too early to announce anything, but we are already experimenting with different models to improve the performance even more and make a better usage of the GPU in embedded devices.

Skia has received several GCC specific optimizations lately, but it’s always more optimized when built with clang. The optimizations are more noticeable in performance when using the CPU for rendering. For this reason, since version 2.46 we recommend to build WebKit with clang for the best performance. GCC is still supported, of course, and performance when built with GCC is quite good too.

HiDPI

Even though there aren’t specific changes about HiDPI in 2.46, users of high resolution screens using a device scale factor bigger than 1 will notice much better performance thanks to scaling being a lot faster on the GPU.

Accelerated canvas

The 2D canvas can be accelerated independently on whether the CPU or the GPU is used for painting layers. In 2.46 there’s a new setting WebKitSettings:enable-2d-canvas-acceleration to control the 2D canvas acceleration. In some embedded devices the combination of CPU rendering for layer tiles and GPU for the canvas gives the best performance. The 2D canvas is normally rendered into an image buffer that is then painted in the layer as an image. We changed that for the accelerated case, so that the canvas is now rendered into a texture that is copied to a compositor texture to be directly composited instead of painted into the layer as an image. In 2.46 the offscreen canvas is enabled by default.

There are more cases where accelerating the canvas is not desired, for example when the canvas size is not big enough it’s faster to use the GPU. Also when there’s going to be many operations to “download” pixels from GPU. Since this is not always easy to predict, in 2.46 we added support for the willReadFrequently canvas setting, so that when set by the application when creating the canvas it causes the canvas to be always unaccelerated.

Filters

All the CSS filters are now implemented using Skia APIs, and accelerated when possible. The most noticeable change here is that sites using blur filters are no longer slow.

Color spaces

Skia brings native support for color spaces, which allows us to greatly simplify the color space handling code in WebKit. WebKit uses color spaces in many scenarios – but especially in case of SVG and filters. In case of some filters, color spaces are necessary as some operations are simpler to perform in linear sRGB. The good example of that is feDiffuseLighting filter – it yielded wrong visual results for a very long time in case of Cairo-based implementation as Cairo doesn’t have a support for color spaces. At some point, however, Cairo-based WebKit implementation has been fixed by converting pixels to linear in-place before applying the filter and converting pixels in-place back to sRGB afterwards. Such a workarounds are not necessary anymore as with Skia, all the pixel-level operations are handled in a color-space-transparent way as long as proper color space information is provided. This not only impacts the results of some filters that are now correct, but improves performance and opens new possibilities for acceleration.

Font rendering

Font rendering is probably the most noticeable visual change after the Skia switch with mixed feedback. Some people reported that several sites look much better, while others reported problems with kerning in other sites. In other cases it’s not really better or worse, it’s just that we were used to the way fonts were rendered before.

Damage tracking

WebKit already tracks the area of the layers that has changed to paint only the dirty regions. This means that we only repaint the areas that changed but the compositor incorporates them and the whole frame is always composited and passed to the system compositor. In 2.46 there’s experimental code to track the damage regions and pass them to the system compositor in addition to the frame. Since this is experimental it’s disabled by default, but can be enabled with the runtime feature PropagateDamagingInformation. There’s also UnifyDamagedRegions feature that can be used in combination with PropagateDamagingInformation to unify the damage regions into one before passing it to the system compositor. We still need to analyze the impact of damage tracking in performance before enabling it by default. We have also started an experiment to use the damage information in WebKit compositor and avoid compositing the entire frame every time.

GPU info

Working on graphics can be really hard in Linux, there are too many variables that can result in different outputs for different users: the driver version, the kernel version, the system compositor, the EGL extensions available, etc. When something doesn’t work for some people and work for others, it’s key for us to gather as much information as possible about the graphics stack. In 2.46 we have added more useful information to webkit://gpu, like the DMA-BUF buffer format and modifier used (for GTK port and WPE when using the new API). Very often the symptom is the same, nothing is rendered in the web view, even when the causes could be very different. For those cases, it’s even more difficult to gather the info because webkit://gpu doesn’t render anything either. In 2.46 it’s possible to load webkit://gpu/stdout to get the information as a JSON directly in stdout.

Sysprof

Another common symptom for people having problems is that a particular website is slow to render, while for others it works fine. In these cases, in addition to the graphics stack information, we need to figure out where we are slower and why. This is very difficult to fix when you can’t reproduce the problem. We added initial support for profiling in 2.46 using sysprof. The code already has some marks so that when run under sysprof we get useful information about timings of several parts of the graphics pipeline.

Next

This is just the beginning, we are already working on changes that will allow us to make a better use of both the GPU and CPU for the best performance. We have also plans to do other changes in the graphics architecture to improve synchronization, latency and security. Now that we have adopted sysprof for profiling, we are also working on improvements and new tools.

By carlos garcia campos at September 27, 2024 10:30 AM

September 17, 2024

Get Ready for Interop 2025: Your Chance to Shape the Web

Surfin’ Safari

Hey web developers! It’s that exciting time of year again when we start considering Interop 2025 proposals. We’re thrilled to invite you to help shape the future of web interoperability.

Interop 2025 is just around the corner, and we want your brilliant ideas to make the web platform even more awesome. Whether you’re a seasoned pro or a newcomer with fresh perspectives, we want to hear from you!

Key Dates to Remember

  • Proposal Submission Opens: September 17, 2024
  • Submission Deadline: October 9th, 2024

Don’t miss this opportunity to influence the direction of web standards and browser implementations!

I’m new to the Interop project, what is it about?

The Interop Project is a collaborative initiative among major browser vendors to improve cross-browser compatibility and interoperability on the web platform. The project focuses development efforts on improving consistency across browsers for key web features and APIs ensuring they are uniformly implemented using a shared test suite called Web Platform Tests (WPT).

This coordinated approach aims to reduce developer frustration, enable new web capabilities, improve user experiences, and accelerate the implementation of web standards.

Screenshot of the Interop 2024 dashboard, showing current scores: Chrome 98, Firefox 92, Safari 97.
The Interop 2024 dashboard with this year’s project in progress

WebKit has made significant strides in improving web interoperability through its participation in Interop 2024. Some notable areas of improvement include CSS nesting, the popover attribute in HTML, scrollbar styling, and text directionality. Features you love in WebKit, like relative color syntax and font-size-adjust, have landed in all browsers thanks to Interop 2024. Our work driving the Accessibility investigation in 2023 led to tests that are now included in Interop 2024, improving web accessibility across all browsers. And there’s much more. These advancements not only make web development more streamlined but also contribute to a more unified and reliable web experience for users across different browsers and devices.

What Makes a Great Proposal?

We’re looking for proposals that address real-world interoperability challenges. The best submissions are typically:

  • Specific: Identify a specific interoperability issue.
  • Impactful: Provide clear use cases and examples, especially from your own experience.
  • Tested: Interop focus areas are scored by the pass rate of web platform tests, this means proposals need good tests to be considered.
  • Stable: Interop is about improving browser compatibility for stable, well-understood web standards.
  • Valuable: Developers and/or users will benefit from improved interoperability. These are some signals to consider including in your proposal.

Ready to dive in? Check out this handy proposal template and submission guide to get started. If you aren’t sure if your proposal meets all of these guidelines, submit it anyway and it will be evaluated by the Interop team.

Resources at Your Fingertips

Join the Interop Party!

Interop 2025 is all about collaboration. By participating, you’re joining a global community of developers, browser vendors, and standards bodies working together to make the web more consistent and reliable across platforms.

Get ready to share your ideas and insights as we make the web even more amazing together. We can’t wait to see your proposals.

Remember, the future of the web is in your hands. Let’s build it together!

September 17, 2024 04:00 PM

September 16, 2024

WebKit Features in Safari 18.0

Surfin’ Safari

Safari 18.0 is here. Along with iOS 18, iPadOS 18, macOS Sequoia and visionOS 2, today is the day another 53 web platform features, as well as 25 deprecations and 209 resolved issues land in WebKit, the rendering engine driving Safari.

New in Safari 18

Distraction Control

Distraction Control lets you hide distracting items as you browse the web, such as sign-in banners, cookie preference popups, newsletter signup overlays, and more, in Safari for iOS 18, iPadOS 18 and macOS Sequoia.

Activate Distraction Control by tapping the Page Menu , and choosing “Hide Distracting Items”. Then tap the element you want to disappear, and watch it fade away. You can easily un-hide items at any time by returning to the Page Menu, and tapping “Show Hidden Items”.

Viewer

Whenever you are on a web page with a prominent video element, you can click on “Video Viewer” in the Page Menu . The video will enlarge to fill the whole window. If you switch tabs, close the window, or occlude the web page with another window, the video enters picture-in-picture.

We always recommend using semantic HTML when creating a website, including <video>,<main>, <article> and other elements that describe content. Doing so helps ensure both Safari Reader and Safari Viewer work best for the users of your website.

Safari windows on a Mac, with a video playing, big, in one window. The website is faintly visible behind the large video.

iPhone Mirroring and remote inspection

With iPhone Mirroring on macOS Sequoia, you can use your iPhone from your Mac. Combine it with remote inspection from Safari, and now it’s easier than ever to test and debug websites on iOS using Web Inspector.

Get set up for remote inspection by first ensuring you have Safari’s developer tools enabled on your Mac (if you can see the Develop menu in Safari, you’ve already done this step). Next, enable Web Inspector on your iPhone at Settings > Apps > Safari > Advanced > Web Inspector. Then, you’ll need to connect the device to your Mac using a cable to grant permission. Once plugged in, your device will appear in the Develop menu in Safari. Finally, to enable wireless debugging, go to Safari on macOS > Develop > [your device] > Connect via Network.

Now you can use Web Inspector to wirelessly debug websites running on iPhone anytime. And with iPhone Mirroring, you don’t even have to pull out your phone. Everything is on your Mac’s screen.

Learn more about remote inspection by reading Inspecting iOS and iPadOS, or by watching Rediscover Safari developer features from WWDC. Learn more about iPhone Mirroring1 on apple.com.

Web apps for Mac

Last year, we added support for web apps in macOS Sonoma. You can add any website to your dock — whether or not it was built with a Manifest file, Service Worker, or other technology to customize the web app experience. Go to the site in Safari, then File > Add to Dock… where you can customize the icon, change the name, and even adjust the URL. Then, just click on the web app icon in your Dock, and the website will open as a stand-alone app.

This year brings two improvements to web apps on Mac.

Opening links

macOS Sequoia adds support for opening links directly in web apps. Now, when a user clicks a link, if it matches the scope of a web app, that link will open in the web app instead of their default web browser. For example, imagine you have added MDN Web Docs to your Dock. Then a colleague sends you a link to an MDN page in Messages, Mail, Slack, Discord, IRC, or any non-browser application on your Mac. Now when you click on that link, it will open in the MDN Web Docs web app instead of your default browser.

Clicking a link within a browser will maintain the current behavior. This feature only affects links opened elsewhere. (When a user is in Safari, clicking on a link that matches the scope of a web app that is added to Dock, they will see an “Open in web app” banner, unless they have previously dismissed the banner.)

By default, this behavior applies when the link matches the host of the web page used to create the web app. As a developer, you can refine this experience by defining the range of URLs that should open in the web app with the scope member in the web app manifest.

Extension support

Now users can personalize web apps on Mac with Safari Web Extensions and Content Blockers. Navigate to the web app’s Settings menu to access all the installed Content Blockers and Web Extensions. Any enabled in Safari will be on by default in the web app. Each web app is uniquely customizable, just like Safari profiles.

CSS

View Transitions

WebKit added support for the View Transitions API in Safari 18. It provides an optimized browser API to animate elements from one state to another. Safari supports the CSS View Transitions Module Level 1 specification that adds new CSS properties and pseudo-elements for defining transition animations, along with a new browser API to start transition animations and react to different transition states. It works by capturing the current (old) state of the page and applying an animated transition to the new state. By default, the browser applies a cross-fade between the states.

Call the document.startViewTransition() method to initiate the capture. You can pass a callback function as the first argument to make DOM state changes between the old and new captures. The method returns a ViewTransition object which contains promises that can be used to track when the view transition starts or ends.

Once the states are captured, a pseudo-element tree is built which can be targeted with CSS, allowing you to modify the CSS animations used for the transitions. The animations out of the old page state and into the new page state can be modified via the ::view-transition-new(*) and ::view-transition-old(*) selectors. You can also ask the browser to independently track state changes for a specific element by naming it with the CSS view-transition-name property. You can then use the pseudo-elements to customize animations for it.

.page-view {
    view-transition-name: page-view;
}
::view-transition-old(page-view) {
    animation: 500ms ease-in-out transition-out-animation;
}
::view-transition-new(page-view) {
    animation: 500ms ease-in-out transition-in-animation;
}

The :active-view-transition pseudo-class becomes active on the root element when a view transition is running.

The example below demonstrates state management with tabbed navigation. Each tab view has a custom transition animation out and a subtly different animation in, while the tabs themselves rely on the default page transition.

See View Transitions in action in this demo.

Style Queries

WebKit for Safari 18.0 adds support for Style Queries when testing CSS Custom Properties. Similar to how developers can use Sass mixins, Style Queries can be used to define a set of reusable styles that get applied as a group.

Here, if the --background custom property is set to black, then certain styles will be applied — in this case to make the headline and paragraph text color white.

@container style(--background: black) {
  h2, h3, p {
    color: white;
  }
}

Don’t forget to pay attention the HTML structure. By default, Style Queries reference the styles on the direct parent element. You can create a different reference through the use of Container Query names.

currentcolor and system color keywords in Relative Color Syntax

Support for Relative Color Syntax shipped in Safari 16.4. It lets you define colors in a more dynamic fashion, creating a new color from an existing color. The value lch(from var(--color) calc(L / 2) C H) for instance uses the lch color space to take the variable --color and calculate a new color that’s half its lightness, calc(L / 2).

Now in Safari 18.0, the first browser to ship support, you can reference the currentcolor or a system color keyword as you define the new color. For example, this code will set the background color to be the same color as the text color, only 4 times lighter, as calculated in the oklch color space.

section { background: oklch(from currentcolor calc(L * 4) C H); }

See how `currentcolor` works with Relative Color Syntax in this demo.

Being able to reference system color keywords opens up another world of options. System colors are like variables that represent the default colors established by the OS, browser, or user — defaults that change depending on whether the system is set to light mode, dark mode, high contrast mode, etc. For example, canvas represents the current default background color of the HTML page, while fieldtext matches the color of text inside form fields. Find the full list of system colors in CSS Color level 4.

Relative Color Syntax lets you define dynamic connections between colors in your CSS, lessening the need to control color through variables in a tightly-regimented design system. Learn more about Relative Color Syntax by watching this portion of What’s new in CSS from WWDC23.

Translucent accent colors

Partially transparent colors in accent-color are now blended on top of the Canvas system color to match the latest updates to the web standard. This means that any of the many ways to define colors using an alpha channel will now work as expected when used to define an accent color for a form control.

.form-control {
    accent-color: rgba(0,0,0,0.6);
}

Animating display

WebKit for Safari 18.0 adds support for transition animation of the display property.

Many developers are excited to use @starting-style along with transition-behavior and display: none interpolation. WebKit for Safari 17.4 added general support for transition-behavior, including transition-behavior: allow-discrete. WebKit for Safari 17.5 added support for @starting-style, letting you define starting values for transitioning an element as it’s created (or re-created). Now in WebKit for Safari 18.0, you can use these features together to transition the display property.

Backdrop Filter

Originally shipped in Safari 9.0, backdrop filter provides a way to apply graphics effects to the content behind a particular element. You can apply backdrop-filter to a headline, for example, and everything behind the headline will be blurred, or have decreased saturation, or increased contrast. Any of the filter functions from SVG can be used — blur(), brightness(), contrast(), drop-shadow(), grayscale(), hue-rotate(), invert(), opacity(), saturate(), and sepia().

For many years, backdrop filter only worked in Safari. It was available when you prefixed the property with -webkit-backdrop-filter. Now, starting in Safari 18.0, you don’t need the prefix. We also improved our implementation, fixing bugs and boosting interoperability.

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

This demo shows eight different filters and what you might do with each one alone. You can, of course, combine filters to create even more interesting results. With backdrop filter supported in Safari since 2015, Edge since 2018, Chrome since 2019, Samsung Internet since 2020, and Firefox since 2022, this is a great time to consider the kind of graphic design possibilities it enables.

Content visibility

WebKit for Safari 18.0 adds support for content-visibility. This property controls whether or not an element renders its contents in a fashion that’s useful for making performance optimizations. It lets you communicate to the browser that certain portions of the page will likely be initially offscreen, and suggest they be omitted from layout and rendering. This can make the page load faster.

And more

WebKit for Safari 18.0 adds parsing support for the custom value for theprefers-contrast media query. (It does not return “true” on Apple platforms, since there is no forced-colors mode in iOS, iPadOS, macOS or visionOS.)

Spatial Web

WebXR

Safari 18.0 for visionOS 2 adds support for immersive-vr sessions with WebXR. Now you can create fully immersive experiences for people using Apple Vision Pro and deliver them through the web. WebXR scenes are displayed using hardware-accelerated graphics driven by WebGL.

A beautiful garden rendered in created graphics. There's a tree with bright red leaves. A blue sky full of puffy white clouds. Bright green grass, with a path leading by plants and garden sculpture. It's a world created in WebXR.
Try out the Chess Garden demo to see WebXR in action.

Safari for visionOS 2 supports the new WebXR transient-pointer input mode. It lets you make the most of natural input on visionOS, and allow your users to interact with a look and a pinch.

We are in a rendered 3d environment, in a garden. We look at a chess board, with a real human hand lifting a rendered chess piece to make the next move in the game. A floating panel has two buttons reading "Leave garden" and "Reset game".
Use transient-pointer in your WebXR experience to support interactions like this, where players use their hands to pinch and drag as they move chess pieces around.

If you want to animate a 3D model of the user’s hands, Safari for visionOS 2 also includes support for WebXR hand tracking. To ensure privacy, permission to allow hand tracking will be requested from users at the start of their WebXR session.

Learn all about WebXR on visionOS 2 by watching Build immersive web experiences with WebXR from WWDC. Learn more about transient-pointer input mode by reading Introducing natural input for WebXR in Apple Vision Pro. And learn all about how to use Safari’s developer tools on Mac to inspect and debug in Apple Vision Pro by reading Try out your website in the spatial web.

Spatial photos and panoramas

One of the amazing experiences you can have on Apple Vision Pro is looking at spatial photos and panoramas. The web is a great place to share these photos with others.

A family blows out candles on a birthday cake in a photo — that's floating in a frame in midair, in a living room. This is a still from the WWDC23 Keynote that introduced Apple Vision Pro. It's an example of how spatial photos work.

When you open the Photos app in visionOS, you see your library of photos. When you tap an image, it appears alone in a floating frame in front of you. Spatial photos appear at just the right height and viewing angle to make it feel like you’ve gone back to a moment in time. A second tap of the UI breaks a spatial photo out of its frame, becoming even more immersive. Similarly, a panorama floats in a frame on first tap. Then on second tap of the UI, it expands to wrap all around you, creating a fully immersive experience.

Now in Safari 18.0 for visionOS 2, you can use the JavaScript Fullscreen API to create a similar experience on the web. You can embed the photo in a web page, and provide the ability to tap. The photo will pop into a floating frame as the Safari window disappears. Then when the user taps on the spatial photo or panorama UI that visionOS provides, the photo will further expand to create a more immersive experience. When they exit the image, the Safari window will return.

Let’s walk through how to support experiencing a spatial photo or panorama on the web using Fullscreen API. First, include the image on your web page using any of the techniques used for years. Here, we can embed a flattened panoramic photo into the web page using simple HTML.

<img src="panorama.jpeg" class="go-fullscreen" alt="[description]">

Then using JavaScript, we’ll trigger .requestFullscreen() on tap. Perhaps like this.

document.querySelectorAll('.go-fullscreen').forEach(element => {
    element.addEventListener('click', async () => {
        await element.requestFullscreen();
    });
});

You could, of course, create your own UI for the user to tap, rather than making the entire photo the tap target.

Spatial images work just the same, although it’s likely we want to provide fallbacks for browsers that do not support HEIC files. We can do so with the picture element.

<picture>
    <source srcset="spatial.heic" type="image/heic">
    <source srcset="fallback.avif" type="image/avif">
    <img src="fallback.jpg" class="go-fullscreen" alt="write descriptive text here" >
</picture>

Spatial images are stereoscopic, with both a left and right channel. In Safari, when the image is embedded in the web page, the browser will show the left channel. And there’s no need to worry about providing a fallback of any sort for Safari on macOS, iOS, or iPadOS — the stereoscopic HEIC file works great.

This technique will also cause images to go fullscreen in any browser that supports Fullscreen API. Learn more about adding panorama and spatial photos to your websites by watching Optimize for the spatial web from WWDC.

Shaping interaction regions on visionOS

As a web developer, you’re very familiar with how link styling works on the web. For decades you’ve been able to use CSS to style text-decoration, color and more for :link, :hover, :active, and :visited states. You’ve also been able to adjust the size of the invisible tap target through use of padding.

Apple Vision Pro adds a new dimension to how links work — tap targets are visible on visionOS. Anytime a user looks at an interactive element, it’s highlighted to let them know that it can be tapped. And you as a designer or developer can intentionally design how an interaction region looks. You may want to add padding, for instance, or even a rounded corner to the otherwise invisible box.

Now in Safari in visionOS 2 , when you use CSS clip-path to change the shape of tappable area of a link, the visible interaction region will change shape as well. Interactive UI elements built with SVG and cursor: pointer will also be highlighted with the proper shape. Learn more by watching Optimize for the spatial web from WWDC.

Video on visionOS

Safari for visionOS 2 adds support for docking fullscreen videos into the current Environment. Anytime a user is watching a video fullscreen, they can tap the mountain symbol to enter an immersive experience. Turning the Digital Crown adjusts the immersion.

HTML

Writing Suggestions

At last year’s WWDC, Apple unveiled inline predictive text on iOS, iPadOS, macOS and more. It helps users input text faster by predicting what they might be typing and finishing the word, phrase or even a whole sentence when the user taps the space bar. Now, WebKit for Safari 18.0 on iOS, iPadOS, visionOS, macOS Sequoia and macOS Sonoma brings inline predictive text to the web.

While inline predictive text makes for a fantastic, personalized user experience, there might be specific situations on the web where it’s better to not have predictions. WebKit for Safari 18.0 on iOS, iPadOS, visionOS, macOS Sequoia and macOS Sonoma gives web developers the opportunity to disable inline predictions through the writingsuggestions attribute. By default, writing suggestions is set to true. You can turn off the capability by including the writingsuggestions="false" attribute on any type of text input field.

Try out the difference between having writing suggestions or not in this demo. Be sure to use a browser and operating system that provide suggestions of what to write, and have support for writingsuggestions.

Switch

WebKit for Safari on iOS 18 adds haptic feedback for <input type=checkbox switch>. This means, now when a user taps a switch control on iPhone, a single tap is felt — just like how toggling a switch feels in Settings app on iOS. Try this demo to see what it’s like.

Date and time inputs

WebKit for Safari 18.0 on macOS improves accessibility support for date and time input field types. Now <input type="date">, <input type="datetime-local">, and <input type="time"> elements work properly with VoiceOver.

ARIA

Usually elements have the labels they need, but sometimes there is no text label for a particular button or UI. In this situation, ARIA can be used to provide an accessible label. The aria-label attribute provides names of labels while aria-roledescription provides the description for the role of an element.

On very rare occasions, you may need to override aria-label or aria-roledescription to provide different names or descriptions specifically for braille. The aria-braillelabel and aria-brailleroledescription attributes provide such an ability. They exist to solve very specific needs, including educational contexts where the site needs to render the specific braille table dot pattern. If you do use braille-related ARIA attributes, be sure to test them using a braille reader. If in doubt, relying on the accessible name from content or aria-label / aria-roledescription is almost always the better user experience. WebKit has supported these ARIA attributes for years.

Now, WebKit for Safari 18.0 adds support for the ariaBrailleLabel and ariaBrailleRoleDescription element reflection properties. These make it possible to get and set the aria-braillelabel and aria-brailleroledescription ARIA attributes on DOM elements directly via JavaScript APIs, rather than by using setAttribute and getAttribute.

JavaScript

WebKit for Safari 18.0 adds support for Unicode 15.1.0 characters in RegExp. Unicode 15.1 added 627 characters, bringing the total of characters to 149,813. Now, these new characters can be used in regular expressions.

WebKit for Safari 18.0 also adds support for the v flag with RegExp.prototype[Symbol.matchAll]. providing more powerful ways to match Unicode characters, as specified in the ECMAScript 2024 standard.

For example, you can now specify to only match on Latin characters, while avoiding matching on Cyrillic script characters.

const regex = /\p{sc=Latin}/v;
console.log(regex.test('A')); // true, 'A' is a Latin script character
console.log(regex.test('А')); // false, 'А' is a Cyrillic script character

Or split a string matching on Emojis.

"a 🥰 b 🥰".split(/[\p{Emoji}--\p{ASCII}]/v)// ["a ", " b ", ""]

Web API

WebKit for Safari 18.0 adds support for URL.parse(), a way to parse URLs which returns null rather than an exception when parsing fails.

// Before
let url = null;
try {
  url = new URL(input, base);
} catch(e) { }

// Now
const url = URL.parse(input, base);

WebKit for Safari 18.0 expands Declarative Shadow tree support by adding the shadowRootDelegatesFocus and shadowRootClonable IDL attributes to the <template> element. It also adds the shadowRootSerializable attribute and shadowRootSerializable IDL attribute to the <template> element, enabling those using Declarative Shadow roots to opt into making them serializable. Serializing can be done through the new getHTML() method that has been added at the same time.

WebKit for Safari 18.0 adds support for PopStateEvent’s hasUAVisualTransition, indicating whether the user agent has a visual transition in place for the fragment navigation.

WebKit for Safari 18.0 adds support for subresource integrity in imported module scripts, which gives cryptographic assurances about the integrity of contents of externally-hosted module scripts.

WebKit for Safari 18.0 adds support for the bytes() method to the Request, Response, Blob, and PushMessageData objects. This replaces the need for web developers to call arrayBuffer(), which can be difficult to use, and wraps the result in a Uint8Array . Calling bytes() is now the recommended way going forward when you need to access the underlying bytes of the data these objects represent.

WebKit for Safari 18.0 adds support for feature detecting text fragments by exposing document.fragmentDirective. Note that the returned object (a FragmentDirective) doesn’t provide any functionality, but it’s helpful if you need to know if Fragment Directives are supported by the browser.

Canvas

WebKit for Safari 18.0 adds support for the willReadFrequently context attribute for the getContext() method. It indicates whether or not a lot of read-back operations are planned. It forces the use of a software accelerated 2D or offscreen canvas, instead of hardware accelerated. This can improve performance when calling getImageData() frequently.

WebKit for Safari 18.0 extends 2D canvas support for currentcolor. It can now be used inside color-mix() or Relative Color Syntax. Here currentcolor will default to the computed color property value on the canvas element.

Managed Media Source

WebKit for Safari 18.0 adds Workers support for both Managed Media Source (MMS) and Media Source Extensions (MSE). This can be especially helpful on complex websites that want to ensure continuous and smooth video playback even when other site activity (such as live commenting) causes a very busy main thread. You can see the performance difference in this demo.

WebRTC

WebKit for Safari 18.0 adds support for the WebRTC HEVC RFC 7789 RTP Payload Format. Previously, the WebRTC HEVC used generic packetization instead of RFC 7789 packetization. This payload format provides a new option for improving videoconferencing, video streaming, and delivering high-bitrate movies and TV shows.

WebKit for Safari 18.0 adds support for MediaStreamTrack processing in a dedicated worker. And it adds support for missing WebRTC stats.

HTTPS

WebKit for Safari 18.0 adds support for secure HTTPS for all images, video, and audio by upgrading passive subresource requests in mixed content settings. This means that if some files for a website are served using HTTPS and some are served using HTTP (known as “mixed content”), all images and media will now be auto-upgraded to HTTPS, in adherence with Mixed Content Level 2.

WebGL

WebKit for Safari 18.0 adds support for six new WebGL extensions:

  • EXT_texture_mirror_clamp_to_edge
  • WEBGL_render_shared_exponent
  • WEBGL_stencil_texturing
  • EXT_render_snorm
  • OES_sample_variables
  • OES_shader_multisample_interpolation

Web Inspector

WebKit for Safari 18.0 adds support for fuzzy search code completion in the Web Inspector’s CSS source editor.

Passkeys

Two years ago at WWDC22, we announced support for passkeys — a groundbreaking industry-standard way to login to websites and app services. Passkeys provide people with an extremely easy user experience, while delivering a profound increase in security. To learn more, watch Meet Passkeys or read Supporting passkeys.

WebKit for Safari 18.0 adds support for three new features as we continue to improve passkeys. First, Safari 18.0 adds support for using mediation=conditional for web authentication credential creation. This allows websites to automatically upgrade existing password-based accounts to use passkeys. Learn more by watching Streamline sign-in with passkey upgrades and credential managers from WWDC.

Second, WebKit for Safari 18.0 adds support for using passkeys across related origins. This lets websites use the same passkey across a limited number of domains which share a credential backend.

And third, WebKit for Safari 18.0 adds support for the WebAuthn prf extension. It allows for retrieving a symmetric key from a passkey to use for the encryption of user data.

Safari Extensions

Safari 18.0 also adds support for Mobile Device Management of extension enabled state, private browsing state, and website access on managed devices. This means schools and businesses that manage iOS, iPadOS, or macOS devices can now include the configuration of Safari App Extensions, Content Blockers, and Web Extensions in their management.

Apple Pay

WebKit for Safari 18.0 adds support for funds transfer via Apple Pay.

Deprecations

While it’s rare to deprecate older technology from the web, there are occasions when it makes sense. We’ve been busy removing -webkit prefixed properties that were never standardized, aging media formats that were never supported in other browsers, and more. This helps align browser engines, improve interoperability, and prevent compatibility problems by reducing the possibility that a website depends on something that’s not a web standard.

Canvas

WebKit for Safari 18.0 removes support for OffscreenCanvasRenderingContext2D’s commit() method.

CSS

WebKit for Safari 18.0 deprecates support for a number of rarely used -webkit prefixed CSS pseudo-classes and properties — and even one -khtml prefixed property.

  • -webkit-alt and alt properties
  • :-webkit-animating-full-screen-transition pseudo-class
  • :-webkit-full-screen-ancestor pseudo-class
  • :-webkit-full-screen-controls-hidden pseudo-class
  • :-webkit-full-page-media pseudo-class
  • :-webkit-full-screen-document pseudo-class
  • :-khtml-drag pseudo-class

WebKit for Safari 18.0 also deprecates support for the resize: auto rule. Support for the resize property remains, just as it’s been since Safari 4. The values Safari continues to support include: none, both, horizontal, vertical, block, inline, plus the global values. Early versions of CSS Basic User Interface Module Level 3 defined auto, but it was later written out of the web standard.

WebKit for Safari 18.0 also deprecates support for non-standardize WEBKIT_KEYFRAMES_RULE and WEBKIT_KEYFRAME_RULE API in CSSRule.

Images

WebKit for Safari 18.0 removes support for the JPEG2000 image format. Safari was the only browser to ever provide support.

If you’ve been serving JPEG2000 files using best practices, then your site is using the picture element to offer multiple file format options to every browser. Safari 18.0 will simply no longer choose JPEG2000, and instead use a file compressed in JPEG XL, AVIF, WebP, HEIC, JPG/JPEG, PNG, or Gif — choosing the file that’s best for each user. Only one image will be downloaded when you use <picture>, and the browser does all the heavy lifting.

We have noticed that some Content Deliver Networks (CDN) use User Agent sniffing to provide one file to each UA, offering only JPEG2000 images to Safari — especially on iPhone and iPad. If you expect this might be happening with your site, we recommend testing in Safari 18.0 on both macOS Sequoia and iOS or iPadOS 18. If you see problems, contact your SaaS provider or change your image delivery settings to ensure your website provides fallback images using industry best practices.

If you notice a broken site, please file an issue at webcompat.com.

JavaScript

WebKit for Safari 18.0 removes [[VarNames]] from the global object to reflect changes in the web standard, a change that now allows this code to work:

<script>
eval('var x;')
</script>
<script>
let x;
</script>

Media

WebKit for Safari 18.0 removes support for non-standard VTTRegion.prototype.track.

Storage

WebKit for Safari 18.0 removes the last bits of support for AppCache.

When AppCache first appeared in 2009, in Safari 4, it held a lot of promise as a tool for caching web pages for use offline. It was imagined as “HTML5 Application Cache” back when HTML itself was being further expanded to handle more use cases for web applications. A developer could create a simple cache manifest file with a list of files to be cached. Its simplicity looked elegant, but there was no mechanism for cache busting, and that made both developing a site and evolving the site over time quite frustrating. AppCache also had security challenges. So new web standards were created to replace it. Today, developers use Service Workers and Cache Storage instead.

WebKit deprecated AppCache with a warning to the Console in Safari 11.0. Then in 2021, we removed support for AppCache from Safari 15.0, with a few exceptions for third-party users of WKWebView. Now we are removing those exceptions. This change to WebKit will only affect the rare web content loaded in older third-party apps that have JavaScript code which relies on the existence of AppCache related interfaces.

SVG

WebKit for Safari 18.0 removes the SVGAnimateColorElement interface, as well as the non-standard getTransformToElement from SVGGraphicsElement.

Web API

WebKit for Safari 18.0 removes support for four non-standard Web APIs:

  • KeyboardEvent.altGraphKey
  • AES-CFB support from WebCrypto
  • KeyboardEvent.prototype.keyLocation
  • HashChangeEvent’s non-standard initHashChangeEvent() method

WebView

Deprecated some legacy WebKit notification names including:

  • WebViewDidBeginEditingNotification
  • WebViewDidChangeNotification
  • WebViewDidEndEditingNotification
  • WebViewDidChangeTypingStyleNotification
  • WebViewDidChangeSelectionNotification

Bug Fixes and more

In addition to all the new features, WebKit for Safari 18.0 includes work to polish existing features.

Accessibility

  • Fixed role assignment for <header> inside <main> and sectioning elements.
  • Fixed range input not firing an input event when incremented or decremented via accessibility APIs.
  • Fixed setting aria-hidden on a slot not hiding the slot’s assigned nodes.
  • Fixed VoiceOver to read hidden associated labels.
  • Fixed comboboxes to expose their linked objects correctly.
  • Fixed VoiceOver support for aria-activedescendant on macOS.
  • Fixed time input accessibility by adding labels to subfields.
  • Fixed aria-hidden=true to be ignored on the <body> and <html> elements.
  • Fixed datetime values being exposed to assistive technologies in the wrong timezone.
  • Fixed wrong datetime value being exposed to assistive technologies for datetime-local inputs.
  • Fixed ignored CSS content property replacement text when it is an empty string.
  • Fixed the computed role for these elements: dd, details, dt, em, hgroup, option, s, and strong.
  • Fixed hidden elements targeted by aria-labelledby to expose their entire subtree text, not just their direct child text.
  • Fixed accessible name computation for elements with visibility: visible inside a container with visibility: hidden.
  • Fixed updating table accessibility text when its caption dynamically changes.
  • Fixed updating aria-describedby text after the targeted element changes its subtree.

Animations

  • Fixed the transition property to produce the shortest serialization.
  • Fixed the animation property to produce the shortest serialization.

Apple Pay

  • Fixed arbitrary 8 digit limit on a line item’s total amount.

Authentication

  • Fixed navigator.credentials.create() rejects with “NotAllowedError: Operation Failed” after a conditional UI request is aborted.
  • Fixed setting the cancel flag once the cancel completes regardless of a subsequent request occurring.

Canvas

  • Fixed drawImage(detachedOffscreenCanvas) to throw an exception.
  • Fixed OffscreenCanvas failing to render to the placeholder with nested workers.
  • Fixed losing the contents layer of the placeholder canvas of OffscreenCanvas when switching off the tab.
  • Fixed drawImage to not alter the input source or the destination rectangles.
  • Fixed toggling the visibility on a canvas parent undoing the effect of clearRect().
  • Fixed the Canvas drawImage() API to throw an exception when the image is in broken state.
  • Fixed a detached OffscreenCanvas to not transfer an ImageBuffer.

Cookies

  • Fixed treating the lack of an explicit “SameSite” attribute as “SameSite=Lax”.

CSS

  • Fixed setting white-space to a non-default value dynamically on a whitespace or a new line.
  • Fixed custom counter styles disclosure-open and disclosure-closed to point to the correct direction in right-to-left.
  • Fixed backface-visibility to create a stacking context and containing block.
  • Fixed getComputedStyle() to work with functional pseudo-elements like ::highlight().
  • Fixed: Aliased :-webkit-full-screen pseudo-class to :fullscreen.
  • Fixed: Aliased :-webkit-any-link to :any-link and :matches() to :is().
  • Fixed getComputedStyle() pseudo-element parsing to support the full range of CSS syntax.
  • Fixed @supports to correctly handle support for some -webkit prefixed pseudo-elements that were incorrectly treated as unsupported.
  • Fixed updating media-query sensitive meta tags after style changes.
  • Fixed changing color scheme to update gradients with system colors or light-dark().
  • Fixed incorrect inline element size when using font-variant-caps: all-small-caps with font-synthesis.
  • Fixed :empty selector to work with animations.
  • Fixed preserving whitespace when serializing custom properties.
  • Fixed updating style correctly for non-inherited custom property mutations.
  • Fixed element removed by parent to end up losing the last remembered size.
  • Fixed an incorrect difference between implicit and explicit initial values for custom properties.
  • Fixed the contrast of Menu and MenuText system colors.
  • Fixed keeping the shorthand value for CSS gap as-is in serialized and computed values.
  • Fixed the style adjuster for @starting-style incorrectly invoking with a null element.
  • Fixed excluding -apple-pay-button from applying to any element that supports appearance: auto and is not a button.
  • Fixed missing color interpretation methods added to CSS color specifications.
  • Fixed hsl() and hsla() implementation to match the latest spec changes.
  • Fixed the implementation of rgb() and rgba() to match the latest spec.
  • Fixed the hwb() implementation to match the latest spec.
  • Fixed the remaining color types to be synced with the latest spec changes.
  • Fixed carrying analogous components forward when interpolating colors.
  • Fixed applying the fill layer pattern for mask-mode.
  • Fixed backdrop-filter: blur to render for elements not present when the page is loaded.
  • Fixed: Improved large Grid performance.
  • Fixed some CSS properties causing quotes to be reset.

Editing

  • Fixed an issue where input method editing would sporadically drop the composition range.
  • Fixed dictation UI no longer showing up when beginning dictation after focusing an empty text field. (FB14277296)

Forms

  • Fixed displayed datalist dropdown to sync its options elements after a DOM update.
  • Fixed input elements to use the [value] as the first fallback step base.
  • Fixed <select multiple> scrollbars to match the used color scheme.
  • Fixed updating the input value when selecting an <option> from a <datalist> element. (FB13688998)
  • Fixed the value attribute not getting displayed in an input element with type="email" and the multiple attribute.
  • Fixed the iOS animation for <input type=checkbox switch>.
  • Fixed form controls drawing with an active appearance when the window is inactive.
  • Fixed constructed FormData object to not include entries for the image button submitter by default.

History

  • Fixed the properties of History to throw a SecurityError when not in a fully active Document.

HTML

  • Fixed “about:blank” document.referrer initialization.
  • Fixed parsing a self-closing SVG script element. It now successfully executes.

JavaScript

  • Fixed RegExp.prototype.@@split to update the following legacy RegExp static properties: RegExp.input, RegExp.lastMatch, RegExp.lastParen, RegExp.leftContext, RegExp.rightContext, and RegExp.$1, ... RegExp.$9.
  • Fixed String.prototype.replace to not take the fast path if the pattern is RegExp Object and the lastIndex is not numeric.
  • Fixed spec compliance for Async / Await, Generators, Async Functions, and Async Generators.
  • Fixed async functions and generators to properly handle promises with throwing “constructor” getter.
  • Fixedreturn in async generators to correctly await its value.
  • Fixed Symbol.species getters to not share a single JS Function.
  • Fixed throwing a RangeError if Set methods are called on an object with negative size property.
  • Fixed eval() function from another realm to not cause a direct eval call.
  • Fixed eval() call with ...spread syntaxt to be a direct call.
  • Fixed try/catch to not intercept errors originated in [[Construct]] of derived class.
  • Fixed several issues:
    • direct eval() in a default value expression inside a rest parameter creates a variable in the environment of the function rather than the separate one of the parameters;
    • a ReferenceError is thrown when accessing a binding, which is defined inside rest parameter, in eval(), or a closure created in a default value expression of a preceding parameter, but only if there is a var binding by the same name;
    • a closure, created in the default value expression inside a rest parameter, is created in a different VariableEnvironment of the function than its counterparts in preceding parameters which causes the incorrect environment to be consulted when querying or modifying parameter names that are “shadowed” by var bindings.
  • Fixed TypedArray sorting methods to have a special-case for camparator returning false.
  • Fixed programming style for bitwise and in setExpectionPorts.
  • Fixed emitReturn() to load this value from arrow function lexical environment prior to the TDZ check.
  • Fixed NFKC normalization to work with Latin-1 characters.
  • Fixed parsing of private names with Unicode start characters.
  • Fixed instanceof to not get RHS prototype when LHS is primitive.
  • Fixed bracket update expression to resolve property key at most once.
  • Fixed bracket compound assignement to resolve the property key at most once.
  • Fixed Object.groupBy and Map.groupBy to work for non-objects.
  • Fixed Array.fromAsync to not call the Array constructor twice.
  • Fixed inconsistent output of Function.prototype.toString for accessor properties.
  • Fixed Set#symmetricDifference to call this.has in each iteration.
  • Fixed logical assignment expressions to throw a syntax error when the left side of the assignment is a function call.
  • Fixed throwing a syntax error for nested duplicate-named capturing groups in RegEx.
  • Fixed ArrayBuffer and SharedArrayBuffer constructor to check length before creating an instance.
  • Fixed Intl implementation to ensure canonicalizing “GMT” to “UTC” based on a spec update.
  • Fixed RegEx lookbehinds differing from v8.
  • Fixed fractionalDigits of Intl.DurationFormat to be treated as at most 9 digits if it is omitted.
  • Fixed optimized TypedArrays giving incorrect results.
  • Fixed Intl.DurationFormat for numeric and 2-digit.

Loading

  • Fixed navigator.cookieEnabled to return false when cookies are blocked.

Media

  • Fixed MediaSession to determine the best size artwork to use when the sizes metadata attribute is provided. (FB9409169)
  • Fixed video sound coming from another window after changing tabs in the Tab Bar in visionOS.
  • Fixed playback for MSE videos on some sites.
  • Fixed allowing a video’s currentTime to be further than the gap’s start time.
  • Fixed broken audio playback for a WebM file with a Vorbis track.
  • Fixed sampleRate and numberOfChannels to be required and non-zero in a valid AudioEncoderConfig.
  • Fixed media elements appending the same media segment twice.
  • Fixed an issue where Safari audio may be emitted from the wrong window in visionOS.
  • Fixedrejecting valid NPT strings if ‘hours’ is defined using 1 digit.
  • Fixed picture-in-picture when hiding the <video> element while in Viewer.
  • Fixed the return button not working after the video is paused and played in picture-in-picture.

Networking

  • Fixed upgrading inactive or passive subresource requests and fetches in would-be mixed security contexts to match standards.
  • Fixed incorrect Sec-Fetch-Site value for navigation of a nested document.
  • Fixed loading WebArchives with a non-persistent datastore.
  • Fixed Timing-Allow-Origin to not apply to an HTTP 302 response.

PDF

  • Fixed print buttons with a print action implementation.
  • Fixed Open in Preview for a PDF with a space in its name.
  • Fixed “Open with Preview” context menu item to work with locked PDF documents.

Rendering

  • Fixed Greek uppercase transforms failing for some characters.
  • Fixed resizing a <textarea> element with 1rem padding.
  • Fixed the color correctness of the color matrix filter.
  • Fixed backdrop-filter to apply to the border area of an element with a border-radius.
  • Fixed intrinsic inline size calculators to account for whitespace before an empty child with nonzero margins.
  • Fixed overlapping elements with flex box when height: 100% is applied on nested content.
  • Fixed incorrect grid item positioning with out-of-flow sibling.
  • Fixed break-word with a float discarding text.
  • Fixed min-content calculation for unstyled only-child inlines elements.
  • Fixed ellipsis rendering multiple times when position: relative and top are used.
  • Fixed a bug for inline elements inserted in reverse order after a block in a continuation.
  • Fixed the flash of a page background-colored bar in the footer when the window is resized.
  • Fixed garbled bold text caused by glyph lookup using the wrong font’s glyph IDs when multiple installed fonts have the same name. (FB13909556)
  • Fixed selecting Japanese text annotated with ruby in a vertical-rl writing mode table.
  • Fixed support for border, padding, and margin on mfrac and mspace elements in MathML.

Scrolling

  • Fixed the cursor not updating as content scrolls under it on some pages.

Security

  • Fixed stripping the scroll-to-text fragment from the URL to prevent exposing the fragment to the page.
  • Fixed CORS bypass on private localhost domain using 0.0.0.0 host and mode “no-cors”.
  • Fixed blocking cross-origin redirect downloads in an iframe.
  • Fixed blocked cross-origin redirect downloads to attempt rendering the page instead.

SVG

  • Fixed the SVG parser to interpret “form feed” as white space.
  • Fixed error handling for invalid filter primitive references.
  • Fixed displaying an SVG element inside a <switch> element.
  • Fixed SVG title to have display: none as the default UA style rule.
  • Fixed the UA stylesheet for links in SVGs to apply cursor: pointer matching standards.
  • Fixed returning the initial value for the SVG gradient stop-color if it is not rendered in the page.
  • Fixed the SVG marker segment calculations if the marker path consists of sub-paths.
  • Fixed SVGLength to sync with the WebIDL specification.

Text

  • Fixed disclosure counter styles to consider writing-mode.

Web Animations

  • Fixed percentage transform animations when width and height are animated.
  • Fixed updating an animation when changing the value of a transform property while that property is animated with an implicit keyframe.
  • Fixed display transition to none.

Web API

  • Fixed cssTextsetter to change the style attribute when the serialization differs. (FB5535475)
  • Fixed history.pushState() and history.replaceState() to ignore the title argument.
  • Fixed URL text fragment directives not fully stripped from JavaScript.
  • Fixed showPicker() method to trigger suggestions from a datalist.
  • Fixed lang attribute in no namespace to only apply to HTML and SVG elements.
  • Fixed unnecessarily unsetting the iframe fullscreen flag.
  • Fixed DOM Range to correctly account for CDATASection nodes.
  • Fixed getGamepads() to no longer trigger an insecure contexts warning.
  • Fixed inserting a <picture> element displaying the same image twice.
  • Fixed throwing exceptions in navigation methods if in a detached state.
  • Fixed a minor issue in URL’s host setter.
  • Fixed cloning of ShadowRoot nodes following a DOM Standard clarification.
  • Fixed GeolocationCoordinates to expose a toJSON() method.
  • Fixed IntersectionObserver notifications that sometimes fail to fire.
  • Fixed GeolocationPosition to expose a toJSON() method.
  • Fixed setting CustomEvent.target when dispatching an event.
  • Fixed navigator.language only returning the system language in iOS 17.4.
  • Fixed: Removed presentational hints from the width attribute for <hr>.
  • Fixed an issue when inserting writing suggestions into an editable display: grid container.
  • Fixed the warning message for window.styleMedia.

Web Apps

  • Fixed resolving www. sub-domain for Associated Domains for all web apps.

Web Assembly

  • Fixed initialization of portable reference typed globals.

Web Extensions

  • Fixed getting an empty key from storage. (FB11427769)
  • Fixed Service Workers not appearing in the Develop menu or remote Web Inspector menu. (130712941)
  • Fixed web extensions unable to start due to an issue parsing declarativeNetRequest rules. (FB14145801)

Web Inspector

  • Fixed font sizes in the Audits tab.
  • Fixed expanded sections of Storage to not collapse.
  • Fixed Web Inspector to show nested workers.
  • Fixed CSS font property values marked !important not getting overridden when using the interactive editing controls.
  • Fixed an issue where the Web Inspector viewport might appear cut off.
  • Fixed runtimes to be aligned in the Audit tab.
  • Fixed remembering the message type selection in the Console tab.
  • Fixed autocomplete for the text-indent property suggesting prefixed properties instead of each-line or hanging.
  • Fixed background autocompletion suggestion to include repeating-conic-gradient.
  • Fixed the list of breakpoints in the Sources tab disappearing when Web Inspector is reloaded.
  • Fixed console clearing unexpectedly when Web Inspector reopens.
  • Fixed console code completion to be case-insensitive.
  • Fixed overflow: scroll elements to scroll as expected when highlighting an element from the DOM tree.
  • Fixed showing additional Safari tabs from an iOS device in the Develop menu.
  • Fixed Console and code editor completion not auto-scrolling the suggestion into view.
  • Fixed search in the DOM tree view unexpectedly chaning the text display.
  • Fixed clicking the “goto” arrow for computed CSS when “show independent Styles sidebar” is disabled.
  • Fixed inspectable tabs from Safari in the visionOS Simulator don’t appear in Developer menu on the host macOS.
  • Fixed Accessibility inspector for switch controls to report “State: on/off” instead of “Checked: true/false”.

Web Views

  • Fixed Gamepad API in WKWebView.
  • Fixed repainting HTML elements when their width or height change in legacy WebView.

WebDriver

  • Fixed retrieving titles containing multibyte characters.

WebRTC

  • Fixed RTCEncodedVideoFrame and RTCEncodedAudioFrame to match the WebIDL specification.
  • Fixed VideoTrackGenerator writer to close when its generator track (and all its clones) are stopped.
  • Fixed WebRTC AV1 HW decoding on iPhone 15 Pro.
  • Fixed black stripes with screen sharing windows.
  • Fixed black stripes with getDisplayMedia captured windows when the window is resized.

Updating to Safari 18.0

Safari 18.0 is available on iOS 18, iPadOS 18, macOS Sequoia, macOS Sonoma, macOS Ventura, and in visionOS 2.

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 on Safari 18.0, find us on Mastodon at @jensimmons@front-end.social and @jondavis@mastodon.social. Or send a reply on X to @webkit. You can also 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 notice a website that seems broken in Safari, but not in other browsers, 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.0 release notes.

1. iPhone Mirroring is available on Mac computers with Apple silicon and Intel-based Mac computers with a T2 Security Chip. Requires that your iPhone and Mac are signed in with the same Apple ID using two-factor authentication, your iPhone and Mac are near each other and have Bluetooth and Wi-Fi turned on, and your Mac is not using AirPlay or Sidecar. iPhone Mirroring is not available in all regions.

September 16, 2024 08:00 AM

September 11, 2024

Release Notes for Safari Technology Preview 203

Surfin’ Safari

Safari Technology Preview Release 203 is now available for download for macOS Sequoia beta 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: 282390@main…283042@main.

Accessibility

Resolved Issues

  • Fixed display: contents on tbody elements preventing table rows from being properly exposed in the accessibility tree. (282413@main) (129131780)
  • Fixed the handling of ElementInternals.ariaValueNow null values so the right value is exposed to assistive technologies. (282422@main) (129218234)
  • Fixed updating the accessibility tree when text underneath an aria-describedby element changes. (282430@main) (131877635)

Canvas

Resolved Issues

  • Fixed CanvasRenderingContext2D globalAlpha property getting ignored for some values of globalCompositeOperation. (282995@main) (134840885)

CSS

New Features

  • Added support for scrollbar-gutter. (282662@main) (111918434)
  • Added support for cursor in ::marker. (282642@main) (133256523)
  • Added support for ruby-overhang. (283012@main) (135058411)

Resolved Issues

  • Fixed text-underline-offset to support percentages. (282611@main) (117246233)
  • Fixed: Updated calc() to the most recent web standard, including support for dividing by numbers with additional units. (282580@main) (134446246)

Editing

Resolved Issues

  • Fixed aligning with the standardized version of the autocorrect attribute, which does not support Email, URL, and Password fields and does not treat the empty string value in a special way. (282792@main) (101036922)
  • Fixed inserting text before a <picture> element inserting the text after the element instead. (282825@main) (134378236)

JavaScript

New Features

  • Added support for Iterator.prototype.constructor and Iterator.prototype[@@toStringTag]. (282687@main) (134598491)
  • Added support for Iterator.from from Iterator Helpers Proposal. (283016@main) (135065388)

Resolved Issues

  • Fixed: Disallow yield and await expressions in class field initializers. (282819@main) (132338331)
  • Fixed Object.keys(global) including non-enumerable properties unless deleted first. (282554@main) (134121649)
  • Fixed the error message of Temporal.Instant.fromEpochMilliseconds. (282587@main) (134454596)
  • Fixed duration format’s nanoseconds calculation ordering. (282690@main) (134526619)
  • Fixed TimeZoneAnnotation to disallow sub-minute. (282710@main) (134541964)
  • Fixed: Temporal.Instant.prototype.epochMilliseconds to return a floored value. (282718@main) (134666158)

Deprecations

  • Remove obsoleted Temporal.Instant API. (282400@main) (134195010)

Media

New Features

  • Added support for allowing websites to override the system-default accessibility caption styling. (282568@main) (134265139)

Resolved Issues

  • Fixed a bug in WebCodecs where audio and video codecs with pending work could be prematurely garbage collected. (282657@main) (134297589)

Networking

Resolved Issues

  • Fixed a bug where Cross-Origin-Opener-Policy header fields in the response of iframes were not ignored, resulting in window.opener being null after multiple cross-origin navigations of the main frame. (282482@main) (132840366)

Rendering

Resolved Issues

  • Fixed items that span multiple tracks with optimizations. (282464@main) (132435056)
  • Fixed rendering tick marks of the range input type when the page zoom is less than 1. (282451@main) (134282707)

SVG

Resolved Issues

  • Fixed an issue for getPointAtLength to throw an exception when path is empty. (282665@main) (122574451)

Web API

Resolved Issues

  • Fixed: Changed click, auxclick, contextmenu, and click() to use PointerEvent. (282524@main) (71202646)
  • Fixed: Aligned oncuechange event handler handling with other event handlers. (282977@main) (98254058)
  • Fixed popovertarget to work on buttons in a form. (282801@main) (131042177)
  • Fixed XMLSerializer.serializeToString() not serializing the children of <img> and also not closing the <img> if it has children. (282725@main) (133404338)
  • Fixed: Moved onbeforeinput to GlobalEventHandlers. (282912@main) (134943272)

Web Apps

New Features

  • Parse dir member of Web Application Manifest. (282761@main) (131900106)

Resolved Issues

  • Fixed Web Application Manifest parsing to trim all ASCII whitespace. (282544@main) (134336817)

Web Assembly

New Features

  • Added support for return_call_ref. (282853@main) (134442713)

Web Extensions

Resolved Issues

  • Fixed Safari Web Extension ports to receive messages in content scripts when sent from the onConnect event listener. (283006@main) (133501214) (FB14721836)

Web Inspector

New Features

  • Added support for sourcemaps to be blackboxed. (282740@main) (133731737)
  • Added support for showing boundThis for arrow functions in the console. (282553@main) (134268331)

September 11, 2024 09:40 PM

September 10, 2024

Enrique Ocaña: Don’t shoot yourself in the foot with the C++ move constructor

Igalia WebKit

Move semantics can be very useful to transfer ownership of resources, but as many other C++ features, it’s one more double edge sword that can harm yourself in new and interesting ways if you don’t read the small print.

For instance, if object moving involves super and subclasses, you have to keep an extra eye on what’s actually happening. Consider the following classes A and B, where the latter inherits from the former:

#include <stdio.h>
#include <utility>

#define PF printf("%s %p\n", __PRETTY_FUNCTION__, this)

class A {
 public:
 A() { PF; }
 virtual ~A() { PF; }
 A(A&& other)
 {
  PF;
  std::swap(i, other.i);
 }

 int i = 0;
};

class B : public A {
 public:
 B() { PF; }
 virtual ~B() { PF; }
 B(B&& other)
 {
  PF;
  std::swap(i, other.i);
  std::swap(j, other.j);
 }

 int j = 0;
};

If your project is complex, it would be natural that your code involves abstractions, with part of the responsibility held by the superclass, and some other part by the subclass. Consider also that some of that code in the superclass involves move semantics, so a subclass object must be moved to become a superclass object, then perform some action, and then moved back to become the subclass again. That’s a really bad idea!

Consider this usage of the classes defined before:

int main(int, char* argv[]) {
 printf("Creating B b1\n");
 B b1;
 b1.i = 1;
 b1.j = 2;
 printf("b1.i = %d\n", b1.i);
 printf("b1.j = %d\n", b1.j);
 printf("Moving (B)b1 to (A)a. Which move constructor will be used?\n");
 A a(std::move(b1));
 printf("a.i = %d\n", a.i);
 // This may be reading memory beyond the object boundaries, which may not be
 // obvious if you think that (A)a is sort of a (B)b1 in disguise, but it's not!
 printf("(B)a.j = %d\n", reinterpret_cast<B&>(a).j);
 printf("Moving (A)a to (B)b2. Which move constructor will be used?\n");
 B b2(reinterpret_cast<B&&>(std::move(a)));
 printf("b2.i = %d\n", b2.i);
 printf("b2.j = %d\n", b2.j);
 printf("^^^ Oops!! Somebody forgot to copy the j field when creating (A)a. Oh, wait... (A)a never had a j field in the first place\n");
 printf("Destroying b2, a, b1\n");
 return 0;
}

If you’ve read the code, those printfs will have already given you some hints about the harsh truth: if you move a subclass object to become a superclass object, you’re losing all the subclass specific data, because no matter if the original instance was one from a subclass, only the superclass move constructor will be used. And that’s bad, very bad. This problem is called object slicing. It’s specific to C++ and can also happen with copy constructors. See it with your own eyes:

Creating B b1
A::A() 0x7ffd544ca690
B::B() 0x7ffd544ca690
b1.i = 1
b1.j = 2
Moving (B)b1 to (A)a. Which move constructor will be used?
A::A(A&&) 0x7ffd544ca6a0
a.i = 1
(B)a.j = 0
Moving (A)a to (B)b2. Which move constructor will be used?
A::A() 0x7ffd544ca6b0
B::B(B&&) 0x7ffd544ca6b0
b2.i = 1
b2.j = 0
^^^ Oops!! Somebody forgot to copy the j field when creating (A)a. Oh, wait... (A)a never had a j field in the first place
Destroying b2, a, b1
virtual B::~B() 0x7ffd544ca6b0
virtual A::~A() 0x7ffd544ca6b0
virtual A::~A() 0x7ffd544ca6a0
virtual B::~B() 0x7ffd544ca690
virtual A::~A() 0x7ffd544ca690

Why can something that seems so obvious become such a problem, you may ask? Well, it depends on the context. It’s not unusual for the codebase of a long lived project to have started using raw pointers for everything, then switching to using references as a way to get rid of null pointer issues when possible, and finally switch to whole objects and copy/move semantics to get rid or pointer issues (references are just pointers in disguise after all, and there are ways to produce null and dangling references by mistake). But this last step of moving from references to copy/move semantics on whole objects comes with the small object slicing nuance explained in this post, and when the size and all the different things to have into account about the project steals your focus, it’s easy to forget about this.

So, please remember: never use move semantics that convert your precious subclass instance to a superclass instance thinking that the subclass data will survive. You can regret about it and create difficult to debug problems inadvertedly.

Happy coding!

By eocanha at September 10, 2024 07:58 AM

August 28, 2024

Release Notes for Safari Technology Preview 202

Surfin’ Safari

Safari Technology Preview Release 202 is now available for download for macOS Sequoia beta 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: 281465@main…282389@main.

Accessibility

Resolved Issues

  • Fixed text-transform: full-size-kana to not affect AT/speech output. (282258@main) (115504070)

CSS

New Features

  • Added support for background-clip: border-area. (282202@main) (133788384)
  • Added support for line-fit-edge and updated text-box-edge. (282228@main) (133834296)
  • Added support for the text-box shorthand. (282282@main) (133942602)
  • Added support for ruby-align. (282106@main) (133656625)
  • Added support for unprefixed ruby-position. (281804@main) (86128259)
  • Added support for scrollbar-width. (282068@main) (133019206)
  • Added support for view transition classes. (282383@main) (134020027)
  • Added support for view transition types. (282344@main) (133610087)
  • Added support for the shape() function. (281924@main) (133322584)
  • Added support for closest-corner and farthest-corner in circle and ellipse shapes. (281808@main) (132936677)
  • Added support for the color-layers() function. (282334@main) (134013898)
  • Added support for @property <string> syntax. (281872@main) (133250776)
  • Added support for ::target-text. (282356@main) (134010063)
  • Added support for @page margin descriptors. (282048@main) (118773100)
  • Added support for jis-b4 and jis-b5 sizes for @page. (281814@main) (133138325)

Resolved Issues

  • Fixed -webkit-line-clamp: none to be parsable. (281826@main) (103158259)
  • Fixed serialization of place-content, place-items, and place-self properties. (281476@main) (125415088)
  • Fixed masonry intrinsic sizing with fixed size and auto. (281677@main) (132849745)

Editing

Resolved Issues

  • Fixed dictation UI no longer showing up when beginning dictation after focusing an empty text field. (281474@main) (131534054) (FB14277296)

JavaScript

New Features

  • Implemented Float16Array. (281870@main) (109883982)
  • Added support for firstDayOfWeek for Intl.Locale info API. (281510@main) (132731533)
  • Enabled Base64 and Hex features. (281910@main) (133312461)
  • Added support for type reflection for WebAssembly.Module.imports and WebAssembly.Module.exports. (281974@main) (133429946)

Resolved Issues

  • Fixed roundingMode for seconds, microseconds, and nanoseconds in Intl.DurationFormat. (281955@main) (130771643)

Media

Resolved Issues

  • Fixed fullscreen error handling to include error messages. (281853@main) (103073510)

Rendering

Resolved Issues

  • Fixed margins used for grid items on relayout. (282092@main) (113984882)

SVG

Resolved Issues

  • Fixed correctly applying clip-path to the SVG element. (281893@main) (80516912)
  • Fixed fill to not be considered a presentation attribute on animation elements. (282100@main) (128896937)

Web Animations

Resolved Issues

  • Fixed alignment-baseline and buffered-rendering to support discrete animation. (281602@main) (94613679)
  • Fixed hanging-punctuation to support discrete animation. (281616@main) (94614108)
  • Fixed scroll-snap-* properties to support discrete animation. (281572@main) (94614257)
  • Fixed column-span to support discrete animation. (281505@main) (96082973)
  • Fixed appearance to support discrete animation. (281568@main) (96082999)
  • Fixed hyphenate-character to support discrete animation. (281484@main) (132698836)
  • Fixed font-optical-sizing to support discrete animation. (281489@main) (132699150)
  • Fixed image-rendering to support discrete animation. (281506@main) (132707652)
  • Fixed the mask-border-* properties to be animatable. (281569@main) (132783274)
  • Fixed stroke-color to be animatable. (281570@main) (132784589)

Web API

New Features

  • Added support for the getPredictedEvents API to PointerEvent. (281756@main) (117767174)
  • Added support for Scroll To Text Fragment Generation. (282379@main) (131712706)
  • Added support for altitudeAngle and azimuthAngle to PointerEvent. (282017@main) (131974392)
  • Added support for the getCoalescedEvents API to PointerEvent. (281520@main) (132210576)

Deprecations

  • Removed support for the non-standard “overflow” event. (281672@main) (71129110)

Web Assembly

New Features

  • Added support for JIT-less Wasm. (281726@main) (113768974)
  • Added support for garbage collection. (281975@main) (126103011)
  • Added support for Wasm Tail Calls. (281716@main) (131410516)

WebDriver

Resolved Issues

  • Fixed WebDriver sometimes taking screenshots with a transparent grey line at the top and no rounded corners. (281887@main) (116020785)

August 28, 2024 09:25 PM

Jani Hautakangas: Bringing WebKit back to Android: Progress and Perspectives

Igalia WebKit

In my previous blog post, I delved into the technical aspects of reintroducing WebKit to the Android platform. It was an exciting journey, filled with the challenges and triumphs that come with working on a project as ambitious as WPE-Android. However, I realize that the technical depth of that post may have left some readers seeking more context. Today, I want to take a step back and offer a broader view of what this project is all about—why we’re doing it, how it builds on the WPEWebKit engine, and the progress we’ve made so far.

The Vision: Reviving WebKit on Android #

WebKit has a storied history in the world of web browsers, serving as the backbone for Safari, Epiphany, and many embedded browsers. However, over time, Android’s landscape has shifted toward Blink/Chromium, the engine behind Chrome. While Blink and Chromium have undoubtedly shaped the modern web, there are compelling reasons to bring WebKit back to Android.

WPE-Android is an effort to reintroduce WebKit into the Android ecosystem as a modern, efficient, and secure browser engine. Our goal is to provide developers with more options—whether they’re building full-fledged browsers, integrating web views into native apps, or exploring innovative applications in IoT and embedded systems. By leveraging WebKit’s unique strengths, we’re opening new doors for creativity and innovation on the Android platform.

Why WPEWebKit? #

At the heart of WPE-Android is WPEWebKit, a streamlined version of the WebKit engine specifically optimized for embedded systems. Unlike its desktop counterpart, WPEWebKit is designed to be lightweight, efficient, and highly adaptable to various hardware environments. This makes it an ideal foundation for bringing WebKit back to Android.

The decision to base WPE-Android on WPEWebKit is strategic. WPEWebKit is not only performant but also backed by a strong community of developers and organizations dedicated to its continuous improvement. This community-driven approach ensures that WPE-Android benefits from a robust, well-maintained codebase, with contributions from experts around the world.

Building on a Strong Foundation #

Since the inception of WPE-Android, our focus has been on making WebKit a viable option for Android developers. This involves more than just getting the engine to run on Android—it’s about ensuring that it’s stable, integrates seamlessly with Android’s unique features, and offers a developer-friendly experience.

A significant part of our work has involved optimizing the interaction between WPEWebKit and Android’s graphics stack. As part of that, we decided to focus on Android API level 30 and higher to keep the prototyping phase faster and simpler. Our efforts have aimed at achieving smooth and consistent performance, ensuring that WPE-Android can meet the needs of modern Android applications.

We are building a foundation to run instrumentation tests in CI to ensure that we don’t regress and that we get consistent results that match Android’s system WebView APIs. We continue adding more APIs that are similar to Android System WebView offerings and provide similar results.

Additionally, we’ve focused on enhancing the integration of WPE-Android with Android-specific features. This includes improving support for touch input and dialogs, refining the way web views are handled within native Android applications, and ensuring compatibility with the Android development environment. These enhancements make WPE-Android a natural fit for developers who are already familiar with the Android platform.

What’s new #

Most of the changes are under the hood improvements. The task that required the most effort was upgrading and rebasing our patches on top of Cerbero. After we upgraded to WPE WebKit 2.44.1, we required a more recent GLib version provided by the newer Cerbero version. Along with the upgrade, we managed to refactor and squash many of the patches that we had on top of Cerbero. We went from 175 patches down to 66, which will simplify the next upgrade.

Here’s a list of the most notable changes since the last update:

  • Upgraded to WPE WebKit 2.44.1.
  • Upgraded Cerbero to version 1.24.2.
  • Upgraded Android NDK to version r26d.
  • Migrated from libsoup2 to libsoup3 for HTTP/2 support.
  • Support for proper device scale ratio according to Android’s DisplayMetrics. This takes into account the screen size and pixel density, automatically adapting rendered content to show with appropriate dimensions on all devices.
  • Support for JS dialogs (Alert, Confirm, Prompt). Integrates Android dialogs with JavaScript alert(), confirm(), and prompt() prompts. Also provides an option to build custom native dialogs for these prompts.
  • Instrumentation tests for recently added features and a CI pipeline for running them.
  • API to receive HTTP errors. WPEViewClient interface onReceivedHttpError to catch HTTP error codes >= 400.
  • API to evaluate JavaScript. Provides the WPEView method evaluateJavascript to inject and evaluate JavaScript code on a loaded page.

Demos #

Dialog prompts #

The demo shows the default WPEView alert() prompt integration on the left side. On the right side, an application using WPEView has overridden the onJsAlert method from the WPEChromeClient interface and provides a custom native alert dialog for the JavaScript alert() prompt. The custom dialog is constructed using Android’s AlertDialog.Builder factory. Similar customization can be applied to JavaScript confirm() and prompt() prompts by overriding the onJsConfirm and onJsPrompt methods from the WPEChromeClient interface.

Default WPEView alert dialog
Custom WPEView alert dialog

Evaluate javascript #

The demo shows how to inject JavaScript and call functions on a loaded page from Kotlin code.

HTML and JavaScript:

<script>
function showName(message) {
document.getElementById('name').innerHTML=message;
}
</script>
<center>
<br><br><br><br>
<h1>WPEView</h1>
<p>Evaluate javascript</p>"
<br><br><br><br>
<h2>What's your name?</h2>
<h1 id="name"></h1>
</center>

Kotlin/WPEView code:

binding.toolbarButton.setOnClickListener {
webview.evaluateJavascript("showName(\"" + binding.toolbarEditText.text + "\")",null)
binding.toolbarEditText.setText("")
}

Device scale factor #

Android devices come with a variety of screen sizes, resolutions, and screen densities (pixels per inch, also known as ppi). In order for the UI to look consistent and good across all different devices, the device scale factor needs to be applied to the UI. Screen density can be fetched via the Android DisplayMetrics API, and in WPE WebKit, this corresponds to the device scale factor that can be set using wpe_view_backend_dispatch_set_device_scale_factor. Previously, in WPE-Android, we had hardcoded that value to 2.0, but now we are using proper metrics specific to each device.

Below are some screenshots from before and after applying the proper device scale. I’m using a Google Pixel 7 device, which has a density value of 2.75.

Old hardcoded device scale factor 2.0
Device scale factor from DisplayMetrics density

Looking Forward #

Our goal is to make WPE-Android even more accessible and usable for the broader Android development community. This involves ongoing performance optimizations, expanding device compatibility, and potentially providing more resources like documentation, example projects, and developer tools to ease the adoption of WPE-Android.

We believe that by offering WebKit as a viable option on Android, we’re contributing to a more diverse and innovative web ecosystem. WPE-Android is not just about bringing back a familiar engine—it’s about giving developers the tools they need to create fast, secure, and beautiful web experiences on Android devices.

Conclusion #

The journey of bringing WebKit back to Android has been both challenging and rewarding so far. By building on the strong foundation of WPEWebKit, we’re crafting a tool that empowers developers to push the boundaries of what’s possible with web technologies on Android. The progress we’ve made so far is just the beginning, and I’m excited to see how the project will continue to evolve.

If you’re interested in learning more or getting involved, you can find all the details on the WPE-Android GitHub page.

August 28, 2024 12:00 AM

August 14, 2024

Release Notes for Safari Technology Preview 201

Surfin’ Safari

Safari Technology Preview Release 201 is now available for download for macOS Sequoia beta 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: 281144@main…281464@main.

CSS

Resolved Issues

  • Fixed defaults for text underline position and text emphasis marks in CJK languages. (281445@main) (132444497)
  • Fixed some CSS properties causing quotes to be reset. (281444@main) (132585704)

DOM

New Features

  • Added auxclick event support for Pointer Events. (281169@main) (25988904)
  • Implemented new dialog initial focus algorithm to match specification changes. (281215@main) (104667732)

Resolved Issues

  • Fixed pointer events generated from platform mouse events to use the platform event’s timestamp. (281161@main) (132051812)
  • Fixed popover tab navigation. (281167@main) (132129060)
  • Fixed two mousemove events dispatched when the mouse enters a web view window instead of a single one. (281225@main) (132251320)

JavaScript

Resolved Issues

  • Fixed Uint8Array#setFromBase64 to decode and write chunks which occur prior to bad data. (281174@main) (132198988)

Media

Resolved Issues

  • Fixed picture-in-picture when hiding the <video> element while in Viewer. (281266@main) (131786564)
  • Fixed the return button not working after the video is paused and played in picture-in-picture. (281145@main) (131791367)

PDF

Resolved Issues

  • Fixed “Open with Preview” context menu item to work with locked PDF documents. (281413@main) (132033502)

Rendering

New Features

  • Added support for text-underline-position: left and text-underline-position: right. (281446@main) (130621143)

SVG

Resolved Issues

  • Fixed zooming in or out of an SVG with transform-origin. (281265@main) (96318505)

Web Animations

New Features

  • Added support for discrete animations on text-underline-position. (281245@main) (94615165)
  • Added support for discrete animations on text-box-edge. (281252@main) (132303461)

Web Extensions

Resolved Issues

  • Fixed web extensions unable to start due to an issue parsing declarativeNetRequest rules. (130861213) (FB14145801)
  • Fixed web extensions not able to display images defined in web_accessible_resources. (281157@main) (131750151) (FB14319689)

August 14, 2024 09:52 PM

August 02, 2024

Pawel Lampe: Nuts and bolts of Canvas2D - globalCompositeOperation and shadows.

Igalia WebKit

In recent months I’ve been privileged to work on the transition from Cairo to Skia for 2D graphics rendering in WPE and GTK WebKit ports. Big reworks like this are a great opportunity to explore all kinds of graphics-related APIs. One of the broader APIs in this area is the CanvasRenderingContext2D API from HTML Canvas. It’s a fairly straightforward yet extensive API allowing one to perform all kinds of drawing operations on the canvas. The comprehensiveness, however, comes at the expense of some complex situations the web engine needs to handle under the hood. One such situation was the issue I was working on recently regarding broken test cases involving drawing shadows when using Skia in WebKit. What makes it complex is that some problems are still visible due to multiple web engine layers being involved, but despite that I was eventually able to address the broken test cases.

In the next few sections I’m going to introduce the parts of the API that are involved in the problems while in the sections closer to the end I will gradually showcase the problems and explore potential paths toward fixing the entire situation.

Drawing on Canvas2D with globalCompositeOperation #

The Canvas2D API offers multiple methods for drawing various primitives such as rectangles, arcs, text etc. On top of that, it allows one to control compositing and clipping using the globalCompositeOperation property. The idea is very simple - the user of an API can change the property using one of the predefined compositing operations and immediately after that, all new drawing operations will behave according to the rules the particular compositing operation specifies:

canvas2DContext.fillRect(...); // Draws rect on top of existing content (default).
canvas2DContext.globalCompositeOperation = 'destination-atop';
canvas2DContext.fillRect(...); // Draws rect according to 'destination-atop'.

There are many compositing operations, but I’ll be focusing mostly on the ones having source and destination in their names. The source and destination terms refer to the new content to be drawn and the existing (already-drawn) content respectively.

The images below present some examples of compositing operations in action:

Compositing operations in action.

Drawing on Canvas2D with shadows #

When drawing primitives using the Canvas2D API one can use shadow* properties to enable drawing of shadows along with any content that is being drawn. The usage is very simple - one has to alter at least one property such as e.g. shadowOffsetX to make the shadow visible:

canvas2DContext.shadowColor = "#0f0";
canvas2DContext.shadowOffsetX = 10;
// From now on, any draw call will have a green shadow attached.

the above combined with simple code to draw a circle produces a following effect:

Circle with shadow.

Shadows meet globalCompositeOperation #

Things are getting interesting once one starts thinking about how globalCompositeOperation may affect the way shadows are drawn. When I thought about it for the first time, I imagined at least 3 possibilities:

  • Shadow and shadow origin are both treated as one entity (shadow always below the origin) and thus are drawn together.
  • Shadow and shadow origin are combined and then drawn as a one entity.
  • Shadow and shadow origin are drawn separately - shadow first, then the content.

When I confronted the above with the drawing model and shadows specification, it turned out the last guess was the correct one. The specification basically says that the shadow should be computed first, then composited within the clipping region over the current canvas content, and finally, the shadow origin should be composited within the clipping region over the current canvas content (the original canvas content combined with shadow).

The above can be confirmed visually using few examples (generated using chromium browser v126.0.6478.126):

Shadows combined with compositing operation.

  • The source-over operation shows the drawing order - destination first, shadow second, and shadow origin third.
  • The destination-over operation shows the reversed drawing order - destination first, shadow second (below destination), and shadow origin third (below destination and shadow).
  • The source-atop operation is more tricky as it behaves like source-over but with clipping to the destination content - therefore, destination is drawn first, then clipping is set to destination, then the shadow is drawn, and finally the shadow origin is drawn.
  • The destination-atop operation is even more tricky as it behaves like destination-over yet with the clipping region always being different. That difference can be seen on the image below that presents intermediate states of canvas after each drawing step:
    Breakdown of destination-atop operation.
    • The initial state shows a canvas after drawing the destination on it.
    • The after drawing shadow state, shows a shadow drawn below the destination. In this case, the clipping is set to new content (shadow), and hence the part of destination that is not “atop” shadow is being clipped out.
    • The after drawing shadow origin state, shows the final state after drawing the shadow origin below the previous canvas content (new destination) that is at this point “a shadow combined with destination”. Similarly as in the previous step, the clipping is set to the new content (shadow origin), and hence any part of new destination that is not “atop” the shadow origin is being clipped out.

Discrepancies between browser engines #

Whenever one realizes the drawing of shadows with globalCompositeOperation in general may be tricky, then one must also consider that when it comes to particular browser engines, the things are even more tricky as virtually no graphics library provides an API that matches the Canvas2D API 1-to-1. This means that depending on the graphics library used, the browser engine must implement more or less integration parts here and there. For example, one can imagine that some graphics library may not have native support for shadows - that would mean the browser engine has to prepare shadows itself by e.g. drawing shadow origin (no matter how complex) on extra surface, changing color, blurring etc. so that it can be used as a whole once prepared.

Having said the above, one would expect that all the above aspects should be tested and implemented really well. After all, whenever the subject matter becomes complicated, extra care is required. It turns out, however, this is not necessarily the case when it comes to globalCompositeOperation and shadows. As for the testing part, there are very few tests (2d.shadow.composite*) in WPT (Web Platform Tests) covering the use cases described above. It’s also not much better for internal web engine test suites. As for implementations, there’s a substantial amount of discrepancy.

Simple examples #

To show exactly what’s the situation, the examples from section Shadows meet globalCompositeOperation can be used again. This time using browsers representing different web engines:

  • Chromium 126.0.6478.126 Shadows combined with compositing operation - Chromium.
  • Firefox 128.0 Shadows combined with compositing operation - Firefox.
  • Gnome Web (Epiphany) 45.0 (WebKit/Cairo) Shadows combined with compositing operation - Epiphany.
  • WPE MiniBrowser build from WebKit@098c58dd13bf40fc81971361162e21d05cb1f74a (WebKit/Skia) Shadows combined with compositing operation - WPE MiniBrowser.
  • Safari 17.1 (WebKit/Core Graphics) Shadows combined with compositing operation - Safari.
  • Servo release from 2024/07/04 Shadows combined with compositing operation - Servo.
  • Ladybird build from 2024/06/29 Shadows combined with compositing operation - Ladybird

First of all, it’s evident that experimental browsers such as servo and ladybird are falling behind the competition - servo doesn’t seem to support shadows at all, while ladybird doesn’t support anything other than drawing a rect filled with color.

Second, the non-experimental browsers are pretty stable in terms of covering most of the combinations presented above.

Finally, the most tricky combination above seems to be the one including destination-atop - in that case almost every mainstream browser renders different results:

  • Chromium is the only one rendering correctly.
  • Firefox and Epiphany are pretty close, but both are suffering from a similar glitch where the red part is covered by the part of destination that should be clipped out already.
  • WPE MiniBrowser and Safari are both rendering in correct order, but the clipping is wrong.

More sophisticated examples #

Until now, the discrepancies don’t seem to be very dramatic, and hence it’s time to present more sophisticated examples that are an extended version of the test case from the WebKit source tree:

  • Chromium 126.0.6478.126

Shadows combined with compositing operation - Chromium.

  • Firefox 128.0

Shadows combined with compositing operation - Firefox.

  • Gnome Web (Epiphany) 45.0 (WebKit/Cairo)

Shadows combined with compositing operation - Epiphany.

  • WPE MiniBrowser build from WebKit@098c58dd13bf40fc81971361162e21d05cb1f74a (WebKit/Skia)

Shadows combined with compositing operation - WPE MiniBrowser.

  • Safari 17.1 (WebKit/Core Graphics)

Shadows combined with compositing operation - Safari.

  • Servo release from 2024/07/04

Shadows combined with compositing operation - Servo.

  • Ladybird build from 2024/06/29

Shadows combined with compositing operation - Ladybird.

Other than destination-out, xor, and a few simple operations presented before, all the operations presented above pose serious problems to the majority of browsers. The only browser that is correct in all the cases (to the best of my understanding) is Chromium that is using rendering engine called blink which in turn uses the Skia library. One may wonder if perhaps it’s Skia that’s responsible for the Chromium success, but given the above results where e.g. WPE MiniBrowser uses Skia as well, it’s evident that the problems lay above the particular graphics library.

Looking at the operations and browsers that render incorrectly, it’s clearly visible that even small problems - with either ordering of draw calls or clipping - lead to spectacularly broken results. The pinnacle of misery is the source-out operation that is the most variable one across browsers. One has to admit, however, that WPE MiniBrowser is slightly closer to being correct than others.

Towards unification #

Fixing the above problems is a long journey. After all, every single web engine has to be fixed in its own, specific way. If the specification would be a problem - it would be the obvious way to start. However, as mentioned in the section Shadows meet globalCompositeOperation, the specification, is pretty clear on how drawing, shadows, and globalCompositeOperation come together. In such case, the next obvious place to start improving things is a WPT test suite.

What makes WPT outstanding is that it is a de facto standard cross-browser test suite for testing the web platform stack. Thus the test suite is developed as an open collaboration effort by developers from around the globe and hence is very broad in terms of specification coverage. What’s also important, the test results are actively evaluated against the popular browser engines and published under wpt.fyi, therefore putting some pressure on web engine developers to fix the problems so that they keep up with competition.

Granted the above, extending WPE test suite by adding test cases to cover globalCompositeOperation operations combined with shadows is the reasonable first step towards the unification of browser implementations. This can be done either by directly contributing tests to WPT, or by creating an issue. Personally, I’ve decided to file an issue first (WPT#46544) and to add tests once I have some time. I haven’t contributed to WPT yet, but I’m excited to work with it soon. Once I land my first pull request, I’ll start fixing WebKit and I won’t hesitate to post some updates on this blog.

August 02, 2024 12:00 AM

July 31, 2024

Release Notes for Safari Technology Preview 200 🎉

Surfin’ Safari

Safari Technology Preview Release 200 is now available for download for macOS Sequoia beta 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: 280675@main…281143@main.

CSS

Resolved Issues

  • Fixed: Optimized Masonry Grids for items with a span of 1. (280919@main) (131407028)

JavaScript

New Features

  • Implemented Uint8Array.prototype.toHex in SIMD. (280719@main) (131249821)

Resolved Issues

  • Fixed class field initializers to disallow yield and await expressions. (280837@main) (119044881)

  • Fixed DestructuringAssignmentTarget to be evaluated prior to calling [[Get]] or a stepping iterator. (281013@main) (121960976)

  • Fixed throwing an exception for negative exponent in BigInt in the JIT compiler. (280841@main) (131051084)

  • Fixed RegExp range quantifier to allow 2^53 – 1. (280953@main) (131710011)

Rendering

Resolved Issues

  • Fixed garbled bold text caused by glyph lookup using the wrong font’s glyph IDs when multiple installed fonts have the same name. (281022@main) (129891005) (FB13909556)

  • Fixed scrolling of content overflowing a flex item in an end-aligned flex container. (279992@main) (131201271)

Web Extensions

Resolved Issues

  • Fixed Service Workers not appearing in the Develop menu or remote Web Inspector menu. (280912@main) (130712941)

July 31, 2024 09:41 PM

July 29, 2024

WebKit Features in Safari 17.6

Surfin’ Safari

This update to Safari is the seventh release of Safari 17.x. With one feature and seven bug fixes, Safari 17.6 focuses on getting important changes into the hands of your users today.

Safe alignment in Flexbox

Announced at WWDC and first seen in Safari 18 beta, the safe keyword for alignment in Flexbox is now arriving in WebKit for Safari 17.6. This provides a mechanism for refining how flex items overflow. Let’s look at an example of a simple navigation menu — a classic use of Flexbox.

<nav aria-label="main"><ul>
  <li><a href="/us">U.S.</a></li>
  <li><a href="/business">Business</a></li>
  <li><a href="/investigations">Investigations</a></li>
  <li><a href="/style">Style</a></li>
  <li><a href="/tech">Tech</a></li>
  <li><a href="/world">World</a></li>
</ul></nav>

The following CSS creates a simple layout that wraps when there’s not enough space on one line for the menu, while centering the items in the available space.

header nav {
  display: flex;
  flex-flow: wrap;
  gap: 1.5rem;
  justify-content: center; /* centers the items in the available space */
}
A simple menu of links, each represented by a word, laid out in two lines of centered text.

By default, justify-content: center will always keep the items centered, even when the content is overflowing the containing box. You might prefer, however, that the content not be centered when it overflows — being centered cuts off both the beginning and end of the word, making the content harder to understand when the overflow is not visible.

Diagram showing the difference between safe and default layout of the same menu, when the space for it is so narrow every word in on its own line, and some of the long words start to get chopped off.
Compare justify-content: center without and with the safe keyword in this demo.

The safe keyword lets you change how alignment works when content overflows. The justify-content: safe center rule will instead start align any item that is overflowing, while continuing to center the items that are not overflowing.

If you want to override the safe keyword, you can use unsafe. The justify-content: unsafe center rule will do the same thing as justify-content: center. The unsafe keyword has been supported in WebKit for Safari for quite some time.

Bug Fixes

WebKit for Safari 17.6 includes work polishing existing features.

Media

  • Fixed firing loadeddata events for <audio> and <video> on page load. (124079735) (FB13675360)
  • Fixed multiple cases of audio distortion occurring when using AudioWorklets. (128551401)

PDF

  • Fixed PDF previews appearing tiny in the top left corner. (125796665)

Rendering

  • Fixed scrolling of content overflowing a flex item in an end-aligned flex container. (131201271)

Safari Web Extensions

  • Fixed an issue where Safari Web Extension background pages would stop responding after about 30 seconds. (127681420)

Web Inspector

  • Fixed showing additional Safari tabs from an iOS device in the Develop menu. (124876362)

WebRTC

  • Fixed navigator.mediaDevices.getDisplayMedia() in WKWebView. (128988615)

Updating to Safari 17.6

Safari 17.6 is available on iOS 17.6, iPadOS 17.6, macOS Sonoma 14.6, macOS Ventura, macOS Monterey and in visionOS 1.3.

If you are running macOS Ventura or macOS Monterey, you can update Safari by itself, without updating macOS. On macOS Ventura, 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 on Safari 17.6, find us on Mastodon at @jensimmons@front-end.social and @jondavis@mastodon.social. Or send a reply on X to @webkit. You can also 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 notice a website that seems broken in Safari, but not in other browsers, 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 17.6 release notes.

July 29, 2024 08:30 PM

July 17, 2024

Release Notes for Safari Technology Preview 199

Surfin’ Safari

Safari Technology Preview Release 199 is now available for download for macOS Sequoia beta 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: 280287@main…280674@main.

Apple Pay

Resolved Issues

  • Fixed arbitrary 8 digit limit on a line item’s total amount. (280584@main) (112078798)

CSS

New Features

  • Added support for (prefers-contrast: custom). (280383@main) (103658875)

Resolved Issues

  • Fixed computed values for text-box-edge. (280413@main) (117643064)
  • Fixed: Improved large Grid performance. (280473@main) (130728344)

Editing

Resolved Issues

  • Fixed an issue where input method editing would sporadically drop the composition range. (280291@main) (130020224)

JavaScript

New Features

  • Added support for Uint8Array.prototype.toBase64 and Uint8Array.prototype.toHex. (280654@main) (129045737)

Resolved Issues

  • Fixed Intl.DurationFormat for numeric and 2-digit. (280460@main) (130279541)

Media

Resolved Issues

  • Fixed missing picture-in-picture when leaving Safari with picture-in-picture enabled from video viewer. (279877@main) (124376686)
  • Fixed a hang in WebAudio. (280604@main) (130531570)

Rendering

Resolved Issues

  • Fixed support for border, padding, and margin on mfrac and mspace elements in MathML. (280665@main) (131119823)

Text

Resolved Issues

  • Fixed disclosure counter styles to consider writing-mode. (280433@main) (130468537)

WebRTC

Resolved Issues

  • Fixed RTCAudioPlayoutStats to match web specifications. (280461@main) (130767124)

July 17, 2024 11:31 PM

July 12, 2024

Georges Stavracas: Profiling a web engine

Igalia WebKit

One topic that interests me endlessly is profiling. I’ve covered this topic many times in this blog, but not enough to risk sounding like a broken record yet. So here we are again!

Not everyone may know this but GNOME has its own browser, Web (a.k.a. Epiphany, or Ephy for the intimates). It’s a fairly old project, descendant of Galeon. It uses the GTK port of WebKit as its web engine.

The recent announcement that WebKit on Linux (both WebKitGTK and WPE WebKit) switched to Skia for rendering brought with it a renewed interest in measuring the performance of WebKit.

And that was only natural; prior to that, WebKit on Linux was using Cairo, which is entirely CPU-based, whereas Skia had both CPU and GPU-based rendering easily available. The CPU renderer mostly matches Cairo in terms of performance and resource usage. Thus one of the big promises of switching to Skia was better hardware utilization and better overall performance by switching to the GPU renderer.

A Note About Cairo

Even though nowadays we often talk about Cairo as a legacy piece of software, there’s no denying that Cairo is really good at what it does. Cairo can and often is extremely fast at 2D rendering on the CPU, specially for small images with simple rendering. Cairo has received optimizations and improvements for this specific use case for almost 20 years, and it is definitely not a low bar to beat.

I think it’s important to keep this in mind because, as tempting as it may sound, simply switching to use GPU rendering doesn’t necessarily imply better performance.

Guesswork is a No-No

Optimizations should always be a byproduct of excellent profiling. Categorically speaking, meaningful optimizations are a consequence of instrumenting the code so much that the bottlenecks become obvious.

I think the most important and practical lesson I’ve learned is: when I’m guessing what are the performance issues of my code, I will be wrong pretty much 100% of the time. The only reliable way to optimize anything is to have hard data about the behavior of the app.

I mean, so many people – myself included – were convinced that GNOME Software was slow due to Flatpak that nobody thought about looking at app icons loading.

Enter the Profiler

Thanks to the fantastic work of Søren Sandmann, Christian Hergert, et al, we have a fantastic modern system profiler: Sysprof.

Sysprof offers a variety of instruments to profile the system. The most basic one uses perf to gather stack traces of the processes that are running. Sysprof also supports time marks, which allow plotting specific events and timings in a timeline. Sysprof also offers extra instrumentation for more specific metrics, such as network usage, graphics, storage, and more.

  • Screenshot of Sysprof's callgraph view
  • Screenshot of Sysprof's flamegraphs view
  • Screenshot of Sysprof's mark chart view
  • Screenshot of Sysprof's waterfall view

All these metrics are super valuable when profiling any app, but they’re particularly useful for profiling WebKit.

One challenging aspect of WebKit is that, well, it’s not exactly a small project. A WebKit build can easily take 30~50min. You need a fairly beefy machine to even be able to build a debug build of WebKit. The debug symbols can take hundreds of megabytes. This makes WebKit particularly challenging to profile.

Another problem is that Sysprof marks require integration code. Apps have to purposefully link against, and use, libsysprof-capture to send these marks to Sysprof.

Integrating with Sysprof

As a first step, Adrian brought the libsysprof-capture code into the WebKit tree. As libsysprof-capture is a static library with minimal dependencies, this was relatively easy. We’re probably going to eventually remove the in-tree copy and switch to host system libsysprof-capture, but having it in-tree was enough to kickstart the whole process.

Originally I started sprinkling Sysprof code all around the WebKit codebase, and to some degree, it worked. But eventually I learned that WebKit has its own macro-based tracing mechanism that is only ever implemented for Apple builds.

Looking at it, it didn’t seem impossible to implement these macros using Sysprof, and that’s what I’ve been doing for the past few weeks. The review was lengthy but behold, WebKit now reports Sysprof marks!

Screenshot of Sysprof with WebKit marks highlighted

Right now these marks cover a variety of JavaScript events, layout and rendering events, and web page resources. This all came for free from integrating with the preexisting tracing mechanism!

This gives us a decent understanding of how the Web process behaves. It’s not yet complete enough, but it’s a good start. I think the most interesting data to me is correlating frame timings across the whole stack, from the kernel driver to the compositor to GTK to WebKit’s UI process to WebKit’s Web process, and back:

Screenshot of Sysprof with lots of compositor and GTK and WebKit marks

But as interesting as it may be, oftentimes the fun part of profiling is being surprised by the data you collect.

For example, in WebKit, one specific, seemingly innocuous, completely bland method is in the top 3 of the callgraph chart:

Screenshot of Sysprof showing the callgraph view with an interesting result highlighted

Why is WebCore::FloatRect::contains so high in the profiling? That’s what I’m investigating right now. Who guessed this specific method would be there? Nobody, as far as I know.

Once this is out in a stable release, anyone will be able to grab a copy of GNOME Web, and run it with Sysprof, and help find out any performance issues that only reproduce in particular combinations of hardware.

Next Plans

To me this already is a game changer for WebKit, but of course we can do more. Besides the rectangular surprise, and one particular slowdown that comes from GTK loading Vulkan on startup, no other big obvious data point popped up. Specially in the marks, I think their coverage is still fairly small compared to what it could have been.

We need more data.

Some ideas that are floating right now:

  • Track individual frames and correlate them with Sysprof marks
  • Measure top-to-bottom-to-top latency
  • Measure input delay
  • Integrate with multimedia frames

Perhaps this will allow us to make WebKit the prime web engine for Linux, with top-tier performance, excellent system integration, and more. Maybe we can even redesign the whole rendering architecture of WebKit on Linux to be more GPU friendly now. I can dream high, can’t I? 🙂

In any case, I think we have a promising and exciting time ahead for WebKit on Linux!

By Georges Stavracas at July 12, 2024 12:42 PM