diff --git a/Blockzilla.xcodeproj/project.pbxproj b/Blockzilla.xcodeproj/project.pbxproj index be5a8e33cd..9fa6851f1e 100644 --- a/Blockzilla.xcodeproj/project.pbxproj +++ b/Blockzilla.xcodeproj/project.pbxproj @@ -7,7 +7,6 @@ objects = { /* Begin PBXBuildFile section */ - 050E8B1E2064FECE00DF6090 /* StringExtensionTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 050E8B1D2064FECE00DF6090 /* StringExtensionTest.swift */; }; 0B0D6BC41F3CDDBB00497D08 /* CollapsedURLTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B0D6BC31F3CDDBB00497D08 /* CollapsedURLTest.swift */; }; 0B37F9A61E2FCAD4002DF74B /* SearchProviderTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B37F9A51E2FCAD4002DF74B /* SearchProviderTest.swift */; }; 0B70C1631DE6128900CEF7E0 /* WebsiteMemoryTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B70C1621DE6128900CEF7E0 /* WebsiteMemoryTest.swift */; }; @@ -255,7 +254,6 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ - 050E8B1D2064FECE00DF6090 /* StringExtensionTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StringExtensionTest.swift; sourceTree = ""; }; 0B0D6BC31F3CDDBB00497D08 /* CollapsedURLTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CollapsedURLTest.swift; sourceTree = ""; }; 0B37F9A51E2FCAD4002DF74B /* SearchProviderTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SearchProviderTest.swift; sourceTree = ""; }; 0B4868651F2250A3008C3C09 /* PastenGoTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PastenGoTest.swift; sourceTree = ""; }; @@ -1211,7 +1209,6 @@ D8E015601FCF409F00CA3B9F /* Info.plist */, D831FEE1205247A400EAE19A /* BrowserViewControllerTests.swift */, D8E0156D1FD9E40F00CA3B9F /* DomainCompletionTests.swift */, - 050E8B1D2064FECE00DF6090 /* StringExtensionTest.swift */, D803D37320EF1A49001F2819 /* UserAgentTests.swift */, ); path = ClientTests; @@ -1873,7 +1870,6 @@ D803D37420EF1A49001F2819 /* UserAgentTests.swift in Sources */, D831FEE2205247A400EAE19A /* BrowserViewControllerTests.swift in Sources */, D8E0155F1FCF409F00CA3B9F /* SearchEngineManagerTests.swift in Sources */, - 050E8B1E2064FECE00DF6090 /* StringExtensionTest.swift in Sources */, D8E0156E1FD9E40F00CA3B9F /* DomainCompletionTests.swift in Sources */, D025F225218B64D600B262D8 /* SearchEngineTests.swift in Sources */, ); diff --git a/Blockzilla/BrowserViewController.swift b/Blockzilla/BrowserViewController.swift index 362a6fec2e..16372ca1e2 100644 --- a/Blockzilla/BrowserViewController.swift +++ b/Blockzilla/BrowserViewController.swift @@ -605,7 +605,13 @@ class BrowserViewController: UIViewController { } fileprivate func presentImageActionSheet(title: String, link: String?, saveAction: @escaping () -> Void, copyAction: @escaping () -> Void) { - let alertController = UIAlertController(title: title.truncated(limit: 160, position: .middle), message: nil, preferredStyle: .actionSheet) + + var normalizedTitle = title + if title.count > UIConstants.layout.truncateCharactersLimit { + normalizedTitle = String("\(title.prefix(UIConstants.layout.truncateHeadCharactersCount))\(UIConstants.strings.truncateLeader)\(title.suffix(UIConstants.layout.truncateTailCharactersCount))") + } + + let alertController = UIAlertController(title: normalizedTitle, message: nil, preferredStyle: .actionSheet) if let link = link { alertController.addAction(UIAlertAction(title: UIConstants.strings.copyLink, style: .default) { _ in diff --git a/Blockzilla/StringExtensions.swift b/Blockzilla/StringExtensions.swift index bc87dfdb07..e6eef6bf11 100644 --- a/Blockzilla/StringExtensions.swift +++ b/Blockzilla/StringExtensions.swift @@ -5,11 +5,6 @@ import Foundation extension String { - enum TruncationPosition { - case head - case middle - case tail - } var isUrl: Bool { let detector = try! NSDataDetector(types: NSTextCheckingResult.CheckingType.link.rawValue) @@ -19,38 +14,4 @@ extension String { return true } - - func truncated(limit: Int, position: TruncationPosition = .tail, leader: String = "...") -> String { - guard count > limit else { return self } - - switch position { - case .head: - let truncated = self[index(endIndex, offsetBy: leader.count - limit)...] - return leader + truncated - case .middle: - let headCharactersCount = (limit - leader.count) / 2 - let head = self[.. Bool { - // rangeOfString returns nil if other is empty, destroying the analogy with (ordered) sets. - if other.isEmpty { - return true - } - - if let range = self.range(of: other, options: .anchored) { - return range.lowerBound == self.startIndex - } - - return false - } } diff --git a/Blockzilla/UIConstants.swift b/Blockzilla/UIConstants.swift index 424beb37a4..7e460e6097 100644 --- a/Blockzilla/UIConstants.swift +++ b/Blockzilla/UIConstants.swift @@ -218,6 +218,9 @@ struct UIConstants { static let shareTrackersHeight: CGFloat = 36 static let homeViewTextOffset: CGFloat = 5 static let homeViewLabelMinimumScale: CGFloat = 0.65 + static let truncateCharactersLimit = 160 + static let truncateHeadCharactersCount = (truncateCharactersLimit - UIConstants.strings.truncateLeader.count) / 2 + static let truncateTailCharactersCount = Int(ceil(Double(truncateCharactersLimit - UIConstants.strings.truncateLeader.count) / 2.0)) } struct strings { @@ -451,5 +454,6 @@ struct UIConstants { static let sumoTopicUsageData = "usage-data" static let encodingNameUTF8 = "utf-8" static let googleAmpURLPrefix = "https://www.google.com/amp/s/" + static let truncateLeader = "..." } } diff --git a/ClientTests/StringExtensionTest.swift b/ClientTests/StringExtensionTest.swift deleted file mode 100644 index 1ed97070a7..0000000000 --- a/ClientTests/StringExtensionTest.swift +++ /dev/null @@ -1,56 +0,0 @@ -/* 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 - -#if FOCUS -@testable import Firefox_Focus -#else -@testable import Firefox_Klar -#endif - -class StringExtensionTest: XCTestCase { - - - func testStringShouldBeTruncated() { - let originalString = "This is a long title string" - - let headTruncatedString = originalString.truncated(limit: 15, position: .head, leader: "..") - XCTAssertEqual(headTruncatedString.count, 15) - XCTAssertEqual(headTruncatedString, ".. title string") - - let middleTruncatedString = originalString.truncated(limit: 15, position: .middle, leader: "..") - XCTAssertEqual(middleTruncatedString.count, 15) - XCTAssertEqual(middleTruncatedString, "This i.. string") - - let tailTruncatedString = originalString.truncated(limit: 15, position: .tail, leader: "..") - XCTAssertEqual(tailTruncatedString.count, 15) - XCTAssertEqual(tailTruncatedString, "This is a lon..") - } - - func testStringShouldStartWithString() { - let originalString = "This is a long title string" - let startString = "This is" - - let isStarting = originalString.startsWith(other: startString) - XCTAssertEqual(isStarting, true) - } - - func testStringShouldStartWithEmptyString() { - let originalString = "This is a long title string" - let startString = "" - - let isStarting = originalString.startsWith(other: startString) - XCTAssertEqual(isStarting, true) - } - - func testStringShouldNotStartWithString() { - let originalString = "This is a long title string" - let startString = "TX" - - let isStarting = originalString.startsWith(other: startString) - XCTAssertEqual(isStarting, false) - } - -}