diff --git a/mobile/modules/orca-mobile-web-shell/ios/MobileWebShellNavigationPolicy.swift b/mobile/modules/orca-mobile-web-shell/ios/MobileWebShellNavigationPolicy.swift
index 7d0005e30e5..5ca4a5f156c 100644
--- a/mobile/modules/orca-mobile-web-shell/ios/MobileWebShellNavigationPolicy.swift
+++ b/mobile/modules/orca-mobile-web-shell/ios/MobileWebShellNavigationPolicy.swift
@@ -41,9 +41,9 @@ enum MobileWebShellNavigationPolicy {
/// WKWebView, off-device: a sandboxed subframe navigating the top frame to the document URL
/// arrives as `.other` with no gesture at all, and under a gesture-shaped rule that is an allow
/// and a shell reload -- the bridge target cleared, the load state restarted, the page's state
- /// gone. `isFromSubframe` is the second discriminator for the same reason: the same probe shows
- /// the shell's own load arriving with source and target both the main frame, and a subframe's top
- /// navigation arriving with the subframe as its source.
+ /// gone. The initiating frame is deliberately not an input: before iOS 18.5 WebKit reports no
+ /// source frame for the view's own `load` (WebKit c28b242), and reading it refused the shell's
+ /// own document. The one-shot flag already refuses a subframe's top navigation, as on Android.
///
/// What is left for the gesture is the only thing an artifact may ask for: a foreign URL, which
/// is refused and handed to the opener. A download is not a document load, so it takes that path
@@ -56,7 +56,6 @@ enum MobileWebShellNavigationPolicy {
static func verdict(
url: String?,
isMainFrame: Bool,
- isFromSubframe: Bool,
isDocumentUrl: Bool,
isShellLoad: Bool,
hasGesture: Bool,
@@ -66,7 +65,7 @@ enum MobileWebShellNavigationPolicy {
return .cancel
}
if isDocumentUrl {
- return isShellLoad && !isFromSubframe && !isDownload ? .allow : .cancel
+ return isShellLoad && !isDownload ? .allow : .cancel
}
guard hasGesture, let offered = offerableUrl(url) else {
return .cancel
diff --git a/mobile/modules/orca-mobile-web-shell/ios/MobileWebShellView.swift b/mobile/modules/orca-mobile-web-shell/ios/MobileWebShellView.swift
index e5575b36e2a..6ed13b44610 100644
--- a/mobile/modules/orca-mobile-web-shell/ios/MobileWebShellView.swift
+++ b/mobile/modules/orca-mobile-web-shell/ios/MobileWebShellView.swift
@@ -479,7 +479,6 @@ final class OrcaMobileWebShellView: ExpoView, WKNavigationDelegate, WKUIDelegate
let verdict = MobileWebShellNavigationPolicy.verdict(
url: navigationAction.request.url?.absoluteString,
isMainFrame: navigationAction.targetFrame?.isMainFrame == true,
- isFromSubframe: !navigationAction.sourceFrame.isMainFrame,
isDocumentUrl: isDocumentUrl(navigationAction.request.url),
isShellLoad: loadState.isShellLoad,
hasGesture: navigationAction.navigationType == .linkActivated,
diff --git a/mobile/modules/orca-mobile-web-shell/tests/MobileWebShellChecks.swift b/mobile/modules/orca-mobile-web-shell/tests/MobileWebShellChecks.swift
index 81afd6fdfc6..be70ef8d184 100644
--- a/mobile/modules/orca-mobile-web-shell/tests/MobileWebShellChecks.swift
+++ b/mobile/modules/orca-mobile-web-shell/tests/MobileWebShellChecks.swift
@@ -545,7 +545,6 @@ import Foundation
func verdict(
_ url: String? = "https://example.com/artifact-link",
isMainFrame: Bool = true,
- isFromSubframe: Bool = false,
isDocumentUrl: Bool = false,
isShellLoad: Bool = false,
hasGesture: Bool = true,
@@ -554,7 +553,6 @@ import Foundation
MobileWebShellNavigationPolicy.verdict(
url: url,
isMainFrame: isMainFrame,
- isFromSubframe: isFromSubframe,
isDocumentUrl: isDocumentUrl,
isShellLoad: isShellLoad,
hasGesture: hasGesture,
@@ -571,18 +569,14 @@ import Foundation
// navigating the top frame to the document URL arrives with no gesture at all.
precondition(verdict(document, isDocumentUrl: true, hasGesture: false) == .cancel)
precondition(verdict(document, isDocumentUrl: true, hasGesture: true) == .cancel)
- precondition(
- verdict(document, isFromSubframe: true, isDocumentUrl: true, isShellLoad: true, hasGesture: false)
- == .cancel
- )
- // The second discriminator, on its own: a load the shell did not start is refused even when the
- // initiating frame is the main one, which is the page rewriting its own document away.
+ // A load the shell did not start is refused whichever frame initiated it: the page rewriting
+ // its own document away, or the sealed preview navigating the top frame.
precondition(verdict(document, isDocumentUrl: true, isShellLoad: false, hasGesture: false) == .cancel)
// A top-page meta refresh or a redirect to somewhere else: refused, and never opened.
precondition(verdict(hasGesture: false) == .cancel)
// A tap inside the sealed preview is exactly a subframe-initiated foreign navigation, and that
// is the one thing the artifact is allowed to ask for.
- precondition(verdict(isFromSubframe: true) == .cancelAndOffer(foreign))
+ precondition(verdict() == .cancelAndOffer(foreign))
// A download is not a document load, so it is refused there rather than allowed; started by a
// tap it reaches the opener, which is what makes `` behave as it does natively.
precondition(
@@ -591,11 +585,8 @@ import Foundation
)
precondition(verdict(isDownload: true) == .cancelAndOffer(foreign))
// ``: a download that still names the shell's own document, which is the
- // one thing never handed to the opener. Refused from either frame, gesture or not.
+ // one thing never handed to the opener. Refused, gesture or not.
precondition(verdict(document, isDocumentUrl: true, isDownload: true) == .cancel)
- precondition(
- verdict(document, isFromSubframe: true, isDocumentUrl: true, isDownload: true) == .cancel
- )
// A subframe is the sealed preview loading itself, which is not the user leaving the app.
precondition(verdict(isMainFrame: false) == .cancel)
precondition(verdict(isMainFrame: false, hasGesture: false) == .cancel)
@@ -624,7 +615,6 @@ import Foundation
MobileWebShellNavigationPolicy.verdict(
url: document,
isMainFrame: true,
- isFromSubframe: false,
isDocumentUrl: true,
isShellLoad: machine.isShellLoad,
hasGesture: false,