Skip to content

Commit

Permalink
Navigation: Improve same-document navigation handling (#702)
Browse files Browse the repository at this point in the history
  • Loading branch information
mallexxx authored Mar 7, 2024
1 parent 2181cdc commit 4504b14
Show file tree
Hide file tree
Showing 39 changed files with 795 additions and 469 deletions.
1 change: 1 addition & 0 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,7 @@ let package = Package(
swiftSettings: [
.define("_IS_USER_INITIATED_ENABLED", .when(platforms: [.macOS])),
.define("_FRAME_HANDLE_ENABLED", .when(platforms: [.macOS])),
.define("_NAVIGATION_REQUEST_ENABLED", .when(platforms: [.macOS])),
.define("PRIVATE_NAVIGATION_DID_FINISH_CALLBACKS_ENABLED", .when(platforms: [.macOS])),
.define("_WEBPAGE_PREFS_CUSTOM_HEADERS_ENABLED", .when(platforms: [.macOS])),
],
Expand Down
2 changes: 0 additions & 2 deletions Sources/BookmarksTestDBBuilder/BookmarksTestDBBuilder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import Persistence
import Bookmarks

// swiftlint:disable force_try
// swiftlint:disable line_length
// swiftlint:disable function_body_length

@main
Expand Down Expand Up @@ -320,5 +319,4 @@ public extension BookmarkEntity {
}

// swiftlint:enable force_try
// swiftlint:enable line_length
// swiftlint:enable function_body_length
4 changes: 2 additions & 2 deletions Sources/BookmarksTestsUtils/BookmarkTree.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import CoreData
import Foundation
import XCTest

// swiftlint:disable cyclomatic_complexity function_body_length line_length
// swiftlint:disable cyclomatic_complexity function_body_length
public struct ModifiedAtConstraint {
var check: (Date?) -> Void

Expand Down Expand Up @@ -384,4 +384,4 @@ public extension XCTestCase {
}
}
}
// swiftlint:enable cyclomatic_complexity function_body_length line_length
// swiftlint:enable cyclomatic_complexity function_body_length
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ import WebKit
import Combine
import UserScript

// swiftlint:disable line_length

public protocol UserContentControllerDelegate: AnyObject {
@MainActor
func userContentController(_ userContentController: UserContentController,
Expand All @@ -39,9 +37,9 @@ public protocol UserContentControllerNewContent {
var makeUserScripts: @MainActor (SourceProvider) -> UserScripts { get }
}

@MainActor
final public class UserContentController: WKUserContentController {
public let privacyConfigurationManager: PrivacyConfigurationManaging
@MainActor
public weak var delegate: UserContentControllerDelegate?

public struct ContentBlockingAssets {
Expand All @@ -62,12 +60,13 @@ final public class UserContentController: WKUserContentController {
}
}

@Published public private(set) var contentBlockingAssets: ContentBlockingAssets? {
@Published @MainActor public private(set) var contentBlockingAssets: ContentBlockingAssets? {
willSet {
self.removeAllContentRuleLists()
self.removeAllUserScripts()
}
}
@MainActor
private func installContentBlockingAssets(_ contentBlockingAssets: ContentBlockingAssets) {
// don‘t install ContentBlockingAssets (especially Message Handlers retaining `self`) after cleanUpBeforeClosing was called
guard assetsPublisherCancellable != nil else { return }
Expand All @@ -83,11 +82,14 @@ final public class UserContentController: WKUserContentController {
updateEvent: contentBlockingAssets.updateEvent)
}

@MainActor
private var localRuleLists = [String: WKContentRuleList]()

@MainActor
private var assetsPublisherCancellable: AnyCancellable?
@MainActor
private let scriptMessageHandler = PermanentScriptMessageHandler()

@MainActor
public init<Pub, Content>(assetsPublisher: Pub, privacyConfigurationManager: PrivacyConfigurationManaging)
where Pub: Publisher, Content: UserContentControllerNewContent, Pub.Output == Content, Pub.Failure == Never {

Expand All @@ -113,6 +115,7 @@ final public class UserContentController: WKUserContentController {
fatalError("init(coder:) has not been implemented")
}

@MainActor
private func installGlobalContentRuleLists(_ contentRuleLists: [String: WKContentRuleList]) {
guard self.privacyConfigurationManager.privacyConfig.isEnabled(featureKey: .contentBlocking) else {
removeAllContentRuleLists()
Expand All @@ -123,6 +126,7 @@ final public class UserContentController: WKUserContentController {
}

public struct ContentRulesNotFoundError: Error {}
@MainActor
public func enableGlobalContentRuleList(withIdentifier identifier: String) throws {
guard let ruleList = self.contentBlockingAssets?.globalRuleLists[identifier] else {
throw ContentRulesNotFoundError()
Expand All @@ -131,35 +135,41 @@ final public class UserContentController: WKUserContentController {
}

public struct ContentRulesNotEnabledError: Error {}
@MainActor
public func disableGlobalContentRuleList(withIdentifier identifier: String) throws {
guard let ruleList = self.contentBlockingAssets?.globalRuleLists[identifier] else {
throw ContentRulesNotEnabledError()
}
self.remove(ruleList)
}

@MainActor
public func installLocalContentRuleList(_ ruleList: WKContentRuleList, identifier: String) {
localRuleLists[identifier] = ruleList
self.add(ruleList)
}

@MainActor
public func removeLocalContentRuleList(withIdentifier identifier: String) {
guard let ruleList = localRuleLists.removeValue(forKey: identifier) else {
return
}
self.remove(ruleList)
}

@MainActor
public override func removeAllContentRuleLists() {
localRuleLists = [:]
super.removeAllContentRuleLists()
}

@MainActor
private func installUserScripts(_ wkUserScripts: [WKUserScript], handlers: [UserScript]) {
handlers.forEach { self.addHandler($0) }
wkUserScripts.forEach(self.addUserScript)
}

@MainActor
public func cleanUpBeforeClosing() {
self.removeAllUserScripts()

Expand All @@ -175,6 +185,7 @@ final public class UserContentController: WKUserContentController {
self.removeAllContentRuleLists()
}

@MainActor
func addHandler(_ userScript: UserScript) {
for messageName in userScript.messageNames {
assert(scriptMessageHandler.messageHandler(for: messageName) == nil || type(of: scriptMessageHandler.messageHandler(for: messageName)!) == type(of: userScript),
Expand Down Expand Up @@ -202,11 +213,13 @@ final public class UserContentController: WKUserContentController {

public extension UserContentController {

@MainActor
var contentBlockingAssetsInstalled: Bool {
contentBlockingAssets != nil
}

// func awaitContentBlockingAssetsInstalled() async non-retaining `self`
@MainActor
var awaitContentBlockingAssetsInstalled: () async -> Void {
guard !contentBlockingAssetsInstalled else { return {} }
return { [weak self] in
Expand Down Expand Up @@ -301,5 +314,3 @@ private class PermanentScriptMessageHandler: NSObject, WKScriptMessageHandler, W
}

}

// swiftlint:enable line_length
5 changes: 5 additions & 0 deletions Sources/Common/Extensions/URLExtension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,11 @@ extension URL {
return components.url
}

/// returns true if URLs are equal except the #fragment part
public func isSameDocument(_ other: URL) -> Bool {
self.absoluteString.droppingHashedSuffix() == other.absoluteString.droppingHashedSuffix()
}

// MARK: - HTTP/HTTPS

public enum URLProtocol: String {
Expand Down
2 changes: 0 additions & 2 deletions Sources/Common/Logging.swift
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,6 @@ extension ProcessInfo {
}
}

// swiftlint:disable line_length
// swiftlint:disable function_parameter_count

// MARK: - message first
Expand Down Expand Up @@ -322,5 +321,4 @@ public func os_log(_ message: @autoclosure () -> String, _ visibility: LogVisibi
os_log(.default, log: .default, message(), visibility)
}

// swiftlint:enable line_length
// swiftlint:enable function_parameter_count
1 change: 0 additions & 1 deletion Sources/Common/TimeoutError.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ public struct TimeoutError: Error, LocalizedError, CustomDebugStringConvertible
public let line: UInt

public var errorDescription: String? {
// swiftlint:disable:next line_length
"TimeoutError(started: \(date), \(interval != nil ? "timeout: \(interval!)s, " : "")\(description != nil ? " description: " + description! : "") at \(file):\(line))"
}

Expand Down
1 change: 0 additions & 1 deletion Sources/DDGSync/DDGSync.swift
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,6 @@ public class DDGSync: DDGSyncing {
try updateAccount(nil)
throw SyncError.unauthenticatedWhileLoggedIn
} catch {
// swiftlint:disable:next line_length
os_log(.error, log: dependencies.log, "Failed to delete account upon unauthenticated server response: %{public}s", error.localizedDescription)
if error is SyncError {
throw error
Expand Down
1 change: 0 additions & 1 deletion Sources/DDGSync/internal/SyncQueue.swift
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,6 @@ final class SyncQueue {
try dataProvider.prepareForFirstSync()
try dataProvider.registerFeature(withState: setupState)
} catch {
// swiftlint:disable:next line_length
os_log(.debug, log: self.log, "Error when preparing %{public}s for first sync: %{public}s", dataProvider.feature.name, error.localizedDescription)
dataProvider.handleSyncError(error)
throw error
Expand Down
Loading

0 comments on commit 4504b14

Please sign in to comment.