Skip to content

Commit

Permalink
Merge branch 'mozilla-mobile:main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
isabelrios authored Apr 24, 2024
2 parents e9d3f4e + 8d5ea4b commit 2d47ff6
Show file tree
Hide file tree
Showing 135 changed files with 2,499 additions and 583 deletions.
41 changes: 41 additions & 0 deletions .github/workflows/firefox-ios-autofill-playwrite-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: Build and Run Autofill Automation
permissions: read-all
on:
pull_request:
paths:
- 'firefox-ios/Client/Assets/CC_Script/**'
push:
branches: ['main']
paths:
- 'firefox-ios/Client/Assets/CC_Script/**'
jobs:
build:
runs-on: macos-13
timeout-minutes: 40
strategy:
matrix:
python-version: [3.9]
xcode: ["15.2"]
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Clone repository
run: |
git clone https://github.com/issammani/test-playwright.git
- name: Install node
uses: actions/setup-node@v4
with:
node-version: 18
- run: |
echo "Install dependencies and run tests"
npm i
npm install --save concurrently
npm i -D @playwright/test
cd test-playwright
echo "Install playwright"
npx playwright install
echo "Run tests"
npm test
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ public struct StandardImageIdentifiers {
public static let creditCard = "creditCardLarge"
public static let criticalFill = "criticalFillLarge"
public static let cross = "crossLarge"
public static let crossCircleFill = "crossCircleFillLarge"
public static let dataClearance = "dataClearanceLarge"
public static let delete = "deleteLarge"
public static let deviceDesktop = "deviceDesktopLarge"
Expand Down
43 changes: 42 additions & 1 deletion BrowserKit/Sources/Common/Extensions/URLExtension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,9 @@ extension URL {
if let range = host.range(of: "^(www|mobile|m)\\.", options: .regularExpression) {
host.replaceSubrange(range, with: "")
}
guard host != publicSuffix else { return nil }
// If the host equals the public suffix, it means that the host is already normalized.
// Therefore, we return the original host without any modifications.
guard host != publicSuffix else { return components.host }

return host
}
Expand All @@ -80,6 +82,45 @@ extension URL {
return normalizedHost.flatMap { $0 + self.path }
}

/// Extracts the subdomain and host from a given URL string and appends a dot to the subdomain.
///
/// This function takes a URL string as input and returns a tuple containing the subdomain and the normalized host.
/// If the URL string does not contain a subdomain, the function returns `nil` for the subdomain.
/// If a subdomain is present, it is returned with a trailing dot.
///
/// - Parameter urlString: The URL string to extract the subdomain and host from.
///
/// - Returns: A tuple containing the subdomain (with a trailing dot) and the normalized host.
/// The subdomain is optional and may be `nil`.
///
/// # Example
/// ```
/// let (subdomain, host) = getSubdomainAndHost(from: "https://docs.github.com")
/// print(subdomain) // Prints "docs."
/// print(host) // Prints "docs.github.com"
/// ```
public static func getSubdomainAndHost(from urlString: String) -> (subdomain: String?, normalizedHost: String) {
guard let url = URL(string: urlString) else { return (nil, urlString) }
let normalizedHost = url.normalizedHost ?? urlString

guard let publicSuffix = url.publicSuffix else { return (nil, normalizedHost) }

let publicSuffixComponents = publicSuffix.split(separator: ".")

let normalizedHostWithoutSuffix = normalizedHost
.split(separator: ".")
.dropLast(publicSuffixComponents.count)
.joined(separator: ".")

let components = normalizedHostWithoutSuffix.split(separator: ".")

guard components.count >= 2 else { return (nil, normalizedHost) }
let subdomain = components.dropLast()
.joined(separator: ".")
.appending(".")
return (subdomain, normalizedHost)
}

/// Returns the public portion of the host name determined by the public suffix list found here: https://publicsuffix.org/list/.
/// For example for the url www.bbc.co.uk, based on the entries in the TLD list, the public suffix would return co.uk.
/// :returns: The public suffix for within the given hostname.
Expand Down
3 changes: 0 additions & 3 deletions BrowserKit/Sources/TabDataStore/WindowData.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import Foundation

public struct WindowData: Codable {
public let id: UUID
public let isPrimary: Bool
public let activeTabId: UUID
public let tabData: [TabData]

Expand All @@ -18,11 +17,9 @@ public struct WindowData: Codable {
/// - activeTabId: the ID of the currently selected tab
/// - tabData: a list of all tabs associated with the window
public init(id: UUID,
isPrimary: Bool = true,
activeTabId: UUID,
tabData: [TabData]) {
self.id = id
self.isPrimary = isPrimary
self.activeTabId = activeTabId
self.tabData = tabData
}
Expand Down
8 changes: 4 additions & 4 deletions BrowserKit/Sources/ToolbarKit/AddressToolbarState.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import Foundation

/// Defines the state for the address toolbar.
public struct AddressToolbarState {
/// URL displayed in the address toolbar
let url: String?
/// View state for the `Location View` in the address toolbar
let locationViewState: LocationViewState

/// Navigation actions of the address toolbar
let navigationActions: [ToolbarElement]
Expand All @@ -26,13 +26,13 @@ public struct AddressToolbarState {

// We need this init as by default the init generated by the compiler for the struct will be internal and
// can therefor not be used outside of the ToolbarKit
public init(url: String?,
public init(locationViewState: LocationViewState,
navigationActions: [ToolbarElement],
pageActions: [ToolbarElement],
browserActions: [ToolbarElement],
shouldDisplayTopBorder: Bool,
shouldDisplayBottomBorder: Bool) {
self.url = url
self.locationViewState = locationViewState
self.navigationActions = navigationActions
self.pageActions = pageActions
self.browserActions = browserActions
Expand Down
20 changes: 8 additions & 12 deletions BrowserKit/Sources/ToolbarKit/BrowserAddressToolbar.swift
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public class BrowserAddressToolbar: UIView, AddressToolbar, ThemeApplicable, Loc
shouldDisplayBottomBorder: state.shouldDisplayBottomBorder)

self.toolbarDelegate = toolbarDelegate
locationView.configure(state.url, delegate: self)
locationView.configure(state.locationViewState, delegate: self)

setNeedsLayout()
layoutIfNeeded()
Expand Down Expand Up @@ -105,17 +105,7 @@ public class BrowserAddressToolbar: UIView, AddressToolbar, ThemeApplicable, Loc
dividerWidthConstraint = locationDividerView.widthAnchor.constraint(equalToConstant: UX.dividerWidth)
dividerWidthConstraint?.isActive = true

let navigationActionWidthAnchor = navigationActionStack.widthAnchor.constraint(equalToConstant: 0)
navigationActionWidthAnchor.isActive = true
navigationActionWidthAnchor.priority = .defaultLow

let pageActionWidthAnchor = pageActionStack.widthAnchor.constraint(equalToConstant: 0)
pageActionWidthAnchor.isActive = true
pageActionWidthAnchor.priority = .defaultLow

let browserActionWidthAnchor = browserActionStack.widthAnchor.constraint(equalToConstant: 0)
browserActionWidthAnchor.isActive = true
browserActionWidthAnchor.priority = .defaultLow
[navigationActionStack, pageActionStack, browserActionStack].forEach(setZeroWidthConstraint)

toolbarTopBorderHeightConstraint = toolbarTopBorderView.heightAnchor.constraint(equalToConstant: 0)
toolbarBottomBorderHeightConstraint = toolbarBottomBorderView.heightAnchor.constraint(equalToConstant: 0)
Expand Down Expand Up @@ -181,6 +171,12 @@ public class BrowserAddressToolbar: UIView, AddressToolbar, ThemeApplicable, Loc
updateActionSpacing()
}

private func setZeroWidthConstraint(_ stackView: UIStackView) {
let widthAnchor = stackView.widthAnchor.constraint(equalToConstant: 0)
widthAnchor.isActive = true
widthAnchor.priority = .defaultHigh
}

private func updateActionStack(stackView: UIStackView, toolbarElements: [ToolbarElement]) {
stackView.removeAllArrangedViews()
toolbarElements.forEach { toolbarElement in
Expand Down
84 changes: 84 additions & 0 deletions BrowserKit/Sources/ToolbarKit/BrowserNavigationToolbar.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/

import UIKit
import Common

/// Navigation toolbar implementation.
public class BrowserNavigationToolbar: UIView, NavigationToolbar, ThemeApplicable {
private enum UX {
static let horizontalEdgeSpace: CGFloat = 16
static let buttonSize = CGSize(width: 48, height: 48)
static let borderHeight: CGFloat = 1
}

private lazy var actionStack: UIStackView = .build { view in
view.distribution = .equalSpacing
}
private lazy var toolbarBorderView: UIView = .build()
private var toolbarBorderHeightConstraint: NSLayoutConstraint?
private var theme: Theme?

override init(frame: CGRect) {
super.init(frame: .zero)
setupLayout()
}

required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

public func configure(state: NavigationToolbarState) {
updateActionStack(toolbarElements: state.actions)

// Update border
toolbarBorderHeightConstraint?.constant = state.shouldDisplayBorder ? UX.borderHeight : 0
}

// MARK: - Private
private func setupLayout() {
addSubview(toolbarBorderView)
addSubview(actionStack)

toolbarBorderHeightConstraint = toolbarBorderView.heightAnchor.constraint(equalToConstant: 0)
toolbarBorderHeightConstraint?.isActive = true

NSLayoutConstraint.activate([
toolbarBorderView.leadingAnchor.constraint(equalTo: leadingAnchor),
toolbarBorderView.topAnchor.constraint(equalTo: topAnchor),
toolbarBorderView.trailingAnchor.constraint(equalTo: trailingAnchor),

actionStack.leadingAnchor.constraint(equalTo: leadingAnchor, constant: UX.horizontalEdgeSpace),
actionStack.topAnchor.constraint(equalTo: toolbarBorderView.bottomAnchor),
actionStack.bottomAnchor.constraint(equalTo: bottomAnchor),
actionStack.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -UX.horizontalEdgeSpace),
])
}

private func updateActionStack(toolbarElements: [ToolbarElement]) {
actionStack.removeAllArrangedViews()
toolbarElements.forEach { toolbarElement in
let button = ToolbarButton()
button.configure(element: toolbarElement)
actionStack.addArrangedSubview(button)

NSLayoutConstraint.activate([
button.widthAnchor.constraint(equalToConstant: UX.buttonSize.width),
button.heightAnchor.constraint(equalToConstant: UX.buttonSize.height),
])

if let theme {
// As we recreate the buttons we need to apply the theme for them to be displayed correctly
button.applyTheme(theme: theme)
}
}
}

// MARK: - ThemeApplicable
public func applyTheme(theme: Theme) {
backgroundColor = theme.colors.layer1
toolbarBorderView.backgroundColor = theme.colors.borderPrimary
self.theme = theme
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import UIKit
public class CompactBrowserAddressToolbar: BrowserAddressToolbar {
override internal func updateActions(state: AddressToolbarState) {
// In compact mode no browser actions will be displayed
let compactState = AddressToolbarState(url: state.url,
let compactState = AddressToolbarState(locationViewState: state.locationViewState,
navigationActions: state.navigationActions,
pageActions: state.pageActions,
browserActions: [],
Expand Down
Loading

0 comments on commit 2d47ff6

Please sign in to comment.