Skip to content

Commit 5a85a66

Browse files
authored
Refactor FXIOS-7301 - Remove 2 closure_body_length violations from BrowserViewController+WebViewDelegates.swift (mozilla-mobile#20859)
* Extract if statement to a function * Extract inline closure to a function * Extract block code to a function * Remove redundant function This function is already defined in another extension of this class. * Remove fileprivate keyword * Extract toast block to a function * Create a protocol to control UIAction buttons * Create a builder class to implement the protocol * Implement AddOpenInNewTab method * Add new tab button using builder * Implement AddOpenInNewPrivateTab method * Add private tab using builder * Implement AddBookmarkLink method * Implement AddRemoveBookmarkLink method * Fix method signature * Add remove and add bookmark using builder * Implement AddDownload method * Add download using builder * Fix trailing whitespace * Implement AddCopyLink method * Add copy link using builder * Implement AddShare method * Add share using builder * Implement AddSaveImage method * Add save image using builder * Implement AddCopyImage method * Add copy image using builder * Implement AddCopyImageLink method * Add copy image link using builder * Rename functions to camel case * Rename variable * Align parameters * Implement build method * Get actions using builder * Move the construction of actions to a new function * Use the new function to create actions * Extract the verification if can handle actions to a new method * Revert "Extract the verification if can handle actions to a new method" This reverts commit 1fb97a127ae065dd6c8526a3501cd91ee47dd0ea. * Move the entire toast construction to a specific method * Extract addTab to a new function * Use the new function to add tab * Remove unused local function * Remove the protocol The builder can works without a protocol. For now, we won't have different implementations of it. * Move ActionProviderBuilder to a specific file * Rebase fixes
1 parent 4075d99 commit 5a85a66

File tree

4 files changed

+341
-238
lines changed

4 files changed

+341
-238
lines changed

firefox-ios/Client.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -564,6 +564,7 @@
564564
782B0A362AB41DFC0049EE1A /* FakespotTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 782B0A352AB41DFC0049EE1A /* FakespotTests.swift */; };
565565
787EDD852943EE75002B93AE /* JumpBackInTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 787EDD832943EE75002B93AE /* JumpBackInTests.swift */; };
566566
78FE1E892B040E7000338465 /* FirefoxSuggestTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78FE1E872B040E7000338465 /* FirefoxSuggestTest.swift */; };
567+
7ADC1D192C27D35B003ED924 /* ActionProviderBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7ADC1D182C27D35B003ED924 /* ActionProviderBuilder.swift */; };
567568
7B10AA9F1E3A15020002DD08 /* DataExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B10AA9E1E3A15020002DD08 /* DataExtensions.swift */; };
568569
7B10AABB1E3A1F650002DD08 /* URLRequestExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B10AABA1E3A1F650002DD08 /* URLRequestExtensions.swift */; };
569570
7B2142FE1E5E055000CDD3FC /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7B2142FC1E5E055000CDD3FC /* InfoPlist.strings */; };
@@ -6055,6 +6056,7 @@
60556056
7AC2423EA6277664A0D3398B /* af */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = af; path = af.lproj/InfoPlist.strings; sourceTree = "<group>"; };
60566057
7ACC4EB59896863B677D102A /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/ClearHistoryConfirm.strings; sourceTree = "<group>"; };
60576058
7AD14377A3F3B824C049E709 /* ta */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ta; path = ta.lproj/PrivateBrowsing.strings; sourceTree = "<group>"; };
6059+
7ADC1D182C27D35B003ED924 /* ActionProviderBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionProviderBuilder.swift; sourceTree = "<group>"; };
60586060
7AEF4108BAAE5BBD5949E64C /* en-CA */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "en-CA"; path = "en-CA.lproj/FindInPage.strings"; sourceTree = "<group>"; };
60596061
7B0A456E95C86CC158227349 /* kab */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = kab; path = kab.lproj/PrivateBrowsing.strings; sourceTree = "<group>"; };
60606062
7B0B49C7B69DC54BC3CA5972 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/ErrorPages.strings; sourceTree = "<group>"; };
@@ -9563,6 +9565,7 @@
95639565
isa = PBXGroup;
95649566
children = (
95659567
5A2918CA2B522338002B197E /* GeneralBrowserAction.swift */,
9568+
7ADC1D182C27D35B003ED924 /* ActionProviderBuilder.swift */,
95669569
);
95679570
path = Actions;
95689571
sourceTree = "<group>";
@@ -15086,6 +15089,7 @@
1508615089
4393932029AC6CE900DC5A85 /* EnvironmentValues+Extension.swift in Sources */,
1508715090
ABEF80D12A24D2BE003F52C4 /* CreditCardBottomSheetViewModel.swift in Sources */,
1508815091
21AFCFF02AE80D370027E9CE /* RemoteTabsCoordinator.swift in Sources */,
15092+
7ADC1D192C27D35B003ED924 /* ActionProviderBuilder.swift in Sources */,
1508915093
43162A2F2492DB7800F91658 /* EmptyPrivateTabsView.swift in Sources */,
1509015094
E1380B8D2AEA897C00630AFA /* SidebarEnabledView.swift in Sources */,
1509115095
D0625C98208E87F10081F3B2 /* DownloadQueue.swift in Sources */,
Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
// This Source Code Form is subject to the terms of the Mozilla Public
2+
// License, v. 2.0. If a copy of the MPL was not distributed with this
3+
// file, You can obtain one at http://mozilla.org/MPL/2.0/
4+
5+
import Common
6+
import WebKit
7+
import Photos
8+
import Shared
9+
10+
class ActionProviderBuilder {
11+
private var actions = [UIAction]()
12+
13+
func build() -> [UIAction] {
14+
return actions
15+
}
16+
17+
func addOpenInNewTab(url: URL, currentTab: Tab, addTab: @escaping (URL, Bool, Tab) -> Void) {
18+
actions.append(
19+
UIAction(
20+
title: .ContextMenuOpenInNewTab,
21+
image: UIImage.templateImageNamed(StandardImageIdentifiers.Large.plus),
22+
identifier: UIAction.Identifier(rawValue: "linkContextMenu.openInNewTab")
23+
) { _ in
24+
addTab(url, false, currentTab)
25+
})
26+
}
27+
28+
func addOpenInNewPrivateTab(url: URL, currentTab: Tab, addTab: @escaping (URL, Bool, Tab) -> Void) {
29+
actions.append(
30+
UIAction(
31+
title: .ContextMenuOpenInNewPrivateTab,
32+
image: UIImage.templateImageNamed(StandardImageIdentifiers.Large.privateMode),
33+
identifier: UIAction.Identifier("linkContextMenu.openInNewPrivateTab")
34+
) { _ in
35+
addTab(url, true, currentTab)
36+
})
37+
}
38+
39+
func addBookmarkLink(url: URL, title: String?, addBookmark: @escaping (String, String?) -> Void) {
40+
actions.append(
41+
UIAction(
42+
title: .ContextMenuBookmarkLink,
43+
image: UIImage.templateImageNamed(StandardImageIdentifiers.Large.bookmark),
44+
identifier: UIAction.Identifier("linkContextMenu.bookmarkLink")
45+
) { _ in
46+
addBookmark(url.absoluteString, title)
47+
TelemetryWrapper.recordEvent(category: .action,
48+
method: .add,
49+
object: .bookmark,
50+
value: .contextMenu)
51+
}
52+
)
53+
}
54+
55+
func addRemoveBookmarkLink(url: URL, title: String?, removeBookmark: @escaping (URL, String?) -> Void) {
56+
actions.append(
57+
UIAction(
58+
title: .RemoveBookmarkContextMenuTitle,
59+
image: UIImage.templateImageNamed(StandardImageIdentifiers.Large.cross),
60+
identifier: UIAction.Identifier("linkContextMenu.removeBookmarkLink")
61+
) { _ in
62+
removeBookmark(url, title)
63+
TelemetryWrapper.recordEvent(category: .action,
64+
method: .delete,
65+
object: .bookmark,
66+
value: .contextMenu)
67+
}
68+
)
69+
}
70+
71+
func addDownload(url: URL, currentTab: Tab, assignWebView: @escaping (WKWebView?) -> Void) {
72+
actions.append(UIAction(
73+
title: .ContextMenuDownloadLink,
74+
image: UIImage.templateImageNamed(
75+
StandardImageIdentifiers.Large.download
76+
),
77+
identifier: UIAction.Identifier("linkContextMenu.download")
78+
) { _ in
79+
// This checks if download is a blob, if yes, begin blob download process
80+
if !DownloadContentScript.requestBlobDownload(url: url, tab: currentTab) {
81+
// if not a blob, set pendingDownloadWebView and load the request in
82+
// the webview, which will trigger the WKWebView navigationResponse
83+
// delegate function and eventually downloadHelper.open()
84+
assignWebView(currentTab.webView)
85+
let request = URLRequest(url: url)
86+
currentTab.webView?.load(request)
87+
}
88+
})
89+
}
90+
91+
func addCopyLink(url: URL) {
92+
actions.append(UIAction(
93+
title: .ContextMenuCopyLink,
94+
image: UIImage.templateImageNamed(StandardImageIdentifiers.Large.link),
95+
identifier: UIAction.Identifier("linkContextMenu.copyLink")
96+
) { _ in
97+
UIPasteboard.general.url = url
98+
})
99+
}
100+
101+
func addShare(url: URL,
102+
tabManager: TabManager,
103+
webView: WKWebView,
104+
view: UIView,
105+
navigationHandler: BrowserNavigationHandler?,
106+
contentContainer: ContentContainer) {
107+
actions.append(UIAction(
108+
title: .ContextMenuShareLink,
109+
image: UIImage.templateImageNamed(StandardImageIdentifiers.Large.shareApple),
110+
identifier: UIAction.Identifier("linkContextMenu.share")
111+
) { _ in
112+
guard let tab = tabManager[webView],
113+
let helper = tab.getContentScript(name: ContextMenuHelper.name()) as? ContextMenuHelper
114+
else { return }
115+
116+
// This is only used on ipad for positioning the popover. On iPhone it is an action sheet.
117+
let point = webView.convert(helper.touchPoint, to: view)
118+
navigationHandler?.showShareExtension(
119+
url: url,
120+
sourceView: view,
121+
sourceRect: CGRect(origin: point, size: CGSize(width: 10.0, height: 10.0)),
122+
toastContainer: contentContainer,
123+
popoverArrowDirection: .unknown
124+
)
125+
})
126+
}
127+
128+
func addSaveImage(url: URL,
129+
getImageData: @escaping (URL, @escaping (Data) -> Void) -> Void,
130+
writeToPhotoAlbum: @escaping (UIImage) -> Void) {
131+
actions.append(UIAction(
132+
title: .ContextMenuSaveImage,
133+
identifier: UIAction.Identifier("linkContextMenu.saveImage")
134+
) { _ in
135+
getImageData(url) { data in
136+
if url.pathExtension.lowercased() == "gif" {
137+
PHPhotoLibrary.shared().performChanges {
138+
let creationRequest = PHAssetCreationRequest.forAsset()
139+
creationRequest.addResource(with: .photo, data: data, options: nil)
140+
}
141+
} else {
142+
guard let image = UIImage(data: data) else { return }
143+
writeToPhotoAlbum(image)
144+
}
145+
}
146+
})
147+
}
148+
149+
func addCopyImage(url: URL) {
150+
actions.append(UIAction(
151+
title: .ContextMenuCopyImage,
152+
identifier: UIAction.Identifier("linkContextMenu.copyImage")
153+
) { _ in
154+
// put the actual image on the clipboard
155+
// do this asynchronously just in case we're in a low bandwidth situation
156+
let pasteboard = UIPasteboard.general
157+
pasteboard.url = url as URL
158+
let changeCount = pasteboard.changeCount
159+
let application = UIApplication.shared
160+
var taskId = UIBackgroundTaskIdentifier(rawValue: 0)
161+
taskId = application.beginBackgroundTask(expirationHandler: {
162+
application.endBackgroundTask(taskId)
163+
})
164+
165+
makeURLSession(
166+
userAgent: UserAgent.fxaUserAgent,
167+
configuration: URLSessionConfiguration.default
168+
).dataTask(with: url) { (data, response, error) in
169+
guard validatedHTTPResponse(response, statusCode: 200..<300) != nil else {
170+
application.endBackgroundTask(taskId)
171+
return
172+
}
173+
174+
// Only set the image onto the pasteboard if the pasteboard hasn't changed since
175+
// fetching the image; otherwise, in low-bandwidth situations,
176+
// we might be overwriting something that the user has subsequently added.
177+
if changeCount == pasteboard.changeCount,
178+
let imageData = data,
179+
error == nil {
180+
pasteboard.addImageWithData(imageData, forURL: url)
181+
}
182+
183+
application.endBackgroundTask(taskId)
184+
}.resume()
185+
})
186+
}
187+
188+
func addCopyImageLink(url: URL) {
189+
actions.append(UIAction(
190+
title: .ContextMenuCopyImageLink,
191+
identifier: UIAction.Identifier("linkContextMenu.copyImageLink")
192+
) { _ in
193+
UIPasteboard.general.url = url as URL
194+
})
195+
}
196+
}

0 commit comments

Comments
 (0)