Skip to content
This repository was archived by the owner on May 18, 2021. It is now read-only.
Open
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
22 changes: 15 additions & 7 deletions AutocompleteTextField.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -233,17 +233,19 @@
D31083311EAA7BF500ECF778 = {
CreatedOnToolsVersion = 8.2.1;
DevelopmentTeam = 43AQ936H96;
LastSwiftMigration = 0820;
LastSwiftMigration = 0940;
ProvisioningStyle = Automatic;
};
D310834F1EAA7C3600ECF778 = {
CreatedOnToolsVersion = 8.2.1;
DevelopmentTeam = 43AQ936H96;
LastSwiftMigration = 0940;
ProvisioningStyle = Automatic;
};
D370686F1EAE68B2000D6BA7 = {
CreatedOnToolsVersion = 8.2.1;
DevelopmentTeam = 43AQ936H96;
LastSwiftMigration = 0940;
ProvisioningStyle = Automatic;
TestTargetID = D310834F1EAA7C3600ECF778;
};
Expand Down Expand Up @@ -476,7 +478,8 @@
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 3.0;
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
SWIFT_VERSION = 4.0;
};
name = Debug;
};
Expand All @@ -497,7 +500,8 @@
PRODUCT_BUNDLE_IDENTIFIER = org.mozilla.ios.AutocompleteTextField;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_VERSION = 3.0;
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
SWIFT_VERSION = 4.0;
};
name = Release;
};
Expand All @@ -511,7 +515,8 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = org.mozilla.ios.AutocompleteTextFieldExample;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 3.0;
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
SWIFT_VERSION = 4.0;
};
name = Debug;
};
Expand All @@ -525,7 +530,8 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = org.mozilla.ios.AutocompleteTextFieldExample;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 3.0;
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
SWIFT_VERSION = 4.0;
};
name = Release;
};
Expand All @@ -537,7 +543,8 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = org.mozilla.ios.AutocompleteTextFieldUITests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 3.0;
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
SWIFT_VERSION = 4.0;
TEST_TARGET_NAME = AutocompleteTextFieldExample;
};
name = Debug;
Expand All @@ -550,7 +557,8 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = org.mozilla.ios.AutocompleteTextFieldUITests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 3.0;
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
SWIFT_VERSION = 4.0;
TEST_TARGET_NAME = AutocompleteTextFieldExample;
};
name = Release;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
2 changes: 1 addition & 1 deletion Example/DomainCompletionSource.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class DomainCompletionSource: AutocompleteTextFieldCompletionSource {
// We don't actually want to match the top-level domain ("com", "org", etc.) by itself, so
// so make sure the result includes at least one ".".
let range = domainWithDotPrefix.index(range.lowerBound, offsetBy: 1)
let matchedDomain: String = domainWithDotPrefix.substring(from: range)
let matchedDomain = String(domainWithDotPrefix[range...])
if matchedDomain.contains(".") {
return matchedDomain + "/"
}
Expand Down
16 changes: 13 additions & 3 deletions Source/AutocompleteTextField.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ open class AutocompleteTextField: UITextField, UITextFieldDelegate {
// The last string used as a replacement in shouldChangeCharactersInRange.
private var lastReplacement: String?

// Used as a state flag after highlighting all the text
private var isHighlightingAll: Bool = false

public init() {
super.init(frame: CGRect.zero)
addTarget(self, action: #selector(textDidChange), for: .editingChanged)
Expand Down Expand Up @@ -109,6 +112,7 @@ open class AutocompleteTextField: UITextField, UITextFieldDelegate {
self.text = nil
setCompletion(text ?? "")
selectedTextRange = textRange(from: beginningOfDocument, to: beginningOfDocument)
isHighlightingAll = true
}

private func applyCompletion() {
Expand All @@ -127,14 +131,20 @@ open class AutocompleteTextField: UITextField, UITextFieldDelegate {
}

private func removeCompletion() {
guard let completionRange = completionRange else { return }
guard var completionRange = completionRange else { return }

applyCompletion()

// Fixes: https://github.com/mozilla-mobile/focus-ios/issues/630
// Prevents the hard crash when you select all and start a new query
guard let count = text?.count, count > 1 else { return }

// Fixes the problem when after highlighting all, entire string is deleted instead of only old part
if isHighlightingAll {
completionRange.location += (count - completionRange.length)
isHighlightingAll = false
}

text = (text as NSString?)?.replacingCharacters(in: completionRange, with: "")
}

Expand All @@ -145,10 +155,10 @@ open class AutocompleteTextField: UITextField, UITextFieldDelegate {
guard !completion.isEmpty, completion.lowercased().hasPrefix(text.lowercased()) else { return }

// Add the completion suffix to the current text and highlight it.
let completion = completion.substring(from: completion.index(completion.startIndex, offsetBy: text.characters.count))
let completion = completion[completion.index(completion.startIndex, offsetBy: text.count)...]
let attributed = NSMutableAttributedString(string: text + completion)
let range = NSMakeRange((text as NSString).length, (completion as NSString).length)
attributed.addAttribute(NSBackgroundColorAttributeName, value: highlightColor, range: range)
attributed.addAttribute(NSAttributedStringKey.backgroundColor, value: highlightColor, range: range)
attributedText = attributed
completionRange = range
}
Expand Down
20 changes: 10 additions & 10 deletions Tests/AutocompleteTextFieldUITests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,26 +22,26 @@ class AutocompleteTextFieldUITests: XCTestCase {

field.typeText("w")
XCTAssertEqual(field.value! as! String, "www.google.com/")
field.typeText(XCUIKeyboardKeyDelete)
field.typeText(XCUIKeyboardKey.delete.rawValue)
XCTAssertEqual(field.value! as! String, "w")
field.typeText("ww.yah")
XCTAssertEqual(field.value! as! String, "www.yahoo.com/")
field.typeText(XCUIKeyboardKeyDelete)
field.typeText(XCUIKeyboardKey.delete.rawValue)
XCTAssertEqual(field.value! as! String, "www.yah")
field.typeText(XCUIKeyboardKeyDelete)
field.typeText(XCUIKeyboardKey.delete.rawValue)
XCTAssertEqual(field.value! as! String, "www.ya")
field.typeText(XCUIKeyboardKeyDelete)
field.typeText(XCUIKeyboardKeyDelete)
field.typeText(XCUIKeyboardKeyDelete)
field.typeText(XCUIKeyboardKeyDelete)
field.typeText(XCUIKeyboardKeyDelete)
field.typeText(XCUIKeyboardKeyDelete)
field.typeText(XCUIKeyboardKey.delete.rawValue)
field.typeText(XCUIKeyboardKey.delete.rawValue)
field.typeText(XCUIKeyboardKey.delete.rawValue)
field.typeText(XCUIKeyboardKey.delete.rawValue)
field.typeText(XCUIKeyboardKey.delete.rawValue)
field.typeText(XCUIKeyboardKey.delete.rawValue)
XCTAssertEqual(field.value! as! String, "")
field.typeText("g")
XCTAssertEqual(field.value! as! String, "google.com/")
field.typeText("z")
XCTAssertEqual(field.value! as! String, "gz")
field.typeText(XCUIKeyboardKeyDelete)
field.typeText(XCUIKeyboardKey.delete.rawValue)
XCTAssertEqual(field.value! as! String, "g")
field.typeText("o")
XCTAssertEqual(field.value! as! String, "google.com/")
Expand Down