From c6f0ebfb47b33dd6fe8453d065ff589343260f14 Mon Sep 17 00:00:00 2001 From: Isabella Date: Wed, 2 Oct 2024 16:54:40 -0600 Subject: [PATCH] Refactor FXIOS-10206 [Unified Search] Separate the toolbar's search engine image into its own class (#22345) * Refactor the toolbar LocationView's search engine image view and container into its own SearchEngineView class. --- .../LocationView/LocationView.swift | 34 ++------- .../LocationView/SearchEngineView.swift | 74 +++++++++++++++++++ 2 files changed, 79 insertions(+), 29 deletions(-) create mode 100644 BrowserKit/Sources/ToolbarKit/AddressToolbar/LocationView/SearchEngineView.swift diff --git a/BrowserKit/Sources/ToolbarKit/AddressToolbar/LocationView/LocationView.swift b/BrowserKit/Sources/ToolbarKit/AddressToolbar/LocationView/LocationView.swift index cd27400fa316..804989a659a4 100644 --- a/BrowserKit/Sources/ToolbarKit/AddressToolbar/LocationView/LocationView.swift +++ b/BrowserKit/Sources/ToolbarKit/AddressToolbar/LocationView/LocationView.swift @@ -10,10 +10,8 @@ final class LocationView: UIView, LocationTextFieldDelegate, ThemeApplicable, Ac private enum UX { static let horizontalSpace: CGFloat = 8 static let gradientViewWidth: CGFloat = 40 - static let searchEngineImageViewCornerRadius: CGFloat = 4 static let iconContainerCornerRadius: CGFloat = 8 static let lockIconImageViewSize = CGSize(width: 40, height: 24) - static let searchEngineImageViewSize = CGSize(width: 24, height: 24) } private var urlAbsolutePath: String? @@ -56,29 +54,22 @@ final class LocationView: UIView, LocationTextFieldDelegate, ThemeApplicable, Ac private var iconContainerStackViewLeadingConstraint: NSLayoutConstraint? private var lockIconWidthAnchor: NSLayoutConstraint? + // MARK: - Search Engine / Lock Image private lazy var iconContainerStackView: UIStackView = .build { view in view.axis = .horizontal view.alignment = .center view.distribution = .fill } - - private lazy var searchEngineContentView: UIView = .build() - private lazy var iconContainerBackgroundView: UIView = .build { view in view.layer.cornerRadius = UX.iconContainerCornerRadius } - - private lazy var searchEngineImageView: UIImageView = .build { imageView in - imageView.contentMode = .scaleAspectFit - imageView.layer.cornerRadius = UX.searchEngineImageViewCornerRadius - imageView.isAccessibilityElement = true - } - + private lazy var searchEngineContentView: SearchEngineView = .build() private lazy var lockIconButton: UIButton = .build { button in button.contentMode = .scaleAspectFit button.addTarget(self, action: #selector(self.didTapLockIcon), for: .touchUpInside) } + // MARK: - URL Text Field private lazy var urlTextField: LocationTextField = .build { [self] urlTextField in urlTextField.backgroundColor = .clear urlTextField.font = FXFontStyles.Regular.body.scaledFont() @@ -118,7 +109,7 @@ final class LocationView: UIView, LocationTextFieldDelegate, ThemeApplicable, Ac } func configure(_ state: LocationViewState, delegate: LocationViewDelegate, isUnifiedSearchEnabled: Bool) { - searchEngineImageView.image = state.searchEngineImage + searchEngineContentView.configure(state, delegate: delegate, isUnifiedSearchEnabled: isUnifiedSearchEnabled) configureLockIconButton(state) configureURLTextField(state) configureA11y(state) @@ -155,7 +146,6 @@ final class LocationView: UIView, LocationTextFieldDelegate, ThemeApplicable, Ac addSubviews(urlTextField, iconContainerStackView, gradientView) iconContainerStackView.addSubview(iconContainerBackgroundView) - searchEngineContentView.addSubview(searchEngineImageView) iconContainerStackView.addArrangedSubview(searchEngineContentView) urlTextFieldLeadingConstraint = urlTextField.leadingAnchor.constraint( @@ -180,15 +170,6 @@ final class LocationView: UIView, LocationTextFieldDelegate, ThemeApplicable, Ac iconContainerBackgroundView.leadingAnchor.constraint(lessThanOrEqualTo: urlTextField.leadingAnchor), iconContainerBackgroundView.trailingAnchor.constraint(equalTo: iconContainerStackView.trailingAnchor), - searchEngineImageView.heightAnchor.constraint(equalToConstant: UX.searchEngineImageViewSize.height), - searchEngineImageView.widthAnchor.constraint(equalToConstant: UX.searchEngineImageViewSize.width), - searchEngineImageView.leadingAnchor.constraint(equalTo: searchEngineContentView.leadingAnchor), - searchEngineImageView.trailingAnchor.constraint(equalTo: searchEngineContentView.trailingAnchor), - searchEngineImageView.topAnchor.constraint(greaterThanOrEqualTo: searchEngineContentView.topAnchor), - searchEngineImageView.bottomAnchor.constraint(lessThanOrEqualTo: searchEngineContentView.bottomAnchor), - searchEngineImageView.centerXAnchor.constraint(equalTo: searchEngineContentView.centerXAnchor), - searchEngineImageView.centerYAnchor.constraint(equalTo: searchEngineContentView.centerYAnchor), - lockIconButton.heightAnchor.constraint(equalToConstant: UX.lockIconImageViewSize.height), lockIconButton.widthAnchor.constraint(equalToConstant: UX.lockIconImageViewSize.width), @@ -401,11 +382,6 @@ final class LocationView: UIView, LocationTextFieldDelegate, ThemeApplicable, Ac lockIconButton.accessibilityIdentifier = state.lockIconButtonA11yId lockIconButton.accessibilityLabel = state.lockIconButtonA11yLabel - searchEngineImageView.accessibilityIdentifier = state.searchEngineImageViewA11yId - searchEngineImageView.accessibilityLabel = state.searchEngineImageViewA11yLabel - searchEngineImageView.largeContentTitle = state.searchEngineImageViewA11yLabel - searchEngineImageView.largeContentImage = nil - urlTextField.accessibilityIdentifier = state.urlTextFieldA11yId urlTextField.accessibilityLabel = state.urlTextFieldA11yLabel } @@ -421,7 +397,7 @@ final class LocationView: UIView, LocationTextFieldDelegate, ThemeApplicable, Ac urlTextFieldColor = colors.textPrimary urlTextFieldSubdomainColor = colors.textSecondary gradientLayer.colors = colors.layerGradientURL.cgColors.reversed() - searchEngineImageView.backgroundColor = colors.layer2 + searchEngineContentView.applyTheme(theme: theme) iconContainerBackgroundView.backgroundColor = colors.layerSearch lockIconButton.tintColor = colors.iconPrimary lockIconButton.backgroundColor = colors.layerSearch diff --git a/BrowserKit/Sources/ToolbarKit/AddressToolbar/LocationView/SearchEngineView.swift b/BrowserKit/Sources/ToolbarKit/AddressToolbar/LocationView/SearchEngineView.swift new file mode 100644 index 000000000000..22e17adc518d --- /dev/null +++ b/BrowserKit/Sources/ToolbarKit/AddressToolbar/LocationView/SearchEngineView.swift @@ -0,0 +1,74 @@ +// 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 + +final class SearchEngineView: UIView, ThemeApplicable { + // MARK: - Properties + private enum UX { + static let searchEngineImageViewCornerRadius: CGFloat = 4 + static let searchEngineImageViewSize = CGSize(width: 24, height: 24) + } + + private weak var delegate: LocationViewDelegate? // TODO Needed for FXIOS-10191 + private var isUnifiedSearchEnabled = false + + private lazy var searchEngineImageView: UIImageView = .build { imageView in + imageView.contentMode = .scaleAspectFit + imageView.layer.cornerRadius = UX.searchEngineImageViewCornerRadius + imageView.isAccessibilityElement = true + } + + // MARK: - Init + override init(frame: CGRect) { + super.init(frame: .zero) + setupLayout() + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + func configure(_ state: LocationViewState, delegate: LocationViewDelegate, isUnifiedSearchEnabled: Bool) { + searchEngineImageView.image = state.searchEngineImage + configureA11y(state) + self.delegate = delegate + self.isUnifiedSearchEnabled = isUnifiedSearchEnabled + } + + // MARK: - Layout + + private func setupLayout() { + translatesAutoresizingMaskIntoConstraints = true + addSubviews(searchEngineImageView) + + NSLayoutConstraint.activate([ + searchEngineImageView.heightAnchor.constraint(equalToConstant: UX.searchEngineImageViewSize.height), + searchEngineImageView.widthAnchor.constraint(equalToConstant: UX.searchEngineImageViewSize.width), + searchEngineImageView.leadingAnchor.constraint(equalTo: self.leadingAnchor), + searchEngineImageView.trailingAnchor.constraint(equalTo: self.trailingAnchor), + searchEngineImageView.topAnchor.constraint(greaterThanOrEqualTo: self.topAnchor), + searchEngineImageView.bottomAnchor.constraint(lessThanOrEqualTo: self.bottomAnchor), + searchEngineImageView.centerXAnchor.constraint(equalTo: self.centerXAnchor), + searchEngineImageView.centerYAnchor.constraint(equalTo: self.centerYAnchor), + ]) + } + + // MARK: - Accessibility + + private func configureA11y(_ state: LocationViewState) { + searchEngineImageView.accessibilityIdentifier = state.searchEngineImageViewA11yId + searchEngineImageView.accessibilityLabel = state.searchEngineImageViewA11yLabel + searchEngineImageView.largeContentTitle = state.searchEngineImageViewA11yLabel + searchEngineImageView.largeContentImage = nil + } + + // MARK: - ThemeApplicable + + func applyTheme(theme: Theme) { + let colors = theme.colors + searchEngineImageView.backgroundColor = colors.layer2 + } +}