Bug 297721

Summary: Safari Technology Preview 226 breaks espn.com title bar
Product: WebKit Reporter: Jeff Johnson <opendarwin>
Component: New BugsAssignee: rupin
Status: RESOLVED FIXED    
Severity: Normal CC: ahmad.saleem792, annevk, karlcow, w0nka, webkit-bug-importer
Priority: P2 Keywords: InRadar
Version: Safari Technology Preview   
Hardware: Mac (Apple Silicon)   
OS: macOS 15   
Attachments:
Description Flags
Screenshot of STP 226 on espn.com
none
Screenshot of Safari on espn.com
none
WebKit ToT (Reference) - Does not reproduce
none
rendering in STP 225.
none
rendering in STP 226.
none
rendering in minibrowser
none
ESPN navigation still broken in STP 229
none
rendering in Safari
none
Safari vs Chrome Navigation API
none
ESPN with Navigation Feature Flagged States none

Jeff Johnson
Reported 2025-08-21 06:03:33 PDT
Created attachment 476471 [details] Screenshot of STP 226 on espn.com The sports categories are missing from the black title bar on espn.com in Safari Technology Preview 226. This bug does not occur in Safari 18.6 or in Safari Technology Preview 224 (nor in 225, I believe). I've reproduced this bug on two different Macs. See the attached screenshots of STP and Safari.
Attachments
Screenshot of STP 226 on espn.com (88.58 KB, image/png)
2025-08-21 06:03 PDT, Jeff Johnson
no flags
Screenshot of Safari on espn.com (109.41 KB, image/png)
2025-08-21 06:03 PDT, Jeff Johnson
no flags
WebKit ToT (Reference) - Does not reproduce (130.87 KB, image/png)
2025-08-21 13:11 PDT, Ahmad Saleem
no flags
rendering in STP 225. (3.73 MB, image/png)
2025-08-21 16:28 PDT, Karl Dubost
no flags
rendering in STP 226. (4.08 MB, image/png)
2025-08-21 16:28 PDT, Karl Dubost
no flags
rendering in minibrowser (3.90 MB, image/png)
2025-08-21 16:33 PDT, Karl Dubost
no flags
ESPN navigation still broken in STP 229 (144.91 KB, image/jpeg)
2025-10-03 08:00 PDT, Jack Wellborn
no flags
rendering in Safari (552.11 KB, image/png)
2025-10-14 00:16 PDT, Karl Dubost
no flags
Safari vs Chrome Navigation API (110.42 KB, image/png)
2025-10-14 05:59 PDT, Jack Wellborn
no flags
ESPN with Navigation Feature Flagged States (591.27 KB, image/png)
2025-10-14 13:10 PDT, Jack Wellborn
no flags
Jeff Johnson
Comment 1 2025-08-21 06:03:49 PDT
Created attachment 476472 [details] Screenshot of Safari on espn.com
Ahmad Saleem
Comment 2 2025-08-21 13:11:02 PDT
Created attachment 476478 [details] WebKit ToT (Reference) - Does not reproduce Definitely broken on Safari Technology Preview 226 but it seems to be fixed already on ToT since I am unable to reproduce. @Karl - by any chance, you are able to reproduce?
Karl Dubost
Comment 3 2025-08-21 16:28:23 PDT
Created attachment 476483 [details] rendering in STP 225.
Karl Dubost
Comment 4 2025-08-21 16:28:49 PDT
Created attachment 476484 [details] rendering in STP 226.
Karl Dubost
Comment 5 2025-08-21 16:33:15 PDT
Created attachment 476485 [details] rendering in minibrowser yesterday minibrowser. Version: commit 7707c83355e323c15a209c63358b5fe6f0167f7a Date: Wed Aug 20 22:29:09 2025 -0700 It's working.
Karl Dubost
Comment 6 2025-08-21 16:40:40 PDT
In the case this is happening. ``` <nav id="global-nav" data-loadtype="client" data-wayfindsport=""> <ul class="espnww-en" itemscope="" itemtype="http://www.schema.org/SiteNavigationElement" style="display: block;"> </ul> </nav> ``` The list for the navigation bar is not being populated at all.
Karl Dubost
Comment 7 2025-08-21 16:47:53 PDT
There are a couple of fonts being blocked over insecure requests http instead of https, but not sure that is the main reason. [Warning] The resource https://a.espncdn.com/fonts/1.0.74/ESPNIcons/ESPNIcons.woff2 was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it wasn't preloaded for nothing. [Warning] The resource https://cdn.registerdisney.go.com/v4/asset/bundler/ESPN/v4/images/v2/espn-red-logo.svg was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it wasn't preloaded for nothing. [Warning] [blocked] The page at https://global.espn.com/ requested insecure content from http://a.espncdn.com/fonts/_Ignite/ESPNIgniteTextCondensed-Bold-Web.woff2. This content was blocked and must be served over HTTPS. (x2) [Warning] [blocked] The page at https://global.espn.com/ requested insecure content from http://a.espncdn.com/fonts/_Ignite/ESPNIgniteTextCondensed-Bold-Web.woff2. This content was blocked and must be served over HTTPS. (espn-critical.js, line 2) The menu is built with ``` if (container.html(html), container.attr("data-loadtype", "client"), "desktop" === type) { $("#global-nav > ul > li.sports").each(function() { $(this).find("div > ul:first > li:gt(8)").hide() }); var $newMore = $("<div></div>"), $editionGrouping = $("<div class='Editions__Group'></div>"); $("#global-nav .more-espn > div > ul > li").each(function() { var $moreUl = $(this).find("ul:first"), moreClass = $moreUl && $moreUl.attr("class"), $wrapped = $(this).wrap("<ul class='" + $(this).find("ul:first").attr("class") + "'></ul>").parent(); "editions" === moreClass || "featured" === moreClass ? ($editionGrouping.append($wrapped), "featured" === moreClass && $newMore.append($editionGrouping)) : $newMore.append($wrapped) }), $("#global-nav .more-espn div").html($newMore.html()), $("#global-nav .more-espn li.footer").parent().addClass("footer").wrap($("<div></div>").addClass("footer-wrapper")), $("#global-nav .more-espn > div > ul.featured > li").addClass("featured-links"), $("#global-nav .more-espn > div > ul.more-more").replaceWith($("#global-nav .more-espn > div > ul.more-more").find("div").first().addClass("footer-links")), $("div.footer-links ul").addClass("pipes"), $("#global-nav .teams:not(.fantasy) > div > ul").each(function() { var $newGroups = $("<ul></ul>"), items = $(this).find("li"); if (items.length > 0) for (var li = 0; li <= items.length - 1; li++) li > 0 && $(items[li]).hasClass("group") && ($(this).parents("div").first().append($newGroups), $newGroups = $("<ul></ul>")), $newGroups.append($(items[li])), li === items.length - 1 && $(this).parents("div").first().append($newGroups); $(this).remove() }); var fantasyContainer = $("#global-nav .teams.fantasy > div"), fantasyBreak = fantasyContainer.find("ul > li.division:gt(1):first"); if (fantasyBreak.length > 0) { var colData = fantasyBreak.nextAll(), newCol = $("<ul></ul>").append(fantasyBreak).append(colData); fantasyContainer.append(newCol) } $(".dropdown-group").each(function(lg, linkGroup) { var $target = $(linkGroup).parents("li.sports > div"); $target.length > 0 && $target.append(linkGroup) }), $("#global-nav .teams:not(.soccer)").each(function() { var $teams = $(this).clone().removeClass("sub"); $teams.find("a[data-sportabbrev]").first().remove(), $(this).find("div").remove(), $(this).parents("div").first().append($($teams).wrap("<ul></ul>").parent()) }), espn_ui.Helpers.nav.showPrimaryNav() } ```
Karl Dubost
Comment 8 2025-08-21 16:57:00 PDT
hmm but that seems to assume it has already been populated in ``` if (container.html(html), container.attr("data-loadtype", "client"), "desktop" === type) { $("#global-nav > ul > li.sports").each(function() { $(this).find("div > ul:first > li:gt(8)").hide() }); ``` so maybe it is before.
Karl Dubost
Comment 9 2025-08-21 16:59:22 PDT
hmm but that seems to assume it has already been populated in ``` if (container.html(html), container.attr("data-loadtype", "client"), "desktop" === type) { $("#global-nav > ul > li.sports").each(function() { $(this).find("div > ul:first > li:gt(8)").hide() }); ``` so maybe it is before.
Radar WebKit Bug Importer
Comment 10 2025-08-22 09:28:47 PDT
Karl Dubost
Comment 11 2025-08-26 00:22:45 PDT
I confirmed that this is working on a very recent build.
Jeff Johnson
Comment 12 2025-09-03 18:17:40 PDT
This bug still exists in Safari Technology Preview 227. Should that be happening?
Ahmad Saleem
Comment 13 2025-09-03 18:19:57 PDT
(In reply to Jeff Johnson from comment #12) > This bug still exists in Safari Technology Preview 227. Should that be > happening? I can also reproduce it in STP227 but definitely not on ToT when I tested but I can't reproduce it on ToT (Minibrowser).
Jeff Johnson
Comment 14 2025-09-06 07:28:20 PDT
(In reply to Ahmad Saleem from comment #13) > (In reply to Jeff Johnson from comment #12) > > This bug still exists in Safari Technology Preview 227. Should that be > > happening? > > I can also reproduce it in STP227 but definitely not on ToT when I tested > but I can't reproduce it on ToT (Minibrowser). According to https://webkit.org/blog/17324/release-notes-for-safari-technology-preview-227/ Safari Technology Preview 227 includes commits through https://commits.webkit.org/299099@main which was August 23. However, you and Karl said that you could not reproduce in WebKit ToT on August 21. Therefore, if the bug was fixed, the fix ought to be included in STP 227. Could there be some relevant difference between the WebKit Minibrowser and Safari Technology Preview?
Jeff Johnson
Comment 15 2025-09-17 18:16:39 PDT
This is STILL broken in Safari Technology Preview 228.
Jack Wellborn
Comment 16 2025-10-03 08:00:46 PDT
Created attachment 476954 [details] ESPN navigation still broken in STP 229 Looks like this is still not fixed in Safari Technology Preview 229.
Karl Dubost
Comment 17 2025-10-05 20:11:34 PDT
I can reproduce the issue on STP 229 too. Let's check the Quirks too. There are a couple of quirks but not related to ESPN on desktop and to the layout, so this is not the source of the difference. https://searchfox.org/wubkat/rev/dd05eb230972a07f0240b959e6e22ca685ef3445/Source/WebCore/page/Quirks.cpp#2564-2580 ```cpp static void handleESPNQuirks(QuirksData& quirksData, const URL& quirksURL, const String& quirksDomainString, const URL& documentURL) { if (quirksDomainString != "espn.com"_s) return; UNUSED_PARAM(quirksURL); UNUSED_PARAM(documentURL); quirksData.isESPN = true; #if PLATFORM(IOS) || PLATFORM(VISION) // espn.com rdar://problem/95651814 quirksData.allowLayeredFullscreenVideos = true; #endif #if ENABLE(VIDEO_PRESENTATION_MODE) // espn.com rdar://problem/73227900 quirksData.shouldDisableEndFullscreenEventWhenEnteringPictureInPictureFromFullscreenQuirk = true; #endif } ``` The navbar is not populated. SAFARI <nav id="global-nav" data-loadtype="client" data-wayfindsport=""> <ul class="espnww-en" itemscope="" itemtype="http://www.schema.org/SiteNavigationElement" style="display: block;"> </ul> </nav> FIREFOX <nav id="global-nav" data-loadtype="client" data-wayfindsport=""> <ul class="espnww-en" itemscope="" itemtype="http://www.schema.org/SiteNavigationElement" style="display: block;"> <li class="sports menu-soccer" itemprop="name"> <a tabindex="0" data-track-nav_item="football" data-track-nav_layer="global nav" itemprop="url" href="/football/" name="&amp;lpos=sitenavdefault+sitenav_soccer" data-icon="soccer"> <span> <span class="link-text">Football</span> <span class="link-text-short">Football</span> </span> </a> <!-- submenu control button (and wrapping element). accessibility (like aria attributes) and submenu controls applied via nav_submenu_button behavior --> <span class="submenu-indicator"> … </span> <!-- submenu-wrapper class is used by nav_submenu_button behavior to show and hide the menu element --> <div class="submenu-wrapper hide-submenu " id="submenu-sportsmenusoccer"> … </div> </li> REPEAT Multiple li <li>…</li> </ul> </nav> This is not user agent sniffing, aka giving chrome or firefox UA doesn't make it work.
Karl Dubost
Comment 18 2025-10-06 20:47:43 PDT
Ha maybe a hint. At a point it reaches a function in charge of parsing the navigation items. The first call is a reference to var nav = espn_ui.Helpers.nav.items, ``` processAPI: function(type) { var nav = espn_ui.Helpers.nav.items, sports = []; $(nav).each(function(i, item) { item.attributes && "sports" === item.attributes.menu && $(item.items).each(function(s, sport) { sports.push(sport) }) }); var newItems = []; if ("desktop" === type) if (customPrimary) { if (nav) for (var i = 0; i <= nav.length - 1; i++) newItems.push(nav[i]) } else for (var n = 1; n <= nav.length - 1; n++) { var items = nav[n].items; if (items) for (var i = 0; i <= items.length - 1; i++) newItems.push(items[i]) } else newItems = espn_ui.Helpers.nav.items; espn_ui.Helpers.nav.items = { items: newItems }, espn_ui.Helpers.nav.sports = sports }, ``` FIREFOX ``` nav Array(3) [ {…}, {…}, {…} ] 0: Object { id: 22025447, text: "ESPN Global Front Page", title: "Global Edition Homepage Menu", … } 1: Object { id: 21959721, title: "Global.espn.com Sports Menu", "$ref": "/v2/navigation/21959721", … } 2: Object { id: 22024775, title: "global.espn.com Pillar menu", "$ref": "/v2/navigation/22024775", … } length: 3 <prototype>: Array [] ``` SAFARI ``` > nav < [] (0) ``` so this espn_ui.Helpers.nav.items is empty in Safari. The content in my case is coming from https://secure.espn.com/core/format/modules/head/i18n?edition-host=global.espn.com&lang=en&region=ww&geo=jp&site=espn&site-type=full&type=ext&build=0.744.0.2 which is correctly fetched by WebKit. And the content is a valid JS file. So that will limit probably the scope for our next clues.
Karl Dubost
Comment 19 2025-10-14 00:16:57 PDT
Created attachment 477067 [details] rendering in Safari This is a dependency on navigation API.
Jack Wellborn
Comment 20 2025-10-14 05:59:37 PDT
Created attachment 477070 [details] Safari vs Chrome Navigation API I suspect this is the same conclusion you came to Karl, but the Navigation API issue you pointed out is because Safari both supports it, has `navigation` in window, and prevents it from being overridden. Chrome also supports the Navigation API and also has `navigation` in window, but lets it be overridden. Firefox doesn't support the Navigation API.
Anne van Kesteren
Comment 21 2025-10-14 07:30:40 PDT
Well, we did follow the specification... I filed https://github.com/whatwg/html/pull/11786 to improve that.
Jack Wellborn
Comment 22 2025-10-14 10:33:43 PDT
Thanks. This is now my go-to example of the challenges of being non-Chromium browser in a world dominated by Chrome. I'm sure the omission of [Replaceable] in the spec was an oversight, but had ESPN (or other sites) broke because this shipped in blue Safari, 99.999% of web devs wouldn't blame Chromium for being out of spec. They would be like "LOL Safari sux. Fix yer browser Apple." Webkit could have preemptively made `navigation` replaceable for website compatibility, but then it too would be out of spec, which would be even worse if/when Chromium one day decided to adhere to the current non-replaceable spec.
rupin
Comment 23 2025-10-14 11:36:12 PDT
rupin
Comment 24 2025-10-14 11:39:52 PDT
This reproduces on ToT WebKit (most recent commit is https://commits.webkit.org/301483@main). I'd expect it to reproduce on any build where the Navigation API is enabled. The comments above are correct about the issue: espn.com is re-assigning the "navigation" variable in this function: ``` preRender: function(type, navCached, defaultNavData) { ... navigation = defaultNavData.navigation ... espn_ui.Helpers.nav.items = navigation.items } ``` which fails because "navigation" is not replaceable. And so the title bar ends up empty. To fix it, we make it replaceable: https://github.com/WebKit/WebKit/pull/52313
Jack Wellborn
Comment 25 2025-10-14 13:10:32 PDT
Created attachment 477075 [details] ESPN with Navigation Feature Flagged States You can also validate the behavior by toggling the feature flag.
EWS
Comment 26 2025-10-15 21:36:04 PDT
Committed 301607@main (ae143edf7fbe): <https://commits.webkit.org/301607@main> Reviewed commits have been landed. Closing PR #52313 and removing active labels.
Note You need to log in before you can comment on or make changes to this bug.