Skip to content

Commit

Permalink
Merge branch 'release/134.1.0-1'
Browse files Browse the repository at this point in the history
  • Loading branch information
diegoreymendez committed Apr 16, 2024
2 parents 715d6f1 + 543398a commit 81330c3
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 26 deletions.
2 changes: 1 addition & 1 deletion Sources/Common/SecurityOrigin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public struct SecurityOrigin: Hashable {

public static let empty = SecurityOrigin(protocol: "", host: "", port: 0)

var isEmpty: Bool {
public var isEmpty: Bool {
self == .empty
}

Expand Down
62 changes: 41 additions & 21 deletions Sources/Navigation/DistributedNavigationDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -539,32 +539,53 @@ extension DistributedNavigationDelegate: WKNavigationDelegate {

@MainActor
public func webView(_ webView: WKWebView, didStartProvisionalNavigation wkNavigation: WKNavigation?) {
let navigation: Navigation
if let expectedNavigation = navigationExpectedToStart,
wkNavigation != nil
|| expectedNavigation.navigationAction.navigationType == .sessionRestoration
|| expectedNavigation.navigationAction.url.scheme.map(URL.NavigationalScheme.init) == .about {
var navigation: Navigation

// regular flow: start .expected navigation
navigation = expectedNavigation
} else if webView.url?.isEmpty == false {
navigation = Navigation(identity: NavigationIdentity(wkNavigation), responders: responders, state: .expected(nil), isCurrent: true)
if let finishedNavigation = wkNavigation?.navigation {
assert(finishedNavigation.state == .finished)
// about: scheme navigation for new window sometimes duplicates didStart/didCommit/didFinish events with the same WKNavigation
let navigationAction = NavigationAction(request: finishedNavigation.request, navigationType: finishedNavigation.navigationAction.navigationType, currentHistoryItemIdentity: nil, redirectHistory: nil, isUserInitiated: false, sourceFrame: finishedNavigation.navigationAction.sourceFrame, targetFrame: finishedNavigation.navigationAction.targetFrame, shouldDownload: false, mainFrameNavigation: navigation)
navigation.navigationActionReceived(navigationAction)
lazy var finishedNavigationAction: NavigationAction? = {
guard let navigation = wkNavigation?.navigation else { return nil }
if navigation.isCompleted, navigation.hasReceivedNavigationAction {
// about: scheme navigation for `<a target='_blank'>` duplicates didStart/didCommit/didFinish events with the same WKNavigation
return navigation.navigationAction
} else {
navigation.navigationActionReceived(.alternateHtmlLoadNavigation(webView: webView, mainFrameNavigation: navigation))
// we‘ll get here when allowing to open a new window with an empty URL (`window.open()`) from a permission context menu
return nil
}
navigation.willStart()
} else if let wkNavigation {
}()

if let approvedNavigation = wkNavigation?.navigation,
approvedNavigation.state == .approved, approvedNavigation.hasReceivedNavigationAction {
// rely on the associated Navigation that is in the correct state
navigation = approvedNavigation

} else if let expectedNavigation = navigationExpectedToStart,
wkNavigation != nil
|| expectedNavigation.navigationAction.navigationType == .sessionRestoration
|| expectedNavigation.navigationAction.url.navigationalScheme == .about {

// regular flow: start .expected navigation
navigation = expectedNavigation

} else {
// make a new Navigation object for unexpected navigations (that didn‘t receive corresponding `decidePolicyForNavigationAction`)
navigation = Navigation(identity: NavigationIdentity(wkNavigation), responders: responders, state: .expected(nil), isCurrent: true)
let navigationAction = NavigationAction(request: URLRequest(url: .empty), navigationType: .other, currentHistoryItemIdentity: nil, redirectHistory: nil, isUserInitiated: false, sourceFrame: .mainFrame(for: webView), targetFrame: .mainFrame(for: webView), shouldDownload: false, mainFrameNavigation: navigation)

let navigationAction: NavigationAction = {
if wkNavigation == nil, webView.url?.isEmpty == false {
// loading error page
return .alternateHtmlLoadNavigation(webView: webView, mainFrameNavigation: navigation)
}
return NavigationAction(request: URLRequest(url: webView.url ?? .empty),
navigationType: finishedNavigationAction?.navigationType ?? .other,
currentHistoryItemIdentity: nil,
redirectHistory: nil,
isUserInitiated: false,
sourceFrame: finishedNavigationAction?.sourceFrame ?? .mainFrame(for: webView),
targetFrame: finishedNavigationAction?.targetFrame ?? .mainFrame(for: webView),
shouldDownload: false,
mainFrameNavigation: navigation)
}()
navigation.navigationActionReceived(navigationAction)
navigation.willStart()
} else {
return
}

navigation.started(wkNavigation)
Expand Down Expand Up @@ -867,7 +888,6 @@ extension DistributedNavigationDelegate: WKNavigationDelegate {
true
}

assert(wkNavigation != nil)
navigation = Navigation(identity: NavigationIdentity(wkNavigation), responders: responders, state: .expected(nil), isCurrent: isCurrent)
let request = wkNavigation?.request ?? URLRequest(url: webView.url ?? .empty)
let navigationAction = NavigationAction(request: request, navigationType: .sameDocumentNavigation(navigationType), currentHistoryItemIdentity: currentHistoryItemIdentity, redirectHistory: nil, isUserInitiated: wkNavigation?.isUserInitiated ?? false, sourceFrame: .mainFrame(for: webView), targetFrame: .mainFrame(for: webView), shouldDownload: false, mainFrameNavigation: navigation)
Expand Down
9 changes: 7 additions & 2 deletions Sources/Navigation/Navigation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
// limitations under the License.
//

import Combine
import Common
import Foundation
import WebKit
Expand All @@ -31,7 +32,7 @@ public final class Navigation {
/// Is the navigation currently loaded in the WebView
private(set) public var isCurrent: Bool

public fileprivate(set) var state: NavigationState
@Published public fileprivate(set) var state: NavigationState
public private(set) var isCommitted: Bool = false
public private(set) var didReceiveAuthenticationChallenge: Bool = false

Expand Down Expand Up @@ -80,7 +81,11 @@ public final class Navigation {

/// is Finished or Failed
public var isCompleted: Bool {
return state.isFinished || state.isFailed
return state.isCompleted
}

internal var hasReceivedNavigationAction: Bool {
navigationActions.isEmpty == false
}

}
Expand Down
24 changes: 23 additions & 1 deletion Sources/Navigation/NavigationState.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import Foundation
import WebKit

public enum NavigationState: Equatable {
public enum NavigationState: Equatable, Comparable {

case expected(NavigationType?)
case navigationActionReceived
Expand Down Expand Up @@ -58,6 +58,10 @@ public enum NavigationState: Equatable {
return false
}

public var isCompleted: Bool {
isFinished || isFailed
}

// swiftlint:disable:next cyclomatic_complexity
public static func == (lhs: NavigationState, rhs: NavigationState) -> Bool {
switch lhs {
Expand All @@ -74,6 +78,24 @@ public enum NavigationState: Equatable {
return false
}

private var rawValue: UInt {
switch self {
case .expected: 0
case .navigationActionReceived: 1
case .approved: 2
case .started: 3
case .willPerformClientRedirect: 4
case .redirected: 5
case .responseReceived: 6
case .finished: 7
case .failed: 8
}
}

public static func < (lhs: NavigationState, rhs: NavigationState) -> Bool {
lhs.rawValue < rhs.rawValue
}

}

extension NavigationState: CustomStringConvertible {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,17 @@ extension Network.NWPath {
description += "unsatisfiedReason: \(unsatisfiedReason), "
}

description += "availableInterfaces: \(availableInterfaces), "
let tunnelCount = availableInterfaces.filter { interface in
interface.type == .other && interface.name.contains("utun")
}.count

let dnsCount = availableInterfaces.filter { interface in
interface.type == .other && interface.name.contains("dns")
}.count

description += "mainInterfaceType: \(String(describing: availableInterfaces.first?.type)), "
description += "tunnelInterfaceCount: \(tunnelCount), "
description += "dnsInterfaceCount: \(dnsCount)), "
description += "isConstrained: \(isConstrained ? "true" : "false"), "
description += "isExpensive: \(isExpensive ? "true" : "false")"
description += ")"
Expand Down

0 comments on commit 81330c3

Please sign in to comment.