Skip to content

Upgrade to upstream WebKit 2603e9eb41f0 - #300

Merged
sosukesuzuki merged 1290 commits into
mainfrom
bun/upgrade-to-c8b6308aaa69
Jul 19, 2026
Merged

Upgrade to upstream WebKit 2603e9eb41f0#300
sosukesuzuki merged 1290 commits into
mainfrom
bun/upgrade-to-c8b6308aaa69

Conversation

@robobun

@robobun robobun commented Jul 16, 2026

Copy link
Copy Markdown
Collaborator

Merge upstream WebKit c8b6308aaa69 into the Bun fork.

Previous sync: d81bcc3d833c (#263, squash-merged as c9ad5813fd23). 1113 upstream commits since then; 211 touch Source/JavaScriptCore / Source/WTF / Source/bmalloc. Because #263 was squash-merged, this branch first records d81bcc3d833c as an ancestor via -s ours (same pattern as 6812aa45de4f) so that git merge-base resolves correctly.

The merge commit's second parent is c8b6308aaa691fa0dd3f84bdcbf2d15a2f97b01e, upstream main as of the time this PR was opened.

Conflict resolutions

22 files conflicted; resolved as follows:

  • DeferredWorkTimer.{h,cpp}: upstream's Ticket refactor (now ThreadSafeRefCountedAndCanMakeThreadSafeWeakPtr, addPendingWork returns WeakTicket, scheduleWorkSoon replaced by scheduleWorkSoonIfActive). Bun's onAddPendingWork/onScheduleWorkSoon/onCancelPendingWork hooks kept, updated to the new types (Ref<Ticket>&& / Ticket&).
  • JSDateMath.{h,cpp}: upstream moved lastTimeZoneID to WTF::lastTimeZoneID() / WTF::timeZoneDidChange() behind USE(TIME_ZONE_CHANGE_NOTIFICATIONS). Bun's || USE(BUN_JSC_ADDITIONS) additions to the old PLATFORM(COCOA) guards are now obsolete; took upstream. Added || USE(BUN_JSC_ADDITIONS) to the USE_TIME_ZONE_CHANGE_NOTIFICATIONS define in PlatformUse.h and a no-op listenForTimeZoneChangeNotifications() stub in WTF/wtf/TimeZone.cpp for the Bun build (no platform notifier; Bun calls WTF::timeZoneDidChange() explicitly).
  • JSMicrotask.cpp: upstream threaded a MicrotaskCallCache* through callMicrotask and the async-generator helpers, and extracted AsyncFunctionResume's body into asyncFunctionGeneratorBodyCall(). Bun's async-context save/restore blocks updated to pass microtaskCallCache and now wrap the new helper call.
  • JSFinalizationRegistry.cpp / WasmStreamingCompiler.cpp: upstream's scheduleWorkSoonIfActive removes the hasPendingWork assertions. Bun's BUN_SKIP_FAILING_ASSERTIONS guards moved to the surviving asserts.
  • PropertySlot.h: upstream added LastAttribute = DOMJITFunction. Kept Bun's Constructable = 1 << 17 and set LastAttribute = Constructable under USE(BUN_JSC_ADDITIONS).
  • JSGlobalObject.h, MicrotaskQueueInlines.h, RunLoop.h, OptionsList.h, DeferredWorkTimer.h, BuiltinNames.{h,cpp}: kept both sides; upstream's additions placed adjacent to Bun's.
  • RunLoopGeneric.cpp: upstream added releaseAssertIsCurrent(m_runLoop) in TimerBase. Under USE(BUN_EVENT_LOOP) the m_runLoop macro expands to the RunLoopGenericState optional, so the Bun branch asserts against m_runLoop->m_parent instead.
  • JavaScriptCore/CMakeLists.txt: re-applied upstream's hunks (new JSCWebPreferenceOptions.h generator/target, Storage.json inspector domain, AsyncGeneratorPrototype.js/StringConstructor.js removed from builtins, DeferredWorkTimerInlines.h removed from private headers, *_HEADERS_DIR rename) on top of Bun's CMakeLists rather than taking upstream wholesale.
  • ArrayPrototype.h, SparseArrayValueMap.h, JSDollarVM.h, WasmTable.h, WasmFormat.h, Interpreter.h, B3EliminateWasmGCAllocations.h: include-block-only conflicts; took upstream.

JSType.h did not change in this range; no src/jsc/JSType.rs update needed.

WebKit upgrade: upstream range d81bcc3d833c..c8b6308aaa69 (211 commits in JSC/WTF/bmalloc)

Notable changes

JIT / DFG / FTL / B3 / Air

  • 6d70d346c664 Add LoadMegamorphicGetter IC
  • 0d5d36b5f94e Add RegExpExecSticky DFG node
  • 23903f1a1cc7 Add AtomString Array loop in DFG / FTL
  • 082efc20347d Handle String#trim / trimStart / trimEnd in DFG / FTL
  • eeb2440ba085 Inline StringSlice rope construction in FTL
  • 752e7e8b0d05 Convert HasOwnProperty on current for-in key to EnumeratorHasOwnProperty
  • 7f538702bc4e Prove resolved values non-thenable for NewResolvedPromise in DFG constant folding
  • 338e02c8838a Fix DFG strength reduction folding compiler-thread RegExp failure into a definite no-match
  • d801f1e36011 / 674917cb5f4d / 71208eb12b5e Shrink Air::Arg to 16 bytes, Air::Inst to 64 bytes
  • 0f2107b6d205 Remove Air::lowerMacros; 5d5a2e3a036f single-pass Air::simplifyCFG
  • ebe71899e170 Adjust JIT tier-up thresholds for Macs with fewer P-cores

GC / Heap

  • 5ecce0f050d2 / 6fddaa00b614 Manually pipeline memory fetching for GC marking (SlotVisitor prefetch)
  • f0df03efe38c Tweak number of GC threads on Apple platforms
  • 904ba5171187 Strong<T> is now pointer-sized
  • b80bcf43bdce SparseArrayValueMap 33% more compact using HashSet

Runtime / Promises / Async

  • d11c8c7ba675 / 3ac446bb73b3 Polymorphic MicrotaskCallCache for microtask calls, threaded through more functions
  • 5f65bd95a4b6 Cooperative driving of async generators
  • 74cc52330394 Use JSSlimPromiseReaction for JSAsyncGenerator queue
  • 793fd5461d93 async-generator fast consume inserts ExitOK
  • 707b16ac07ea PromiseResolveThenableJob rejects when SpeciesConstructor throws
  • 8490d02c5dcc AsyncFromSyncIterator closes correctly on rejected value promise
  • 8e15aeeee3bc Improve exception unwinding performance
  • 3bd19f0a328e Move object structured-cloning code into JSC

Strings / RegExp / YARR

  • 4e93b58dfd8e Array#join writes rope elements directly into result buffer
  • 485bcf1b176a Fast path for Array#concat with multiple arguments
  • bef2808f4db2 Parse replacement template once in String#replace (global + $ substitutions)
  • 5031c9001ee2 Implement String.raw in C++
  • 7a764d7acc54 Yarr collects BM info for fixed-count terms; e13280f56c44 rearrange YarrJIT registers for regT3
  • 630d6be8962a Fix YARR EOL string-list optimization with multiline flag

WebAssembly

  • c7bfc7c0ca52 Add B3::eliminateWasmGCAllocations phase; a2bb3b59f1cc fold WasmGC object comparisons
  • 1152f3717e9b Implement Table64 JS API
  • 7f065ab4abdb Fix streaming instantiation using result promise as import object when imports omitted
  • 228685d7d2a3 Names in Error stacktrace for instantiateStreaming modules
  • bccb52eace5b / f854abcc8468 BBQ strength-reduce signed div/rem by negative pow2; mask before shr
  • fb30bac88bb4 Wasm debugger: replace polling STW participation with VMBlockingScope

Temporal / Intl

  • 23eb4f85f358 Enable Temporal object by default
  • cfda643c04c0 / 2fb282a82538 / 170ee738c6f1 / bdd3b71e35c2 / d3c7fd25598a / a0433cfeb9ab / 1482a7ad4add / 75d9be0204db / f9f65c7ff4f6 Multiple Temporal spec-alignment & calendar fixes (ZonedDateTime, PlainDateTime, PlainYearMonth, PlainMonthDay, non-ISO calendars, Duration rounding)
  • 6ea58a42a909 Add useIntlEraMonthcode option, narrow AvailableCalendars
  • 824d2b29e233 Use modern unit/ skeleton in Intl.NumberFormat
  • cde1f2154e51 Use IntlCache for Temporal pattern generation in Intl.DateTimeFormat

Parser / Bytecode / LLInt

  • d981384b263d Add TokNumberInt32 to LiteralParser to remove number-conversion overhead
  • 1994bc0cc3e2 Skip unreachable implicit return for arrow function expression bodies
  • c0e48d007a10 LLInt records IterationMode::Generic in op_iterator_next / op_async_iterator_next
  • 69ab6c6330aa Fix CLoop with loadh / storeh

WTF / bmalloc

  • 3aa0615a5649 Fix WTF::divideRoundedUp overflow near type max
  • 39dc095e8f0e Fix calculateBase64EncodedSize() truncation for >4 GB inputs
  • b420bd341074 Fix pairIntHash bit extraction degrading hash distribution
  • 6cccd5ef64ee / 82b692fc69fc / dce31d0f206f libpas: fix OoB paths in MAR code, segregated-heap race, zeroed-alloc bug

Bun-relevant API changes

  • DeferredWorkTimer Ticket refactor (15c117a5444a): TicketData is now ThreadSafeRefCountedAndCanMakeThreadSafeWeakPtr. addPendingWork() returns a WeakTicket (ThreadSafeWeakPtr<TicketData>) instead of a raw Ticket. scheduleWorkSoon(Ticket, Task&&) is replaced by scheduleWorkSoonIfActive(WeakTicket&&, Task&&) / mustScheduleWorkSoonIfActive(...), and cancelPendingWork() now takes a WeakTicket&&. Callers that held a raw Ticket must be updated to hold WeakTicket and use the *IfActive variants.
  • Time-zone change detection moved to WTF (65d36770c7a6, a01ee718ca4d): JSDateMath now checks WTF::lastTimeZoneID() / WTF::timeZoneDidChange() guarded by USE(TIME_ZONE_CHANGE_NOTIFICATIONS). Ports without notifications re-read the host zone on each cache reset. Embedders that previously called DateCache::timeZoneChanged() directly should route through the new WTF hooks.
  • Microtask call cache (d11c8c7ba675, 3ac446bb73b3, 5f65bd95a4b6): callMicrotask() in JSMicrotask now takes an additional MicrotaskCallCache* parameter. AsyncFunctionResume's body was factored out into asyncFunctionGeneratorBodyCall() which also threads the cache. Any Bun code calling callMicrotask / resuming async functions directly needs the extra argument.
  • PropertyAttribute::LastAttribute sentinel (b80bcf43bdce): the PropertyAttribute enum gained a LastAttribute sentinel used by the new compact SparseArrayValueMap encoding. static_asserts against attribute bit-width may need updating.
  • New generated header JSCWebPreferenceOptions.h (3af9d4073d75): JSC feature flags are now driven by UnifiedWebPreferences.yaml; the build emits a new JSCWebPreferenceOptions.h that must be on the include path / in generated-sources lists.

Ahmad-S792 and others added 30 commits July 14, 2026 08:46
…hat have no port

https://bugs.webkit.org/show_bug.cgi?id=319366
rdar://182171465

Reviewed by Devin Rousso.

WI.HARBuilder.port() guarded its "no port present" case with `if (!index)`
after `remoteAddress.lastIndexOf(":")`. That guard only fires when the colon
is at index 0 (a leading-colon address); it never fires for the not-found
case, because lastIndexOf() returns -1, which is truthy. As a result, an
address with no trailing ":port" fell through to substring(-1 + 1) ==
substring(0) and parsed the entire string, e.g. parseInt("12.34.56.78")
yields 12, so the HAR entry recorded a nonsensical serverPort.

Fix the guard to test `index === -1` so an address without a port correctly
returns undefined.

Test: http/tests/inspector/network/har/har-remote-address-port.html

* Source/WebInspectorUI/UserInterface/Controllers/HARBuilder.js:
(WI.HARBuilder.port):
* LayoutTests/http/tests/inspector/network/har/har-remote-address-port.html: Added.
* LayoutTests/http/tests/inspector/network/har/har-remote-address-port-expected.txt: Added.

Canonical link: https://commits.webkit.org/317155@main
…ot by wrong node field count

https://bugs.webkit.org/show_bug.cgi?id=319347
rdar://182161230

Reviewed by Devin Rousso.

HeapSnapshot.updateDeadNodesAndGatherCollectionData() walked
previousSnapshot._nodes but strided by this._nodeFieldCount, the current
snapshot's field count. _nodeFieldCount is per-instance (4 for an
"Inspector" snapshot, 7 for a "GCDebugging" one), so when the two
snapshots had different layouts the loop read node identifiers from
misaligned offsets and produced a garbage collected-nodes set.

Stride the previous snapshot's node list by its own field count instead.

Test: inspector/heap/collection-diff-across-node-layouts.html

* LayoutTests/inspector/heap/collection-diff-across-node-layouts-expected.txt: Added.
* LayoutTests/inspector/heap/collection-diff-across-node-layouts.html: Added.
* Source/WebInspectorUI/UserInterface/Workers/HeapSnapshot/HeapSnapshot.js:
(HeapSnapshot.prototype.updateDeadNodesAndGatherCollectionData):

Canonical link: https://commits.webkit.org/317156@main
…t because "canvas" is wrongly treated as a void element

https://bugs.webkit.org/show_bug.cgi?id=319365
rdar://182171240

Reviewed by Devin Rousso.

HTMLTreeBuilderFormatter.TagNamesWithoutChildren lists the HTML void
elements: tags that can never have children, so the tree builder does
not push them onto the stack of open elements. "canvas" was included in
this set since the formatter was first added, but <canvas> is not a void
element -- it has a transparent content model and legitimately contains
fallback content (e.g. <p> or <a> shown when canvas is unsupported).

Because "canvas" was in the set, _isEmptyNode() returned true for it, so
its fallback content was attached as siblings instead of children and
its closing tag went unmatched. Pretty-printing HTML that used canvas
fallback content therefore produced incorrectly-nested, non-indented
output.

Remove "canvas" from TagNamesWithoutChildren so it is treated as a
normal container element.

* LayoutTests/inspector/formatting/formatting-html-expected.txt:
* LayoutTests/inspector/formatting/formatting-html.html:
* LayoutTests/inspector/formatting/resources/html-tests/canvas-expected.html: Added.
* LayoutTests/inspector/formatting/resources/html-tests/canvas.html: Added.
* Source/WebInspectorUI/UserInterface/Workers/Formatter/HTMLTreeBuilderFormatter.js:

Canonical link: https://commits.webkit.org/317157@main
…y-initialize.html fails

https://bugs.webkit.org/show_bug.cgi?id=319295

Reviewed by Anne van Kesteren.

The failure was caused by usesNullCustomElementRegistry not getting propagated to a node during
fragment parsing because the tree scope of a node during a fragment parsing is document, which
does not have usesNullCustomElementRegistry flag set like its context element. Propagate the flag
from the context element to the document fragment we use for parsing to fix the bug.

Also add a test case for constructing an element using setHTMLUnsafe inside a declarative shadow DOM
with null custom element registry, which was not tested by any existing test cases.

Tests: imported/w3c/web-platform-tests/custom-elements/registries/CustomElementRegistry-initialize.html
       imported/w3c/web-platform-tests/custom-elements/registries/ShadowRoot-init-declarative.html

* LayoutTests/imported/w3c/web-platform-tests/custom-elements/registries/CustomElementRegistry-initialize-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/custom-elements/registries/Element-innerHTML-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/custom-elements/registries/ShadowRoot-init-declarative-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/custom-elements/registries/ShadowRoot-init-declarative.html:
* LayoutTests/imported/w3c/web-platform-tests/custom-elements/registries/scoped-custom-element-registry-customelementregistry-attribute-expected.txt:
* Source/WebCore/dom/DocumentFragment.cpp:
(WebCore::DocumentFragment::parseHTML):
* Source/WebCore/dom/Element.cpp:
(WebCore::Element::replaceChildrenWithMarkup):
(WebCore::Element::setOuterHTML):
(WebCore::Element::insertAdjacentHTML):
* Source/WebCore/dom/ShadowRoot.cpp:
(WebCore::ShadowRoot::replaceChildrenWithMarkup):
* Source/WebCore/editing/markup.cpp:
(WebCore::createFragmentForMarkup):
(WebCore::createFragmentForInnerOuterHTML):
(WebCore::createContextualFragment):
* Source/WebCore/editing/markup.h:
* Source/WebCore/html/parser/HTMLConstructionSite.cpp:
(WebCore::HTMLConstructionSite::containerForCurrentNode):
(WebCore::HTMLConstructionSite::createHTMLElementOrFindCustomElementInterface):
* Source/WebCore/html/parser/HTMLConstructionSite.h:

Canonical link: https://commits.webkit.org/317158@main
… / overlapping audio in Safari

https://bugs.webkit.org/show_bug.cgi?id=319271
rdar://179910591

Reviewed by Jer Noble.

Spotify start several audio elements at once when navigating within the page
(e.g. returning to a landing view). Each play() is authorized by the transient
user activation produced by the navigation click: that activation is
document-scoped and stays valid for several seconds, so every play() issued
during the window is permitted no matter how many elements are involved. The
result is several tracks playing on top of each other.

Add a site quirk, ShouldBlockAudiblePlaybackWhileAudioIsPlaying, that denies an
audible element from starting while another element in the same document is
already playing audio, unless a user gesture is being directly processed (so
deliberately choosing a track is unaffected). Enable it for open.spotify.com.

To distinguish a directly-processed gesture from transient activation, add
Document::mediaUserGestureReason(), reporting which branch of
processingUserGestureForMedia() authorized playback; the latter is refactored to
use it and is otherwise unchanged.

* Source/WebCore/dom/Document.cpp:
(WebCore::Document::processingUserGestureForMedia const):
(WebCore::Document::mediaUserGestureReason const):
* Source/WebCore/dom/Document.h:
* Source/WebCore/html/MediaElementSession.cpp:
(WebCore::mediaGestureReasonString):
(WebCore::MediaElementSession::playbackStateChangePermitted const):
* Source/WebCore/page/Quirks.cpp:
(WebCore::Quirks::shouldBlockAudiblePlaybackWhileAudioIsPlaying const):
(WebCore::handleSpotifyQuirks):
* Source/WebCore/page/Quirks.h:
* Source/WebCore/page/QuirksData.h:

Canonical link: https://commits.webkit.org/317159@main
…cationPayload has no options

https://bugs.webkit.org/show_bug.cgi?id=319238
rdar://182085034

Reviewed by Chris Dumez.

NotificationData::direction had no default member initializer, so when
NotificationPayload::toNotificationData() runs with no options, it stays
indeterminate and is then serialized over IPC (undefined behavior, and
possibly an out-of-range NotificationDirection).

Initialize it explicitly to NotificationDirection::Auto, and drop the
redundant WebCore:: qualifier since the struct is already in the WebCore
namespace.

Since the initializer now references the NotificationDirection::Auto
enumerator, the enum can no longer be an incomplete forward declaration.
Include <WebCore/NotificationDirection.h> and remove the forward
declaration so the enumerator is visible.

* Source/WebCore/Modules/notifications/NotificationData.h:

Canonical link: https://commits.webkit.org/317160@main
…"1e2px", and uppercase units

https://bugs.webkit.org/show_bug.cgi?id=319362
rdar://182169640

Reviewed by Devin Rousso.

WI.BoxShadow.parseNumberComponent() split a length component into value and
unit by calling `string.replace(value, "")`, passing the parsed Number as the
search argument. String.prototype.replace coerces that Number to a string via
String(value) and removes only the first literal occurrence, so it only worked
when String(parseFloat(s)) reproduced the exact numeric prefix of the source
text. It did not for several valid CSS length forms:

- "1.50px": String(1.5) is "1.5", so "1.5" was stripped leaving "0px", which
  is not a valid unit, so the whole box-shadow failed to parse.
- "1e2px": String(100) is "100", which is not a substring of "1e2px", so the
  number was left in place leaving unit "1e2px".
- ".5px": String(0.5) is "0.5", which is not a substring of ".5px".

Strip the leading number positionally with a regular expression instead, so the
remaining text is always the unit regardless of how the number is spelled. The
exponent group requires a trailing digit, so units that begin with "e" (em, ex)
are preserved rather than mistaken for scientific notation.

While here, also fix two related issues at the same time:

- Non-finite values: a literal that overflows to Infinity (e.g. "1e400px")
  passed the previous isNaN() guard and, with the regex now yielding a valid
  "px" unit, would serialize as "Infinitypx". Guard with isFinite() so NaN,
  Infinity, and -Infinity are all rejected.

- Case-insensitive units: CSS units are case-insensitive, but the unit was
  matched against a lowercase Set, so "1PX" was rejected. Lowercase the unit
  before the membership check, which also canonicalizes serialization.

* LayoutTests/inspector/model/boxShadow-expected.txt:
* LayoutTests/inspector/model/boxShadow.html:
* Source/WebInspectorUI/UserInterface/Models/BoxShadow.js:
(WI.BoxShadow.parseNumberComponent):

Canonical link: https://commits.webkit.org/317161@main
https://bugs.webkit.org/show_bug.cgi?id=319332
rdar://182148177

Reviewed by Sosuke Suzuki.

This patch moves TypedArray.of from builtin JS to C++.
This is trivially convertible as it is not involving callbacks etc.
We have a fast path for normal TypedArray constructors and we store
arguments quickly by using type-specialized path.

* Source/JavaScriptCore/builtins/TypedArrayConstructor.js:
(of): Deleted.
* Source/JavaScriptCore/runtime/JSGlobalObject.h:
* Source/JavaScriptCore/runtime/JSGlobalObjectInlines.h:
(JSC::JSGlobalObject::typedArrayConstructorConcurrently const):
* Source/JavaScriptCore/runtime/JSTypedArrayViewConstructor.cpp:
(JSC::JSTypedArrayViewConstructor::finishCreation):
(JSC::typedArrayOfSetElements):
(JSC::typedArrayOfFast):
(JSC::JSC_DEFINE_HOST_FUNCTION):

Canonical link: https://commits.webkit.org/317162@main
https://bugs.webkit.org/show_bug.cgi?id=318695
rdar://181510590

Reviewed by Sihui Liu.

Ensure `window.sessionStorage` is cleared between test iterations by
adding WebKit::WebsiteDataType::SessionStorage to the data types in
WKWebsiteDataStoreClearStorage().

The previous workaround, clearSessionStorage.js, is now unnecessary and
was removed. One test, however, included it as a random script to be
blocked for policy reasons (sessionstorage/blocked-file-access.html).
For that, a new script, `should-not-be-allowed-to-load.js`, was
introduced.

Change: Source/WebKit/UIProcess/API/C/WKWebsiteDataStoreRef.cpp:
(WKWebsiteDataStoreClearStorage):

Test added: LayoutTests/fast/harness/sessionstorage-cleared-between-iterations.html

Test adjustment:
* LayoutTests/storage/domstorage/sessionstorage/resources/clearSessionStorage.js: Removed.
* LayoutTests/storage/domstorage/sessionstorage/resources/should-not-be-allowed-to-load.js: Added.
* LayoutTests/storage/domstorage/sessionstorage/resources/blocked-example.html:
* LayoutTests/storage/domstorage/sessionstorage/blocked-file-access-expected.txt:
* LayoutTests/storage/domstorage/sessionstorage/delete-removal.html:
* LayoutTests/storage/domstorage/sessionstorage/enumerate-storage.html:
* LayoutTests/storage/domstorage/sessionstorage/enumerate-with-length-and-key.html:
* LayoutTests/storage/domstorage/sessionstorage/index-get-and-set.html:
* LayoutTests/storage/domstorage/sessionstorage/set-item-synchronous-keydown.html:
* LayoutTests/storage/domstorage/sessionstorage/simple-usage.html:
* LayoutTests/storage/domstorage/sessionstorage/string-conversion.html:
* LayoutTests/storage/domstorage/sessionstorage/window-open.html:

Canonical link: https://commits.webkit.org/317163@main
…nstead of a parallel array

https://bugs.webkit.org/show_bug.cgi?id=318599

Reviewed by Antti Koivisto.

performFlexLayout kept each flex item's main-axis margin extent in a parallel array
(marginsList) computed up front and threaded through the main-size pipeline. Snapshot it
onto FlexLayoutItem instead, as the first of the geometry the core reads off the renderer.

FlexLayoutItem gains a mainAxisMargin field, populated in collectFlexItems from the flow-aware
margin extent right after the item's flexBaseAndHypotheticalMainSize is computed. That timing
matters: an orthogonal flex item only resolves its physical margins when it is laid out for its
flex base size, so the snapshot has to happen after that layout -- reading the margin at
FlexLayoutItem construction would capture stale, pre-layout values and throw off margin-trim.
This is the same point the old marginsList was filled (after collectFlexItems returned). The
field is mutable because margin-trim reduces it during line collection, so
trimMainAxisMarginStart/End now take a FlexLayoutItem& and adjust the field. The margin-box
helpers (flexBaseMarginBoxSize, hypotheticalMainAxisMarginBoxSize, flexedMarginBoxSize) and
canFitItemWithTrimmedMarginEnd read the field, and the marginsList array plus the margin
parameter to computeFlexLines, computeMainSizeForFlexItems, resolveFlexibleLengthsForLineItems,
handleMainAxisAlignment, and distributeMainAxisFreeSpaceForMultilineColumnIfNeeded are gone.

No change in behavior: the margin is computed the same way, snapshotted at the same point, and
follows the same trim. Covered by existing tests (e.g.
imported/w3c/web-platform-tests/css/css-box/margin-trim/flex-row-orthogonal-item.html).

* Source/WebCore/rendering/RenderFlexibleBox.cpp:
* Source/WebCore/rendering/RenderFlexibleBox.h:

Canonical link: https://commits.webkit.org/317164@main
https://bugs.webkit.org/show_bug.cgi?id=319281
rdar://182120327

Reviewed by Alan Baradlay.

In 317067@main we had RenderGrid store its resolved track listing as a
specific output of layout instead of trying to reverse engineer it from
the positions vector, gap sizes, etc.

In this patch we adopt the new behavior and make sure that any content
that runs through GFC can still report its resolved track listing
correctly in the same way. This is done by just having the integration
logic set the value in the same way legacy grid layout does on the end
of layout.

* Source/WebCore/rendering/RenderGrid.cpp:
(WebCore::RenderGrid::layoutGrid):
Now that GFC also writes to the same structure we can have legacy grid
layout invalidate it even earlier.

Canonical link: https://commits.webkit.org/317165@main
https://bugs.webkit.org/show_bug.cgi?id=319322
rdar://182144347

Reviewed by Alan Baradlay.

When computing the block min/max content contributions for a grid item,
GFC will call into the respective integration function to to get this
value. What these two end up doing is calling into layoutWithFormattingContextForBox
in order to get that size. This function optionally takes in a width and
height constraint for the renderer that is sets as the overriding size
on it. Unfortunately, it does not clear the overriding height like it does
with the width so this can result in that size staying on the renderer
after the function returns. With respect to the described bug what ends
up happening is:

Layout frame 1:
- Compute the block min/max contributions
- Perform a final layout on the grid item which uses the same
  integration API *and does pass an overriding width/height*

** Some mutation occurs that causes us to do layout again **

Layout frame 2:
- Compute the block min/max contributions
Now we have the wrong values because the overriding sizes were not
cleared so we use those values again

So the fix is to clear the overriding block size because we do not want
these things living around longer than they need to.

Canonical link: https://commits.webkit.org/317166@main
…es duplicates the prefix (e.g. -apple--apple-system)

https://bugs.webkit.org/show_bug.cgi?id=319374
rdar://182178871

Reviewed by Devin Rousso.

Typing a hyphen-prefixed CSS value such as `-apple-system` or `-webkit-flex`
in the Elements > Styles sidebar and then picking a completion produced a
duplicated prefix like `-apple--apple-system`, which is invalid and gets
dropped until the page is reloaded.

The CodeMirror CSS-mode tokenizer splits a hyphen-prefixed identifier in two
different ways: a value like `-name` becomes a bare `-` token followed by
`name`, while a value like `-apple-system` becomes a `-apple-` meta token
followed by `system`. `forPartialPropertyValue` only rejoined the preceding
token when it was exactly `-`, so once the second hyphen was typed the prefix
was computed as just the trailing segment (`system`). Applying the completion
then removed only that segment and inserted the full value on top of the
leftover `-apple-`, yielding `-apple--apple-system`.

Rejoin any hyphen-terminated preceding token (covering both the bare `-` and
the `-vendor-` meta token) so the whole identifier is used as the prefix.

* Source/WebInspectorUI/UserInterface/Models/CSSKeywordCompletions.js:
(WI.CSSKeywordCompletions.forPartialPropertyValue): Rejoin the preceding
token when it ends with `-`, not only when it is exactly `-`.

* LayoutTests/inspector/unit-tests/css-keyword-completions-expected.txt:
* LayoutTests/inspector/unit-tests/css-keyword-completions.html:
* Source/WebInspectorUI/UserInterface/Models/CSSKeywordCompletions.js:

Canonical link: https://commits.webkit.org/317167@main
https://bugs.webkit.org/show_bug.cgi?id=319163
rdar://182001231

Reviewed by Andy Estes.

When a find starts from a selection, all of a video's matching cues
share the media element's document position, so the closest match
always resolved to the run's first/last cue.
Instead, pick the cue nearest the video's playhead in the search direction.

Added additional find-in-video navigation coverage on macOS, covering
both the new behavior and stepping through interleaved page text and
caption cues.

* Source/WebKit/WebProcess/WebPage/FindController.cpp:
(WebKit::cueIndexNearestPlayhead):
(WebKit::indexClosestToSelection):
* Tools/TestWebKitAPI/Tests/WebKit/WKWebView/FindInPage.mm:
(configurationWithFindInVideoEnabled):
(waitForVideoCurrentTimeNear):
(TEST(WebKit, FindInPageVideoCaptionStepThroughCues)):
(TEST(WebKit, FindInPageVideoCaptionCueInSubframe)):
(seekAndPlaceCaretBeforeVideo):
(seekAndPlaceCaretAfterVideo):
(TEST(WebKit, FindInPageVideoCaptionNearestCueForward)):
(TEST(WebKit, FindInPageVideoCaptionNearestCueBackward)):
(TEST(WebKit, FindInPageVideoCaptionNearestCuePastAllForward)):
(TEST(WebKit, FindInPageVideoCaptionNearestCueBeforeAllBackward)):
(currentTimeAfterHighlighting):

Canonical link: https://commits.webkit.org/317168@main
https://bugs.webkit.org/show_bug.cgi?id=319308
rdar://181007316

Reviewed by Abrar Rahman Protyasha.

Scroll anchoring on apple.com/retail causes jumpy scrolling near the top of the page.
The React-based content changes an element from `position: static` to `position: fixed`
which correctly suppresses anchoring, but in a subsequent update changes `padding`, which
triggers anchoring. This anchoring happens via WebKit's zero-delay layout timer, so escapes
the earlier suppression; other browsers see both as happening in the same suppression window,
although the behavior is poorly specified and browser behavior differs[1], as shown by a
new tentative WPT[2].

Because of differences between browsers, and real fix (removing the zero-delay layout
timer) being a very risky change, for now quirk scroll anchoring off for apple.com/retail
(and the equivalent sites like apple.com.cn/retail and apple.com/uk/retail).

[1] w3c/csswg-drafts#14177
[2] web-platform-tests/wpt#61263

* Source/WebCore/page/Quirks.cpp:
* Source/WebCore/page/QuirksData.h:

Canonical link: https://commits.webkit.org/317169@main
https://bugs.webkit.org/show_bug.cgi?id=319341
rdar://182154374

Reviewed by Sammy Gill.

Upstream commit: web-platform-tests/wpt@96f7977

* LayoutTests/imported/w3c/web-platform-tests/css/css-scroll-snap/input/paged.html:
* LayoutTests/imported/w3c/web-platform-tests/css/css-scroll-snap/scroll-snap-stop-002-nested.html:
* LayoutTests/imported/w3c/web-platform-tests/css/css-scroll-snap/scroll-snap-stop-002.html:
* LayoutTests/imported/w3c/web-platform-tests/css/css-scroll-snap/snap-after-relayout/multiple-aligned-targets/nested-supercedes-common-to-both-axes.html:
* LayoutTests/imported/w3c/web-platform-tests/css/css-scroll-snap/snap-after-relayout/multiple-aligned-targets/prefer-common-to-both-axes-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/css/css-scroll-snap/snap-after-relayout/multiple-aligned-targets/re-snap-focused-target-after-scrollBy-expected.txt: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-scroll-snap/snap-after-relayout/multiple-aligned-targets/re-snap-focused-target-after-scrollBy.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-scroll-snap/snap-after-relayout/multiple-aligned-targets/resources/common.js:
(async runScrollSnapSelectionVerificationTest):
* LayoutTests/imported/w3c/web-platform-tests/css/css-scroll-snap/snap-after-relayout/multiple-aligned-targets/w3c-import.log:
* LayoutTests/imported/w3c/web-platform-tests/css/css-scroll-snap/unreachable-snap-positions-003-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/css/css-scroll-snap/unreachable-snap-positions-003.html:
* LayoutTests/imported/w3c/web-platform-tests/css/css-scroll-snap/unreachable-snap-positions-004-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/css/css-scroll-snap/unreachable-snap-positions-004.html:
* LayoutTests/imported/w3c/web-platform-tests/css/css-scroll-snap/unrelated-gesture-scroll-during-snap.html:
* LayoutTests/imported/w3c/web-platform-tests/css/css-scroll-snap/w3c-import.log:

Canonical link: https://commits.webkit.org/317170@main
…pTests

https://bugs.webkit.org/show_bug.cgi?id=319382
rdar://182204529

Reviewed by Marcus Plutowski.

Add two fragmentation sequences on the simple and fast heaps.
testFragmentationSplitRecoalescePreservesZero seeds an is_all_zero region,
splits it into sub-ranges, and frees them back is_all_zero -- the recoalesced
region must stay is_all_zero. testFragmentationSplitRecoalesceContaminatedByNonZero
does the same but frees the pieces back may_have_non_zero; the recoalesced whole
must then be may_have_non_zero (pas_zero_mode_merge), since a later zeroedMalloc
trusting is_all_zero would otherwise skip zeroing and return stale bytes.

Test: Source/bmalloc/libpas/src/test/LargeFreeHeapTests.cpp

* Source/bmalloc/libpas/src/test/LargeFreeHeapTests.cpp:
(std::testFragmentationSplitRecoalescePreservesZero):
(std::testFragmentationSplitRecoalesceContaminatedByNonZero):
(addLargeFreeHeapTests):

Canonical link: https://commits.webkit.org/317171@main
…-after)

https://bugs.webkit.org/show_bug.cgi?id=319169
rdar://182007943

Reviewed by Antti Koivisto.

Implement the 'discard-before' and 'discard-after' values of the CSS Text 4
'white-space-trim' property (https://drafts.csswg.org/css-text-4/#white-space-trim)
in the modern inline layout path, behind the CSSWhiteSpaceTrimEnabled setting
(off by default).

'discard-before' / 'discard-after' remove the collapsible white space
immediately before the start / after the end of an element. We do this at
inline-item building time: InlineItemsBuilder::adjustInlineItemsForWhiteSpaceTrim
discards the corresponding InlineTextItems in a single forward pass before line
building, bidi resolution and intrinsic sizing run, so the removed white space
is kept out of every downstream computation (rendering, soft-wrap opportunities
and min/max-content) at once. The property applies to inline boxes and block
containers, so an inline box or a non-replaced inline-block carries it. Inline
box boundaries -- and floats / out-of-flow boxes -- are transparent to this
adjacency, matching white space collapsing, while other atomic inlines, replaced
content, iframes and block-in-inline boxes are real content that ends it.

Because the property changes which inline items are generated, a value change
invalidates the cached inline item list (InlineInvalidation) and requires layout
(StyleDifference). Since the discard depends on cross-box adjacency that a
partial rebuild starting mid-content cannot resolve, the inline formatting
context re-collects all inline items whenever the content carries
white-space-trim rather than doing an incremental rebuild.

'discard-inner' parses and computes to a value but has no layout effect yet.

* LayoutTests/imported/w3c/web-platform-tests/css/css-cascade/all-prop-initial-xml-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/css/css-cascade/all-prop-revert-layer-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/parsing/white-space-trim-computed-expected.txt: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/parsing/white-space-trim-computed.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/parsing/white-space-trim-invalid-expected.txt: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/parsing/white-space-trim-invalid.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/parsing/white-space-trim-valid-expected.txt: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/parsing/white-space-trim-valid.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/white-space/reference/white-space-trim-atomic-inline-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/white-space/reference/white-space-trim-block-in-inline-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/white-space/reference/white-space-trim-break-spaces-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/white-space/reference/white-space-trim-content-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/white-space/reference/white-space-trim-discard-after-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/white-space/reference/white-space-trim-discard-before-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/white-space/reference/white-space-trim-discard-before-after-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/white-space/reference/white-space-trim-dynamic-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/white-space/reference/white-space-trim-generated-content-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/white-space/reference/white-space-trim-inline-block-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/white-space/reference/white-space-trim-inline-block-dynamic-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/white-space/reference/white-space-trim-interaction-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/white-space/reference/white-space-trim-nested-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/white-space/reference/white-space-trim-rtl-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/white-space/reference/white-space-trim-white-space-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/white-space/reference/white-space-trim-wrap-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/white-space/white-space-trim-atomic-inline-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/white-space/white-space-trim-atomic-inline.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/white-space/white-space-trim-block-in-inline-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/white-space/white-space-trim-block-in-inline.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/white-space/white-space-trim-break-spaces-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/white-space/white-space-trim-break-spaces.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/white-space/white-space-trim-content-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/white-space/white-space-trim-content.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/white-space/white-space-trim-discard-after-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/white-space/white-space-trim-discard-after.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/white-space/white-space-trim-discard-before-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/white-space/white-space-trim-discard-before.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/white-space/white-space-trim-discard-before-after-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/white-space/white-space-trim-discard-before-after.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/white-space/white-space-trim-dynamic-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/white-space/white-space-trim-dynamic.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/white-space/white-space-trim-generated-content-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/white-space/white-space-trim-generated-content.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/white-space/white-space-trim-inline-block-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/white-space/white-space-trim-inline-block.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/white-space/white-space-trim-inline-block-dynamic-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/white-space/white-space-trim-inline-block-dynamic.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/white-space/white-space-trim-interaction-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/white-space/white-space-trim-interaction.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/white-space/white-space-trim-intrinsic-width-expected.txt: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/white-space/white-space-trim-intrinsic-width.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/white-space/white-space-trim-nested-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/white-space/white-space-trim-nested.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/white-space/white-space-trim-rtl-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/white-space/white-space-trim-rtl.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/white-space/white-space-trim-white-space-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/white-space/white-space-trim-white-space.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/white-space/white-space-trim-wrap-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/white-space/white-space-trim-wrap.html: Added.
  (each with its reference/*-ref.html and byte-copy *-expected.html; intrinsic-width is a
  testharness test with *-expected.txt. inline-block, inline-block-dynamic and block-in-inline
  cover the inline-block carrier, its dynamic invalidation and the block-in-inline construct.)

* LayoutTests/imported/w3c/web-platform-tests/css/css-typed-om/the-stylepropertymap/properties/white-space-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/html/rendering/widgets/shadow-dom-expected.txt:
* LayoutTests/platform/glib/imported/w3c/web-platform-tests/css/css-cascade/all-prop-initial-xml-expected.txt:
* Source/WTF/Scripts/Preferences/UnifiedWebPreferences.yaml: Add the CSSWhiteSpaceTrimEnabled
  setting (testable, off by default).

* Source/WebCore/Headers.cmake:
* Source/WebCore/Sources.txt:
* Source/WebCore/WebCore.xcodeproj/project.pbxproj: Build the new files.

* Source/WebCore/css/CSSProperties.json: Add the white-space-trim longhand.
* Source/WebCore/css/CSSValueKeywords.in: Add discard-before / discard-after / discard-inner.
* Source/WebCore/layout/formattingContexts/inline/InlineContentCache.h: Carry a hasWhiteSpaceTrim
content attribute.
(WebCore::Layout::InlineContentCache::InlineItems::hasWhiteSpaceTrim const):
* Source/WebCore/layout/formattingContexts/inline/InlineFormattingContext.cpp:
(WebCore::Layout::InlineFormattingContext::rebuildInlineItemListIfNeeded): Force a full inline-item
re-collection when the content has white-space-trim.
* Source/WebCore/layout/formattingContexts/inline/InlineItemsBuilder.cpp:
(WebCore::Layout::isNonReplacedInlineBlock): The inline-level block container that white-space-trim
can carry; excludes replaced content and iframes.
(WebCore::Layout::InlineItemsBuilder::build):
(WebCore::Layout::InlineItemsBuilder::adjustInlineItemsForWhiteSpaceTrim): Discard the collapsible
white space items before/after the boxes that carry white-space-trim (inline boxes and non-replaced
inline-blocks) in a single forward pass; treat inline box boundaries, floats and out-of-flow boxes as
transparent, and other atomic and block-in-inline boxes as real content. Record hasWhiteSpaceTrim on
the content cache attributes.
(WebCore::Layout::InlineItemsBuilder::handleInlineBoxStart): Track whether any inline box carries
white-space-trim.
(WebCore::Layout::InlineItemsBuilder::handleInlineLevelBox): Track whether any inline-block carries
white-space-trim.
* Source/WebCore/layout/formattingContexts/inline/InlineItemsBuilder.h:
* Source/WebCore/layout/formattingContexts/inline/IntrinsicWidthHandler.cpp:
(WebCore::Layout::isBoxEligibleForNonLineBuilderMinimumWidth):
* Source/WebCore/layout/formattingContexts/inline/TextOnlySimpleLineBuilder.cpp: Disqualify the
simplified min-content / text-only fast paths when white-space-trim is present.
(WebCore::Layout::TextOnlySimpleLineBuilder::isEligibleForSimplifiedInlineLayoutByStyle):
* Source/WebCore/layout/formattingContexts/inline/invalidation/InlineInvalidation.cpp:
(WebCore::Layout::InlineInvalidation::rootStyleWillChange):
(WebCore::Layout::InlineInvalidation::styleWillChange): Mark the inline item list dirty when
white-space-trim changes on the root, an inline box or an inline-block.
* Source/WebCore/layout/formattingContexts/inline/text/TextUtil.cpp:
(WebCore::Layout::TextUtil::mayBreakInBetween): Use the next item's own leading content when it does
not start at the beginning of its text box (its leading white space may have been discarded), while
avoiding a substring allocation on the common path.
* Source/WebCore/style/StyleDifference.cpp:
* Source/WebCore/style/computed/StyleComputedStyleBase.h:
* Source/WebCore/style/computed/data/StyleNonInheritedRareData.cpp: Store white-space-trim in
  non-inherited rare data.
(WebCore::Style::whiteSpaceTrim):
(WebCore::Style::NonInheritedRareData::NonInheritedRareData):
(WebCore::Style::NonInheritedRareData::operator== const):
(WebCore::Style::NonInheritedRareData::dumpDifferences const):
(WebCore::Style::scrollSnapStop): Deleted.
* Source/WebCore/style/computed/data/StyleNonInheritedRareData.h:
* Source/WebCore/style/values/primitives/StyleKeyword+Mappings.h: Map the new keywords.
* Source/WebCore/style/values/text/StyleWhiteSpaceTrim.cpp: Added.
(WebCore::Style::CSSValueConversion<WhiteSpaceTrim>::operator):
* Source/WebCore/style/values/text/StyleWhiteSpaceTrim.h: Added.
(WebCore::Style::WhiteSpaceTrim::WhiteSpaceTrim):
(WebCore::Style::WhiteSpaceTrim::fromRaw):
(WebCore::Style::WhiteSpaceTrim::toRaw const):
(WebCore::Style::WhiteSpaceTrim::contains const):
(WebCore::Style::WhiteSpaceTrim::containsAny const):
(WebCore::Style::WhiteSpaceTrim::containsAll const):
(WebCore::Style::WhiteSpaceTrim::containsOnly const):
(WebCore::Style::WhiteSpaceTrim::isNone const):
(WebCore::Style::WhiteSpaceTrim::switchOn const):

Canonical link: https://commits.webkit.org/317172@main
… Use

https://bugs.webkit.org/show_bug.cgi?id=319361
rdar://182168974

Unreviewed build fix. Marked WebContentAnalysis selectors as legacy SPI.

* Source/WebCore/Configurations/AllowedSPI-legacy.toml:

Canonical link: https://commits.webkit.org/317173@main
https://bugs.webkit.org/show_bug.cgi?id=319359
rdar://182168302

Reviewed by Abrar Rahman Protyasha.

They have the same value now.

Tests: Tools/TestWebKitAPI/Tests/WebKit/WKWebView/FullscreenVideoTextRecognition.mm
       Tools/TestWebKitAPI/Tests/WebKit/WKWebView/ImageAnalysisTests.mm

* Source/WTF/Scripts/Preferences/UnifiedWebPreferences.yaml:
* Source/WTF/wtf/PlatformEnable.h:
* Source/WTF/wtf/PlatformEnableCocoa.h:
* Source/WebCore/PAL/pal/cocoa/VisionKitCoreSoftLink.h:
* Source/WebCore/PAL/pal/cocoa/VisionKitCoreSoftLink.mm:
* Source/WebCore/PAL/pal/spi/cocoa/VisionKitCoreSPI.h:
* Source/WebCore/editing/cocoa/EditorCocoa.mm:
(WebCore::selectionInImageOverlayAsAttributedString):
* Source/WebCore/loader/EmptyClients.cpp:
* Source/WebCore/page/ContextMenuClient.h:
* Source/WebCore/page/ContextMenuController.cpp:
(WebCore::ContextMenuController::populate):
* Source/WebCore/platform/LocalizedStrings.h:
* Source/WebCore/platform/TextRecognitionResult.h:
* Source/WebCore/platform/cocoa/LocalizedStringsCocoa.mm:
* Source/WebCore/platform/cocoa/TextRecognitionResultCocoa.mm:
* Source/WebCore/testing/Internals.cpp:
(WebCore::Internals::installImageOverlay):
* Source/WebCore/testing/Internals.h:
* Source/WebCore/testing/Internals.mm:
* Source/WebKit/Platform/cocoa/ImageAnalysisUtilities.h:
* Source/WebKit/Platform/cocoa/ImageAnalysisUtilities.mm:
(WebKit::createImageAnalyzer):
(WebKit::createImageAnalyzerRequest):
(WebKit::makeTextRecognitionResult):
(WebKit::languageIdentifierSupportsLiveText):
* Source/WebKit/Shared/Cocoa/WebPreferencesDefaultValuesCocoa.mm:
(WebKit::defaultTextRecognitionInVideosEnabled):
(WebKit::defaultVisualTranslationEnabled):
(WebKit::defaultRemoveBackgroundEnabled):
* Source/WebKit/Shared/TextRecognitionResult.serialization.in:
* Source/WebKit/UIProcess/API/Cocoa/_WKElementAction.mm:
(+[_WKElementAction _elementActionWithType:customTitle:assistant:disabled:]):
* Source/WebKit/UIProcess/Cocoa/WebPageProxyCocoa.mm:
* Source/WebKit/UIProcess/WebContextMenuProxy.h:
* Source/WebKit/UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::contextMenuItemSelected):
* Source/WebKit/UIProcess/WebPageProxy.h:
* Source/WebKit/UIProcess/ios/WKActionSheetAssistant.h:
* Source/WebKit/UIProcess/ios/WKActionSheetAssistant.mm:
(-[WKActionSheetAssistant defaultActionsForLinkSheet:]):
(-[WKActionSheetAssistant defaultActionsForImageSheet:]):
(-[WKActionSheetAssistant handleElementActionWithType:element:needsInteraction:]):
* Source/WebKit/UIProcess/ios/WKContentViewInteraction.h:
* Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm:
(-[WKContentView hasSelectablePositionAtPoint:]):
(-[WKContentView pointIsNearMarkedText:]):
(-[WKContentView textInteractionGesture:shouldBeginAtPoint:]):
(-[WKContentView _singleTapRecognized:]):
(-[WKContentView requestPreferredArrowDirectionForEditMenuWithCompletionHandler:]):
(-[WKContentView _handleTapOverInteractiveControl:]):
(-[WKContentView _didCommitLoadForMainFrame]):
(-[WKContentView _internalSelectTextForContextMenuWithLocationInView:completionHandler:]):
(-[WKContentView _shouldIgnoreTouchEvent:]):
(-[WKContentView deferringGestureRecognizer:shouldDeferGesturesForEventThatWillBeginAction:]):
(-[WKContentView buildMenuForWebViewWithBuilder:]):
(-[WKContentView _setUpImageAnalysis]):
(-[WKContentView _tearDownImageAnalysis]):
(-[WKContentView requestTextRecognition:imageData:sourceLanguageIdentifier:targetLanguageIdentifier:completionHandler:]):
(-[WKContentView _completeImageAnalysisRequestForContextMenu:requestIdentifier:hasTextResults:]):
(-[WKContentView beginTextRecognitionForFullscreenVideo:playerViewController:]):
(-[WKContentView cancelTextRecognitionForFullscreenVideo:]):
(-[WKContentView isTextRecognitionInFullscreenVideoEnabled]):
(-[WKContentView beginTextRecognitionForVideoInElementFullscreen:bounds:]):
(-[WKContentView cancelTextRecognitionForVideoInElementFullscreen]):
(-[WKContentView _shouldAvoidSecurityHeuristicScoreUpdates]):
* Source/WebKit/UIProcess/mac/WebContextMenuProxyMac.h:
* Source/WebKit/UIProcess/mac/WebContextMenuProxyMac.mm:
(WebKit::WebContextMenuProxyMac::appendRemoveBackgroundItemToControlledImageMenuIfNeeded):
(WebKit::WebContextMenuProxyMac::removeBackgroundFromControlledImage):
(WebKit::WebContextMenuProxyMac::getContextMenuFromItems):
* Source/WebKit/UIProcess/mac/WebPageProxyMac.mm:
* Source/WebKit/UIProcess/mac/WebViewImpl.h:
* Source/WebKit/UIProcess/mac/WebViewImpl.mm:
(WebKit::WebViewImpl::mouseUp):
(WebKit::WebViewImpl::requestTextRecognition):
(WebKit::WebViewImpl::imageAnalysisOverlayViewHasCursorAtPoint const):
(WebKit::WebViewImpl::beginTextRecognitionForVideoInElementFullscreen):
(WebKit::WebViewImpl::cancelTextRecognitionForVideoInElementFullscreen):
* Source/WebKit/WebProcess/WebCoreSupport/WebContextMenuClient.h:
* Source/WebKit/WebProcess/WebPage/Cocoa/WebPageCocoa.mm:
* Source/WebKit/WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::didCommitLoad):
* Source/WebKit/WebProcess/WebPage/WebPage.h:
* Source/WebKit/WebProcess/WebPage/WebPage.messages.in:
* Source/WebKitLegacy/mac/WebCoreSupport/WebContextMenuClient.h:
* Tools/TestWebKitAPI/Helpers/cocoa/ImageAnalysisTestingUtilities.h:
* Tools/TestWebKitAPI/Helpers/cocoa/ImageAnalysisTestingUtilities.mm:
* Tools/TestWebKitAPI/Tests/WebKit/WKWebView/FullscreenVideoTextRecognition.mm:
* Tools/TestWebKitAPI/Tests/WebKit/WKWebView/ImageAnalysisTests.mm:

Canonical link: https://commits.webkit.org/317174@main
…te tests

rdar://182125983
https://bugs.webkit.org/show_bug.cgi?id=319287

Reviewed by Tim Nguyen.

/resize-observer/observe.html contains 20 different subtests which are run
sequentially, so one test timing out will block subsequent tests from running.
Fix this by splitting it into 20 different test files.

The motivation of this change is from WebKit#69080,
which fixes test 15. Turns out, /resize-observer/observe.html has been marked as
skipped because it times out. On further investigation, we do pass most of the
subtests, but because of test 15 timing out, we don't have visibility into whether
subsequent tests also pass or not.

* LayoutTests/TestExpectations:
* LayoutTests/imported/w3c/web-platform-tests/resize-observer/observe-001-expected.txt: Added.
* LayoutTests/imported/w3c/web-platform-tests/resize-observer/observe-001.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/resize-observer/observe-002-expected.txt: Added.
* LayoutTests/imported/w3c/web-platform-tests/resize-observer/observe-002.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/resize-observer/observe-003-expected.txt: Added.
* LayoutTests/imported/w3c/web-platform-tests/resize-observer/observe-003.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/resize-observer/observe-004-expected.txt: Added.
* LayoutTests/imported/w3c/web-platform-tests/resize-observer/observe-004.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/resize-observer/observe-005-expected.txt: Added.
* LayoutTests/imported/w3c/web-platform-tests/resize-observer/observe-005.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/resize-observer/observe-006-expected.txt: Added.
* LayoutTests/imported/w3c/web-platform-tests/resize-observer/observe-006.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/resize-observer/observe-007-expected.txt: Added.
* LayoutTests/imported/w3c/web-platform-tests/resize-observer/observe-007.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/resize-observer/observe-008-expected.txt: Added.
* LayoutTests/imported/w3c/web-platform-tests/resize-observer/observe-008.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/resize-observer/observe-009-expected.txt: Added.
* LayoutTests/imported/w3c/web-platform-tests/resize-observer/observe-009.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/resize-observer/observe-010-expected.txt: Added.
* LayoutTests/imported/w3c/web-platform-tests/resize-observer/observe-010.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/resize-observer/observe-011-expected.txt: Added.
* LayoutTests/imported/w3c/web-platform-tests/resize-observer/observe-011.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/resize-observer/observe-012-expected.txt: Added.
* LayoutTests/imported/w3c/web-platform-tests/resize-observer/observe-012.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/resize-observer/observe-013-expected.txt: Added.
* LayoutTests/imported/w3c/web-platform-tests/resize-observer/observe-013.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/resize-observer/observe-014-expected.txt: Added.
* LayoutTests/imported/w3c/web-platform-tests/resize-observer/observe-014.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/resize-observer/observe-015-expected.txt: Added.
* LayoutTests/imported/w3c/web-platform-tests/resize-observer/observe-015.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/resize-observer/observe-016-expected.txt: Added.
* LayoutTests/imported/w3c/web-platform-tests/resize-observer/observe-016.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/resize-observer/observe-017-expected.txt: Added.
* LayoutTests/imported/w3c/web-platform-tests/resize-observer/observe-017.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/resize-observer/observe-018-expected.txt: Added.
* LayoutTests/imported/w3c/web-platform-tests/resize-observer/observe-018.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/resize-observer/observe-019-expected.txt: Added.
* LayoutTests/imported/w3c/web-platform-tests/resize-observer/observe-019.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/resize-observer/observe-020-expected.txt: Added.
* LayoutTests/imported/w3c/web-platform-tests/resize-observer/observe-020.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/resize-observer/observe-expected.txt: Removed.
* LayoutTests/imported/w3c/web-platform-tests/resize-observer/observe.html: Removed.

Canonical link: https://commits.webkit.org/317175@main
https://bugs.webkit.org/show_bug.cgi?id=319298
rdar://181719662

Reviewed by Mike Wyrzykowski.

ANGLE translates GLSL out and inout function parameters into Metal using small
helper structs whose conversion operator returns a reference into the struct.
Older Metal compilers placed that reference in the thread address space by
default, but a recent Metal compiler change defaults unlabeled references to the
generic address space instead. The returned reference no longer matches the
declared thread reference, so the shader fails to compile and WebGL pages that
pass out/inout parameters render nothing, producing many console errors.

Fix by adding a trailing thread qualifier to the conversion operator of each
helper struct (ANGLE_Out, ANGLE_InOut, ANGLE_VectorElemRef, and
ANGLE_SwizzleRef), which keeps both the object and the reference it returns in
the thread address space and restores the previous behavior.

* Source/ThirdParty/ANGLE/src/compiler/translator/msl/ProgramPrelude.cpp:

Canonical link: https://commits.webkit.org/317176@main
… to update

https://bugs.webkit.org/show_bug.cgi?id=319138
rdar://181954984

Reviewed by Ryosuke Niwa.

We should ensures that the window's updated activity state always propogates to the
test / UI Process.

* Tools/TestWebKitAPI/Tests/WebKit/WKWebView/WindowBlurInputChangeEvent.mm:
(TEST(WKWebView, InputChangeFiresOnWindowBlur)):

Canonical link: https://commits.webkit.org/317177@main
… tree-item level for a treeitem nested in a plain <ul>

https://bugs.webkit.org/show_bug.cgi?id=319267
rdar://180455904

Reviewed by Dominic Mazzoni.

294788@main (bc34242) moved hierarchicalLevel() to AXCoreObject and, in doing
so, changed the tree-level ancestor walk from the authored ARIA role
(ariaRoleAttribute()) to the computed role(). A plain <ul> whose only child is a
role="treeitem" is demoted to a generic Group role by the list heuristic, so the
walk began counting it as a grouping level, reporting level 2 instead of 1.

Per the ARIA tree pattern, only an explicitly-authored role="group" establishes a
grouping level. Introduce AXCoreObject::hasExplicitGroupRole() (cached on the
isolated tree) and count only those ancestors, matching the pre-294788 behavior
and other browsers.

* LayoutTests/accessibility/treeitem-hierarchical-level-in-plain-list-expected.txt: Added.
* LayoutTests/accessibility/treeitem-hierarchical-level-in-plain-list.html: Added.
* Source/WebCore/accessibility/AXCoreObject.cpp:
(WebCore::AXCoreObject::hierarchicalLevel const):
* Source/WebCore/accessibility/AXCoreObject.h:
* Source/WebCore/accessibility/AXLogger.cpp:
(WebCore::operator<<):
* Source/WebCore/accessibility/AccessibilityObject.h:
* Source/WebCore/accessibility/isolatedtree/AXIsolatedObject.h:
* Source/WebCore/accessibility/isolatedtree/AXIsolatedTree.cpp:
(WebCore::createIsolatedObjectData):
* Source/WebCore/accessibility/isolatedtree/AXIsolatedTree.h:

Canonical link: https://commits.webkit.org/317178@main
https://bugs.webkit.org/show_bug.cgi?id=319300
rdar://182135437

Reviewed by Dan Glastonbury.

WebXRGamepad.cpp includes Gamepad.h but never references the Gamepad class. No change in behavior.

* Source/WebCore/Modules/webxr/WebXRGamepad.cpp:

Canonical link: https://commits.webkit.org/317179@main
https://bugs.webkit.org/show_bug.cgi?id=319343
rdar://176493823

Reviewed by Sihui Liu.

Add flag that allows users to override default SiteIsolationEnabled value for testing

Manual testing detailed in ticket.

* Source/WTF/Scripts/Preferences/UnifiedWebPreferences.yaml:

Canonical link: https://commits.webkit.org/317180@main
https://bugs.webkit.org/show_bug.cgi?id=319393
rdar://182224083

Reviewed by Keith Miller.

We can stop using JSFullPromiseReaction and use JSSlimPromiseReaction if
we apply the following changes in JSAsyncGenerator.

1. We can just use circular singly-linked-list for queueing. Since
   queueing is always just enqueue and dequeue, we do not need to have
   doubly-linked-list.
2. Pack resumeMode into JSSlimPromiseReaction's payload.

* Source/JavaScriptCore/runtime/JSAsyncGenerator.cpp:
(JSC::JSAsyncGenerator::enqueue):
(JSC::JSAsyncGenerator::dequeue):
* Source/JavaScriptCore/runtime/JSPromiseReaction.cpp:
(JSC::JSSlimPromiseReaction::create):
(JSC::JSSlimPromiseReaction::createAsyncGeneratorRequest):
* Source/JavaScriptCore/runtime/JSPromiseReaction.h:
(JSC::JSPromiseReaction::JSPromiseReaction):

Canonical link: https://commits.webkit.org/317181@main
https://bugs.webkit.org/show_bug.cgi?id=318918
rdar://181751564

Reviewed by Antti Koivisto.

Add the CSS Text Level 4 'wrap-inside' property (auto | avoid), gated behind the
cssWrapInsideEnabled setting.

'wrap-inside: avoid' suppresses soft wrap opportunities within an inline box: the
line breaks before the box - keeping it together - rather than inside it, and
breaks inside the box only as a last resort when there is no other break
opportunity on the line. A 'wrap-inside: auto' box nested inside an 'avoid' box
does not re-enable breaking, and breaks between sibling avoid boxes are preferred
over breaks inside them.

Whether content is inside an avoid box (the box's own value or inherited from an
ancestor avoid box) is precomputed during style resolution as
effectiveWrapInsideAvoid(), so inline layout reads a flat flag and never walks
the box tree. It propagates only through inline boxes, so it does not cross into
a block, inline-block or other independent formatting context child. The break
decision is made by InlineContentBreaker: when the
overflowing content is inside an avoid box and there is an earlier wrap
opportunity, it asks the line builder to revert to the last wrap opportunity. The
line builder records all wrap opportunities and, on such a revert, prefers the
last one outside any avoid box; when every opportunity is inside an avoid box it
reverts to the outermost such box - a break in an outer box is used before a
break within an inner one - breaking inside the box only as a last resort when it
is the only content on the line.

* LayoutTests/imported/w3c/web-platform-tests/css/css-cascade/all-prop-initial-xml-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/wrap-inside/wrap-inside-auto-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/wrap-inside/wrap-inside-auto-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/wrap-inside/wrap-inside-auto.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/wrap-inside/wrap-inside-avoid-break-before-then-inside-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/wrap-inside/wrap-inside-avoid-break-before-then-inside-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/wrap-inside/wrap-inside-avoid-break-before-then-inside.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/wrap-inside/wrap-inside-avoid-forced-break-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/wrap-inside/wrap-inside-avoid-forced-break-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/wrap-inside/wrap-inside-avoid-forced-break.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/wrap-inside/wrap-inside-avoid-keeps-box-together-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/wrap-inside/wrap-inside-avoid-keeps-box-together-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/wrap-inside/wrap-inside-avoid-keeps-box-together.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/wrap-inside/wrap-inside-avoid-last-resort-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/wrap-inside/wrap-inside-avoid-last-resort-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/wrap-inside/wrap-inside-avoid-last-resort.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/wrap-inside/wrap-inside-avoid-nested-auto-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/wrap-inside/wrap-inside-avoid-nested-auto-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/wrap-inside/wrap-inside-avoid-nested-auto.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/wrap-inside/wrap-inside-avoid-nested-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/wrap-inside/wrap-inside-avoid-nested-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/wrap-inside/wrap-inside-avoid-nested.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/wrap-inside/wrap-inside-avoid-nowrap-child-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/wrap-inside/wrap-inside-avoid-nowrap-child-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/wrap-inside/wrap-inside-avoid-nowrap-child.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/wrap-inside/wrap-inside-avoid-nowrap-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/wrap-inside/wrap-inside-avoid-nowrap-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/wrap-inside/wrap-inside-avoid-nowrap.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/wrap-inside/wrap-inside-avoid-siblings-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/wrap-inside/wrap-inside-avoid-siblings-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/wrap-inside/wrap-inside-avoid-siblings.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/wrap-inside/wrap-inside-avoid-single-word-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/wrap-inside/wrap-inside-avoid-single-word-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/wrap-inside/wrap-inside-avoid-single-word.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/wrap-inside/wrap-inside-computed-expected.txt: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/wrap-inside/wrap-inside-computed.html: Added.
* Source/WTF/Scripts/Preferences/UnifiedWebPreferences.yaml: Add cssWrapInsideEnabled.
* Source/WebCore/css/CSSProperties.json: Add the wrap-inside property.
* Source/WebCore/layout/formattingContexts/inline/AbstractLineBuilder.h: Add the WrapOpportunityList alias.
* Source/WebCore/layout/formattingContexts/inline/InlineContentBreaker.cpp:
(WebCore::Layout::InlineContentBreaker::processOverflowingContent const): Revert to the
(WebCore::Layout::shouldRevertToEarlierWrapOpportunity):
last wrap opportunity when overflowing content is inside a wrap-inside: avoid box.
* Source/WebCore/layout/formattingContexts/inline/InlineLineBuilder.cpp:
(WebCore::Layout::enclosingBoxForWrapOpportunity):
(WebCore::Layout::wrapOpportunityToRevertTo): Prefer a wrap opportunity outside any avoid box; when
all opportunities are inside avoid boxes, revert to the outermost one.
(WebCore::Layout::LineBuilder::processLineBreakingResult):
* Source/WebCore/rendering/style/RenderStyleConstants.cpp:
(WebCore::operator<<):
* Source/WebCore/rendering/style/RenderStyleConstants.h: Add the WrapInside enum.
* Source/WebCore/style/StyleAdjuster.cpp:
(WebCore::Style::Adjuster::adjust const): Compute effectiveWrapInsideAvoid.
* Source/WebCore/style/computed/StyleComputedStyleBase+GettersInlines.h:
(WebCore::Style::ComputedStyleBase::effectiveWrapInsideAvoid const):
* Source/WebCore/style/computed/StyleComputedStyleBase+SettersInlines.h:
(WebCore::Style::ComputedStyleBase::setEffectiveWrapInsideAvoid):
* Source/WebCore/style/computed/StyleComputedStyleBase.h:
* Source/WebCore/style/computed/data/StyleInheritedRareData.cpp:
(WebCore::Style::InheritedRareData::InheritedRareData):
(WebCore::Style::InheritedRareData::operator== const):
(WebCore::Style::InheritedRareData::dumpDifferences const):
* Source/WebCore/style/computed/data/StyleInheritedRareData.h: Store effectiveWrapInsideAvoid.
* Source/WebCore/style/computed/data/StyleNonInheritedRareData.cpp:
(WebCore::Style::NonInheritedRareData::NonInheritedRareData):
(WebCore::Style::NonInheritedRareData::operator== const):
(WebCore::Style::NonInheritedRareData::dumpDifferences const):
* Source/WebCore/style/computed/data/StyleNonInheritedRareData.h: Store wrap-inside.
* Source/WebCore/style/values/primitives/StyleKeyword+Mappings.h: Map the wrap-inside keywords.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/wrap-inside/wrap-inside-avoid-break-all-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/wrap-inside/wrap-inside-avoid-break-all-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/wrap-inside/wrap-inside-avoid-break-all.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/wrap-inside/wrap-inside-avoid-line-break-anywhere-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/wrap-inside/wrap-inside-avoid-line-break-anywhere-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/wrap-inside/wrap-inside-avoid-line-break-anywhere.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/wrap-inside/wrap-inside-avoid-overflow-wrap-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/wrap-inside/wrap-inside-avoid-overflow-wrap-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/wrap-inside/wrap-inside-avoid-overflow-wrap.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/wrap-inside/wrap-inside-avoid-block-child-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/wrap-inside/wrap-inside-avoid-block-child-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/wrap-inside/wrap-inside-avoid-block-child.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/wrap-inside/wrap-inside-avoid-inline-block-child-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/wrap-inside/wrap-inside-avoid-inline-block-child-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/wrap-inside/wrap-inside-avoid-inline-block-child.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/wrap-inside/wrap-inside-avoid-inline-flex-child-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/wrap-inside/wrap-inside-avoid-inline-flex-child-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/wrap-inside/wrap-inside-avoid-inline-flex-child.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/wrap-inside/wrap-inside-avoid-inline-grid-child-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/wrap-inside/wrap-inside-avoid-inline-grid-child-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/wrap-inside/wrap-inside-avoid-inline-grid-child.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/wrap-inside/wrap-inside-avoid-inline-table-child-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/wrap-inside/wrap-inside-avoid-inline-table-child-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/wrap-inside/wrap-inside-avoid-inline-table-child.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/wrap-inside/wrap-inside-avoid-nested-deep-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/wrap-inside/wrap-inside-avoid-nested-deep-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/wrap-inside/wrap-inside-avoid-nested-deep.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/wrap-inside/wrap-inside-avoid-nested-only-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/wrap-inside/wrap-inside-avoid-nested-only-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/wrap-inside/wrap-inside-avoid-nested-only.html: Added.
* LayoutTests/platform/glib/imported/w3c/web-platform-tests/css/css-cascade/all-prop-initial-xml-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/wrap-inside/wrap-inside-avoid-dynamic-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/wrap-inside/wrap-inside-avoid-dynamic-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/wrap-inside/wrap-inside-avoid-dynamic.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/wrap-inside/wrap-inside-avoid-removed-dynamic-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/wrap-inside/wrap-inside-avoid-removed-dynamic-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-text/wrap-inside/wrap-inside-avoid-removed-dynamic.html: Added.
* Source/WebCore/style/StyleDifference.cpp:
* LayoutTests/imported/w3c/web-platform-tests/html/rendering/widgets/shadow-dom-expected.txt:

Canonical link: https://commits.webkit.org/317182@main
…outItem

https://bugs.webkit.org/show_bug.cgi?id=318600

Reviewed by Antti Koivsito.

Snapshot the flex item's cross-axis border+padding onto FlexLayoutItem, mirroring the
existing mainAxisBorderAndPadding field. It is populated at construction from the
flow-aware border+padding extent.

The only flow-based cross-axis border+padding read is in computeMainSizeFromAspectRatioUsing,
so that helper and its caller adjustFlexItemSizeForAspectRatioCrossAxisMinAndMax now take a
const FlexLayoutItem& (both are only ever reached from the item-having flex-base subgraph) and
the read comes from the field. The read already ran during flex-base sizing, so the
construction-time snapshot is the same value. The item-logical border+padding reads in the
stretch path are left as-is: those are the item's own logical-height border+padding, which
differs from the flow-based cross-axis value for orthogonal flows.

No change in behavior.

* Source/WebCore/rendering/RenderFlexibleBox.cpp:
* Source/WebCore/rendering/RenderFlexibleBox.h:

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Canonical link: https://commits.webkit.org/317183@main
https://bugs.webkit.org/show_bug.cgi?id=319394
rdar://182224827

Reviewed by Aditya Keerthi.

Follow up to 317174@main

* Source/WebKit/Platform/cocoa/ImageAnalysisUtilities.h:
* Source/WebKit/Platform/cocoa/ImageAnalysisUtilities.mm:
(WebKit::createImageAnalyzer):
(WebKit::createImageAnalyzerRequest):
(WebKit::makeTextRecognitionResult):
(WebKit::requestVisualTranslation):
* Source/WebKit/UIProcess/ios/WKContentViewInteraction.h:
* Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm:
(-[WKContentView imageAnalyzer]):
(-[WKContentView createImageAnalyzerRequest:image:imageURL:]):
(-[WKContentView createImageAnalyzerRequest:image:]):
(-[WKContentView updateImageAnalysisForContextMenuPresentation:elementBounds:]):
(-[WKContentView requestTextRecognition:imageData:sourceLanguageIdentifier:targetLanguageIdentifier:completionHandler:]):
(-[WKContentView imageAnalysisGestureDidBegin:]):
(shouldUseMachineReadableCodeMenuFromImageAnalysisResult):
(-[WKContentView _completeImageAnalysisRequestForContextMenu:requestIdentifier:hasTextResults:]):
(-[WKContentView beginTextRecognitionForFullscreenVideo:playerViewController:]):
(-[WKContentView beginTextRecognitionForVideoInElementFullscreen:bounds:]):
* Source/WebKit/UIProcess/mac/WebViewImpl.h:
* Source/WebKit/UIProcess/mac/WebViewImpl.mm:
(WebKit::WebViewImpl::ensureImageAnalyzer):
(WebKit::WebViewImpl::processImageAnalyzerRequest):
(WebKit::createImageAnalyzerRequest):
(WebKit::WebViewImpl::requestTextRecognition):
(WebKit::WebViewImpl::computeHasVisualSearchResults):
(WebKit::WebViewImpl::beginTextRecognitionForVideoInElementFullscreen):

Canonical link: https://commits.webkit.org/317184@main
achristensen07 and others added 22 commits July 17, 2026 07:19
…rMessage in imported/w3c/web-platform-tests/html/cross-origin-opener-policy/resource-popup.https.html

https://bugs.webkit.org/show_bug.cgi?id=319273
rdar://182115695

Reviewed by Chris Dumez.

317090@main wasn't quite enough.  We also need to prevent multiple calls to WebFrameProxy::waitForCertificateInfoFromNetworkProcess
in case multiple frames are committing in fast succession.

* LayoutTests/platform/mac-wk2/TestExpectations:
* Source/WebKit/UIProcess/Network/NetworkProcessProxy.h:
* Source/WebKit/UIProcess/WebFrameProxy.cpp:
(WebKit::WebFrameProxy::waitForCertificateInfoFromNetworkProcess):
(WebKit::WebFrameProxy::commitCertificateInfo):

Canonical link: https://commits.webkit.org/317375@main
…hin the nearest `timeline-scope` element for that name

https://bugs.webkit.org/show_bug.cgi?id=319589
rdar://182417407

Reviewed by Cameron McCormack.

Only the nearest parent with a `timeline-scope` [0] value matching the `animation-timeline`
should be considered as establishing a valid scope [1]. As such, we look for such an element
in `StyleOriginatedTimelinesController::attachAnimation()` and pass it down to `determineTimelineForElement()`
and `determineTreeOrder()` to determine what the matching timeline, if any, is.

[0] https://drafts.csswg.org/scroll-animations-1/#timeline-scope
[1] https://drafts.csswg.org/scroll-animations-1/#timeline-scoping

* LayoutTests/imported/w3c/web-platform-tests/scroll-animations/css/view-timeline-lookup-expected.txt:
* Source/WebCore/animation/StyleOriginatedTimelinesController.cpp:
(WebCore::StyleOriginatedTimelinesController::determineTreeOrder):
(WebCore::StyleOriginatedTimelinesController::determineTimelineForElement):
(WebCore::StyleOriginatedTimelinesController::attachAnimation):
(WebCore::containsElement): Deleted.
* Source/WebCore/animation/StyleOriginatedTimelinesController.h:

Canonical link: https://commits.webkit.org/317376@main
…through the bindings

https://bugs.webkit.org/show_bug.cgi?id=319593
rdar://182421884

Reviewed by Cameron McCormack.

The CSS WG resolved [0] that deferred timelines should be represented as null through the bindings.

[0] w3c/csswg-drafts#13807 (comment)

* LayoutTests/imported/w3c/web-platform-tests/scroll-animations/css/animation-timeline-deferred-expected.txt:
* Source/WebCore/animation/WebAnimation.cpp:
(WebCore::WebAnimation::bindingsTimeline const):
* Source/WebCore/animation/WebAnimation.h:
(WebCore::WebAnimation::bindingsTimeline const): Deleted.

Canonical link: https://commits.webkit.org/317377@main
https://bugs.webkit.org/show_bug.cgi?id=319476

Reviewed by Xabier Rodriguez-Calvar.

Check the element factory name in addition to the element name.

* Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:
(WebCore::MediaPlayerPrivateGStreamer::configureVideoDecoder):

Canonical link: https://commits.webkit.org/317378@main
… to flush compositing state

https://bugs.webkit.org/show_bug.cgi?id=319596

Reviewed by Fujii Hironori.

The scene state lock currently covers the compositor's entire per-layer flush
(positions, transforms, animations, backing store and tile bookkeeping), so the
scrolling thread's end-of-walk commit in flushPendingState() can wait for up to
a whole flush, milliseconds on layer-heavy pages, adding input latency.

Split the compositor's flush in two passes. The first pass, under the scene
state lock, applies only Change::Position and Change::BoundsOrigin to the
targets: positions are the only state committed by the scrolling thread, and
applying them for the whole tree under a single lock hold is what keeps the
compositor from observing a half-committed set (bug 315185). The second pass
everything else, runs without the scene state lock.

* Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedPlatformLayer.cpp:
(WebCore::CoordinatedPlatformLayer::flushPositionChanges):
(WebCore::CoordinatedPlatformLayer::flushCompositingStateOnTarget):
(WebCore::CoordinatedPlatformLayer::flushCompositingStateOnSkiaTarget):
* Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedPlatformLayer.h:
* Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/CoordinatedSceneState.cpp:
(WebKit::CoordinatedSceneState::flushCompositingState):

Canonical link: https://commits.webkit.org/317379@main
…harness and enable the passing tests

https://bugs.webkit.org/show_bug.cgi?id=319008
rdar://181853035

Reviewed by Sam Sneddon.

Reland of 317331@main, which was reverted because it broke Xcode builds.

The WPT webtransport/ tests could not connect because the layout-test harness never launched the
WPT WebTransport-over-HTTP/3 (webtransport-h3) QUIC server. The vendored aioquic-based server exists
under tools/webtransport/h3/ and upstream's `wpt serve` supports it, but it is opt-in and the harness
did not declare the port, pass the flag, check its liveness, or provision aioquic.

Wire the harness to launch the server and provision its dependency:

- Declare a webtransport-h3 UDP port in the WPT config and pass --webtransport-h3 to `wpt serve`.
- Provision aioquic through webkitpy's AutoInstall so a fresh checkout / CI bot needs no manual pip
  install. aioquic is the one dependency the h3 server needs that wpt does not vendor under
  tools/third_party, so it is registered alongside every other package in webkitpy/__init__.py.
  aioquic 1.2.0 needs a newer crypto stack than webkitpy pinned and AutoInstall keeps one version per
  package name, so this bumps the shared pins (pyOpenSSL -> 24.3.0, cryptography -> 44.0.3 -- the highest
  under pyOpenSSL's cryptography<45 pin that still ships prebuilt wheels for every arch). AutoInstall only
  mutates the in-process sys.path, so WebPlatformTestServer imports aioquic to trigger provisioning and
  appends AutoInstall.directory to the `wpt serve` subprocess PYTHONPATH. The import is done inside
  WebPlatformTestServer.__init__ rather than at module scope: build scripts such as generate-xcfilelists
  import this module transitively with the autoinstaller disabled, so a top-level import would fail there
  with ModuleNotFoundError (this is what broke 317331@main).
- Add a UDP-listener liveness check (QUIC is UDP; the inherited TCP connect() check never sees it) and
  exclude UDP ports from TCP device-forwarding. Both live in the HttpServerBase superclass, keyed off a
  per-mapping 'udp' flag, so WebPlatformTestServer no longer overrides ports_to_forward.

With the server running, un-skip the WebTransport tests that pass on Cocoa (connect, constructor,
congestion-control, csp, datagram-bad-chunk, incoming-multiple-streams, sendstream-bad-chunk,
server-certificate-hashes, in-removed-iframe) and add their expectations. The remaining tests stay
skipped, grouped by reason. Skip the Cocoa-only suite on platform/glib (GTK/WPE have no QUIC/HTTP-3
backend; Windows already skips it) and on platform/mac-sequoia (the tests need the Network.framework
QUIC SPI that ships on Tahoe but not Sequoia; open-source CI runs Tahoe).

This reland differs from 317331@main only in that aioquic is imported lazily inside
WebPlatformTestServer.__init__ instead of at module scope, so build scripts that import this module
with the autoinstaller disabled no longer fail.

* LayoutTests/imported/w3c/resources/config.json: Add the webtransport-h3 port.
* LayoutTests/TestExpectations: Un-skip the passing WebTransport tests; group the remaining skips by reason.
* LayoutTests/platform/glib/TestExpectations: Skip the Cocoa-only WebTransport suite on GTK/WPE.
* LayoutTests/platform/mac-sequoia/TestExpectations: Skip the WebTransport suite on Sequoia (QUIC SPI is Tahoe-only).
* LayoutTests/imported/w3c/web-platform-tests/webtransport/*-expected.txt: Baselines for the un-skipped tests.
* Tools/Scripts/libraries/webkitcorepy/webkitcorepy/__init__.py: Bump pyOpenSSL to 24.3.0 and collapse the
per-Python cryptography branch into a single 44.0.3 pin to satisfy aioquic 1.2.0.
* Tools/Scripts/libraries/resultsdbpy/resultsdbpy/__init__.py: Bump pyasn1_modules to 0.4.2 and
service_identity to 24.2.0 to match webkitpy's shared pins (both are imported in the same interpreter).
* Tools/Scripts/webkitpy/__init__.py: Register aioquic 1.2.0 and its deps (pylsqpack, pyasn1,
pyasn1_modules, service_identity).
* Tools/Scripts/webkitpy/layout_tests/servers/http_server_base.py:
(HttpServerBase.ports_to_forward): Exclude UDP-flagged ports from TCP device forwarding.
(HttpServerBase._is_server_running_on_all_ports): Validate UDP ports via the new listener probe.
(HttpServerBase._is_udp_port_listening): Added.
* Tools/Scripts/webkitpy/layout_tests/servers/http_server_base_unittest.py:
(TestHttpServerBase.test_is_udp_port_listening): Added.
* Tools/Scripts/webkitpy/layout_tests/servers/web_platform_test_server.py:
(WebPlatformTestServer.__init__): Lazily import aioquic to provision it, append the autoinstall directory
to the serve PYTHONPATH, pass --webtransport-h3, and flag the h3 mapping as UDP.
(WebPlatformTestServer.ports_to_forward): Deleted.
(WebPlatformTestServer._is_udp_port_listening): Deleted.
(WebPlatformTestServer._is_server_running_on_all_ports): Deleted.
(WebPlatformTestServer._spawn_process): Pass the aioquic-provisioned env to the wpt serve process.
* Tools/Scripts/webkitpy/layout_tests/servers/web_platform_test_server_unittest.py:
(TestWebPlatformTestServer.setUp): Deleted; the test harness already installs registered packages.

Canonical link: https://commits.webkit.org/317380@main
… unicode mode is `O(count)` per step

https://bugs.webkit.org/show_bug.cgi?id=319370

Reviewed by Yusuke Suzuki.

When backtracking a greedy character class that can match both BMP and
non-BMP characters under the unicode flag, backtrackCharacterClassGreedy
rewinds to the start of the term and rematches count - 1 characters
forward to recompute the index, because the width of the last matched
character is not fixed. This makes matching O(n^3) overall, while the
interpreter handles the same case in O(n^2):

    /[^"]*X/u.test("\u2014" + "a".repeat(4000))  // JIT: ~9.5s, interpreter: 56ms

typescript-eslint's JSX detection regexp hits this path and makes
prettier hang for ~10 seconds on real-world input.

We can step back in O(1) instead: since all term positions in unicode
mode lie on code point boundaries, the last matched character occupied
two code units iff the two code units preceding the current position
form a surrogate pair. When the new match count is zero, we reload the
begin position from the frame instead. Also drop the storeToFrame of
the match count, which only existed so the rematch loop could reload it.

The example above now completes in 16ms (~600x), scaling as O(n^2).

Tests: JSTests/stress/regexp-unicode-greedy-charclass-backtrack-exhaustive.js
       JSTests/stress/regexp-unicode-greedy-charclass-backtrack-linear.js

* JSTests/stress/regexp-unicode-greedy-charclass-backtrack-exhaustive.js: Added.
(shouldBe):
(checkSubject):
(enumerate):
* JSTests/stress/regexp-unicode-greedy-charclass-backtrack-linear.js: Added.
(shouldBe):
* Source/JavaScriptCore/yarr/YarrJIT.cpp:

Canonical link: https://commits.webkit.org/317381@main
…vigation

https://bugs.webkit.org/show_bug.cgi?id=319629
<rdar://182258311>

Reviewed by Mike Wyrzykowski.

The previous fix cleaned-up the Immersive Model's state when entering
bfcache, causing it to stop rendering during the dismissal animation.

Instead, do the clean-up when _restoring_ from the bfcache.

Test: model-element/immersive/model-element-immersive-bfcache.html

* LayoutTests/model-element/immersive/model-element-immersive-bfcache-expected.txt: Added.
* LayoutTests/model-element/immersive/model-element-immersive-bfcache.html: Added.
Add a test covering the bfcache scenario.

* Source/WebCore/dom/Document.cpp:
(WebCore::Document::setBackForwardCacheState):
(WebCore::Document::resume):
Move the call from the entering code path to the resume code path.

* Source/WebCore/dom/DocumentImmersive.cpp:
(WebCore::DocumentImmersive::didResumeFromBackForwardCache):
(WebCore::DocumentImmersive::clearForBackForwardCache): Deleted.
* Source/WebCore/dom/DocumentImmersive.h:
Rename the method to make it clearer.

Canonical link: https://commits.webkit.org/317382@main
https://bugs.webkit.org/show_bug.cgi?id=302211

Reviewed by Timothy Hatcher.

Port the WebExtensionAPITest JavaScript API to C++. Some components, namely any that use a Promise, are still in Cocoa for now as most Promise handling is mostly platform-specific in JavaScriptCore (and thus it’s easier to just leave any promise or callback code in Cocoa). As well, this provides a way to generate the JS interfaces in C++, allowing for them to be built on more platforms besides Cocoa. This does not unify the files, as there’s only one API built at the moment.

* Source/WebKit/CMakeLists.txt:
* Source/WebKit/DerivedSources-output.xcfilelist:
* Source/WebKit/DerivedSources.make:
* Source/WebKit/Shared/Extensions/WebExtensionContentWorldType.h:
(WebKit::toDebugString):
* Source/WebKit/Shared/Extensions/WebExtensionEventListenerType.h:
(WebKit::toAPIString):
* Source/WebKit/Sources.txt:
* Source/WebKit/WebKit.xcodeproj/project.pbxproj:
* Source/WebKit/WebProcess/Extensions/API/Cocoa/WebExtensionAPIEventCocoa.mm:
(WebKit::WebExtensionAPIEvent::invokeListenersWithJSONArgument):
* Source/WebKit/WebProcess/Extensions/API/Cocoa/WebExtensionAPITestCocoa.mm:
(WebKit::WebExtensionAPITest::assertRejects):
(WebKit::WebExtensionAPITest::assertResolves):
(WebKit::WebExtensionAPITest::addTest):
(WebKit::WebExtensionAPITest::startNextTest):
(WebKit::scriptLocation): Deleted.
(WebKit::WebExtensionAPITest::notifyFail): Deleted.
(WebKit::WebExtensionAPITest::notifyPass): Deleted.
(WebKit::WebExtensionAPITest::sendMessage): Deleted.
(WebKit::WebExtensionAPITest::onMessage): Deleted.
(WebKit::WebExtensionAPITest::onTestStarted): Deleted.
(WebKit::WebExtensionAPITest::onTestFinished): Deleted.
(WebKit::WebExtensionAPITest::runWithUserGesture): Deleted.
(WebKit::WebExtensionAPITest::isProcessingUserGesture): Deleted.
(WebKit::debugString): Deleted.
(WebKit::WebExtensionAPITest::log): Deleted.
(WebKit::WebExtensionAPITest::fail): Deleted.
(WebKit::WebExtensionAPITest::succeed): Deleted.
(WebKit::WebExtensionAPITest::assertTrue): Deleted.
(WebKit::WebExtensionAPITest::assertFalse): Deleted.
(WebKit::WebExtensionAPITest::assertDeepEq): Deleted.
(WebKit::combineMessages): Deleted.
(WebKit::WebExtensionAPITest::assertEquals): Deleted.
(WebKit::WebExtensionAPITest::assertEq): Deleted.
(WebKit::WebExtensionAPITest::assertThrows): Deleted.
(WebKit::WebExtensionAPITest::assertSafe): Deleted.
(WebKit::WebExtensionAPITest::assertSafeResolve): Deleted.
(WebKit::WebExtensionAPITest::runTests): Deleted.
(WebKit::WebExtensionAPITest::recordAssertionIfNeeded): Deleted.
(WebKit::WebExtensionContextProxy::dispatchTestMessageEvent): Deleted.
(WebKit::WebExtensionContextProxy::dispatchTestStartedEvent): Deleted.
(WebKit::WebExtensionContextProxy::dispatchTestFinishedEvent): Deleted.
* Source/WebKit/WebProcess/Extensions/API/WebExtensionAPIEvent.h:
* Source/WebKit/WebProcess/Extensions/API/WebExtensionAPINamespace.h:
* Source/WebKit/WebProcess/Extensions/API/WebExtensionAPITest.cpp: Added.
(WebKit::WebExtensionAPITest::scriptLocation):
(WebKit::WebExtensionAPITest::invokeMethod):
(WebKit::WebExtensionAPITest::notifyFail):
(WebKit::WebExtensionAPITest::notifyPass):
(WebKit::WebExtensionAPITest::sendMessage):
(WebKit::WebExtensionAPITest::onMessage):
(WebKit::WebExtensionAPITest::onTestStarted):
(WebKit::WebExtensionAPITest::onTestFinished):
(WebKit::WebExtensionAPITest::runWithUserGesture):
(WebKit::WebExtensionAPITest::isProcessingUserGesture):
(WebKit::WebExtensionAPITest::debugString):
(WebKit::WebExtensionAPITest::log):
(WebKit::WebExtensionAPITest::fail):
(WebKit::WebExtensionAPITest::succeed):
(WebKit::WebExtensionAPITest::assertTrue):
(WebKit::WebExtensionAPITest::assertFalse):
(WebKit::WebExtensionAPITest::assertDeepEq):
(WebKit::WebExtensionAPITest::combineMessages):
(WebKit::WebExtensionAPITest::assertEquals):
(WebKit::WebExtensionAPITest::assertEq):
(WebKit::WebExtensionAPITest::assertThrows):
(WebKit::WebExtensionAPITest::assertSafe):
(WebKit::WebExtensionAPITest::assertSafeResolve):
(WebKit::WebExtensionAPITest::addTest):
(WebKit::WebExtensionAPITest::runTests):
(WebKit::WebExtensionAPITest::recordAssertionIfNeeded):
(WebKit::WebExtensionContextProxy::dispatchTestMessageEvent):
(WebKit::WebExtensionContextProxy::dispatchTestStartedEvent):
(WebKit::WebExtensionContextProxy::dispatchTestFinishedEvent):
* Source/WebKit/WebProcess/Extensions/API/WebExtensionAPITest.h:
* Source/WebKit/WebProcess/Extensions/API/WebExtensionAPIWebPageNamespace.h:
* Source/WebKit/WebProcess/Extensions/Bindings/JSWebExtensionWrapper.cpp:
(WebKit::callWithArguments):
(WebKit::toVector<JSValueRef>):
(WebKit::toVector<Protected<JSValueRef>>):
* Source/WebKit/WebProcess/Extensions/Bindings/JSWebExtensionWrapper.h:
(WebKit::callObjectWithArguments):
* Source/WebKit/WebProcess/Extensions/Bindings/Scripts/CodeGeneratorExtensions.pm:
(_generateImplementationFile):
(_installAutomaticExceptions):
(_platformType):
(_platformTypeConstructor):
(_platformTypeVariableDeclaration):
* Source/WebKit/WebProcess/Extensions/Bindings/Scripts/IDLAttributes.json:
* Source/WebKit/WebProcess/Extensions/Interfaces/WebExtensionAPITest.idl:
* Source/WebKit/WebProcess/Inspector/WasmDebuggerDispatcher.cpp:
* Source/WebKit/WebProcess/WebPage/WebPage.h:
* Tools/Scripts/webkitpy/style/checker.py:
* Source/WebKit/Shared/Protected.h:
(WebKit::Protected::context const):

Canonical link: https://commits.webkit.org/317383@main
https://bugs.webkit.org/show_bug.cgi?id=319650
rdar://182472828

Reviewed by Sosuke Suzuki.

Let's have per-VM MicrotaskCallCache for async generator driver path.
Since MicrotaskCallCache is no longer on the stack, we need to finalize
the MicrotaskCall when GC happens. When it is used on-stack, we do not
need it since everything is alive via conservative scanning. But now
VM's one is not so we should purge invalid entries.

* Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp:
* Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileCompareStrictEq):
* Source/JavaScriptCore/heap/Heap.cpp:
(JSC::Heap::finalizeUnconditionalFinalizers):
* Source/JavaScriptCore/interpreter/MicrotaskCall.cpp:
(JSC::MicrotaskCall::visitWeak):
* Source/JavaScriptCore/interpreter/MicrotaskCall.h:
* Source/JavaScriptCore/jit/JITCall.cpp:
(JSC::JIT::emit_op_async_iterator_next):
* Source/JavaScriptCore/jit/JITOperations.cpp:
(JSC::JSC_DEFINE_JIT_OPERATION):
* Source/JavaScriptCore/jit/JITOperations.h:
* Source/JavaScriptCore/llint/LLIntSlowPaths.cpp:
(JSC::LLInt::LLINT_SLOW_PATH_DECL):
* Source/JavaScriptCore/runtime/AsyncGeneratorPrototype.cpp:
(JSC::asyncGeneratorNext):
(JSC::JSC_DEFINE_HOST_FUNCTION):
* Source/JavaScriptCore/runtime/JSAsyncGenerator.h:
* Source/JavaScriptCore/runtime/JSMicrotask.cpp:
(JSC::enqueueAsyncGeneratorDriver):
(JSC::asyncIteratorNextWithDriver):
* Source/JavaScriptCore/runtime/JSMicrotask.h:
* Source/JavaScriptCore/runtime/VM.cpp:
(JSC::VM::VM):
(JSC::VM::finalizeUnconditionally):
* Source/JavaScriptCore/runtime/VM.h:
(JSC::VM::syncResumeCallCache):

Canonical link: https://commits.webkit.org/317384@main
…ontent set and a shared finalize

https://bugs.webkit.org/show_bug.cgi?id=318629

Reviewed by Antti Koivisto.

updateLogicalHeightForFlexContent bundled work that only row flow needs (set the container height to the
accumulated line content extent, then add the inter-line gaps) with work both flows need (reserve a
line's height if empty, then resolve the final height via updateLogicalHeight). Column flow passed a
nullopt content height and a zero gap through it just to reach that shared tail.

Split it into setLogicalHeightForRowFlexContent, which the caller invokes only for row flow, and
finalizeFlexContainerLogicalHeight, which both flows call. The row content height now carries the
inter-line gaps folded in, so the shared finalize is a clean tail and column flow no longer passes
through the row-shaped path.

This reorders one thing for row flow: the empty-line floor now sees the content plus the inter-line gaps
rather than the content alone, so max(content, floor) + gaps becomes max(content + gaps, floor). The two
differ only when the accumulated content is shorter than a single line, which also requires the
empty-line floor to apply, i.e. an editable root or a form control (button, select, input) flex
container that additionally wraps to multiple lines with a row-gap. That combination does not occur in
practice, but it is not strictly a no-op, so it is called out here rather than claimed as
behavior-preserving. Column flow is unchanged.

* Source/WebCore/rendering/RenderFlexLayout.cpp:
* Source/WebCore/rendering/RenderFlexibleBox.cpp:
* Source/WebCore/rendering/RenderFlexibleBox.h:

Canonical link: https://commits.webkit.org/317385@main
…ender-remote-audio-* are failing

https://bugs.webkit.org/show_bug.cgi?id=318459
rdar://181257156

Reviewed by Sihui Liu.

The following tests are timing out with site isolation enabled:

http/tests/security/webaudio-render-remote-audio-allowed-crossorigin-redirect.html
http/tests/security/webaudio-render-remote-audio-allowed-crossorigin.html
http/tests/security/webaudio-render-remote-audio-blocked-no-crossorigin-redirect.html
http/tests/security/webaudio-render-remote-audio-blocked-no-crossorigin.html

```
context.resume().then(() => {   // ← promise stays pending
  audio.play();                 // ← never called
});
```

AudioContext first asks the UIProcess if it has playback permission.
However, there is a race where AudioContext asks the UIProcess about
playback permission before the RemoteMediaSessionState is registered with the UIProcess.

In terms of IPC messages, the UI process receives MediaSessionWillBeginPlayback
before AddMediaSession (comes from setActive(true)).

If the RemoteMediaSessionState doesn't exist in MediaSessionWillBeginPlayback, then
RemoteMediaSessionManagerProxy::mediaSessionWillBeginPlayback will call
completionHandler(false). This leads to AudioContext::resumeRendering
to be called with willBegin == false and the resume() promise is stored
until some point when the context starts running again.
This storage of the promise is what causes the resume() promise to
hang in the test JS.

setActive(true) ran synchronously before clientWillBeginPlayback() until
clientWillBeginPlayback was made asynchronous. Restore that ordering by calling
setActive(true) before clientWillBeginPlayback(), matching
HTMLMediaElement::playInternal(). This sends AddMediaSession ahead of
MediaSessionWillBeginPlayback so the UI-process manager can find the session.

The this fixes the following tests with site isolation enabled:

http/tests/security/webaudio-render-remote-audio-allowed-crossorigin-redirect.html
http/tests/security/webaudio-render-remote-audio-allowed-crossorigin.html
http/tests/security/webaudio-render-remote-audio-blocked-no-crossorigin-redirect.html
http/tests/security/webaudio-render-remote-audio-blocked-no-crossorigin.html

* LayoutTests/platform/ios-site-isolation/TestExpectations:
* Source/WebCore/Modules/webaudio/AudioContext.cpp:
(WebCore::AudioContext::willBeginPlayback):

Canonical link: https://commits.webkit.org/317386@main
https://bugs.webkit.org/show_bug.cgi?id=319615

Reviewed by Alejandro G. Castro.

Take a damage region in paint() and limit the draws to it. No region paints
everything, as before. An empty region paints nothing, because the target already
holds the frame. Otherwise every content draw limits itself to the region's rects:
the backing store's tiles and the contents image split by rect and stay batched,
the solid color, the hole punch and the tiled shader draw once per rect, and the
composite of a filtered or masked layer's intermediate surface is limited the same
way.

The walk deliberately does not clip the canvas to the damage, because a clip of more
than one rect cannot be a scissor, so Skia would build a mask for it and break the
batching. Each draw limits itself instead, which is a convention every content type
added here has to follow. The subtree of a filtered layer keeps painting in full,
because the filter samples outside the damage, and only the composite of its result
is limited.

A region that covers the whole surface is dropped for a full repaint. The region
itself decides that, not its bounding box: two rects in opposite corners span a box
that covers the surface while the rects cover almost none of it.

The compositor still passes no region, so nothing is restricted yet.
Added a new API test to cover damaging + HiDPI.

* Source/WebCore/platform/graphics/skia/SkiaCompositingLayer.cpp:
(WebCore::SkiaCompositingLayer::paint):
(WebCore::SkiaCompositingLayer::paintContents):
(WebCore::SkiaCompositingLayer::paintWithIntermediateSurface):
* Source/WebCore/platform/graphics/skia/SkiaCompositingLayer.h:
* Source/WebCore/platform/graphics/skia/SkiaDamageRegion.h:
(WebCore::SkiaDamageRegion::create):
(WebCore::SkiaDamageRegion::SkiaDamageRegion):
(WebCore::SkiaDamageRegion::operator=):
(WebCore::SkiaDamageRegion::forEachDamagedSubRect const):
(WebCore::SkiaDamageRegion::restrictDraw const):
(WebCore::drawRectRestricted):
(WebCore::drawImageRectRestricted):
* Tools/TestWebKitAPI/Tests/WebCore/glib/SkiaCompositingLayerDamage.cpp:
(TestWebKitAPI::TEST(SkiaCompositingLayerDamage, PartialRepaintRegionUnderHiDPIRestrictsToTheDamageRect)):

Canonical link: https://commits.webkit.org/317387@main
https://bugs.webkit.org/show_bug.cgi?id=319626
rdar://problem/182450492

Reviewed by Alan Baradlay.

https://drafts.csswg.org/css-grid-1/#extra-space

This is the very first implementation and focuses the new function on
specifically distributing space to the base sizes of the tracks. The
basic idea is that we just through each item and the track is spans,
then add extra space to the tracks so that the total size of the area is
enough to fit its contribution.

Steps 2.3 and 2.4 (distribute to non-affected tracks / distribute beyond limits) are left as
notImplemented() lambdas since neither can fire for the reachable cases today: only items spanning
a single track are supported, and the affected flexible tracks that reach this step still have
infinite growth limits, so step 2.2 absorbs the entire space.

Canonical link: https://commits.webkit.org/317388@main
… is a permanent crash

https://bugs.webkit.org/show_bug.cgi?id=319576
rdar://182407431

Reviewed by Youenn Fablet.

315066@main made an incorrect assumption and skip on why removeCodedFramesInternal
can be called with an invalid end time.
The test added was skipped on debug when it shouldn't have been.

It is possible for the SourceBuffer's tracks to not overlap, as such the
buffered range after currentTime could be empty. This would have caused
buffered.maximumBufferedTime(); to return MediaTime::invalidTime and would
have caused the problem 315066@main attempted to fix.

We avoid the condition altogether by exiting the loop early if the buffered
intersection is empty, this was likely the primary root cause for 315066@main.

Additionally, we optimised the loop by calculating the intersected range
from the currentTime, so there's no need to skip unnecessarily the segments
prior currentTime later.

Covered by existing tests.

* LayoutTests/TestExpectations:
* Source/WebCore/platform/graphics/SourceBufferPrivate.cpp:
(WebCore::SourceBufferPrivate::evictFrames):

Canonical link: https://commits.webkit.org/317389@main
https://bugs.webkit.org/show_bug.cgi?id=319621
rdar://182446375

Reviewed by Keith Miller.

The >= 1 MB zeroed path leaves pages zero-fill-on-demand (madvise(MADV_ZERO)
or the mmap fallback), so a page is only observed zero when first faulted.
The other tests read and write ascending, so they only ever fault pages in
ascending order -- but a hashtable, the workload where this matters, reads
its buckets in hash order, i.e. effectively at random.

Add a test that puts dirty data under a large region (allocate, dirty,
free), reallocates the same size so the zeroed path runs over that dirty
backing, then verifies the buffer reads zero while first-faulting its pages
in ascending, descending, and deterministically shuffled orders, under both
immediate free-list reuse and forced decommit/recommit, across the
threshold and a multi-megabyte size. The reused-buffer check and the shared
reuse case gain an optional FaultOrder parameter; the generic runs keep the
default ascending scan.

* Source/bmalloc/libpas/src/test/AllocationZeroingTests.cpp:
(addAllocationZeroingTests):

Canonical link: https://commits.webkit.org/317390@main
https://bugs.webkit.org/show_bug.cgi?id=319433
rdar://182250995

Reviewed by Eric Carlson.

Currently, WebKit fails WebVTT WPT 2_cues_overlapping_partially_move_up.html
and 2_cues_overlapping_partially_move_down.html. These tests check that when
a VTT file uses the line setting to position cues such that they overlap,
the browser moves the second cue as minimally as possible so that they do not overlap.

The rendered cues' top and bottom edges should be flush with each other, since the spec
expects the cue to be moved minimally and makes no indication that we should be
rounding to the nearest integer. However, WebKit's rendering of these vtt files
puts a gap between the two cues. This is caused by our use of integers in RenderVTTCue.
We should instead use floats.

No new test expectations due to bugs in the wpt tests that cause us to still fail them.
One a future patch fixes the tests the expectations will be updated.

* Source/WebCore/rendering/RenderVTTCue.cpp:
(WebCore::RenderVTTCue::unroundedAbsoluteBoundingBoxRect):
(WebCore::RenderVTTCue::isOutside const):
(WebCore::RenderVTTCue::rectIsWithinContainer const):
(WebCore::RenderVTTCue::overlappingObject const):
(WebCore::RenderVTTCue::overlappingObjectForRect const):
(WebCore::RenderVTTCue::moveIfNecessaryToKeepWithinContainer):
(WebCore::RenderVTTCue::findNonOverlappingPosition const):
(WebCore::RenderVTTCue::repositionCueSnapToLinesNotSet):
* Source/WebCore/rendering/RenderVTTCue.h:

Canonical link: https://commits.webkit.org/317391@main
https://bugs.webkit.org/show_bug.cgi?id=319594

Reviewed by Yusuke Suzuki.

DataView.prototype.getBigInt64 / getBigUint64 / setBigInt64 / setBigUint64
were the only DataView accessors without JIT intrinsics, so every call was
a C++ host call.

This handles them as the byteSize == 8 integer case of the existing
DataViewGetInt / DataViewSet nodes. Gets do the 64-bit load and byte swap
inline and box the result via operationInt64ToBigInt / newly added
operationUInt64ToBigInt. Sets speculate the value as HeapBigInt and store its
low 64 bits (toBigInt64), which is exactly the ToBigInt64 / ToBigUint64
wrapping the spec requires.

                                       Baseline                  Patched

data-view-bigint64-byte-swap      146.5305+-4.5918     ^     30.7756+-0.1811        ^ definitely 4.7613x faster
data-view-set-bigint64            127.1115+-1.1375     ^     15.5786+-1.0692        ^ definitely 8.1593x faster
data-view-get-bigint64            135.3561+-0.8063     ^     56.3917+-0.4440        ^ definitely 2.4003x faster

Tests: JSTests/microbenchmarks/data-view-bigint64-byte-swap.js
       JSTests/microbenchmarks/data-view-get-bigint64.js
       JSTests/microbenchmarks/data-view-set-bigint64.js
       JSTests/stress/dataview-jit-bigint64-byte-offset.js
       JSTests/stress/dataview-jit-bigint64-cse-and-aliasing.js
       JSTests/stress/dataview-jit-bigint64-type-check-failures.js
       JSTests/stress/dataview-jit-bigint64.js

* JSTests/microbenchmarks/data-view-bigint64-byte-swap.js: Added.
(byteSwap64):
* JSTests/microbenchmarks/data-view-get-bigint64.js: Added.
(getInt64):
(getUint64):
* JSTests/microbenchmarks/data-view-set-bigint64.js: Added.
(setInt64):
(setUint64):
* JSTests/stress/dataview-jit-bigint64-byte-offset.js: Added.
(shouldBe):
(shouldThrow):
(get dv):
(set dv):
* JSTests/stress/dataview-jit-bigint64-cse-and-aliasing.js: Added.
(shouldBe):
(getSetGet):
(getTwice):
(getArrayStoreGet):
* JSTests/stress/dataview-jit-bigint64-type-check-failures.js: Added.
(shouldBe):
(shouldThrow):
(get dv):
(set dv):
(shouldBe.get dv):
* JSTests/stress/dataview-jit-bigint64.js: Added.
(shouldBe):
(shouldThrow):
(toUint64):
(toInt64):
(refSetBigUint64):
(getBE):
(getDefault):
(getVar):
(setLE):
(setBE):
(setDefault):
(setVar):
(oobGet):
(oobSet):
(setAny):
(shouldBe.view.getBigUint64):
(shouldThrow.rget):
(shouldThrow.rset):
(gcGet):
(view.setBigUint64):
(setZero):
* Source/JavaScriptCore/b3/B3AbstractHeapRepository.h:
* Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
* Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::handleIntrinsicCall):
* Source/JavaScriptCore/dfg/DFGDoesGC.cpp:
(JSC::DFG::doesGC):
* Source/JavaScriptCore/dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* Source/JavaScriptCore/dfg/DFGOperations.cpp:
(JSC::DFG::JSC_DEFINE_JIT_OPERATION):
* Source/JavaScriptCore/dfg/DFGOperations.h:
* Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileCompareStrictEq):
* Source/JavaScriptCore/runtime/Intrinsic.h:
* Source/JavaScriptCore/runtime/JSDataViewPrototype.cpp:

Canonical link: https://commits.webkit.org/317392@main
…ilable

https://bugs.webkit.org/show_bug.cgi?id=319613

Reviewed by Keith Miller.

Add "//@ skip if not $jitTests" for skipping stress tests using
`numberOfDFGComples` when JIT is unavailable to fix ARMv7 EWS.

* JSTests/stress/promise-prototype-catch-on-non-promise.js:
* JSTests/stress/regexp-prototype-symbol-search-on-non-regexp.js:
* JSTests/stress/regexp-prototype-test-on-non-regexp.js:
* JSTests/stress/string-replace-regexp-with-own-property.js:

Canonical link: https://commits.webkit.org/317393@main
https://bugs.webkit.org/show_bug.cgi?id=319635
rdar://182030086

Reviewed by Keith Miller.

In MacroAssemblerARM64, ldrb's signature is (RegisterID dest, RegisterID rn,
RegisterID rm), where rn is the offset register and rm is the memory base
register.

branchTest{8,16} currently passes them in the opposite order, and this PR swaps
it for clarity.

There is no test for this codegen.

* Source/JavaScriptCore/assembler/MacroAssemblerARM64.h:
(JSC::MacroAssemblerARM64::branchTest8):
(JSC::MacroAssemblerARM64::branchTest16):

Canonical link: https://commits.webkit.org/317394@main
…mation updates

https://bugs.webkit.org/show_bug.cgi?id=319670
rdar://182514341

Reviewed by Simon Fraser.

* Source/WTF/wtf/SystemTracing.h:
* Source/WTF/wtf/glib/SysprofAnnotator.h:
* Source/WebKit/Resources/Signposts/SystemTracePoints.plist:
* Source/WebKit/UIProcess/RemoteLayerTree/ios/RemoteScrollingCoordinatorProxyIOS.mm:
(WebKit::RemoteScrollingCoordinatorProxyIOS::updateAnimationStacks):
* Source/WebKit/UIProcess/RemoteLayerTree/mac/RemoteLayerTreeEventDispatcher.mm:
(WebKit::RemoteLayerTreeEventDispatcher::updateAnimations):

Canonical link: https://commits.webkit.org/317395@main
robobun added a commit to oven-sh/bun that referenced this pull request Jul 17, 2026
… memory transfer

WebKit: re-merged upstream/main at 2603e9eb41f0 (84 more commits, 22 in
JSC/WTF/bmalloc, incl. MicrotaskCallCache for the async-generator driver
path, DataView BigInt64 DFG/FTL, YARR backtracking fixes, libpas zeroing
tests). No conflicts. oven-sh/WebKit#300 head is now 4559ebe7e2.

Bun:
- Set Options::useTemporal() = false in the JSC options callback so
  Temporal stays off by default despite upstream flipping it on.
  BUN_JSC_useTemporal=1 still enables it for opt-in testing.
- Reinstate an isWasmMemory() gate in SerializedScriptValue so a
  WebAssembly.Memory buffer in a transfer list throws TypeError (per the
  spec's [[ArrayBufferDetachKey]] requirement) while Bun-pinned buffers
  still fall through to transferTo()'s copyTo() fallback.
- Bump WEBKIT_VERSION to autobuild-preview-pr-300-4559ebe7.

Tests: temporal-global.test.ts now covers the default-off + opt-in-on
split; structured-clone.test.ts gained a WebAssembly.Memory transfer
rejection case.
@robobun robobun changed the title Upgrade to upstream WebKit c8b6308aaa69 Upgrade to upstream WebKit 2603e9eb41f0 Jul 17, 2026

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both prior findings look fixed in a67975c — the TimeZone.cpp stub guard now keys on OS(DARWIN), and AsyncGeneratorDriverResume has the async-context wrap/unwrap matching its siblings. No new issues surfaced on this pass, but a 211-commit upstream merge with 22 hand-resolved conflicts across the JIT tiers, GC, DeferredWorkTimer, and the async/microtask runtime is well beyond what I'd sign off on without a human look.

What was reviewed:

  • Re-checked the TimeZone.cpp / PlatformUse.h / PlatformJSCOnly.cmake interaction — OS(DARWIN) now matches the CMake APPLE gate, so the macOS JSCOnly build gets exactly one listenForTimeZoneChangeNotifications definition.
  • Re-checked JSMicrotask.cpp — the AsyncGeneratorDriverResume enqueue sites and dispatch case now carry m_asyncContextData under USE(BUN_JSC_ADDITIONS) like the other resume-body cases.
  • Scanned the remaining conflict-resolution files (DeferredWorkTimer, PropertySlot.h LastAttribute, RunLoopGeneric.cpp, CMakeLists) and the Bun-hook call sites for the new WeakTicket / scheduleWorkSoonIfActive API — nothing further stood out.
Extended reasoning...

Overview

This PR merges upstream WebKit d81bcc3d833c..c8b6308aaa69 (211 commits touching JSC/WTF/bmalloc, ~300 files in the diff) into the Bun fork. It is not a mechanical merge: 22 files conflicted and were hand-resolved, several of them at Bun's integration seams — DeferredWorkTimer (Ticket → ThreadSafeWeakPtr refactor with Bun's onAddPendingWork/onScheduleWorkSoon/onCancelPendingWork hooks re-plumbed), JSMicrotask.cpp (new MicrotaskCallCache* threading + asyncFunctionGeneratorBodyCall extraction interleaved with Bun's async-context save/restore), JSDateMath/PlatformUse.h/TimeZone.cpp (time-zone-change detection moved to WTF), PropertySlot.h (LastAttribute sentinel vs. Bun's Constructable bit), RunLoopGeneric.cpp under USE(BUN_EVENT_LOOP), and the JSC CMakeLists.txt. Upstream also enables Temporal by default, adds a LoadMegamorphicGetter IC, reworks Air arg/inst layout, and introduces the cooperative async-generator driver that my earlier finding was about.

Security risks

The upstream range includes JIT codegen changes (new IC kind, Air layout shrink, B3 WasmGC allocation elimination, YARR register reshuffle), GC marking pipelining, and libpas fixes. None of the Bun-side conflict resolutions introduce new attack surface on their own, but mis-merged JIT/GC code is exactly the class of change where a subtle error becomes a memory-safety bug. The two issues found on the first pass were a build break and an async-context correctness regression — not security bugs — and both are now addressed. I did not identify any injection, auth, or data-exposure surface; the risk here is entirely in engine correctness/memory-safety, which is inherent to the upstream content rather than the merge mechanics.

Level of scrutiny

High. This is the core JS engine for a production runtime, the diff is ~700 KB, and the interesting parts are precisely the 22 hand-resolved conflicts plus any upstream additions that silently bypass Bun's USE(BUN_JSC_ADDITIONS) hooks (the AsyncGeneratorDriverResume case was one such — it caused no textual conflict). That combination puts it firmly outside "approve without a human look." The preview autobuilds passing on both post-fix commits is a good signal that the platform-guard fix took, but CI can't validate the semantics of the conflict resolutions.

Other factors

On the previous run I flagged two issues; robobun fixed both in a67975c412, resolved the threads, and added Bun-side AsyncLocalStorage + for await coverage. This run's bug-hunting pass over the updated branch found nothing new, and I spot-checked the fixes against the described root causes — they match the pattern used by the sibling code. Given the scope, the right outcome is a human review of the conflict-resolution hunks (particularly DeferredWorkTimer.{h,cpp}, JSMicrotask.cpp, and the CMake re-application) rather than an automated approval.

Resolves the Lookup.cpp conflict by taking main's #306 version of
setUpStaticFunctionSlot: both branches independently dropped the
ThrowScope from the reifyStaticProperty call site; main's version
checks vm.exceptionForInspection() directly and keeps the original
RELEASE_ASSERT_NOT_REACHED for the no-exception-but-no-offset case.

Also brings in #304 (Windows WallTime/MonotonicTime) and #310
(preCommitStackMemory guard).
@sosukesuzuki
sosukesuzuki merged commit a0e65bf into main Jul 19, 2026
49 checks passed
Comment on lines +65 to +71
async function* g() { yield 1; yield 2; yield 3; }
const it = g();
const first = await it.next(); // manual drive one step
log.push("manual:" + first.value);
for await (const x of it) log.push("v" + x); // for-await consumes the rest via the same iterator
return log;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 The a67975c fix for the AsyncGeneratorDriverResume async-context regression is incomplete: wrapWithCurrent at JSMicrotask.cpp:491 runs at dequeue time inside the producer's AsyncContextSwapScope (from the AsyncGeneratorYieldAwaited/BodyCallNormal dispatch cases), so it captures the producer's context — while the generator-queue enqueue at line 636 still stores the driver raw. When the generator is already Executing when for await starts (e.g. a prior .next() under context X, then for await under context Y), the consumer's loop body resumes under X instead of Y. Fix: wrap the driver at line 636 (which runs under the consumer's context, like the completed-state branch at 628-632 already does) and use the dequeued target's captured context in asyncGeneratorCompleteStep instead of wrapWithCurrent.

Extended reasoning...

What the bug is

Commit a67975c addressed the earlier review finding that InternalMicrotask::AsyncGeneratorDriverResume had no Bun async-context handling. It added the standard unwrap+swap block to the dispatch case (JSMicrotask.cpp:1998-2005), wrapped the driver in the completed-state fast path of enqueueAsyncGeneratorDriver (line 628-632), and — for the general case — called AsyncContextSwapScope::wrapWithCurrent in asyncGeneratorCompleteStep at line 491, i.e. at the point where a driver is dequeued from the generator's queue and an AsyncGeneratorDriverResume microtask is scheduled.

The problem is that line 491 executes inside the producer's async-context swap scope, not the consumer's. asyncGeneratorCompleteStep is reached synchronously from asyncGeneratorYield / asyncGeneratorBodyCall, which are invoked from the AsyncGeneratorYieldAwaited and AsyncGeneratorBodyCallNormal dispatch cases (lines 1954-1973). Each of those cases constructs an AsyncContextSwapScope from the context the producer captured on its own earlier await (via resolveWithInternalMicrotaskForAsyncAwait at lines 716/721). So wrapWithCurrent at line 491 reads back whatever context the producer was running under — not the context the consumer was in when it enqueued the driver.

Meanwhile, the actual enqueue site — iterator->enqueue(vm, jsUndefined(), NormalMode, driver) at line 636 — runs synchronously from op_async_iterator_next under the consumer's context, but stores the driver raw with no capture.

Why the common case still works

When the generator is idle (Init / SuspendedYield) at the time for await calls next, line 639 is true and asyncGeneratorResume runs the producer synchronously under the consumer's context. Every subsequent producer await captures that same context, so when line 491 later runs it reads back the consumer's context by coincidence. This is why the new AsyncLocalStorage.test.ts cases added alongside a67975c pass.

The failing case

When the generator is already Executing/Awaiting at the time for await starts, none of that propagation happens:

  • asyncIteratorOpenTryFastImpl (CommonSlowPaths.cpp:959-996) checks only JSAsyncGeneratorType + primordial @@asyncIterator/.next + species watchpoint; it does not check generator state, so an already-executing generator still gets the FastAsyncGenerator sentinel.
  • enqueueAsyncGeneratorDriver: state is not Completed (skip 626-633) and not Init/SuspendedYield (line 639 false), so line 636 enqueues the raw driver under the consumer's context Y and returns without resuming.
  • asyncFunctionArrangeAwaitResume (line 1632) sees the fast sentinel and returns early — the consumer's own await-time ForAsyncAwait capture, which pre-merge would have snapshotted Y, is bypassed.
  • Later the producer's pending await resolves → AsyncGeneratorBodyCallNormal/YieldAwaited restores the producer's context X → the generator runs to a yield or completion → asyncGeneratorCompleteStep dequeues the driver → line 491 wrapWithCurrent captures XAsyncGeneratorDriverResume dispatch (1998-2005) restores X → the consumer's loop body runs under X instead of Y.

Step-by-step proof

async function* g() { await sleep(10); yield 1; yield 2; }
const it = g();
als.run(X, () => { it.next(); });                 // (1)
als.run(Y, async () => {
  for await (const v of it)                       // (2)
    console.log(als.getStore());                  // prints X, expected Y
});
  1. Manual .next() under X → asyncGeneratorResume runs the producer synchronously under X; producer hits await sleep(10)resolveWithInternalMicrotaskForAsyncAwait captures X; state = Executing/Await; queue = [JSPromise-for-manual-next].
  2. for await under Y → op_async_iterator_open stamps the fast sentinel (no state check) → op_async_iterator_nextenqueueAsyncGeneratorDriver: state is Await, so line 636 enqueues the raw driver; line 639 false, no resume. Consumer suspends; its own await-time capture is skipped by the sentinel early-return.
  3. sleep resolves → AsyncGeneratorBodyCallNormal restores X, producer resumes and reaches yield 1AsyncGeneratorYieldAwaited (also captured X) → asyncGeneratorYieldasyncGeneratorCompleteStep dequeues the manual-next JSPromise and resolves it. Queue still has [driver]; asyncGeneratorYield line 671 sees the queue non-empty and re-enters the producer without suspending. Producer reaches yield 2asyncGeneratorCompleteStep dequeues driver → line 491 wrapWithCurrent reads m_asyncContextData, which is X (set by the enclosing swap scope) → schedules AsyncGeneratorDriverResume(driver-wrapped-with-X).
  4. Dispatch case 1998-2005 unwraps X, swaps it in, and resumes the consumer → als.getStore() returns X.

Pre-merge, step (2) would have called real .next() returning a JSPromise, and the consumer's own implicit await would have gone through resolveWithInternalMicrotaskForAsyncAwait capturing Y at .then()-time (Node.js semantics). Post-merge the fast path skips that entirely; the only capture point is line 491, under the producer's scope.

The same failure applies to two concurrent for await loops from different contexts on the same generator: the second loop's driver is enqueued while state=Executing (from the first loop) and later dequeued under the first loop's propagated context.

Fix

The original review comment recommended capturing "at the enqueue sites". a67975c did this correctly for the completed-state branch (line 628-632, which runs under the consumer's context) but placed the general capture at the wrong end of the queue. To fix:

  • At line 636, wrap the driver with the current async context (e.g. via InternalFieldTuple, matching line 629). This is the point that runs under the consumer's context. JSAsyncGenerator::enqueue/dequeue may need to accept a JSValue target under USE(BUN_JSC_ADDITIONS).
  • In asyncGeneratorCompleteStep, when the dequeued target is a driver, pass it through as-is (it is already wrapped) instead of calling wrapWithCurrent on the ambient context.

robobun added a commit to oven-sh/bun that referenced this pull request Jul 19, 2026
Replaces the preview tag now that the WebKit upgrade PR has landed on
oven-sh/WebKit main. The merged commit also carries oven-sh/WebKit#304
(Windows WallTime/MonotonicTime), #306 (reifyStaticProperty ThrowScope
drop on main) and #310 (preCommitStackMemory guard).
robobun added a commit to oven-sh/bun that referenced this pull request Jul 19, 2026
Resolves the WEBKIT_VERSION conflict: main bumped to 639550acdc via
#34669; this branch already pointed at a0e65bf298 (the squash-merge of
oven-sh/WebKit#300, which has 639550acdc as its parent). Keep
a0e65bf298 in main's bare-sha format.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.