Skip to content

Commit

Permalink
Merge branch 'main' into dominik/xcode-16
Browse files Browse the repository at this point in the history
* main:
  Second macOS CPM experiment (#1017)
  fix HStack width (#1022)
  Change tab URL calculation for contentblockerrules.js and surrogates.js (#1021)
  Add Events Firing for Phishing Detection Settings (#1012)
  Sabrina/onboarding UI updates (#1015)
  • Loading branch information
samsymons committed Oct 21, 2024
2 parents c4aaa66 + f1a033c commit d42b173
Show file tree
Hide file tree
Showing 10 changed files with 131 additions and 75 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -42,20 +42,17 @@ public class AdClickAttributionDetection {
private let tld: TLD
private let eventReporting: EventMapping<AdClickAttributionEvents>?
private let errorReporting: EventMapping<AdClickAttributionDebugEvents>?
private let cpmExperimentOn: Bool?

public weak var delegate: AdClickAttributionDetectionDelegate?

public init(feature: AdClickAttributing,
tld: TLD,
eventReporting: EventMapping<AdClickAttributionEvents>? = nil,
errorReporting: EventMapping<AdClickAttributionDebugEvents>? = nil,
cpmExperimentOn: Bool? = nil) {
errorReporting: EventMapping<AdClickAttributionDebugEvents>? = nil) {
self.attributionFeature = feature
self.tld = tld
self.eventReporting = eventReporting
self.errorReporting = errorReporting
self.cpmExperimentOn = cpmExperimentOn
}

// MARK: - Public API
Expand Down Expand Up @@ -146,12 +143,9 @@ public class AdClickAttributionDetection {
domainDetection = "none"
}

var parameters = [AdClickAttributionEvents.Parameters.domainDetection: domainDetection,
let parameters = [AdClickAttributionEvents.Parameters.domainDetection: domainDetection,
AdClickAttributionEvents.Parameters.domainDetectionEnabled: attributionFeature.isDomainDetectionEnabled ? "1" : "0",
AdClickAttributionEvents.Parameters.heuristicDetectionEnabled: attributionFeature.isHeuristicDetectionEnabled ? "1" : "0"]
if let cpmExperimentOn {
parameters[AdClickAttributionEvents.Parameters.cpmExperiment] = cpmExperimentOn ? "1" : "0"
}
eventReporting?.fire(.adAttributionDetected, parameters: parameters)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ public enum AdClickAttributionEvents {
public static let heuristicDetectionEnabled = "heuristicDetectionEnabled"
public static let domainDetectionEnabled = "domainDetectionEnabled"
public static let count = "count"
public static let cpmExperiment = "cpmExperiment"
}

case adAttributionDetected
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -207,15 +207,11 @@ public class AdClickAttributionLogic {
}
}

public func onRequestDetected(request: DetectedRequest, cpmExperimentOn: Bool? = nil) {
public func onRequestDetected(request: DetectedRequest) {
guard registerFirstActivity,
BlockingState.allowed(reason: .adClickAttribution) == request.state else { return }

var parameters: [String: String] = [:]
if let cpmExperimentOn {
parameters[AdClickAttributionEvents.Parameters.cpmExperiment] = cpmExperimentOn ? "1" : "0"
}
eventReporting?.fire(.adAttributionActive, parameters: parameters)
eventReporting?.fire(.adAttributionActive)
registerFirstActivity = false
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,37 @@
// "use strict";

(function () {
const topLevelUrl = getTopLevelURL()


/**
* Best guess effort of the tabs hostname. Cribbed from getTabHostname in: https://github.com/duckduckgo/content-scope-scripts/
* @returns {string|null} inferred tab hostname
*/
function getTabURL () {
let framingOrigin = null
try {
// @ts-expect-error - globalThis.top is possibly 'null' here
framingOrigin = globalThis.top.location.href
} catch {
framingOrigin = globalThis.document.referrer
}

// Not supported in Firefox
if ('ancestorOrigins' in globalThis.location && globalThis.location.ancestorOrigins.length) {
// ancestorOrigins is reverse order, with the last item being the top frame
framingOrigin = globalThis.location.ancestorOrigins.item(globalThis.location.ancestorOrigins.length - 1)
}

try {
// @ts-expect-error - framingOrigin is possibly 'null' here
framingOrigin = new URL(framingOrigin)
} catch {
framingOrigin = null
}
return framingOrigin
}

const topLevelUrl = getTabURL()

let unprotectedDomain = false
const domainParts = topLevelUrl && topLevelUrl.host ? topLevelUrl.host.split('.') : []
Expand Down Expand Up @@ -133,21 +163,6 @@
return false
}

// private
function getTopLevelURL () {
try {
// FROM: https://stackoverflow.com/a/7739035/73479
// FIX: Better capturing of top level URL so that trackers in embedded documents are not considered first party
if (window.location !== window.parent.location) {
return new URL(window.location.href !== 'about:blank' ? document.referrer : window.parent.location.href)
} else {
return new URL(document.location.href)
}
} catch (error) {
return new URL(location.href)
}
}

if (!window.__firefox__) {
Object.defineProperty(window, '__firefox__', {
enumerable: false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,35 @@
}
])

const topLevelUrl = getTopLevelURL()
/**
* Best guess effort of the tabs hostname. Cribbed from getTabHostname in: https://github.com/duckduckgo/content-scope-scripts/
* @returns {string|null} inferred tab hostname
*/
function getTabURL () {
let framingOrigin = null
try {
// @ts-expect-error - globalThis.top is possibly 'null' here
framingOrigin = globalThis.top.location.href
} catch {
framingOrigin = globalThis.document.referrer
}

// Not supported in Firefox
if ('ancestorOrigins' in globalThis.location && globalThis.location.ancestorOrigins.length) {
// ancestorOrigins is reverse order, with the last item being the top frame
framingOrigin = globalThis.location.ancestorOrigins.item(globalThis.location.ancestorOrigins.length - 1)
}

try {
// @ts-expect-error - framingOrigin is possibly 'null' here
framingOrigin = new URL(framingOrigin)
} catch {
framingOrigin = null
}
return framingOrigin
}

const topLevelUrl = getTabURL()

let unprotectedDomain = false
const domainParts = topLevelUrl && topLevelUrl.host ? topLevelUrl.host.split('.') : []
Expand Down Expand Up @@ -466,17 +494,6 @@
return false
}

// private
function getTopLevelURL () {
try {
// FROM: https://stackoverflow.com/a/7739035/73479
// FIX: Better capturing of top level URL so that trackers in embedded documents are not considered first party
return new URL(window.location !== window.parent.location ? document.referrer : document.location.href)
} catch (error) {
return new URL(location.href)
}
}

// private
function loadSurrogate (surrogatePattern) {
trackers.surrogateList[surrogatePattern]()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ public enum AutoconsentSubfeature: String, PrivacySubfeature {
}

case onByDefault
case filterlistExperiment
case filterlistExperiment2
}

public enum PrivacyProSubfeature: String, Equatable, PrivacySubfeature {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,11 +97,12 @@ public struct ContextualDaxDialogContent: View {
nonTypingElements
}
} else if case .horizontalStack(let alignment) = orientation {
HStack(alignment: alignment, spacing: 10) {
HStack(alignment: alignment, spacing: 5) {
typingElements
Spacer()
nonTypingElements
}
.frame(width: 488)
}
}
.onAppear {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ public struct ContextualOnboardingListView: View {

#if os(macOS)
private var strokeColor: Color {
return (colorScheme == .dark) ? Color.white.opacity(0.09) : Color.black.opacity(0.09)
return (colorScheme == .dark) ? Color.white.opacity(0.12) : Color.black.opacity(0.09)
}
#else
private let strokeColor = Color.blue
Expand All @@ -92,7 +92,7 @@ private let strokeColor = Color.blue
.frame(width: iconSize, height: iconSize)
Text(list[index].visibleTitle)
.frame(alignment: .leading)
Spacer()
Spacer(minLength: 0)
}
})
.buttonStyle(OnboardingStyles.ListButtonStyle())
Expand Down
82 changes: 54 additions & 28 deletions Sources/Onboarding/Styles/DaxDialogStyles.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@

import SwiftUI

enum OnboardingStyles {}
public enum OnboardingStyles {}

extension OnboardingStyles {
public extension OnboardingStyles {

struct ListButtonStyle: ButtonStyle {
@Environment(\.colorScheme) private var colorScheme
Expand All @@ -30,49 +30,73 @@ extension OnboardingStyles {
#else
private let maxHeight = 40.0
#endif
private var maxWidth: CGFloat? = .infinity

#if os(macOS)
private let fontSize = 12.0
#else
private let fontSize = 15.0
#endif

init() {}
@State private var isHovered = false

func makeBody(configuration: Configuration) -> some View {
public init(maxWidth: CGFloat? = .infinity) {
self.maxWidth = maxWidth
}

public func makeBody(configuration: Configuration) -> some View {
configuration.label
.font(.system(size: fontSize, weight: .bold))
.fixedSize(horizontal: false, vertical: true)
.multilineTextAlignment(.center)
.lineLimit(nil)
.foregroundColor(foregroundColor(configuration.isPressed))
.foregroundColor(foregroundColor(isPressed: configuration.isPressed, isHovered: isHovered))
.padding()
.frame(minWidth: 0, maxWidth: .infinity, maxHeight: maxHeight)
.background(backgroundColor(configuration.isPressed))
.frame(minWidth: 0, maxWidth: maxWidth, maxHeight: maxHeight)
.background(backgroundColor(isPressed: configuration.isPressed, isHovered: isHovered))
.cornerRadius(8)
.contentShape(Rectangle()) // Makes whole button area tappable, when there's no background
.onHover { hovering in
#if os(macOS)
self.isHovered = hovering
#endif
}
}

private func foregroundColor(_ isPressed: Bool) -> Color {
switch (colorScheme, isPressed) {
case (.dark, false):
return .blue30
case (.dark, true):
return .blue20
case (_, false):
return .blueBase
case (_, true):
return .blue70
private func foregroundColor(isPressed: Bool, isHovered: Bool) -> Color {
switch (colorScheme, isPressed, isHovered) {
case (.light, false, false):
return .lightRestBlue
case (.dark, false, false):
return .darkRestBlue
case (.light, false, true):
return .lightHoverBlue
case (.dark, false, true):
return .darkHoverBlue
case (.light, true, _):
return .lightPressedBlue
case (.dark, true, _):
return .darkPressedBlue
case (_, _, _):
return .lightRestBlue
}
}

private func backgroundColor(_ isPressed: Bool) -> Color {
switch (colorScheme, isPressed) {
case (.light, true):
return .blueBase.opacity(0.2)
case (.dark, true):
return .blue30.opacity(0.2)
default:
private func backgroundColor(isPressed: Bool, isHovered: Bool) -> Color {
switch (colorScheme, isPressed, isHovered) {
case (.light, false, false):
return .black.opacity(0.01)
case (.dark, false, false):
return .white.opacity(0.03)
case (.light, false, true):
return .black.opacity(0.03)
case (.dark, false, true):
return .white.opacity(0.06)
case (.light, true, _):
return .black.opacity(0.06)
case (.dark, true, _):
return .white.opacity(0.06)
case (_, _, _):
return .clear
}
}
Expand All @@ -81,10 +105,12 @@ extension OnboardingStyles {
}

extension Color {
static let blue70 = Color(0x1E42A4)
static let blueBase = Color(0x3969EF)
static let blue30 = Color(0x7295F6)
static let blue20 = Color(0x8FABF9)
static let lightRestBlue = Color(0x3969EF)
static let darkRestBlue = Color(0x7295F6)
static let lightHoverBlue = Color(0x2B55CA)
static let darkHoverBlue = Color(0x8FABF9)
static let lightPressedBlue = Color(0x1E42A4)
static let darkPressedBlue = Color(0xADC2FC)

init(_ hex: UInt, alpha: Double = 1) {
self.init(
Expand Down
8 changes: 8 additions & 0 deletions Sources/PhishingDetection/PhishingDetectionEvents.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import PixelKit
public extension PixelKit {
enum Parameters: Hashable {
public static let clientSideHit = "client_side_hit"
public static let settingToggledTo = "setting_toggled_to"
}
}

Expand All @@ -30,6 +31,7 @@ public enum PhishingDetectionEvents: PixelKitEventV2 {
case visitSite
case iframeLoaded
case updateTaskFailed48h(error: Error?)
case settingToggled(to: Bool)

public var name: String {
switch self {
Expand All @@ -41,6 +43,8 @@ public enum PhishingDetectionEvents: PixelKitEventV2 {
return "phishing_detection_iframe-loaded"
case .updateTaskFailed48h:
return "phishing_detection_update-task-failed-48h"
case .settingToggled:
return "phishing_detection_setting-toggled"
}
}

Expand All @@ -54,6 +58,8 @@ public enum PhishingDetectionEvents: PixelKitEventV2 {
return [:]
case .updateTaskFailed48h(let error):
return error?.pixelParameters
case .settingToggled(let state):
return [PixelKit.Parameters.settingToggledTo: String(state)]
}
}

Expand All @@ -67,6 +73,8 @@ public enum PhishingDetectionEvents: PixelKitEventV2 {
return nil
case .iframeLoaded:
return nil
case .settingToggled:
return nil
}
}

Expand Down

0 comments on commit d42b173

Please sign in to comment.