Bug 1349797 - Make domain autocompletion case-insensitive. r?janH draft
authorMehdi Soleimannejad <mehdisolamannejad@gmail.com>
Wed, 26 Jul 2017 18:41:36 +0430
changeset 618097 e5f5c43a61ce83a759c1ad6668d3c8f68550b020
parent 615779 e8400551c2e39f24c75a009ebed496c7acd7bf47
child 639965 8e4a174e957471e8b897a3f65507a57aa03a6a3e
push id71218
push userbmo:mehdisolamannejad@gmail.com
push dateSun, 30 Jul 2017 02:58:02 +0000
reviewersjanH
bugs1349797
milestone56.0a1
Bug 1349797 - Make domain autocompletion case-insensitive. r?janH MozReview-Commit-ID: EQy9qbTnBFQ
mobile/android/base/java/org/mozilla/gecko/home/BrowserSearch.java
mobile/android/base/java/org/mozilla/gecko/toolbar/ToolbarEditText.java
mobile/android/geckoview/src/main/java/org/mozilla/gecko/util/StringUtils.java
--- a/mobile/android/base/java/org/mozilla/gecko/home/BrowserSearch.java
+++ b/mobile/android/base/java/org/mozilla/gecko/home/BrowserSearch.java
@@ -593,17 +593,17 @@ public class BrowserSearch extends HomeF
                 }
             }
         }
         return domains;
     }
 
     private String searchDomains(String search) {
         for (String domain : getDomains()) {
-            if (domain.startsWith(search)) {
+            if (StringUtils.caseInsensitiveStartsWith(domain, search)) {
                 return domain;
             }
         }
         return null;
     }
 
     private String findAutocompletion(String searchTerm, Cursor c, boolean searchPath) {
         if (!c.moveToFirst()) {
@@ -622,35 +622,35 @@ public class BrowserSearch extends HomeF
                 // Prefetch the first item in the list since it's weighted the highest
                 final GeckoBundle data = new GeckoBundle(1);
                 data.putString("url", url);
                 EventDispatcher.getInstance().dispatch("Session:Prefetch", data);
             }
 
             // Does the completion match against the whole URL? This will match
             // about: pages, as well as user input including "http://...".
-            if (url.startsWith(searchTerm)) {
+            if (StringUtils.caseInsensitiveStartsWith(url, searchTerm)) {
                 return uriSubstringUpToMatchedPath(url, 0,
                         (searchLength > HTTPS_PREFIX_LENGTH) ? searchLength : HTTPS_PREFIX_LENGTH);
             }
 
             final Uri uri = Uri.parse(url);
             final String host = uri.getHost();
 
             // Host may be null for about pages.
             if (host == null) {
                 continue;
             }
 
-            if (host.startsWith(searchTerm)) {
+            if (StringUtils.caseInsensitiveStartsWith(host, searchTerm)) {
                 return host + "/";
             }
 
             final String strippedHost = StringUtils.stripCommonSubdomains(host);
-            if (strippedHost.startsWith(searchTerm)) {
+            if (StringUtils.caseInsensitiveStartsWith(strippedHost, searchTerm)) {
                 return strippedHost + "/";
             }
 
             ++searchCount;
 
             if (!searchPath) {
                 continue;
             }
@@ -661,17 +661,17 @@ public class BrowserSearch extends HomeF
                 // This was a URL string that parsed to a different host (normalized?).
                 // Give up.
                 continue;
             }
 
             // We already matched the non-stripped host, so now we're
             // substring-searching in the part of the URL without the common
             // subdomains.
-            if (url.startsWith(searchTerm, hostOffset)) {
+            if (StringUtils.caseInsensitiveStartsWith(url, searchTerm, hostOffset)) {
                 // Great! Return including the rest of the path segment.
                 return uriSubstringUpToMatchedPath(url, hostOffset, hostOffset + searchLength);
             }
         } while (searchCount < MAX_AUTOCOMPLETE_SEARCH && c.moveToNext());
 
         // If we can't find an autocompletion domain from history, let's try using the fallback list.
         return searchDomains(searchTerm);
     }
@@ -1381,9 +1381,9 @@ public class BrowserSearch extends HomeF
 
             super.setPrivateMode(isPrivate);
         }
 
         private void setSelector(boolean isPrivate) {
             setSelector(isPrivate ? R.drawable.search_list_selector_private : R.drawable.search_list_selector);
         }
     }
-}
+}
\ No newline at end of file
--- a/mobile/android/base/java/org/mozilla/gecko/toolbar/ToolbarEditText.java
+++ b/mobile/android/base/java/org/mozilla/gecko/toolbar/ToolbarEditText.java
@@ -308,17 +308,18 @@ public class ToolbarEditText extends Cus
         final int autoCompleteStart = text.getSpanStart(AUTOCOMPLETE_SPAN);
         mAutoCompleteResult = result;
 
         if (autoCompleteStart > -1) {
             // Autocomplete text already exists; we should replace existing autocomplete text.
 
             // If the result and the current text don't have the same prefixes,
             // the result is stale and we should wait for the another result to come in.
-            if (!TextUtils.regionMatches(result, 0, text, 0, autoCompleteStart)) {
+            final String userText = text.toString().substring(0, autoCompleteStart);
+            if (!StringUtils.caseInsensitiveStartsWith(result, userText)) {
                 return;
             }
 
             beginSettingAutocomplete();
 
             // Replace the existing autocomplete text with new one.
             // replace() preserves the autocomplete spans that we set before.
             text.replace(autoCompleteStart, textLength, result, autoCompleteStart, resultLength);
@@ -331,17 +332,17 @@ public class ToolbarEditText extends Cus
             endSettingAutocomplete();
 
         } else {
             // No autocomplete text yet; we should add autocomplete text
 
             // If the result prefix doesn't match the current text,
             // the result is stale and we should wait for the another result to come in.
             if (resultLength <= textLength ||
-                    !TextUtils.regionMatches(result, 0, text, 0, textLength)) {
+                    !StringUtils.caseInsensitiveStartsWith(result, text.toString())) {
                 return;
             }
 
             final Object[] spans = text.getSpans(textLength, textLength, Object.class);
             final int[] spanStarts = new int[spans.length];
             final int[] spanEnds = new int[spans.length];
             final int[] spanFlags = new int[spans.length];
 
@@ -529,17 +530,17 @@ public class ToolbarEditText extends Cus
             }
 
             mAutoCompletePrefixLength = textLength;
 
             // If we are not autocompleting, we set mDiscardAutoCompleteResult to true
             // to discard any autocomplete results that are in-flight, and vice versa.
             mDiscardAutoCompleteResult = !doAutocomplete;
 
-            if (doAutocomplete && mAutoCompleteResult.startsWith(text)) {
+            if (doAutocomplete && StringUtils.caseInsensitiveStartsWith(mAutoCompleteResult, text)) {
                 // If this text already matches our autocomplete text, autocomplete likely
                 // won't change. Just reuse the old autocomplete value.
                 onAutocomplete(mAutoCompleteResult);
                 doAutocomplete = false;
             } else {
                 // Otherwise, remove the old autocomplete text
                 // until any new autocomplete text gets added.
                 removeAutocomplete(editable);
@@ -627,9 +628,9 @@ public class ToolbarEditText extends Cus
                 removeAutocomplete(getText())) {
                 // Delete autocomplete text when backspacing or forward deleting.
                 return true;
             }
 
             return false;
         }
     }
-}
+}
\ No newline at end of file
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/util/StringUtils.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/util/StringUtils.java
@@ -271,9 +271,23 @@ public class StringUtils {
      */
     public static String forceLTR(String text) {
         if (!isRTL(text)) {
             return text;
         }
 
         return "\u200E" + text;
     }
-}
+
+    /**
+     * Case-insensitive version of {@link String#startsWith(String)}.
+     */
+    public static boolean caseInsensitiveStartsWith(String text, String prefix) {
+        return caseInsensitiveStartsWith(text, prefix, 0);
+    }
+
+    /**
+     * Case-insensitive version of {@link String#startsWith(String, int)}.
+     */
+    public static boolean caseInsensitiveStartsWith(String text, String prefix, int start) {
+        return text.regionMatches(true, start, prefix, 0, prefix.length());
+    }
+}
\ No newline at end of file