diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 000000000..c565e54a4 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,51 @@ +name: Build Ghostery + +on: + push: + branches: [main] + pull_request: + branches: [main] + +jobs: + test: + runs-on: macos-latest-xl + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Setup branding + run: sh Branding/setup.sh Ghostery ./ + - name: Install Nodejs + uses: actions/setup-node@v3 + with: + node-version-file: '.tool-versions' + cache: 'npm' + cache-dependency-path: ./package-lock.json + - name: Instal Node Modules + run: npm ci + - name: Build content scripts + run: npm run build-user-scripts + - name: Install Ruby + uses: ruby/setup-ruby@v1 + with: + bundler-cache: true + - name: Setup CocoaPods cache + uses: actions/cache@v2 + id: cocoapods-cache + with: + path: Pods + key: ${{ runner.os }}-pods-${{ hashFiles('**/Podfile.lock') }} + restore-keys: | + ${{ runner.os }}-pods- + - name: Update Cocoapods + if: steps.cocoapods-cache.outputs.cache-hit != 'true' + run: bundle exec pod install --repo-update + - name: Build + uses: sersoft-gmbh/xcodebuild-action@v2 + with: + workspace: UserAgent.xcworkspace + scheme: Ghostery + configuration: CI + sdk: iphonesimulator + destination: platform=iOS Simulator,name=iPhone 14 + action: build + output-formatter: 'bundle exec xcpretty' diff --git a/.node-version b/.node-version deleted file mode 100644 index b06cd07c4..000000000 --- a/.node-version +++ /dev/null @@ -1 +0,0 @@ -12.18.0 diff --git a/.ruby-version b/.ruby-version deleted file mode 100644 index 57cf282eb..000000000 --- a/.ruby-version +++ /dev/null @@ -1 +0,0 @@ -2.6.5 diff --git a/.tool-versions b/.tool-versions new file mode 100644 index 000000000..ae06f256f --- /dev/null +++ b/.tool-versions @@ -0,0 +1,2 @@ +nodejs 16.20.0 +ruby 2.7.3 \ No newline at end of file diff --git a/Branding/Ghostery/Assets/brand.xcassets/logo.imageset/Contents.json b/Branding/Ghostery/Assets/brand.xcassets/logo.imageset/Contents.json index 88ff645db..06a331903 100644 --- a/Branding/Ghostery/Assets/brand.xcassets/logo.imageset/Contents.json +++ b/Branding/Ghostery/Assets/brand.xcassets/logo.imageset/Contents.json @@ -1,17 +1,17 @@ { "images" : [ { - "filename" : "ghostery-wordmark-white (2).png", + "filename" : "ghostery-wordmark-white-1x.png", "idiom" : "universal", "scale" : "1x" }, { - "filename" : "ghostery-wordmark-white (3).png", + "filename" : "ghostery-wordmark-white-2x.png", "idiom" : "universal", "scale" : "2x" }, { - "filename" : "ghostery-wordmark-white (4).png", + "filename" : "ghostery-wordmark-white-3x.png", "idiom" : "universal", "scale" : "3x" } diff --git a/Branding/Ghostery/Assets/brand.xcassets/logo.imageset/ghostery-wordmark-white (2).png b/Branding/Ghostery/Assets/brand.xcassets/logo.imageset/ghostery-wordmark-white (2).png deleted file mode 100644 index 066f75eb9..000000000 Binary files a/Branding/Ghostery/Assets/brand.xcassets/logo.imageset/ghostery-wordmark-white (2).png and /dev/null differ diff --git a/Branding/Ghostery/Assets/brand.xcassets/logo.imageset/ghostery-wordmark-white (3).png b/Branding/Ghostery/Assets/brand.xcassets/logo.imageset/ghostery-wordmark-white (3).png deleted file mode 100644 index e90e12b23..000000000 Binary files a/Branding/Ghostery/Assets/brand.xcassets/logo.imageset/ghostery-wordmark-white (3).png and /dev/null differ diff --git a/Branding/Ghostery/Assets/brand.xcassets/logo.imageset/ghostery-wordmark-white (4).png b/Branding/Ghostery/Assets/brand.xcassets/logo.imageset/ghostery-wordmark-white (4).png deleted file mode 100644 index 45dfa1fb7..000000000 Binary files a/Branding/Ghostery/Assets/brand.xcassets/logo.imageset/ghostery-wordmark-white (4).png and /dev/null differ diff --git a/Branding/Ghostery/Assets/brand.xcassets/logo.imageset/ghostery-wordmark-white-1x.png b/Branding/Ghostery/Assets/brand.xcassets/logo.imageset/ghostery-wordmark-white-1x.png new file mode 100644 index 000000000..712de459c Binary files /dev/null and b/Branding/Ghostery/Assets/brand.xcassets/logo.imageset/ghostery-wordmark-white-1x.png differ diff --git a/Branding/Ghostery/Assets/brand.xcassets/logo.imageset/ghostery-wordmark-white-2x.png b/Branding/Ghostery/Assets/brand.xcassets/logo.imageset/ghostery-wordmark-white-2x.png new file mode 100644 index 000000000..b7a7d4596 Binary files /dev/null and b/Branding/Ghostery/Assets/brand.xcassets/logo.imageset/ghostery-wordmark-white-2x.png differ diff --git a/Branding/Ghostery/Assets/brand.xcassets/logo.imageset/ghostery-wordmark-white-3x.png b/Branding/Ghostery/Assets/brand.xcassets/logo.imageset/ghostery-wordmark-white-3x.png new file mode 100644 index 000000000..7050d06e6 Binary files /dev/null and b/Branding/Ghostery/Assets/brand.xcassets/logo.imageset/ghostery-wordmark-white-3x.png differ diff --git a/Branding/Ghostery/Configuration/GhosteryAdHoc.xcconfig b/Branding/Ghostery/Configuration/GhosteryAdHoc.xcconfig index f8dd9a646..6355b1cb4 100644 --- a/Branding/Ghostery/Configuration/GhosteryAdHoc.xcconfig +++ b/Branding/Ghostery/Configuration/GhosteryAdHoc.xcconfig @@ -1,11 +1,11 @@ // Display name -BUNDLE_DISPLAY_NAME = Ghostery Dawn +BUNDLE_DISPLAY_NAME = Ghostery Private Browser // Bundle Identifier APP_BUNDLE_ID = com.ghostery.browser.nightly // Marketing version -APP_MARKETING_VERSION = 3.1.1 +APP_MARKETING_VERSION = 3.2.0 // URL Scheme USER_AGENT_URL_SCHEME = GhosteryNightly diff --git a/Branding/Ghostery/Configuration/GhosteryDebug.xcconfig b/Branding/Ghostery/Configuration/GhosteryDebug.xcconfig index eace9fba3..1ab7dc048 100644 --- a/Branding/Ghostery/Configuration/GhosteryDebug.xcconfig +++ b/Branding/Ghostery/Configuration/GhosteryDebug.xcconfig @@ -1,11 +1,11 @@ // Display name -BUNDLE_DISPLAY_NAME = Ghostery Dawn +BUNDLE_DISPLAY_NAME = Ghostery Private Browser // Bundle Identifier APP_BUNDLE_ID = com.ghostery.browser // Marketing version -APP_MARKETING_VERSION = 3.1.1 +APP_MARKETING_VERSION = 3.2.0 // URL Scheme USER_AGENT_URL_SCHEME = GhosteryDebug diff --git a/Branding/Ghostery/Configuration/GhosteryRelease.xcconfig b/Branding/Ghostery/Configuration/GhosteryRelease.xcconfig index 7ab915658..2c95c4e82 100644 --- a/Branding/Ghostery/Configuration/GhosteryRelease.xcconfig +++ b/Branding/Ghostery/Configuration/GhosteryRelease.xcconfig @@ -1,11 +1,11 @@ // Display name -BUNDLE_DISPLAY_NAME = Ghostery Dawn +BUNDLE_DISPLAY_NAME = Ghostery Private Browser // Bundle Identifier APP_BUNDLE_ID = com.evidon.Ghostery // Marketing version -APP_MARKETING_VERSION = 3.1.1 +APP_MARKETING_VERSION = 3.2.0 // URL Scheme USER_AGENT_URL_SCHEME = Ghostery diff --git a/Branding/Ghostery/Entitlements/GhosteryAdHoc.entitlements b/Branding/Ghostery/Entitlements/GhosteryAdHoc.entitlements index e76cb161b..58054652c 100644 --- a/Branding/Ghostery/Entitlements/GhosteryAdHoc.entitlements +++ b/Branding/Ghostery/Entitlements/GhosteryAdHoc.entitlements @@ -2,8 +2,6 @@ - com.apple.developer.web-browser - com.apple.security.application-groups group.com.evidon.Ghostery.browser.nightly diff --git a/Branding/Ghostery/Entitlements/GhosteryDebug.entitlements b/Branding/Ghostery/Entitlements/GhosteryDebug.entitlements index c02ba18a6..798bfd20b 100644 --- a/Branding/Ghostery/Entitlements/GhosteryDebug.entitlements +++ b/Branding/Ghostery/Entitlements/GhosteryDebug.entitlements @@ -2,8 +2,6 @@ - com.apple.developer.web-browser - com.apple.security.application-groups group.com.ghostery.browser diff --git a/Branding/Ghostery/InfoPlists/OpenIn/de.lproj/InfoPlist.strings b/Branding/Ghostery/InfoPlists/OpenIn/de.lproj/InfoPlist.strings index 7030e568c..87b373c70 100644 --- a/Branding/Ghostery/InfoPlists/OpenIn/de.lproj/InfoPlist.strings +++ b/Branding/Ghostery/InfoPlists/OpenIn/de.lproj/InfoPlist.strings @@ -6,4 +6,4 @@ Copyright © 2020 Cliqz. All rights reserved. */ -"CFBundleDisplayName" = "In Ghostery Dawn öffnen"; +"CFBundleDisplayName" = "In Ghostery Private Browser öffnen"; diff --git a/Branding/Ghostery/InfoPlists/OpenIn/en.lproj/InfoPlist.strings b/Branding/Ghostery/InfoPlists/OpenIn/en.lproj/InfoPlist.strings index f375ea51c..01171cc15 100644 --- a/Branding/Ghostery/InfoPlists/OpenIn/en.lproj/InfoPlist.strings +++ b/Branding/Ghostery/InfoPlists/OpenIn/en.lproj/InfoPlist.strings @@ -6,4 +6,4 @@ Copyright © 2020 Cliqz. All rights reserved. */ -"CFBundleDisplayName" = "Open In Ghostery Dawn"; +"CFBundleDisplayName" = "Open In Ghostery Private Browser"; diff --git a/Branding/Ghostery/Siri/de.lproj/Intents.strings b/Branding/Ghostery/Siri/de.lproj/Intents.strings index 0aebdef3d..3b8c67c94 100644 --- a/Branding/Ghostery/Siri/de.lproj/Intents.strings +++ b/Branding/Ghostery/Siri/de.lproj/Intents.strings @@ -1,10 +1,10 @@ "3fYgNr" = "Suchanfrage"; -"WogcPW" = "Suche mit Ghostery Dawn"; +"WogcPW" = "Suche mit Ghostery Private Browser"; "ZrmRcJ" = "Wonach möchtest du suchen?"; -"nChTLr" = "Mit Ghostery Dawn suchen"; +"nChTLr" = "Mit Ghostery Private Browser suchen"; -"uYCcdq" = "Suche mit Ghostery Dawn"; +"uYCcdq" = "Suche mit Ghostery Private Browser"; diff --git a/Branding/Ghostery/Siri/en.lproj/Intents.strings b/Branding/Ghostery/Siri/en.lproj/Intents.strings index c3e158116..e537efe30 100644 --- a/Branding/Ghostery/Siri/en.lproj/Intents.strings +++ b/Branding/Ghostery/Siri/en.lproj/Intents.strings @@ -1,10 +1,10 @@ "3fYgNr" = "Query"; -"WogcPW" = "Search With Ghostery Dawn"; +"WogcPW" = "Search With Ghostery Private Browser"; "ZrmRcJ" = "What do you want to search?"; -"nChTLr" = "Search query with Ghostery Dawn"; +"nChTLr" = "Search query with Ghostery Private Browser"; -"uYCcdq" = "Search With Ghostery Dawn"; +"uYCcdq" = "Search With Ghostery Private Browser"; diff --git a/Brewfile b/Brewfile deleted file mode 100644 index 2be0a7489..000000000 --- a/Brewfile +++ /dev/null @@ -1,5 +0,0 @@ -# for some reason we cannot install watchman in CI, it works when installed manually - -brew 'nodenv' -brew 'rbenv' -brew 'watchman' diff --git a/Client/Application/AppDelegate.swift b/Client/Application/AppDelegate.swift index 5af7297e2..210838a52 100644 --- a/Client/Application/AppDelegate.swift +++ b/Client/Application/AppDelegate.swift @@ -412,7 +412,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UIViewControllerRestorati // readable from extensions, so they can just use the cached identifier. SDWebImageDownloader.shared.setValue(firefoxUA, forHTTPHeaderField: "User-Agent") - //SDWebImage is setting accept headers that report we support webp. We don't + // SDWebImage is setting accept headers that report we support webp. We don't SDWebImageDownloader.shared.setValue("image/*;q=0.8", forHTTPHeaderField: "Accept") FaviconFetcher.userAgent = UserAgent.desktopUserAgent() diff --git a/Client/Application/NavigationRouter.swift b/Client/Application/NavigationRouter.swift index bb65145cd..7dd24711d 100644 --- a/Client/Application/NavigationRouter.swift +++ b/Client/Application/NavigationRouter.swift @@ -140,9 +140,9 @@ enum NavigationPath { private static func handleHomePanel(panel: HomePanelPath, with bvc: BrowserViewController) { switch panel { - case .bookmarks: break //Todo: #228 show bookmarks - case .history: break //Todo: #228 show history - case .downloads: break //Todo: #228 show downloads + case .bookmarks: break // Todo: #228 show bookmarks + case .history: break // Todo: #228 show history + case .downloads: break // Todo: #228 show downloads case .topSites: bvc.openURLInNewTab(HomePanelType.topSites.internalUrl, isPrivileged: true) case .newPrivateTab: bvc.openBlankNewTab(focusLocationField: false, isPrivate: true) } diff --git a/Client/Assets/Search/SearchPlugins/ghostery-glow.xml b/Client/Assets/Search/SearchPlugins/ghostery-glow.xml index 54c497c14..d1e46957b 100644 --- a/Client/Assets/Search/SearchPlugins/ghostery-glow.xml +++ b/Client/Assets/Search/SearchPlugins/ghostery-glow.xml @@ -4,16 +4,16 @@ - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> - Ghostery Glow + Ghostery Private Search data:image/png;base64,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 - + - + - + - + - https://glowstery.com + https://ghosterysearch.com diff --git a/Client/DocumentServicesHelper.swift b/Client/DocumentServicesHelper.swift index c7770e189..00caed9c0 100644 --- a/Client/DocumentServicesHelper.swift +++ b/Client/DocumentServicesHelper.swift @@ -13,8 +13,8 @@ protocol DocumentAnalyser { } struct LanguageDetector: DocumentAnalyser { - let name = "language" //This key matches the DerivedMetadata property - typealias NewMetadata = String //This matches the value for the DerivedMetadata key above + let name = "language" // This key matches the DerivedMetadata property + typealias NewMetadata = String // This matches the value for the DerivedMetadata key above func analyse(metadata: PageMetadata) -> LanguageDetector.NewMetadata? { if let metadataLanguage = metadata.language { diff --git a/Client/Frontend/Browser/BackForwardListViewController.swift b/Client/Frontend/Browser/BackForwardListViewController.swift index bb9ee3082..2594d08e5 100644 --- a/Client/Frontend/Browser/BackForwardListViewController.swift +++ b/Client/Frontend/Browser/BackForwardListViewController.swift @@ -116,7 +116,7 @@ class BackForwardListViewController: UIViewController, UITableViewDataSource, UI func homeAndNormalPagesOnly(_ bfList: WKBackForwardList) { let items = bfList.forwardList.reversed() + [bfList.currentItem].compactMap({$0}) + bfList.backList.reversed() - //error url's are OK as they are used to populate history on session restore. + // error url's are OK as they are used to populate history on session restore. listData = items.filter { guard let internalUrl = InternalURL($0.url) else { return true } if internalUrl.isAboutHomeURL { diff --git a/Client/Frontend/Browser/BrowserTrayAnimators.swift b/Client/Frontend/Browser/BrowserTrayAnimators.swift index 29b5b7941..c608286ef 100644 --- a/Client/Frontend/Browser/BrowserTrayAnimators.swift +++ b/Client/Frontend/Browser/BrowserTrayAnimators.swift @@ -27,7 +27,7 @@ private extension TrayToBrowserAnimator { let displayedTabs = selectedTab.isPrivate ? tabManager.privateTabs : tabManager.normalTabs guard let expandFromIndex = displayedTabs.firstIndex(of: selectedTab) else { return } - //Disable toolbar until animation completes + // Disable toolbar until animation completes tabTray.toolbar.isUserInteractionEnabled = false bvc.view.frame = transitionContext.finalFrame(for: bvc) @@ -133,7 +133,7 @@ private extension BrowserToTrayAnimator { let displayedTabs = selectedTab.isPrivate ? tabManager.privateTabs : tabManager.normalTabs guard let scrollToIndex = displayedTabs.firstIndex(of: selectedTab) else { return } - //Disable toolbar until animation completes + // Disable toolbar until animation completes tabTray.toolbar.isUserInteractionEnabled = false tabTray.view.frame = transitionContext.finalFrame(for: tabTray) diff --git a/Client/Frontend/Browser/BrowserViewController.swift b/Client/Frontend/Browser/BrowserViewController.swift index 1b9bc565a..7cd536047 100644 --- a/Client/Frontend/Browser/BrowserViewController.swift +++ b/Client/Frontend/Browser/BrowserViewController.swift @@ -833,7 +833,7 @@ class BrowserViewController: UIViewController { } let blurEffect = UIBlurEffect(style: .light) let blurEffectView = UIVisualEffectView(effect: blurEffect) - //always fill the view + // always fill the view blurEffectView.frame = self.view.bounds blurEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight] self.view.addSubview(blurEffectView) @@ -2065,7 +2065,7 @@ extension BrowserViewController: ContextMenuHelperDelegate { let downloadAction = UIAlertAction(title: Strings.ContextMenu.DownloadLink, style: .default) { _ in // This checks if download is a blob, if yes, begin blob download process if !DownloadContentScript.requestBlobDownload(url: url, tab: currentTab) { - //if not a blob, set pendingDownloadWebView and load the request in the webview, which will trigger the WKWebView navigationResponse delegate function and eventually downloadHelper.open() + // if not a blob, set pendingDownloadWebView and load the request in the webview, which will trigger the WKWebView navigationResponse delegate function and eventually downloadHelper.open() self.pendingDownloadWebView = currentTab.webView let request = URLRequest(url: url) currentTab.webView?.load(request) @@ -2178,10 +2178,10 @@ extension BrowserViewController: ContextMenuHelperDelegate { } } - //Support for CMD+ Click on link to open in a new tab + // Support for CMD+ Click on link to open in a new tab override func pressesBegan(_ presses: Set, with event: UIPressesEvent?) { super.pressesBegan(presses, with: event) - guard let key = presses.first?.key, (key.keyCode == .keyboardLeftGUI || key.keyCode == .keyboardRightGUI) else { return } //GUI buttons = CMD buttons on ipad/mac + guard let key = presses.first?.key, (key.keyCode == .keyboardLeftGUI || key.keyCode == .keyboardRightGUI) else { return } // GUI buttons = CMD buttons on ipad/mac self.isCmdClickForNewTab = true } diff --git a/Client/Frontend/Browser/BrowserViewController/BrowserViewController+WebViewDelegates.swift b/Client/Frontend/Browser/BrowserViewController/BrowserViewController+WebViewDelegates.swift index 8f3fd8a46..ba3e434c7 100644 --- a/Client/Frontend/Browser/BrowserViewController/BrowserViewController+WebViewDelegates.swift +++ b/Client/Frontend/Browser/BrowserViewController/BrowserViewController+WebViewDelegates.swift @@ -152,7 +152,7 @@ extension BrowserViewController: WKUIDelegate { actions.append(UIAction(title: Strings.ContextMenu.DownloadLink, image: UIImage.templateImageNamed("menu-panel-Downloads"), identifier: UIAction.Identifier("linkContextMenu.download")) {_ in // This checks if download is a blob, if yes, begin blob download process if !DownloadContentScript.requestBlobDownload(url: url, tab: currentTab) { - //if not a blob, set pendingDownloadWebView and load the request in the webview, which will trigger the WKWebView navigationResponse delegate function and eventually downloadHelper.open() + // if not a blob, set pendingDownloadWebView and load the request in the webview, which will trigger the WKWebView navigationResponse delegate function and eventually downloadHelper.open() self.pendingDownloadWebView = currentTab.webView let request = URLRequest(url: url) currentTab.webView?.load(request) diff --git a/Client/Frontend/Browser/Punycode.swift b/Client/Frontend/Browser/Punycode.swift index 6fe52c2a8..826f2c8b1 100644 --- a/Client/Frontend/Browser/Punycode.swift +++ b/Client/Frontend/Browser/Punycode.swift @@ -9,7 +9,7 @@ private let tMin = 1 private let tMax = 26 private let initialBias = 72 private let initialN: Int = 128 // 0x80 -private let delimiter: Character = "-"; // '\x2D' +private let delimiter: Character = "-" // '\x2D' private let prefixPunycode = "xn--" private let asciiPunycode = Array("abcdefghijklmnopqrstuvwxyz0123456789") diff --git a/Client/Frontend/Browser/ScreenshotHelper.swift b/Client/Frontend/Browser/ScreenshotHelper.swift index 5b5acd74f..3ffdd219d 100644 --- a/Client/Frontend/Browser/ScreenshotHelper.swift +++ b/Client/Frontend/Browser/ScreenshotHelper.swift @@ -28,16 +28,16 @@ class ScreenshotHelper { Sentry.shared.send(message: "Tab Snapshot Error", tag: .tabManager, severity: .debug, description: "Tab webView or url is nil") return } - //Handle home page snapshots, can not use Apple API snapshot function for this + // Handle home page snapshots, can not use Apple API snapshot function for this if InternalURL(url)?.isAboutHomeURL ?? false { if let homePanel = controller?.homeViewController { let screenshot = homePanel.view.screenshot(quality: UIConstants.ActiveScreenshotQuality) tab.setScreenshot(screenshot) } - //Handle webview screenshots + // Handle webview screenshots } else { let configuration = WKSnapshotConfiguration() - //This is for a bug in certain iOS 13 versions, snapshots cannot be taken correctly without this boolean being set + // This is for a bug in certain iOS 13 versions, snapshots cannot be taken correctly without this boolean being set if #available(iOS 13.0, *) { configuration.afterScreenUpdates = false } diff --git a/Client/Frontend/Browser/Tab.swift b/Client/Frontend/Browser/Tab.swift index 6a8f3d5d2..540c70d39 100644 --- a/Client/Frontend/Browser/Tab.swift +++ b/Client/Frontend/Browser/Tab.swift @@ -389,7 +389,7 @@ class Tab: NSObject { return Strings.Menu.OpenHomePageTitleString } - //lets double check the sessionData in case this is a non-restored new tab + // lets double check the sessionData in case this is a non-restored new tab if let firstURL = sessionData?.urls.first, sessionData?.urls.count == 1, InternalURL(firstURL)?.isAboutHomeURL ?? false { return Strings.Menu.OpenHomePageTitleString } @@ -731,7 +731,7 @@ class TabWebView: WKWebView, MenuHelperInterface { /// Override evaluateJavascript - should not be called directly on TabWebViews any longer // We should only be calling evaluateJavascriptInDefaultContentWorld in the future - @available(*, unavailable, message:"Do not call evaluateJavaScript directly on TabWebViews, should only be called on super class") + @available(*, unavailable, message: "Do not call evaluateJavaScript directly on TabWebViews, should only be called on super class") override func evaluateJavaScript(_ javaScriptString: String, completionHandler: ((Any?, Error?) -> Void)? = nil) { super.evaluateJavaScript(javaScriptString, completionHandler: completionHandler) } diff --git a/Client/Frontend/Browser/TabDisplayManager.swift b/Client/Frontend/Browser/TabDisplayManager.swift index d1cea93a2..6efa5652a 100644 --- a/Client/Frontend/Browser/TabDisplayManager.swift +++ b/Client/Frontend/Browser/TabDisplayManager.swift @@ -119,7 +119,7 @@ class TabDisplayManager: NSObject { refreshStore() if createTabOnEmptyPrivateMode { - //if private tabs is empty and we are transitioning to it add a tab + // if private tabs is empty and we are transitioning to it add a tab if tabManager.privateTabs.isEmpty && isPrivate { tabManager.addTab(isPrivate: true) } diff --git a/Client/Frontend/Browser/TabManager.swift b/Client/Frontend/Browser/TabManager.swift index 6d8d4a903..beb9b53b9 100644 --- a/Client/Frontend/Browser/TabManager.swift +++ b/Client/Frontend/Browser/TabManager.swift @@ -292,9 +292,9 @@ class TabManager: NSObject { return profile.prefs.boolForKey("settings.closePrivateTabs") ?? false } - //Called by other classes to signal that they are entering/exiting private mode - //This is called by TabTrayVC when the private mode button is pressed and BEFORE we've switched to the new mode - //we only want to remove all private tabs when leaving PBM and not when entering. + // Called by other classes to signal that they are entering/exiting private mode + // This is called by TabTrayVC when the private mode button is pressed and BEFORE we've switched to the new mode + // we only want to remove all private tabs when leaving PBM and not when entering. func willSwitchTabMode(leavingPBM: Bool) { recentlyClosedForUndo.removeAll() diff --git a/Client/Frontend/Browser/TabScrollController.swift b/Client/Frontend/Browser/TabScrollController.swift index dcd6c3d4c..f41ff8392 100644 --- a/Client/Frontend/Browser/TabScrollController.swift +++ b/Client/Frontend/Browser/TabScrollController.swift @@ -303,13 +303,13 @@ extension TabScrollingController: UIScrollViewDelegate { return } - //scrollViewDidZoom will be called multiple times when a rotation happens. + // scrollViewDidZoom will be called multiple times when a rotation happens. // In that case ALWAYS reset to the minimum zoom level if the previous state was zoomed out (isZoomedOut=true) if isZoomedOut { scrollView.zoomScale = scrollView.minimumZoomScale } else if roundNum(scrollView.zoomScale) > roundNum(self.lastZoomedScale) && self.lastZoomedScale != 0 { - //When we have manually zoomed in we want to preserve that scale. - //But sometimes when we rotate a larger zoomScale is appled. In that case apply the lastZoomedScale + // When we have manually zoomed in we want to preserve that scale. + // But sometimes when we rotate a larger zoomScale is appled. In that case apply the lastZoomedScale scrollView.zoomScale = self.lastZoomedScale } } diff --git a/Client/Frontend/Browser/TabTrayControllerV1.swift b/Client/Frontend/Browser/TabTrayControllerV1.swift index 5b0dbe4fb..8c97ce34d 100644 --- a/Client/Frontend/Browser/TabTrayControllerV1.swift +++ b/Client/Frontend/Browser/TabTrayControllerV1.swift @@ -176,7 +176,7 @@ class TabTrayControllerV1: UIViewController { } override var preferredStatusBarStyle: UIStatusBarStyle { - //special case for iPad + // special case for iPad if UIDevice.current.isPad { return .default } @@ -238,7 +238,7 @@ class TabTrayControllerV1: UIViewController { let toView: UIView if !privateTabsAreEmpty(), let newSnapshot = collectionView.snapshotView(afterScreenUpdates: !exitingPrivateMode) { emptyPrivateTabsView.isHidden = true - //when exiting private mode don't screenshot the collectionview (causes the UI to hang) + // when exiting private mode don't screenshot the collectionview (causes the UI to hang) newSnapshot.frame = collectionView.frame view.insertSubview(newSnapshot, aboveSubview: fromView) collectionView.alpha = 0 diff --git a/Client/Frontend/Browser/TopTabsLayout.swift b/Client/Frontend/Browser/TopTabsLayout.swift index 7534cf4cb..ae34a41e3 100644 --- a/Client/Frontend/Browser/TopTabsLayout.swift +++ b/Client/Frontend/Browser/TopTabsLayout.swift @@ -41,7 +41,7 @@ class TopTabsViewLayout: UICollectionViewFlowLayout { var decorationAttributeArr: [Int: UICollectionViewLayoutAttributes?] = [:] let separatorYOffset = TopTabsUX.SeparatorYOffset let separatorSize = TopTabsUX.SeparatorHeight - let SeparatorZIndex = -2 ///Prevent the header/footer from appearing above the Tabs + let SeparatorZIndex = -2 /// Prevent the header/footer from appearing above the Tabs override var collectionViewContentSize: CGSize { let tabsWidth = ((CGFloat(collectionView!.numberOfItems(inSection: 0))) * (TopTabsUX.TabWidth + TopTabsUX.SeparatorWidth)) - TopTabsUX.SeparatorWidth diff --git a/Client/Frontend/Browser/TopTabsViews.swift b/Client/Frontend/Browser/TopTabsViews.swift index 8d7597c39..51917c6cf 100644 --- a/Client/Frontend/Browser/TopTabsViews.swift +++ b/Client/Frontend/Browser/TopTabsViews.swift @@ -64,7 +64,7 @@ class TopTabsHeaderFooter: UICollectionReusableView { class TopTabCell: UICollectionViewCell { static let Identifier = "TopTabCellIdentifier" - static let ShadowOffsetSize: CGFloat = 2 //The shadow is used to hide the tab separator + static let ShadowOffsetSize: CGFloat = 2 // The shadow is used to hide the tab separator var selectedTab = false { didSet { diff --git a/Client/Frontend/Settings/Clearables.swift b/Client/Frontend/Settings/Clearables.swift index 6c4de8471..f5fd6362c 100644 --- a/Client/Frontend/Settings/Clearables.swift +++ b/Client/Frontend/Settings/Clearables.swift @@ -154,7 +154,7 @@ class CookiesClearable: Clearable { } class TrackingProtectionClearable: Clearable { - //TO DO: re-using string because we are too late in cycle to change strings + // TO DO: re-using string because we are too late in cycle to change strings var label: String { return Strings.Settings.PrivacyDashboard.Title } diff --git a/Client/Frontend/Settings/CustomSearchViewController.swift b/Client/Frontend/Settings/CustomSearchViewController.swift index 3bb86513a..fbf9342da 100644 --- a/Client/Frontend/Settings/CustomSearchViewController.swift +++ b/Client/Frontend/Settings/CustomSearchViewController.swift @@ -93,7 +93,7 @@ class CustomSearchViewController: SettingsTableViewController { func fillDeferred(image: UIImage?) { let engine = OpenSearchEngine(engineID: nil, shortName: name, image: image, searchTemplate: template, suggestTemplate: nil, isCustomEngine: true) - //Make sure a valid scheme is used + // Make sure a valid scheme is used let testUrl = engine.searchURLForQuery("test") let maybe = (testUrl == nil) ? Maybe(failure: CustomSearchError(.FormInput)) : Maybe(success: engine) deferred.fill(maybe) @@ -118,8 +118,8 @@ class CustomSearchViewController: SettingsTableViewController { } func getSearchTemplate(withString query: String) -> String? { - let SearchTermComponent = "%s" //Placeholder in User Entered String - let placeholder = "{searchTerms}" //Placeholder looked for when using Custom Search Engine in OpenSearch.swift + let SearchTermComponent = "%s" // Placeholder in User Entered String + let placeholder = "{searchTerms}" // Placeholder looked for when using Custom Search Engine in OpenSearch.swift if query.contains(SearchTermComponent) { return query.replacingOccurrences(of: SearchTermComponent, with: placeholder) @@ -148,7 +148,7 @@ class CustomSearchViewController: SettingsTableViewController { titleField.textField.accessibilityIdentifier = "customEngineTitle" let urlField = CustomSearchEngineTextView(placeholder: Strings.Settings.Search.AddCustomEngine.URLPlaceholder, height: 133, keyboardType: .URL, settingIsValid: { text in - //Can check url text text validity here. + // Can check url text text validity here. return true }, settingDidChange: {fieldText in self.urlString = fieldText diff --git a/Client/Frontend/Settings/SearchSettingsTableViewController.swift b/Client/Frontend/Settings/SearchSettingsTableViewController.swift index fb25936e6..a6e67a36c 100644 --- a/Client/Frontend/Settings/SearchSettingsTableViewController.swift +++ b/Client/Frontend/Settings/SearchSettingsTableViewController.swift @@ -262,7 +262,7 @@ class SearchSettingsTableViewController: ThemedTableViewController { return sourceIndexPath } - //Can't drag/drop over "Add Custom Engine button" + // Can't drag/drop over "Add Custom Engine button" if sourceIndexPath.item + 1 == model.orderedEngines.count || proposedDestinationIndexPath.item + 1 == model.orderedEngines.count { return sourceIndexPath } diff --git a/Client/Frontend/Strings.swift b/Client/Frontend/Strings.swift index 252d1ba29..103411031 100644 --- a/Client/Frontend/Strings.swift +++ b/Client/Frontend/Strings.swift @@ -263,7 +263,7 @@ extension Strings { public static let FxAAccountUpgradeFirefox = NSLocalizedString("Upgrade Firefox to connect", comment: "Text message in the settings table view") } -//Hotkey Titles +// Hotkey Titles extension Strings { public static let ReloadPageTitle = NSLocalizedString("Hotkeys.Reload.DiscoveryTitle", value: "Reload Page", comment: "Label to display in the Discoverability overlay for keyboard shortcuts") public static let BackTitle = NSLocalizedString("Hotkeys.Back.DiscoveryTitle", value: "Back", comment: "Label to display in the Discoverability overlay for keyboard shortcuts") @@ -376,7 +376,7 @@ extension Strings { public static let TabSearchPlaceholderText = NSLocalizedString("Tabs.Search.PlaceholderText", value: "Search Tabs", comment: "The placeholder text for the tab search bar") } -//Clipboard Toast +// Clipboard Toast extension Strings { public static let GoToCopiedLink = NSLocalizedString("ClipboardToast.GoToCopiedLink.Title", value: "Go to copied link?", comment: "Message displayed when the user has a copied link on the clipboard") public static let GoButtonTittle = NSLocalizedString("ClipboardToast.GoToCopiedLink.Button", value: "Go", comment: "The button to open a new tab with the copied link") @@ -672,7 +672,7 @@ extension Strings { public static let CardTitleFxASyncDevices = NSLocalizedString("Intro.Slides.Firefox.Account.Sync.Title", tableName: "Intro", value: "Sync Firefox Between Devices", comment: "Title for the first item in the table related to syncing data (bookmarks, history) via firefox account between devices") public static let CardDescriptionFxASyncDevices = NSLocalizedString("Intro.Slides.Firefox.Account.Sync.Description", tableName: "Intro", value: "Bring bookmarks, history, and passwords to Firefox on this device.", comment: "Description for the first item in the table related to syncing data (bookmarks, history) via firefox account between devices") - //----Other----// + // ----Other----// public static let CardTitleSearch = NSLocalizedString("Intro.Slides.Search.Title", tableName: "Intro", value: "Your search, your way", comment: "Title for the second panel 'Search' in the First Run tour.") public static let CardTitlePrivate = NSLocalizedString("Intro.Slides.Private.Title", tableName: "Intro", value: "Browse like no one’s watching", comment: "Title for the third panel 'Private Browsing' in the First Run tour.") public static let CardTitleMail = NSLocalizedString("Intro.Slides.Mail.Title", tableName: "Intro", value: "You’ve got mail… options", comment: "Title for the fourth panel 'Mail' in the First Run tour.") @@ -733,7 +733,7 @@ extension Strings { } -//passwordAutofill extension +// passwordAutofill extension extension Strings { public static let PasswordAutofillTitle = NSLocalizedString("PasswordAutoFill.SectionTitle", value: "Firefox Credentials", comment: "Title of the extension that shows firefox passwords") public static let CredentialProviderNoCredentialError = NSLocalizedString("PasswordAutoFill.NoPasswordsFoundTitle", value: "You don’t have any credentials synced from your Firefox Account", comment: "Error message shown in the remote tabs panel") diff --git a/Client/Frontend/Widgets/PhotonActionSheet/PageActionMenu.swift b/Client/Frontend/Widgets/PhotonActionSheet/PageActionMenu.swift index 3c5f2e780..69251fd88 100644 --- a/Client/Frontend/Widgets/PhotonActionSheet/PageActionMenu.swift +++ b/Client/Frontend/Widgets/PhotonActionSheet/PageActionMenu.swift @@ -33,7 +33,7 @@ extension PhotonActionSheetProtocol { func getTabActions(tab: Tab, buttonView: UIView, presentShareMenu: @escaping (URL, Tab, UIView, UIPopoverArrowDirection) -> Void, - findInPage: @escaping () -> Void, + findInPage: @escaping () -> Void, presentableVC: PresentableVC, isBookmarked: Bool, isPinned: Bool, diff --git a/Client/Frontend/Widgets/PhotonActionSheet/PhotonActionSheetProtocol.swift b/Client/Frontend/Widgets/PhotonActionSheet/PhotonActionSheetProtocol.swift index 7c07aa2c3..b51e83b61 100644 --- a/Client/Frontend/Widgets/PhotonActionSheet/PhotonActionSheetProtocol.swift +++ b/Client/Frontend/Widgets/PhotonActionSheet/PhotonActionSheetProtocol.swift @@ -34,8 +34,8 @@ extension PhotonActionSheetProtocol { viewController.present(sheet, animated: true, completion: nil) } - //Returns a list of actions which is used to build a menu - //OpenURL is a closure that can open a given URL in some view controller. It is up to the class using the menu to know how to open it + // Returns a list of actions which is used to build a menu + // OpenURL is a closure that can open a given URL in some view controller. It is up to the class using the menu to know how to open it func getControlCenterActions(vcDelegate: PageOptionsVC) -> [[PhotonActionSheetItem]] { guard let tab = self.tabManager.selectedTab else { return [] } @@ -213,7 +213,7 @@ extension PhotonActionSheetProtocol { func getTabActions(tab: Tab, buttonView: UIView, presentShareMenu: @escaping (URL, Tab, UIView, UIPopoverArrowDirection) -> Void, - findInPage: @escaping () -> Void, + findInPage: @escaping () -> Void, presentableVC: PresentableVC, isBookmarked: Bool, isPinned: Bool, diff --git a/Client/Frontend/Widgets/SiteTableViewController.swift b/Client/Frontend/Widgets/SiteTableViewController.swift index e80147c40..b525aa005 100644 --- a/Client/Frontend/Widgets/SiteTableViewController.swift +++ b/Client/Frontend/Widgets/SiteTableViewController.swift @@ -143,7 +143,7 @@ class SiteTableViewController: UIViewController, UITableViewDelegate, UITableVie super.viewWillTransition(to: size, with: coordinator) tableView.setEditing(false, animated: false) coordinator.animate(alongsideTransition: { context in - //The AS context menu does not behave correctly. Dismiss it when rotating. + // The AS context menu does not behave correctly. Dismiss it when rotating. if let _ = self.presentedViewController as? PhotonActionSheet { self.presentedViewController?.dismiss(animated: true, completion: nil) } diff --git a/Client/Frontend/Widgets/SnackBar.swift b/Client/Frontend/Widgets/SnackBar.swift index 1bcf96c09..33f2ee17e 100644 --- a/Client/Frontend/Widgets/SnackBar.swift +++ b/Client/Frontend/Widgets/SnackBar.swift @@ -148,7 +148,7 @@ class SnackBar: UIView { } backgroundColor = UIColor.clear - self.clipsToBounds = true //overridden by masksToBounds = false + self.clipsToBounds = true // overridden by masksToBounds = false self.layer.borderWidth = SnackBarUX.BorderWidth self.layer.borderColor = Theme.snackbar.border.cgColor self.layer.cornerRadius = 8 diff --git a/Client/Utils/FaviconFetcher.swift b/Client/Utils/FaviconFetcher.swift index f76f9c2be..8b9beed43 100644 --- a/Client/Utils/FaviconFetcher.swift +++ b/Client/Utils/FaviconFetcher.swift @@ -135,7 +135,7 @@ open class FaviconFetcher: NSObject, XMLParserDelegate { for link in root.xpath("//head//link[contains(@rel, 'icon')]") { guard let href = link["href"] else { - continue //Skip the rest of the loop. But don't stop the loop + continue // Skip the rest of the loop. But don't stop the loop } if let iconUrl = NSURL(string: href, relativeTo: url as URL), let absoluteString = iconUrl.absoluteString { diff --git a/Gemfile b/Gemfile index 926249714..0ba6989a7 100644 --- a/Gemfile +++ b/Gemfile @@ -1,6 +1,8 @@ source 'https://rubygems.org' -gem "cocoapods", "1.9.3" +gem "cocoapods", "1.12.1" gem "fastlane" plugins_path = File.join(File.dirname(__FILE__), 'fastlane', 'Pluginfile') eval_gemfile(plugins_path) if File.exist?(plugins_path) + +gem "xcpretty", "~> 0.3.0" diff --git a/Gemfile.lock b/Gemfile.lock index 55e09195e..9ba69fb60 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -2,16 +2,17 @@ GEM remote: https://rubygems.org/ specs: CFPropertyList (3.0.2) - activesupport (4.2.11.3) - i18n (~> 0.7) - minitest (~> 5.1) - thread_safe (~> 0.3, >= 0.3.4) - tzinfo (~> 1.1) - addressable (2.7.0) - public_suffix (>= 2.0.2, < 5.0) - algoliasearch (1.27.4) + activesupport (7.0.7) + concurrent-ruby (~> 1.0, >= 1.0.2) + i18n (>= 1.6, < 2) + minitest (>= 5.1) + tzinfo (~> 2.0) + addressable (2.8.5) + public_suffix (>= 2.0.2, < 6.0) + algoliasearch (1.27.5) httpclient (~> 2.8, >= 2.8.3) json (>= 1.5.1) + artifactory (3.0.15) atomos (0.1.3) aws-eventstream (1.1.0) aws-partitions (1.378.0) @@ -31,48 +32,48 @@ GEM aws-eventstream (~> 1, >= 1.0.2) babosa (1.0.3) claide (1.0.3) - cocoapods (1.9.3) - activesupport (>= 4.0.2, < 5) + cocoapods (1.12.1) + addressable (~> 2.8) claide (>= 1.0.2, < 2.0) - cocoapods-core (= 1.9.3) + cocoapods-core (= 1.12.1) cocoapods-deintegrate (>= 1.0.3, < 2.0) - cocoapods-downloader (>= 1.2.2, < 2.0) + cocoapods-downloader (>= 1.6.0, < 2.0) cocoapods-plugins (>= 1.0.0, < 2.0) cocoapods-search (>= 1.0.0, < 2.0) - cocoapods-stats (>= 1.0.0, < 2.0) - cocoapods-trunk (>= 1.4.0, < 2.0) + cocoapods-trunk (>= 1.6.0, < 2.0) cocoapods-try (>= 1.1.0, < 2.0) colored2 (~> 3.1) escape (~> 0.0.4) fourflusher (>= 2.3.0, < 3.0) gh_inspector (~> 1.0) - molinillo (~> 0.6.6) + molinillo (~> 0.8.0) nap (~> 1.0) - ruby-macho (~> 1.4) - xcodeproj (>= 1.14.0, < 2.0) - cocoapods-core (1.9.3) - activesupport (>= 4.0.2, < 6) + ruby-macho (>= 2.3.0, < 3.0) + xcodeproj (>= 1.21.0, < 2.0) + cocoapods-core (1.12.1) + activesupport (>= 5.0, < 8) + addressable (~> 2.8) algoliasearch (~> 1.0) concurrent-ruby (~> 1.1) fuzzy_match (~> 2.0.4) nap (~> 1.0) netrc (~> 0.11) + public_suffix (~> 4.0) typhoeus (~> 1.0) - cocoapods-deintegrate (1.0.4) - cocoapods-downloader (1.4.0) + cocoapods-deintegrate (1.0.5) + cocoapods-downloader (1.6.3) cocoapods-plugins (1.0.0) nap - cocoapods-search (1.0.0) - cocoapods-stats (1.1.0) - cocoapods-trunk (1.5.0) + cocoapods-search (1.0.1) + cocoapods-trunk (1.6.0) nap (>= 0.8, < 2.0) netrc (~> 0.11) cocoapods-try (1.2.0) colored (1.2) colored2 (3.1.2) - commander-fastlane (4.4.6) - highline (~> 1.7.2) - concurrent-ruby (1.1.7) + commander (4.6.0) + highline (~> 2.0.0) + concurrent-ruby (1.2.2) declarative (0.0.20) declarative-option (0.1.0) digest-crc (0.6.1) @@ -82,8 +83,8 @@ GEM dotenv (2.7.6) emoji_regex (3.0.0) escape (0.0.4) - ethon (0.12.0) - ffi (>= 1.3.0) + ethon (0.16.0) + ffi (>= 1.15.0) excon (0.76.0) faraday (1.0.1) multipart-post (>= 1.2, < 3) @@ -93,14 +94,15 @@ GEM faraday_middleware (1.0.0) faraday (~> 1.0) fastimage (2.2.0) - fastlane (2.162.0) + fastlane (2.187.0) CFPropertyList (>= 2.3, < 4.0.0) addressable (>= 2.3, < 3.0.0) + artifactory (~> 3.0) aws-sdk-s3 (~> 1.0) babosa (>= 1.0.3, < 2.0.0) bundler (>= 1.12.0, < 3.0.0) colored - commander-fastlane (>= 4.4.6, < 5.0.0) + commander (~> 4.6) dotenv (>= 2.1.1, < 3.0.0) emoji_regex (>= 0.1, < 4.0) excon (>= 0.71.0, < 1.0.0) @@ -109,18 +111,19 @@ GEM faraday_middleware (~> 1.0) fastimage (>= 2.1.0, < 3.0.0) gh_inspector (>= 1.1.2, < 2.0.0) - google-api-client (>= 0.37.0, < 0.39.0) - google-cloud-storage (>= 1.15.0, < 2.0.0) - highline (>= 1.7.2, < 2.0.0) + google-apis-androidpublisher_v3 (~> 0.1) + google-apis-playcustomapp_v1 (~> 0.1) + google-cloud-storage (~> 1.31) + highline (~> 2.0) json (< 3.0.0) jwt (>= 2.1.0, < 3) mini_magick (>= 4.9.4, < 5.0.0) multipart-post (~> 2.0.0) + naturally (~> 2.2) plist (>= 3.1.0, < 4.0.0) rubyzip (>= 2.0.0, < 3.0.0) security (= 0.1.3) simctl (~> 1.6.3) - slack-notifier (>= 2.0.0, < 3.0.0) terminal-notifier (>= 2.0.0, < 3.0.0) terminal-table (>= 1.4.5, < 2.0.0) tty-screen (>= 0.6.3, < 1.0.0) @@ -131,43 +134,53 @@ GEM xcpretty-travis-formatter (>= 0.0.3) fastlane-plugin-changelog (0.15.0) fastlane-plugin-sentry (1.6.0) - ffi (1.13.1) + ffi (1.15.5) fourflusher (2.3.1) fuzzy_match (2.0.4) gh_inspector (1.1.3) - google-api-client (0.38.0) + google-apis-androidpublisher_v3 (0.48.0) + google-apis-core (>= 0.11.0, < 2.a) + google-apis-core (0.11.1) addressable (~> 2.5, >= 2.5.1) - googleauth (~> 0.9) - httpclient (>= 2.8.1, < 3.0) + googleauth (>= 0.16.2, < 2.a) + httpclient (>= 2.8.1, < 3.a) mini_mime (~> 1.0) representable (~> 3.0) - retriable (>= 2.0, < 4.0) - signet (~> 0.12) + retriable (>= 2.0, < 4.a) + rexml + webrick + google-apis-iamcredentials_v1 (0.17.0) + google-apis-core (>= 0.11.0, < 2.a) + google-apis-playcustomapp_v1 (0.13.0) + google-apis-core (>= 0.11.0, < 2.a) + google-apis-storage_v1 (0.24.0) + google-apis-core (>= 0.11.0, < 2.a) google-cloud-core (1.5.0) google-cloud-env (~> 1.0) google-cloud-errors (~> 1.0) google-cloud-env (1.3.3) faraday (>= 0.17.3, < 2.0) google-cloud-errors (1.0.1) - google-cloud-storage (1.29.0) + google-cloud-storage (1.31.1) addressable (~> 2.5) digest-crc (~> 0.4) - google-api-client (~> 0.33) + google-apis-iamcredentials_v1 (~> 0.1) + google-apis-storage_v1 (~> 0.1) google-cloud-core (~> 1.2) googleauth (~> 0.9) mini_mime (~> 1.0) - googleauth (0.13.1) + googleauth (0.17.0) faraday (>= 0.17.3, < 2.0) jwt (>= 1.4, < 3.0) memoist (~> 0.16) multi_json (~> 1.11) os (>= 0.9, < 2.0) signet (~> 0.14) - highline (1.7.10) + highline (2.0.3) http-cookie (1.0.3) domain_name (~> 0.5) httpclient (2.8.3) - i18n (0.9.5) + i18n (1.14.1) concurrent-ruby (~> 1.0) jmespath (1.4.0) json (2.3.1) @@ -175,8 +188,8 @@ GEM memoist (0.16.2) mini_magick (4.10.1) mini_mime (1.0.2) - minitest (5.14.2) - molinillo (0.6.6) + minitest (5.19.0) + molinillo (0.8.0) multi_json (1.15.0) multipart-post (2.0.0) nanaimo (0.3.0) @@ -192,8 +205,9 @@ GEM declarative-option (< 0.2.0) uber (< 0.2.0) retriable (3.1.2) + rexml (3.2.6) rouge (2.0.7) - ruby-macho (1.4.0) + ruby-macho (2.5.1) rubyzip (2.3.0) security (0.1.3) signet (0.14.0) @@ -204,44 +218,45 @@ GEM simctl (1.6.8) CFPropertyList naturally - slack-notifier (2.3.2) terminal-notifier (2.0.0) terminal-table (1.8.0) unicode-display_width (~> 1.1, >= 1.1.1) - thread_safe (0.3.6) tty-cursor (0.7.1) tty-screen (0.8.1) tty-spinner (0.9.3) tty-cursor (~> 0.7) typhoeus (1.4.0) ethon (>= 0.9.0) - tzinfo (1.2.7) - thread_safe (~> 0.1) + tzinfo (2.0.6) + concurrent-ruby (~> 1.0) uber (0.1.0) unf (0.1.4) unf_ext unf_ext (0.0.7.7) unicode-display_width (1.7.0) + webrick (1.8.1) word_wrap (1.0.0) - xcodeproj (1.18.0) + xcodeproj (1.22.0) CFPropertyList (>= 2.3.3, < 4.0) atomos (~> 0.1.3) claide (>= 1.0.2, < 2.0) colored2 (~> 3.1) nanaimo (~> 0.3.0) + rexml (~> 3.2.4) xcpretty (0.3.0) rouge (~> 2.0.7) - xcpretty-travis-formatter (1.0.0) + xcpretty-travis-formatter (1.0.1) xcpretty (~> 0.2, >= 0.0.7) PLATFORMS ruby DEPENDENCIES - cocoapods (= 1.9.3) + cocoapods (= 1.12.1) fastlane fastlane-plugin-changelog fastlane-plugin-sentry + xcpretty (~> 0.3.0) BUNDLED WITH - 2.1.4 + 2.4.19 diff --git a/Podfile.lock b/Podfile.lock index a7fd5192f..347f35586 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -273,7 +273,7 @@ PODS: - SQLCipher/common (4.4.0) - SQLCipher/standard (4.4.0): - SQLCipher/common - - SwiftLint (0.39.2) + - SwiftLint (0.52.4) - SwiftyJSON (5.0.0) - TLDExtract (1.0.1): - Punycode (~> 1.0) @@ -451,7 +451,7 @@ SPEC CHECKSUMS: Sentry: 5267d493a398663538317e4dcc438c12c66202ed SnapKit: 97b92857e3df3a0c71833cce143274bf6ef8e5eb SQLCipher: e434ed542b24f38ea7b36468a13f9765e1b5c072 - SwiftLint: 22ccbbe3b8008684be5955693bab135e0ed6a447 + SwiftLint: 1cc5cd61ba9bacb2194e340aeb47a2a37fda00b3 SwiftyJSON: 36413e04c44ee145039d332b4f4e2d3e8d6c4db7 TLDExtract: 63aa739e9b50052ef04e792927c43db62b2bb6b5 XCGLogger: 1943831ef907df55108b0b18657953f868de973b @@ -459,4 +459,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: feeda49a3205216d5074edab539b0daaeccdf6db -COCOAPODS: 1.9.3 +COCOAPODS: 1.12.1 diff --git a/README.md b/README.md index 37ca403ee..e80091725 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,15 @@ User Agent is the internal name for the Ghostery iOS browser. A diferent name wa ```shell git clone git@github.com:ghostery/user-agent-ios.git ``` + +1. Setup ASDF for nodejs and ruby +```shell +brew install asdf +asdf plugin add nodejs +asdf plugin add ruby +asdf install +``` + 1. Run the bootstrap script to install dependencies ```shell cd user-agent-ios diff --git a/Shared/Colors/Colors.swift b/Shared/Colors/Colors.swift index 2c48d223c..79b065eef 100644 --- a/Shared/Colors/Colors.swift +++ b/Shared/Colors/Colors.swift @@ -52,7 +52,7 @@ extension UIColor { public static let Blue50 = UIColor(named: "Blue50")! public static let Blue60 = UIColor(named: "Blue60")! - //Contextual Onboarding Colors + // Contextual Onboarding Colors public static let COLightBlue = UIColor(named: "COLightBlue")! public static let CODarkBlue = UIColor(named: "CODarkBlue")! public static let COLightRed = UIColor(named: "COLightRed")! diff --git a/Shared/Functions.swift b/Shared/Functions.swift index d3eaf0ddc..4e9fc9f91 100644 --- a/Shared/Functions.swift +++ b/Shared/Functions.swift @@ -222,9 +222,9 @@ public func jsonsToStrings(_ arr: [JSON]?) -> [String]? { // Encapsulate a callback in a way that we can use it with NSTimer. private class Callback { - private let handler:() -> Void + private let handler: () -> Void - init(handler:@escaping () -> Void) { + init(handler: @escaping () -> Void) { self.handler = handler } @@ -238,7 +238,7 @@ private class Callback { * Taken from http://stackoverflow.com/questions/27116684/how-can-i-debounce-a-method-call * Allows creating a block that will fire after a delay. Resets the timer if called again before the delay expires. **/ -public func debounce(_ delay: TimeInterval, action:@escaping () -> Void) -> () -> Void { +public func debounce(_ delay: TimeInterval, action: @escaping () -> Void) -> () -> Void { let callback = Callback(handler: action) var timer: Timer? diff --git a/Shared/Prefs.swift b/Shared/Prefs.swift index 563174751..e6cb0a90f 100644 --- a/Shared/Prefs.swift +++ b/Shared/Prefs.swift @@ -15,10 +15,10 @@ public struct PrefsKeys { public static let OpenLinks = "OpenLinks" public static let OnBrowserStartTab = "OnBrowserStartTab" - //Today Widget + // Today Widget public static let TodayWidgetWeatherLocation = "WeatherLocation" - //Pull to refresh + // Pull to refresh public static let RefreshControlEnabled = "RefreshControlEnabled" // Contextual Onboarding @@ -30,14 +30,14 @@ public struct PrefsKeys { public static let Adblocker = "Adblocker" public static let PopupBlocker = "PopupBlocker" - //News + // News public static let NewTabNewsEnabled = "NewTabNewsEnabled" public static let NewTabNewsImagesEnabled = "NewTabNewsImagesEnabled" public static let ContextMenuShowLinkPreviews = "showLinkPreviews" public static let NewTabCustomUrlPrefKey = "HomePageURLPref" - //Activity Stream + // Activity Stream public static let KeyTopSitesCacheIsValid = "topSitesCacheIsValid" public static let KeyTopSitesCacheSize = "topSitesCacheSize" diff --git a/Storage/ExtensionUtils.swift b/Storage/ExtensionUtils.swift index 832337994..89c5ca6d3 100644 --- a/Storage/ExtensionUtils.swift +++ b/Storage/ExtensionUtils.swift @@ -24,7 +24,7 @@ public struct ExtensionUtils { case rawText(String) public func isUrlType() -> Bool { - if case .shareItem(_) = self { + if case .shareItem = self { return true } else { return false diff --git a/Storage/SQL/SQLiteBookmarksModel.swift b/Storage/SQL/SQLiteBookmarksModel.swift index c1af12cab..4bdfccf86 100644 --- a/Storage/SQL/SQLiteBookmarksModel.swift +++ b/Storage/SQL/SQLiteBookmarksModel.swift @@ -648,7 +648,7 @@ class BookmarkFactory { let hasDupe = row.getBoolean("hasDupe") // Mirror only. TO DO - //let is_overridden = row.getBoolean("is_overridden") + // let is_overridden = row.getBoolean("is_overridden") // Use the struct initializer directly. Yes, this doesn't validate as strongly as // using the static constructors, but it'll be as valid as the contents of the DB. diff --git a/Storage/SQL/SQLiteBookmarksSyncing.swift b/Storage/SQL/SQLiteBookmarksSyncing.swift index b565c2760..5768bbfd0 100644 --- a/Storage/SQL/SQLiteBookmarksSyncing.swift +++ b/Storage/SQL/SQLiteBookmarksSyncing.swift @@ -254,10 +254,10 @@ private extension BookmarkMirrorItem { func getUpdateOrInsertArgs() -> Args { let args: Args = [ - self.type.rawValue , + self.type.rawValue, self.dateAdded, self.serverModified, - self.isDeleted ? 1 : 0 , + self.isDeleted ? 1 : 0, self.hasDupe ? 1 : 0, self.parentID, self.parentName ?? "", // Workaround for dirty data before Bug 1318414. diff --git a/Storage/SQL/SQLiteHistoryFavicons.swift b/Storage/SQL/SQLiteHistoryFavicons.swift index a23e4d4c8..b949cbe61 100644 --- a/Storage/SQL/SQLiteHistoryFavicons.swift +++ b/Storage/SQL/SQLiteHistoryFavicons.swift @@ -31,8 +31,8 @@ private var defaultFaviconImageCache = [String: UIImage]() // region-specific TLDs. This helps us resolve them. private let multiRegionTopSitesDomains = ["craigslist", "google", "amazon"] -private let topSitesIcons: [String : (color: UIColor, fileURL: URL)] = { - var icons: [String : (color: UIColor, fileURL: URL)] = [:] +private let topSitesIcons: [String: (color: UIColor, fileURL: URL)] = { + var icons: [String: (color: UIColor, fileURL: URL)] = [:] let filePath = Bundle.main.path(forResource: "top_sites", ofType: "json") let file = try! Data(contentsOf: URL(fileURLWithPath: filePath!)) diff --git a/Translations/de.lproj/Settings.strings b/Translations/de.lproj/Settings.strings index e030729db..82b447ba3 100644 --- a/Translations/de.lproj/Settings.strings +++ b/Translations/de.lproj/Settings.strings @@ -156,7 +156,7 @@ "Settings.Support.SendUsageTitle" = "Interaktions-Statistiken"; /* The title for the human web setting. */ -"Settings.Support.HumanWebTitle" = "Human Web"; +"Settings.Support.HumanWebTitle" = "WhoTracks.Me"; /* The description of the open new tab siri shortcut */ "Settings.General.Siri.OpenTabShortcut" = "Neuen Tab öffnen"; diff --git a/Translations/en.lproj/Settings.strings b/Translations/en.lproj/Settings.strings index 926a57145..ce8f79e2c 100644 --- a/Translations/en.lproj/Settings.strings +++ b/Translations/en.lproj/Settings.strings @@ -153,7 +153,7 @@ "Settings.Support.SendUsageTitle" = "Send Usage Data"; /* The title for the human web setting. */ -"Settings.Support.HumanWebTitle" = "Human Web"; +"Settings.Support.HumanWebTitle" = "WhoTracks.Me"; /* The description of the open new tab siri shortcut */ "Settings.General.Siri.OpenTabShortcut" = "Open New Tab"; diff --git a/UserAgent.xcodeproj/project.pbxproj b/UserAgent.xcodeproj/project.pbxproj index cc7e5d909..fabab7592 100644 --- a/UserAgent.xcodeproj/project.pbxproj +++ b/UserAgent.xcodeproj/project.pbxproj @@ -4869,8 +4869,8 @@ buildConfigurationList = F84B21DD1A090F8100AAB793 /* Build configuration list for PBXNativeTarget "Cliqz" */; buildPhases = ( EDE37F14F4B6596330F4A6A5 /* [CP] Check Pods Manifest.lock */, - ACB6D4302306A77D002D64E6 /* Lint with SwiftLint */, 46C41EDB230EC92000CE54D2 /* Start React Native Server */, + ACB6D4302306A77D002D64E6 /* Lint with SwiftLint */, F84B21BA1A090F8100AAB793 /* Sources */, F84B21BC1A090F8100AAB793 /* Resources */, 28CE83DE1A1D1E7C00576538 /* Frameworks */, @@ -5615,7 +5615,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "export NODE_BINARY=node\n./node_modules/react-native/scripts/react-native-xcode.sh\n"; + shellScript = "export NODE_BINARY=`realpath ~/.asdf/shims/node`\n\n./node_modules/react-native/scripts/react-native-xcode.sh\n"; }; 2DC5D550E7F9897533FC0409 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; @@ -5713,7 +5713,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "export NODE_BINARY=node\n./node_modules/react-native/scripts/react-native-xcode.sh\n"; + shellScript = "export NODE_BINARY=`realpath ~/.asdf/shims/node`\n\n./node_modules/react-native/scripts/react-native-xcode.sh\n"; }; 46504079241672C30086CFAF /* Bundle React Native code and images */ = { isa = PBXShellScriptBuildPhase; @@ -5767,7 +5767,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "export NODE_BINARY=node\n./node_modules/react-native/scripts/react-native-xcode.sh\n"; + shellScript = "export NODE_BINARY=`realpath ~/.asdf/shims/node`\n\n./node_modules/react-native/scripts/react-native-xcode.sh\n"; }; 6D73AECF1E1B3946094B40BC /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; @@ -8389,9 +8389,11 @@ CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_IDENTITY = "iPhone Developer"; - CODE_SIGN_STYLE = Automatic; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; + CODE_SIGN_STYLE = Manual; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - DEVELOPMENT_TEAM = "${APP_DEVELOPMENT_TEAM}"; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = HPY23A294X; GCC_C_LANGUAGE_STANDARD = gnu11; INFOPLIST_FILE = Extensions/Siri/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 13.2; @@ -8401,6 +8403,8 @@ OTHER_SWIFT_FLAGS = "$(inherited) -Xcc -DFB_SONARKIT_ENABLED"; PRODUCT_BUNDLE_IDENTIFIER = "${APP_BUNDLE_ID}.Siri"; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "Ghostery Private Browser - Siri"; SKIP_INSTALL = YES; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; @@ -8418,9 +8422,11 @@ CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_IDENTITY = "iPhone Developer"; - CODE_SIGN_STYLE = Automatic; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; + CODE_SIGN_STYLE = Manual; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - DEVELOPMENT_TEAM = "${APP_DEVELOPMENT_TEAM}"; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = HPY23A294X; GCC_C_LANGUAGE_STANDARD = gnu11; INFOPLIST_FILE = Extensions/Siri/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 13.2; @@ -8430,6 +8436,8 @@ OTHER_SWIFT_FLAGS = "$(inherited) -Xcc -DFB_SONARKIT_ENABLED"; PRODUCT_BUNDLE_IDENTIFIER = "${APP_BUNDLE_ID}.Siri"; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "Ghostery Private Browser - Siri"; SKIP_INSTALL = YES; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; @@ -8723,9 +8731,11 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_ENTITLEMENTS = Extensions/OpenIn/Entitlements/OpenIn.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; - CODE_SIGN_STYLE = Automatic; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; + CODE_SIGN_STYLE = Manual; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - DEVELOPMENT_TEAM = "${APP_DEVELOPMENT_TEAM}"; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = HPY23A294X; GCC_C_LANGUAGE_STANDARD = gnu11; INFOPLIST_FILE = Extensions/OpenIn/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 12.0; @@ -8735,6 +8745,8 @@ OTHER_SWIFT_FLAGS = "$(inherited) -Xcc -DFB_SONARKIT_ENABLED"; PRODUCT_BUNDLE_IDENTIFIER = "${APP_BUNDLE_ID}.${EXTENSION_OPEN_IN_APP_BUNDLE_ID_POSTFIX}"; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "Ghostery Private Browser - OpenIn"; SKIP_INSTALL = YES; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; @@ -8757,9 +8769,11 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_ENTITLEMENTS = Extensions/OpenIn/Entitlements/OpenIn.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; - CODE_SIGN_STYLE = Automatic; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; + CODE_SIGN_STYLE = Manual; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - DEVELOPMENT_TEAM = "${APP_DEVELOPMENT_TEAM}"; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = HPY23A294X; GCC_C_LANGUAGE_STANDARD = gnu11; INFOPLIST_FILE = Extensions/OpenIn/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 12.0; @@ -8769,6 +8783,8 @@ OTHER_SWIFT_FLAGS = "$(inherited) -Xcc -DFB_SONARKIT_ENABLED"; PRODUCT_BUNDLE_IDENTIFIER = "${APP_BUNDLE_ID}.${EXTENSION_OPEN_IN_APP_BUNDLE_ID_POSTFIX}"; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "Ghostery Private Browser - OpenIn"; SKIP_INSTALL = YES; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; @@ -9067,7 +9083,7 @@ CURRENT_PROJECT_VERSION = 1; DEBUG_ACTIVITY_MODE = ""; "DEBUG_ACTIVITY_MODE[sdk=iphonesimulator*]" = disable; - ENABLE_BITCODE = YES; + ENABLE_BITCODE = NO; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; @@ -9159,8 +9175,10 @@ BUNDLE_DISPLAY_NAME = "${BUNDLE_DISPLAY_NAME}"; CODE_SIGN_ENTITLEMENTS = "$(inherit)Branding/Ghostery/Entitlements/Ghostery.entitlements"; CODE_SIGN_IDENTITY = "iPhone Developer"; - CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = "${APP_DEVELOPMENT_TEAM}"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; + CODE_SIGN_STYLE = Manual; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = HPY23A294X; ENABLE_TESTABILITY = YES; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; HEADER_SEARCH_PATHS = ( @@ -9188,6 +9206,7 @@ PRODUCT_MODULE_NAME = Client; PRODUCT_NAME = UserAgent; PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "Ghostery Private Browser"; SWIFT_OBJC_BRIDGING_HEADER = "$(PROJECT_DIR)/Client/Client-Bridging-Header.h"; }; name = CI; @@ -9201,8 +9220,10 @@ BUNDLE_DISPLAY_NAME = "${BUNDLE_DISPLAY_NAME}"; CODE_SIGN_ENTITLEMENTS = "$(inherit)Extensions/ShareTo/Entitlements/ShareTo.entitlements"; CODE_SIGN_IDENTITY = "iPhone Developer"; - CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = "${APP_DEVELOPMENT_TEAM}"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; + CODE_SIGN_STYLE = Manual; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = HPY23A294X; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; INFOPLIST_FILE = Extensions/ShareTo/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 12.0; @@ -9212,6 +9233,7 @@ PRODUCT_BUNDLE_IDENTIFIER = "${APP_BUNDLE_ID}.ShareTo"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "Ghostery Private Browser - ShareTo"; SKIP_INSTALL = YES; TARGETED_DEVICE_FAMILY = "1,2"; }; @@ -9478,7 +9500,7 @@ CURRENT_PROJECT_VERSION = 1; DEBUG_ACTIVITY_MODE = ""; "DEBUG_ACTIVITY_MODE[sdk=iphonesimulator*]" = disable; - ENABLE_BITCODE = YES; + ENABLE_BITCODE = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; @@ -9947,8 +9969,10 @@ BUNDLE_DISPLAY_NAME = "${BUNDLE_DISPLAY_NAME}"; CODE_SIGN_ENTITLEMENTS = "$(inherit)Branding/Ghostery/Entitlements/Ghostery.entitlements"; CODE_SIGN_IDENTITY = "iPhone Developer"; - CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = "${APP_DEVELOPMENT_TEAM}"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; + CODE_SIGN_STYLE = Manual; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = HPY23A294X; ENABLE_TESTABILITY = YES; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; HEADER_SEARCH_PATHS = ( @@ -9976,6 +10000,7 @@ PRODUCT_MODULE_NAME = Client; PRODUCT_NAME = UserAgent; PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "Ghostery Private Browser"; SWIFT_OBJC_BRIDGING_HEADER = "$(PROJECT_DIR)/Client/Client-Bridging-Header.h"; }; name = Release; @@ -10019,7 +10044,7 @@ CURRENT_PROJECT_VERSION = 1; DEBUG_ACTIVITY_MODE = ""; "DEBUG_ACTIVITY_MODE[sdk=iphonesimulator*]" = disable; - ENABLE_BITCODE = YES; + ENABLE_BITCODE = NO; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; @@ -10134,8 +10159,10 @@ BUNDLE_DISPLAY_NAME = "${BUNDLE_DISPLAY_NAME}"; CODE_SIGN_ENTITLEMENTS = "$(inherit)Extensions/ShareTo/Entitlements/ShareTo.entitlements"; CODE_SIGN_IDENTITY = "iPhone Developer"; - CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = "${APP_DEVELOPMENT_TEAM}"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; + CODE_SIGN_STYLE = Manual; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = HPY23A294X; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; INFOPLIST_FILE = Extensions/ShareTo/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 12.0; @@ -10145,6 +10172,7 @@ PRODUCT_BUNDLE_IDENTIFIER = "${APP_BUNDLE_ID}.ShareTo"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "Ghostery Private Browser - ShareTo"; SKIP_INSTALL = YES; TARGETED_DEVICE_FAMILY = "1,2"; }; diff --git a/UserAgent/Interceptor/AntiPhishing/AntiPhishingDetector.swift b/UserAgent/Interceptor/AntiPhishing/AntiPhishingDetector.swift index a7b567bfb..2f85fa5de 100644 --- a/UserAgent/Interceptor/AntiPhishing/AntiPhishingDetector.swift +++ b/UserAgent/Interceptor/AntiPhishing/AntiPhishingDetector.swift @@ -23,7 +23,7 @@ class AntiPhishingDetector: NSObject { } // MARK: - public APIs - func isPhishingURL(_ url: URL, completion:@escaping AntiPhishingCheck) -> Bool { + func isPhishingURL(_ url: URL, completion: @escaping AntiPhishingCheck) -> Bool { guard url.host != "localhost" && url.host != "local" else { completion(false) return false @@ -45,7 +45,7 @@ class AntiPhishingDetector: NSObject { return detectedPhishingURLs.contains(url) } - private func scanURL(_ url: URL, completion:@escaping (Bool) -> Void) { + private func scanURL(_ url: URL, completion: @escaping (Bool) -> Void) { guard let host = url.host else { completion(false) return diff --git a/azure-pipelines.yml b/azure-pipelines.yml deleted file mode 100644 index 5de6c9e9a..000000000 --- a/azure-pipelines.yml +++ /dev/null @@ -1,73 +0,0 @@ -trigger: -- master -- develop - -pr: - branches: - include: - - '*' - -strategy: - matrix: - Cliqz: - scheme: 'Cliqz' - actions: 'build' - Ghostery: - scheme: 'Ghostery' - actions: 'build' - CliqzTests: - scheme: 'Cliqz' - actions: 'test' - -pool: - vmImage: 'macOS-10.15' - -steps: -- bash: | - sudo xcode-select --switch /Applications/Xcode_12.app - displayName: 'Change XCode to 12' - -- task: NodeTool@0 - displayName: 'Define Node to v12.18.4' - inputs: - versionSpec: '12.18.4' - -- bash: | - set -x - npm i -g npm@6.5 - /usr/local/bin/npm ci - displayName: 'Install Node modules' - -- bash: | - set -x - npm run build-user-scripts - displayName: Generate User Scripts - -- task: UseRubyVersion@0 - inputs: - versionSpec: '2.6' - addToPath: true - -- bash: | - set -x - gem install bundler:2.1.4 --force - bundle install --retry=3 - bundle exec pod repo update - bundle exec pod install - displayName: 'Install CocoaPods' - -- bash: bundle exec fastlane lint - displayName: 'Lint' - -- task: Xcode@5 - inputs: - actions: '$(actions)' - sdk: 'iphonesimulator' - xcWorkspacePath: 'UserAgent.xcworkspace' - scheme: '$(scheme)' - packageApp: true - configuration: 'CI' - destinationPlatformOption: 'iOS' - destinationSimulators: 'iPhone 11' - publishJUnitResults: true - args: '-derivedDataPath builds' diff --git a/bootstrap.sh b/bootstrap.sh index 687d164b8..6d6e31e61 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -6,25 +6,17 @@ # if [ -z "$1" ]; then - echo "No argument specified. Fallback to Cliqz" - sh Branding/setup.sh Cliqz ./ + echo "No argument specified. Fallback to Ghostery" + sh Branding/setup.sh Ghostery ./ else sh Branding/setup.sh $1 ./ fi -set -e +# nodejs +npm ci +npm run build-user-scripts -brew update -brew bundle - -nodenv install -s -eval "$(nodenv init -)" -nodenv exec npm i -g npm@6.5 -nodenv exec npm ci -nodenv exec npm run build-user-scripts - -rbenv install -s -eval "$(rbenv init -)" -rbenv exec gem install bundler -rbenv exec bundle install -rbenv exec bundle exec pod install --repo-update +# ruby +gem install bundler +bundle install +bundle exec pod install --repo-update