Skip to content

Bugix [Content Sharing opt] fix home page activity and File copy to clipboard message #26167

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

Merged
merged 2 commits into from
Apr 24, 2025
Merged
Show file tree
Hide file tree
Changes from all 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
8 changes: 8 additions & 0 deletions firefox-ios/Client.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@
0B7C1E951F6097AD006A8869 /* TrackingProtectionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B7C1E941F6097AD006A8869 /* TrackingProtectionTests.swift */; };
0B7CF8872CAC1C4E00DC02F8 /* DefaultFolderHierarchyFetcherTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B7CF8862CAC1C4E00DC02F8 /* DefaultFolderHierarchyFetcherTests.swift */; };
0B7FC3D32CAE811F005C5CCE /* DefaultBookmarksSaverTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B7FC3D12CAE811B005C5CCE /* DefaultBookmarksSaverTests.swift */; };
0B81AFEC2DB1000C000AF70F /* HomePageActivity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B81AFEB2DB1000C000AF70F /* HomePageActivity.swift */; };
0B81AFEE2DB1036B000AF70F /* HomePageActivityTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B81AFED2DB1036B000AF70F /* HomePageActivityTests.swift */; };
0B8A39EF2D3514C100853E47 /* EditBookmarkDiffableDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B8A39EE2D3514C100853E47 /* EditBookmarkDiffableDataSource.swift */; };
0B8A39F12D351C2500853E47 /* EditBookmarkDataSourceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B8A39F02D351C2500853E47 /* EditBookmarkDataSourceTests.swift */; };
0B8BF3702CA2D60B00E9812D /* BookmarksViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B8BF36F2CA2D60B00E9812D /* BookmarksViewController.swift */; };
Expand Down Expand Up @@ -2432,6 +2434,8 @@
0B7C1E941F6097AD006A8869 /* TrackingProtectionTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrackingProtectionTests.swift; sourceTree = "<group>"; };
0B7CF8862CAC1C4E00DC02F8 /* DefaultFolderHierarchyFetcherTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefaultFolderHierarchyFetcherTests.swift; sourceTree = "<group>"; };
0B7FC3D12CAE811B005C5CCE /* DefaultBookmarksSaverTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefaultBookmarksSaverTests.swift; sourceTree = "<group>"; };
0B81AFEB2DB1000C000AF70F /* HomePageActivity.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomePageActivity.swift; sourceTree = "<group>"; };
0B81AFED2DB1036B000AF70F /* HomePageActivityTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomePageActivityTests.swift; sourceTree = "<group>"; };
0B8749EB891EE229EA88FEF3 /* kn */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = kn; path = kn.lproj/ErrorPages.strings; sourceTree = "<group>"; };
0B8A39EE2D3514C100853E47 /* EditBookmarkDiffableDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditBookmarkDiffableDataSource.swift; sourceTree = "<group>"; };
0B8A39F02D351C2500853E47 /* EditBookmarkDataSourceTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditBookmarkDataSourceTests.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -14025,6 +14029,7 @@
2128E27A292E624400FB91BE /* SendToDeviceActivity.swift */,
E1AFBAF8292EA0330065E35E /* SendToDeviceHelper.swift */,
D3972BF11C22412B00035B87 /* ShareManager.swift */,
0B81AFEB2DB1000C000AF70F /* HomePageActivity.swift */,
ED67B2952D0C921600BDC599 /* ShareTelemetry.swift */,
ED7A08DA2CF674730035EC8F /* ShareMessage.swift */,
ED7A08DC2CF6749B0035EC8F /* ShareType.swift */,
Expand Down Expand Up @@ -14820,6 +14825,7 @@
ED67B2932D0B80E200BDC599 /* TitleActivityItemProviderTests.swift */,
ED67B2912D0B79F000BDC599 /* TitleSubtitleActivityItemProviderTests.swift */,
ED33E3562D0A4CE9002265A7 /* URLActivityItemProviderTests.swift */,
0B81AFED2DB1036B000AF70F /* HomePageActivityTests.swift */,
);
path = Sharing;
sourceTree = "<group>";
Expand Down Expand Up @@ -17077,6 +17083,7 @@
C2D71B9B2A3850B4003DEC7A /* ThemedTableViewCellViewModel.swift in Sources */,
C869912F28917688007ACC5C /* WallpaperMetadataLoader.swift in Sources */,
8A6904802B97BBAE00E30047 /* SplashScreenAnimation.swift in Sources */,
0B81AFEC2DB1000C000AF70F /* HomePageActivity.swift in Sources */,
2137785D297F1F2800D01309 /* DownloadedFile.swift in Sources */,
1DCEC4142D83B7EB00129966 /* ASSearchEngineIconDataFetcher.swift in Sources */,
745DAB301CDAAFAA00D44181 /* RecentlyClosedTabsPanel.swift in Sources */,
Expand Down Expand Up @@ -18140,6 +18147,7 @@
8A8629E72880B7330096DDB1 /* LegacyBookmarksPanelTests.swift in Sources */,
61A1644A2CE7BE8A001D6058 /* WallpaperMiddlewareTests.swift in Sources */,
C8B394362A0ED55D00700E49 /* MockOnboardingCardDelegate.swift in Sources */,
0B81AFEE2DB1036B000AF70F /* HomePageActivityTests.swift in Sources */,
8A5604F829DF0D2600035CA3 /* BrowserCoordinatorTests.swift in Sources */,
8ABB15C92D5A4E3900A4635C /* RemoteTabsMiddlewareTests.swift in Sources */,
C787D8C32C1CB77900940123 /* FirefoxAccountSignInViewControllerTests.swift in Sources */,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,11 @@ class ShareSheetCoordinator: BaseCoordinator,
showSendToDevice(url: shareType.wrappedURL, relatedTab: nil)
}
case .copyToPasteboard:
showToast(text: .LegacyAppMenu.AppMenuCopyURLConfirmMessage)
if case .file = shareType {
showToast(text: .ShareFileCopiedToClipboard)
} else {
showToast(text: .LegacyAppMenu.AppMenuCopyURLConfirmMessage)
}
dequeueNotShownJSAlert()
default:
dequeueNotShownJSAlert()
Expand Down
38 changes: 38 additions & 0 deletions firefox-ios/Client/Frontend/Share/HomePageActivity.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// 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 Shared
import WebKit

/// The activity representing in the Share sheet the action to add a website to the iOS homepage.
///
/// - Note: the activity is a `WKWebView` cause the frameworks generates the add to home page activity only
/// when passing a `WKWebView`. This `WKWebView` subclass gives the ability to modify the content of the activity,
/// by modifying the title and/or the url.
class HomePageActivity: WKWebView {
private let stubbedURL: URL?
private let stubbedTitle: String?

init(url: URL?, title: String?) {
if let internalURL = InternalURL(url) {
stubbedURL = internalURL.extractedUrlParam
} else {
stubbedURL = url
}
stubbedTitle = title
super.init(frame: .zero, configuration: .init())
}

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

override var url: URL? {
return stubbedURL
}

override var title: String? {
return stubbedTitle
}
}
5 changes: 2 additions & 3 deletions firefox-ios/Client/Frontend/Share/ShareManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -115,9 +115,8 @@ class ShareManager: NSObject, FeatureFlaggable {

// Add the webview for an option to add a website to the iOS home screen
if #available(iOS 16.4, *), let webView = tab.webView {
// NOTE: You will not see "Add to Home Screen" option on debug builds. Possibly this is because of how the
// com.apple.developer.web-browser entitlement is applied...
activityItems.append(webView)
activityItems.append(HomePageActivity(url: webView.url,
title: webView.title))
}

if let explicitShareMessage {
Expand Down
5 changes: 5 additions & 0 deletions firefox-ios/Shared/Strings.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5401,6 +5401,11 @@ extension String {
tableName: nil,
value: "Add to Reading List",
comment: "Action label on share extension to add page to the Firefox reading list.")
public static let ShareFileCopiedToClipboard = MZLocalizedString(
key: "ShareExtension.FileCopiedToClipboard.Title.v139",
tableName: "Share",
value: "File Copied To Clipboard",
comment: "The Toast message that appears when the user press copy on the share sheet with a file like a pdf")
public static let ShareAddToReadingListDone = MZLocalizedString(
key: "ShareExtension.AddToReadingListActionDone.Title",
tableName: nil,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// 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 XCTest
import Common
import Shared
@testable import Client

final class HomePageActivityTests: XCTestCase {
func testInit_withOnlineURL_returnsSameURL() {
let urlString = "https://www.google.com"
let url = URL(string: urlString)!
let title = "test title"
let subject = createSubject(url: url, title: title)

XCTAssertEqual(subject.url, url)
XCTAssertEqual(subject.title, title)
RunLoop.current.run(until: Date().addingTimeInterval(0.1))
}

func testInit_withLocalURL_returnsNilURL() {
let urlString = "internal://fennec.test"
let url = URL(string: urlString)!
let subject = createSubject(url: url)

// has to be nil since we try only to unwrap the url param from internal url
XCTAssertNil(subject.url)
RunLoop.current.run(until: Date().addingTimeInterval(0.1))
}

func testInit_withLocalHostURL_returnsUnwrappedURLParameter() {
let innerUrl = "https//:www.google.com"
let urlString = "http://localhost:\(AppInfo.webserverPort)/?url=\(innerUrl)"
let url = URL(string: urlString)!
let subject = createSubject(url: url)

XCTAssertEqual(subject.url, URL(string: innerUrl))
// needed to fully deallocate the WKWebView
RunLoop.current.run(until: Date().addingTimeInterval(0.1))
}

private func createSubject(url: URL? = nil,
title: String? = nil) -> HomePageActivity {
let subject = HomePageActivity(url: url, title: title)
trackForMemoryLeaks(subject)
return subject
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ final class ShareManagerTests: XCTestCase {

_ = try XCTUnwrap(activityItems[safe: 1] as? TabPrintPageRenderer)

_ = try XCTUnwrap(activityItems[safe: 2] as? TabWebView)
_ = try XCTUnwrap(activityItems[safe: 2] as? HomePageActivity)

let titleActivityItemProvider = try XCTUnwrap(activityItems[safe: 3] as? TitleActivityItemProvider)
let itemForTitleActivity = titleActivityItemProvider.activityViewController(
Expand Down Expand Up @@ -244,7 +244,7 @@ final class ShareManagerTests: XCTestCase {

_ = try XCTUnwrap(activityItems[safe: 1] as? TabPrintPageRenderer)

_ = try XCTUnwrap(activityItems[safe: 2] as? TabWebView)
_ = try XCTUnwrap(activityItems[safe: 2] as? HomePageActivity)

let titleActivityItemProvider = try XCTUnwrap(activityItems[safe: 3] as? TitleActivityItemProvider)
let itemForTitleActivity = titleActivityItemProvider.activityViewController(
Expand Down Expand Up @@ -290,7 +290,7 @@ final class ShareManagerTests: XCTestCase {

_ = try XCTUnwrap(activityItems[safe: 1] as? TabPrintPageRenderer)

_ = try XCTUnwrap(activityItems[safe: 2] as? TabWebView)
_ = try XCTUnwrap(activityItems[safe: 2] as? HomePageActivity)

let titleActivityItemProvider = try XCTUnwrap(activityItems[safe: 3] as? TitleSubtitleActivityItemProvider)

Expand Down Expand Up @@ -339,7 +339,7 @@ final class ShareManagerTests: XCTestCase {
// The rest of the content should be unchanged from other tests:
_ = try XCTUnwrap(activityItems[safe: 1] as? TabPrintPageRenderer)

_ = try XCTUnwrap(activityItems[safe: 2] as? TabWebView)
_ = try XCTUnwrap(activityItems[safe: 2] as? HomePageActivity)

let titleActivityItemProvider = try XCTUnwrap(activityItems[safe: 3] as? TitleActivityItemProvider)
let itemForTitleActivity = titleActivityItemProvider.activityViewController(
Expand Down Expand Up @@ -389,7 +389,7 @@ final class ShareManagerTests: XCTestCase {
// The rest of the content should be unchanged from other tests:
_ = try XCTUnwrap(activityItems[safe: 1] as? TabPrintPageRenderer)

_ = try XCTUnwrap(activityItems[safe: 2] as? TabWebView)
_ = try XCTUnwrap(activityItems[safe: 2] as? HomePageActivity)

let titleActivityItemProvider = try XCTUnwrap(activityItems[safe: 3] as? TitleActivityItemProvider)
let itemForTitleActivity = titleActivityItemProvider.activityViewController(
Expand Down Expand Up @@ -437,7 +437,7 @@ final class ShareManagerTests: XCTestCase {
// The rest of the content should be unchanged from other tests:
_ = try XCTUnwrap(activityItems[safe: 1] as? TabPrintPageRenderer)

_ = try XCTUnwrap(activityItems[safe: 2] as? TabWebView)
_ = try XCTUnwrap(activityItems[safe: 2] as? HomePageActivity)

let titleActivityItemProvider = try XCTUnwrap(activityItems[safe: 3] as? TitleActivityItemProvider)
let itemForTitleActivity = titleActivityItemProvider.activityViewController(
Expand Down Expand Up @@ -485,7 +485,7 @@ final class ShareManagerTests: XCTestCase {
// The rest of the content should be unchanged from other tests:
_ = try XCTUnwrap(activityItems[safe: 1] as? TabPrintPageRenderer)

_ = try XCTUnwrap(activityItems[safe: 2] as? TabWebView)
_ = try XCTUnwrap(activityItems[safe: 2] as? HomePageActivity)

let titleActivityItemProvider = try XCTUnwrap(activityItems[safe: 3] as? TitleActivityItemProvider)
let itemForTitleActivity = titleActivityItemProvider.activityViewController(
Expand Down Expand Up @@ -535,7 +535,7 @@ final class ShareManagerTests: XCTestCase {
// The rest of the content should be unchanged from other tests:
_ = try XCTUnwrap(activityItems[safe: 1] as? TabPrintPageRenderer)

_ = try XCTUnwrap(activityItems[safe: 2] as? TabWebView)
_ = try XCTUnwrap(activityItems[safe: 2] as? HomePageActivity)

let titleActivityItemProvider = try XCTUnwrap(activityItems[safe: 3] as? TitleActivityItemProvider)
let itemForTitleActivity = titleActivityItemProvider.activityViewController(
Expand Down Expand Up @@ -592,7 +592,7 @@ final class ShareManagerTests: XCTestCase {
// The rest of the content should be unchanged from other tests:
_ = try XCTUnwrap(activityItems[safe: 1] as? TabPrintPageRenderer)

_ = try XCTUnwrap(activityItems[safe: 2] as? TabWebView)
_ = try XCTUnwrap(activityItems[safe: 2] as? HomePageActivity)

let titleActivityItemProvider = try XCTUnwrap(activityItems[safe: 3] as? TitleActivityItemProvider)
let itemForTitleActivity = titleActivityItemProvider.activityViewController(
Expand Down Expand Up @@ -651,7 +651,7 @@ final class ShareManagerTests: XCTestCase {
// The rest of the content should be unchanged from other tests:
_ = try XCTUnwrap(activityItems[safe: 1] as? TabPrintPageRenderer)

_ = try XCTUnwrap(activityItems[safe: 2] as? TabWebView)
_ = try XCTUnwrap(activityItems[safe: 2] as? HomePageActivity)

let titleActivityItemProvider = try XCTUnwrap(activityItems[safe: 3] as? TitleActivityItemProvider)
let itemForTitleActivity = titleActivityItemProvider.activityViewController(
Expand Down