Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

remove Tab.TabContent.url #2647

Merged
merged 16 commits into from
Apr 26, 2024
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion DuckDuckGo/Feedback/View/FeedbackViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ final class FeedbackViewController: NSViewController {

var currentTab: Tab?
var currentTabUrl: URL? {
guard let url = currentTab?.content.url else {
guard let url = currentTab?.content.urlForWebView else {
return nil
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ extension URL {
]

var canFireproof: Bool {
guard let host = self.host else { return false }
guard let host = self.host, [.http, .https].contains(self.navigationalScheme) else { return false }
mallexxx marked this conversation as resolved.
Show resolved Hide resolved
return (host != Self.cookieDomain)
}

Expand Down
23 changes: 12 additions & 11 deletions DuckDuckGo/NavigationBar/View/AddressBarButtonsViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ final class AddressBarButtonsViewController: NSViewController {
guard let tabViewModel, tabViewModel.canBeBookmarked else { return false }

var isUrlBookmarked = false
if let url = tabViewModel.tab.content.url,
if let url = tabViewModel.tab.content.userEditableUrl,
bookmarkManager.isUrlBookmarked(url: url) {
isUrlBookmarked = true
}
Expand Down Expand Up @@ -413,7 +413,7 @@ final class AddressBarButtonsViewController: NSViewController {
permissions.microphone = tabViewModel.usedPermissions.microphone
}

let url = tabViewModel.tab.content.url ?? .empty
let url = tabViewModel.tab.content.urlForWebView ?? .empty
let domain = url.isFileURL ? .localhost : (url.host ?? "")

PermissionContextMenu(permissions: permissions.map { ($0, $1) }, domain: domain, delegate: self)
Expand All @@ -432,7 +432,7 @@ final class AddressBarButtonsViewController: NSViewController {
return
}

let url = tabViewModel.tab.content.url ?? .empty
let url = tabViewModel.tab.content.urlForWebView ?? .empty
let domain = url.isFileURL ? .localhost : (url.host ?? "")

PermissionContextMenu(permissions: [(.microphone, state)], domain: domain, delegate: self)
Expand All @@ -451,7 +451,7 @@ final class AddressBarButtonsViewController: NSViewController {
return
}

let url = tabViewModel.tab.content.url ?? .empty
let url = tabViewModel.tab.content.urlForWebView ?? .empty
let domain = url.isFileURL ? .localhost : (url.host ?? "")

PermissionContextMenu(permissions: [(.geolocation, state)], domain: domain, delegate: self)
Expand All @@ -475,7 +475,7 @@ final class AddressBarButtonsViewController: NSViewController {
$0.append( (.popups, .requested($1)) )
}
} else {
let url = tabViewModel.tab.content.url ?? .empty
let url = tabViewModel.tab.content.urlForWebView ?? .empty
domain = url.isFileURL ? .localhost : (url.host ?? "")
permissions = [(.popups, state)]
}
Expand All @@ -499,7 +499,7 @@ final class AddressBarButtonsViewController: NSViewController {
}

permissions = [(permissionType, state)]
let url = tabViewModel.tab.content.url ?? .empty
let url = tabViewModel.tab.content.urlForWebView ?? .empty
let domain = url.isFileURL ? .localhost : (url.host ?? "")

PermissionContextMenu(permissions: permissions, domain: domain, delegate: self)
Expand Down Expand Up @@ -733,7 +733,7 @@ final class AddressBarButtonsViewController: NSViewController {
}

private func updateBookmarkButtonImage(isUrlBookmarked: Bool = false) {
if let url = tabViewModel?.tab.content.url,
if let url = tabViewModel?.tab.content.userEditableUrl,
isUrlBookmarked || bookmarkManager.isUrlBookmarked(url: url)
{
bookmarkButton.image = .bookmarkFilled
Expand Down Expand Up @@ -770,11 +770,12 @@ final class AddressBarButtonsViewController: NSViewController {
private func updatePrivacyEntryPointButton() {
guard let tabViewModel else { return }

let urlScheme = tabViewModel.tab.content.url?.scheme
let isHypertextUrl = urlScheme == "http" || urlScheme == "https"
let isHypertextUrl = if case .url(let url, _, _) = tabViewModel.tab.content,
!(url.isDuckPlayer || url.isDuckURLScheme),
Copy link
Contributor

Choose a reason for hiding this comment

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

I wonder if a computed property for this condition would make sense for reuse in future since these URLs will always have a special treatment.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

refined it a little bit for more clarity

Copy link
Contributor

Choose a reason for hiding this comment

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

better 👍 thank you!

[.http, .https].contains(url.navigationalScheme) { true } else { false}
let isEditingMode = controllerMode?.isEditing ?? false
let isTextFieldValueText = textFieldValue?.isText ?? false
let isLocalUrl = tabViewModel.tab.content.url?.isLocalURL ?? false
let isLocalUrl = tabViewModel.tab.content.userEditableUrl?.isLocalURL ?? false

// Privacy entry point button
privacyEntryPointButton.isHidden = isEditingMode
Expand Down Expand Up @@ -922,7 +923,7 @@ final class AddressBarButtonsViewController: NSViewController {

private func bookmarkForCurrentUrl(setFavorite: Bool, accessPoint: Pixel.Event.AccessPoint) -> (bookmark: Bookmark?, isNew: Bool) {
guard let tabViewModel,
let url = tabViewModel.tab.content.url else {
let url = tabViewModel.tab.content.userEditableUrl else {
assertionFailure("No URL for bookmarking")
return (nil, false)
}
Expand Down
2 changes: 1 addition & 1 deletion DuckDuckGo/NavigationBar/View/AddressBarTextField.swift
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ final class AddressBarTextField: NSTextField {
guard let selectedTabViewModel = selectedTabViewModel ?? tabCollectionViewModel.selectedTabViewModel else { return }

let addressBarString = addressBarString ?? selectedTabViewModel.addressBarString
let isSearch = selectedTabViewModel.tab.content.url?.isDuckDuckGoSearch ?? false
let isSearch = selectedTabViewModel.tab.content.userEditableUrl?.isDuckDuckGoSearch ?? false
self.value = Value(stringValue: addressBarString, userTyped: false, isSearch: isSearch)
clearUndoManager()
}
Expand Down
4 changes: 2 additions & 2 deletions DuckDuckGo/NavigationBar/View/AddressBarViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -244,9 +244,9 @@ final class AddressBarViewController: NSViewController {

func shouldShowLoadingIndicator(for tabViewModel: TabViewModel, isLoading: Bool, error: Error?) -> Bool {
if isLoading,
let url = tabViewModel.tab.content.url,
let url = tabViewModel.tab.content.urlForWebView,
[.http, .https].contains(url.navigationalScheme),
url.isDuckDuckGoSearch == false,
!url.isDuckDuckGoSearch, !url.isDuckPlayer,
error == nil {
return true
} else {
Expand Down
37 changes: 21 additions & 16 deletions DuckDuckGo/NavigationBar/View/MoreOptionsMenu.swift
Original file line number Diff line number Diff line change
Expand Up @@ -420,36 +420,41 @@ final class MoreOptionsMenu: NSMenu {
#endif

private func addPageItems() {
guard let url = tabCollectionViewModel.selectedTabViewModel?.tab.content.url else { return }
guard let tabViewModel = tabCollectionViewModel.selectedTabViewModel,
let url = tabViewModel.tab.content.userEditableUrl else { return }
let oldItemsCount = items.count

if url.canFireproof, let host = url.host {

let isFireproof = FireproofDomains.shared.isFireproof(fireproofDomain: host)
let title = isFireproof ? UserText.removeFireproofing : UserText.fireproofSite
let image: NSImage = isFireproof ? .burn : .fireproof

addItem(withTitle: title, action: #selector(toggleFireproofing(_:)), keyEquivalent: "")
.targetting(self)
.withImage(image)

}

addItem(withTitle: UserText.findInPageMenuItem, action: #selector(findInPage(_:)), keyEquivalent: "f")
.targetting(self)
.withImage(.findSearch)
.withAccessibilityIdentifier("MoreOptionsMenu.findInPage")

addItem(withTitle: UserText.shareMenuItem, action: nil, keyEquivalent: "")
.targetting(self)
.withImage(.share)
.withSubmenu(sharingMenu)
if tabViewModel.canReload {
addItem(withTitle: UserText.findInPageMenuItem, action: #selector(findInPage(_:)), keyEquivalent: "f")
.targetting(self)
.withImage(.findSearch)
.withAccessibilityIdentifier("MoreOptionsMenu.findInPage")

addItem(withTitle: UserText.printMenuItem, action: #selector(doPrint(_:)), keyEquivalent: "")
.targetting(self)
.withImage(.print)
addItem(withTitle: UserText.shareMenuItem, action: nil, keyEquivalent: "")
.targetting(self)
.withImage(.share)
.withSubmenu(sharingMenu)
}

addItem(NSMenuItem.separator())
if tabViewModel.canPrint {
addItem(withTitle: UserText.printMenuItem, action: #selector(doPrint(_:)), keyEquivalent: "")
.targetting(self)
.withImage(.print)
}

if items.count > oldItemsCount {
addItem(NSMenuItem.separator())
}
}

private func makeNetworkProtectionItem() -> NSMenuItem {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -690,7 +690,7 @@ final class NavigationBarViewController: NSViewController {
passwordManagementButton.menu = menu
passwordManagementButton.toolTip = UserText.autofillShortcutTooltip

let url = tabCollectionViewModel.selectedTabViewModel?.tab.content.url
let url = tabCollectionViewModel.selectedTabViewModel?.tab.content.userEditableUrl

passwordManagementButton.image = .passwordManagement

Expand Down
4 changes: 3 additions & 1 deletion DuckDuckGo/PinnedTabs/View/PinnedTabView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,9 @@ struct PinnedTabInnerView: View {
.resizable()
mutedTabIndicator
}
} else if let domain = model.content.url?.host, let eTLDplus1 = ContentBlocking.shared.tld.eTLDplus1(domain), let firstLetter = eTLDplus1.capitalized.first.flatMap(String.init) {
} else if let domain = model.content.userEditableUrl?.host,
let eTLDplus1 = ContentBlocking.shared.tld.eTLDplus1(domain),
let firstLetter = eTLDplus1.capitalized.first.flatMap(String.init) {
ZStack {
Rectangle()
.foregroundColor(.forString(eTLDplus1))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ final class PrivacyDashboardPermissionHandler {
assertionFailure("PrivacyDashboardViewController: tabViewModel not set")
return
}
guard let domain = tabViewModel?.tab.content.url?.host else {
guard let domain = tabViewModel?.tab.content.urlForWebView?.host else {
onPermissionChange?([])
return
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ extension PrivacyDashboardViewController {

// ⚠️ To limit privacy risk, site URL is trimmed to not include query and fragment
guard let currentTab = tabViewModel?.tab,
let currentURL = currentTab.content.url?.trimmingQueryItemsAndFragment() else {
let currentURL = currentTab.content.urlForWebView?.trimmingQueryItemsAndFragment() else {
throw BrokenSiteReportError.failedToFetchTheCurrentURL
}
let blockedTrackerDomains = currentTab.privacyInfo?.trackerInfo.trackersBlocked.compactMap { $0.domain } ?? []
Expand All @@ -337,7 +337,7 @@ extension PrivacyDashboardViewController {

// current domain's protection status
let configuration = ContentBlocking.shared.privacyConfigurationManager.privacyConfig
let protectionsState = configuration.isFeature(.contentBlocking, enabledForDomain: currentTab.content.url?.host)
let protectionsState = configuration.isFeature(.contentBlocking, enabledForDomain: currentTab.content.urlForWebView?.host)

let webVitals = await calculateWebVitals(performanceMetrics: currentTab.brokenSiteInfo?.performanceMetrics, privacyConfig: configuration)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ extension RecentlyClosedTab: RecentlyClosedCacheItemBurning {
}

private func contentContainsDomains(_ baseDomains: Set<String>, tld: TLD) -> Bool {
if let host = tabContent.url?.host, let baseDomain = tld.eTLDplus1(host), baseDomains.contains(baseDomain) {
if let host = tabContent.urlForWebView?.host, let baseDomain = tld.eTLDplus1(host), baseDomains.contains(baseDomain) {
return true
} else {
return false
Expand Down
2 changes: 1 addition & 1 deletion DuckDuckGo/RecentlyClosed/View/RecentlyClosedMenu.swift
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ private extension NSMenuItem {
case .url, .subscription, .identityTheftRestoration:
image = recentlyClosedTab.favicon
image?.size = NSSize.faviconSize
title = recentlyClosedTab.title ?? recentlyClosedTab.tabContent.url?.absoluteString ?? ""
title = recentlyClosedTab.title ?? recentlyClosedTab.tabContent.userEditableUrl?.absoluteString ?? ""

if title.count > MainMenu.Constants.maxTitleLength {
title = String(title.truncated(length: MainMenu.Constants.maxTitleLength))
Expand Down
2 changes: 1 addition & 1 deletion DuckDuckGo/Sharing/SharingMenu.swift
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ final class SharingMenu: NSMenu {
guard let tabViewModel = WindowControllersManager.shared.lastKeyMainWindowController?.mainViewController.tabCollectionViewModel.selectedTabViewModel,
tabViewModel.canReload,
!tabViewModel.isShowingErrorPage,
let url = tabViewModel.tab.content.url else { return nil }
let url = tabViewModel.tab.content.userEditableUrl else { return nil }

let sharingData = DuckPlayer.shared.sharingData(for: tabViewModel.title, url: url) ?? (tabViewModel.title, url)

Expand Down
18 changes: 11 additions & 7 deletions DuckDuckGo/Tab/Model/Tab.swift
Original file line number Diff line number Diff line change
Expand Up @@ -461,7 +461,7 @@ protocol NewWindowPolicyDecisionMaker {
if let url = webView.url {
let content = TabContent.contentFromURL(url, source: .webViewUpdated)

if self.content.isUrl, self.content.url == url {
if self.content.isUrl, self.content.urlForWebView == url {
// ignore content updates when tab.content has userEntered or credential set but equal url as it comes from the WebView url updated event
} else if content != self.content {
self.content = content
Expand Down Expand Up @@ -579,7 +579,7 @@ protocol NewWindowPolicyDecisionMaker {
@MainActor
var currentHistoryItem: BackForwardListItem? {
webView.backForwardList.currentItem.map(BackForwardListItem.init)
?? (content.url ?? navigationDelegate.currentNavigation?.url).map { url in
?? (content.urlForWebView ?? navigationDelegate.currentNavigation?.url).map { url in
BackForwardListItem(kind: .url(url), title: webView.title ?? title, identity: nil)
}
}
Expand Down Expand Up @@ -608,7 +608,11 @@ protocol NewWindowPolicyDecisionMaker {

let canGoBack = webView.canGoBack
let canGoForward = webView.canGoForward
let canReload = self.content.userEditableUrl != nil
let canReload = if case .url(let url, credential: _, source: _) = content, !(url.isDuckPlayer || url.isDuckURLScheme) {
true
} else {
false
}

if canGoBack != self.canGoBack {
self.canGoBack = canGoBack
Expand Down Expand Up @@ -895,7 +899,7 @@ protocol NewWindowPolicyDecisionMaker {
}

func requestFireproofToggle() {
guard let url = content.userEditableUrl,
guard case .url(let url, _, _) = content, !(url.isDuckPlayer || url.isDuckURLScheme),
let host = url.host
else { return }

Expand Down Expand Up @@ -992,7 +996,7 @@ protocol NewWindowPolicyDecisionMaker {
if cachedFavicon != favicon {
favicon = cachedFavicon
}
} else if oldValue?.url?.host != url.host {
} else if oldValue?.urlForWebView?.host != url.host {
// If the domain matches the previous value, just keep the same favicon
favicon = nil
}
Expand Down Expand Up @@ -1031,7 +1035,7 @@ extension Tab: FaviconUserScriptDelegate {
for documentUrl: URL) {
guard documentUrl != .error else { return }
faviconManagement.handleFaviconLinks(faviconLinks, documentUrl: documentUrl) { favicon in
guard documentUrl == self.content.url, let favicon = favicon else {
guard documentUrl == self.content.urlForWebView, let favicon = favicon else {
return
}
self.favicon = favicon.image
Expand Down Expand Up @@ -1098,7 +1102,7 @@ extension Tab/*: NavigationResponder*/ { // to be moved to Tab+Navigation.swift
// credential is removed from the URL and set to TabContent to be used on next Challenge
self.content = .url(navigationAction.url.removingBasicAuthCredential(), credential: credential, source: .webViewUpdated)
// reload URL without credentialss
request.url = self.content.url!
request.url = self.content.urlForWebView!
navigator.load(request)
}
}
Expand Down
17 changes: 9 additions & 8 deletions DuckDuckGo/Tab/Model/TabContent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -195,19 +195,20 @@ extension TabContent {
}
}

var url: URL? {
userEditableUrl
}
// !!! don‘t add `url` property to avoid ambiguity with the `.url` enum case
// use `userEditableUrl` or `urlForWebView` instead.

/// user-editable URL displayed in the address bar
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we rename it to urlForAddressBar? 🤷 Not a strong opinion.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I don‘t know, I think user editable url is pretty expressive to keep it

var userEditableUrl: URL? {
switch self {
case .url(let url, credential: _, source: _) where !(url.isDuckPlayer || url.isDuckURLScheme):
return url
default:
return nil
let url = urlForWebView
if let url, url.isDuckPlayer,
let (videoID, timestamp) = url.youtubeVideoParams {
return .duckPlayer(videoID, timestamp: timestamp)
}
return url
}

/// `real` URL loaded in the web view
var urlForWebView: URL? {
switch self {
case .url(let url, credential: _, source: _):
Expand Down
2 changes: 1 addition & 1 deletion DuckDuckGo/Tab/TabExtensions/TabExtensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ extension TabExtensionsBuilder {
HistoryTabExtension(isBurner: args.isTabBurner,
historyCoordinating: dependencies.historyCoordinating,
trackersPublisher: contentBlocking.trackersPublisher,
urlPublisher: args.contentPublisher.map { content in content.isUrl ? content.url : nil },
urlPublisher: args.contentPublisher.map { content in content.isUrl ? content.urlForWebView : nil },
titlePublisher: args.titlePublisher)
}
add {
Expand Down
3 changes: 2 additions & 1 deletion DuckDuckGo/Tab/TabExtensions/TabSnapshotExtension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,8 @@ final class TabSnapshotExtension {

@MainActor
func renderWebViewSnapshot() async {
guard let webView, let tabContent, let url = tabContent.url else {
guard let webView, let tabContent,
let url = tabContent.userEditableUrl, !url.isDuckURLScheme else {
// Previews of native views are rendered in renderNativePreview()
return
}
Expand Down
2 changes: 1 addition & 1 deletion DuckDuckGo/Tab/TabLazyLoader/LazyLoadable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ protocol LazyLoadable: AnyObject, Identifiable {
extension Tab: LazyLoadable {
var isUrl: Bool { content.isUrl }

var url: URL? { content.url }
var url: URL? { content.urlForWebView }

var loadingFinishedPublisher: AnyPublisher<Tab, Never> {
navigationStatePublisher.compactMap { $0 }
Expand Down
4 changes: 2 additions & 2 deletions DuckDuckGo/Tab/ViewModel/TabViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -233,11 +233,11 @@ final class TabViewModel {
}

private func updateCanBeBookmarked() {
canBeBookmarked = !isShowingErrorPage && (tab.content.url ?? .blankPage) != .blankPage
canBeBookmarked = !isShowingErrorPage && (tab.content.userEditableUrl ?? .blankPage) != .blankPage
}

private var tabURL: URL? {
return tab.content.url
return tab.content.userEditableUrl
}

private var tabHostURL: URL? {
Expand Down
Loading
Loading