1f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "components/omnibox/url_prefix.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h"
9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
10a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
11a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochnamespace {
12a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
13a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// Like URLPrefix::BestURLPrefix() except also handles the prefix of
14a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// "www.".
15a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochconst URLPrefix* BestURLPrefixWithWWWCase(
16a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    const base::string16& text,
17a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    const base::string16& prefix_suffix) {
18a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  CR_DEFINE_STATIC_LOCAL(URLPrefix, www_prefix,
19a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                         (base::ASCIIToUTF16("www."), 1));
20a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  const URLPrefix* best_prefix = URLPrefix::BestURLPrefix(text, prefix_suffix);
21a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  if ((best_prefix == NULL) ||
22a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      (best_prefix->num_components < www_prefix.num_components)) {
23a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    if (URLPrefix::PrefixMatch(www_prefix, text, prefix_suffix))
24a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      best_prefix = &www_prefix;
25a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  }
26a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  return best_prefix;
27a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch}
28a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
29a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch}  // namespace
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)URLPrefix::URLPrefix(const base::string16& prefix, size_t num_components)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : prefix(prefix),
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      num_components(num_components) {
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const URLPrefixes& URLPrefix::GetURLPrefixes() {
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CR_DEFINE_STATIC_LOCAL(URLPrefixes, prefixes, ());
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (prefixes.empty()) {
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    prefixes.push_back(URLPrefix(base::ASCIIToUTF16("https://www."), 2));
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    prefixes.push_back(URLPrefix(base::ASCIIToUTF16("http://www."), 2));
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    prefixes.push_back(URLPrefix(base::ASCIIToUTF16("ftp://www."), 2));
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    prefixes.push_back(URLPrefix(base::ASCIIToUTF16("https://"), 1));
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    prefixes.push_back(URLPrefix(base::ASCIIToUTF16("http://"), 1));
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    prefixes.push_back(URLPrefix(base::ASCIIToUTF16("ftp://"), 1));
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    prefixes.push_back(URLPrefix(base::string16(), 0));
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return prefixes;
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
52a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)bool URLPrefix::IsURLPrefix(const base::string16& prefix) {
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const URLPrefixes& list = GetURLPrefixes();
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (URLPrefixes::const_iterator i = list.begin(); i != list.end(); ++i)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (i->prefix == prefix)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
61a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)const URLPrefix* URLPrefix::BestURLPrefix(const base::string16& text,
62a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                          const base::string16& prefix_suffix) {
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const URLPrefixes& list = GetURLPrefixes();
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (URLPrefixes::const_iterator i = list.begin(); i != list.end(); ++i)
65a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (PrefixMatch(*i, text, prefix_suffix))
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return &(*i);
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
69a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
70a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// static
71a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)bool URLPrefix::PrefixMatch(const URLPrefix& prefix,
72a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                            const base::string16& text,
73a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                            const base::string16& prefix_suffix) {
74a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return StartsWith(text, prefix.prefix + prefix_suffix, false);
75a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
76a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
77a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// static
780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochsize_t URLPrefix::GetInlineAutocompleteOffset(
7946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const base::string16& input,
8046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const base::string16& fixed_up_input,
81a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    const bool allow_www_prefix_without_scheme,
820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const base::string16& text) {
83a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  const URLPrefix* best_prefix = allow_www_prefix_without_scheme ?
8446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      BestURLPrefixWithWWWCase(text, input) : BestURLPrefix(text, input);
8546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  const base::string16* matching_string = &input;
86a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  // If we failed to find a best_prefix initially, try again using a fixed-up
87a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  // version of the user input.  This is especially useful to get about: URLs
88a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  // to inline against chrome:// shortcuts.  (about: URLs are fixed up to the
89a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  // chrome:// scheme.)
9046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (!best_prefix && !fixed_up_input.empty() && (fixed_up_input != input)) {
91a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    best_prefix = allow_www_prefix_without_scheme ?
9246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        BestURLPrefixWithWWWCase(text, fixed_up_input) :
9346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        BestURLPrefix(text, fixed_up_input);
9446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    matching_string = &fixed_up_input;
95a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  }
960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  return (best_prefix != NULL) ?
970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      (best_prefix->prefix.length() + matching_string->length()) :
980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      base::string16::npos;
99a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch}
100