summaryrefslogtreecommitdiffstats
path: root/chrome/common
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/common')
-rw-r--r--chrome/common/gfx/url_elider.cc100
-rw-r--r--chrome/common/gfx/url_elider.h41
-rw-r--r--chrome/common/gfx/url_elider_unittest.cc47
3 files changed, 171 insertions, 17 deletions
diff --git a/chrome/common/gfx/url_elider.cc b/chrome/common/gfx/url_elider.cc
index f21888e..1cc92ca 100644
--- a/chrome/common/gfx/url_elider.cc
+++ b/chrome/common/gfx/url_elider.cc
@@ -20,7 +20,8 @@ namespace gfx {
// Appends the given part of the original URL to the output string formatted for
// the user. The given parsed structure will be updated. The host name formatter
-// also takes the same accept languages component as ElideURL.
+// also takes the same accept languages component as ElideURL. |new_parsed| may
+// be null.
static void AppendFormattedHost(const GURL& url,
const std::wstring& languages,
std::wstring* output,
@@ -36,10 +37,12 @@ static void AppendFormattedComponent(const std::string& spec,
// A helper function to get Clean Url String from a GURL. The parsing of the
// URL may change because various parts of the string will change lengths. The
-// new parsing will be placed in the given out parameter.
+// new parsing will be placed in the given out parameter. |prefix_end| is set
+// to the end of the prefix (spec and separator characters before host).
static std::wstring GetCleanStringFromUrl(const GURL& url,
const std::wstring& languages,
- url_parse::Parsed* new_parsed);
+ url_parse::Parsed* new_parsed,
+ size_t* prefix_end);
// This function takes a GURL object and elides it. It returns a string
// which composed of parts from subdomain, domain, path, filename and query.
@@ -57,7 +60,8 @@ std::wstring ElideUrl(const GURL& url,
const std::wstring& languages) {
// Get a formatted string and corresponding parsing of the url.
url_parse::Parsed parsed;
- std::wstring url_string = GetCleanStringFromUrl(url, languages, &parsed);
+ std::wstring url_string = GetCleanStringFromUrl(url, languages, &parsed,
+ NULL);
if (available_pixel_width <= 0)
return url_string;
@@ -325,7 +329,8 @@ void AppendFormattedHost(const GURL& url,
if (host.is_nonempty()) {
// Handle possible IDN in the host name.
- new_parsed->host.begin = static_cast<int>(output->length());
+ if (new_parsed)
+ new_parsed->host.begin = static_cast<int>(output->length());
const std::string& spec = url.possibly_invalid_spec();
DCHECK(host.begin >= 0 &&
@@ -333,9 +338,11 @@ void AppendFormattedHost(const GURL& url,
host.begin < static_cast<int>(spec.length())));
net::IDNToUnicode(&spec[host.begin], host.len, languages, output);
- new_parsed->host.len =
- static_cast<int>(output->length()) - new_parsed->host.begin;
- } else {
+ if (new_parsed) {
+ new_parsed->host.len =
+ static_cast<int>(output->length()) - new_parsed->host.begin;
+ }
+ } else if (new_parsed) {
new_parsed->host.reset();
}
}
@@ -359,12 +366,16 @@ void AppendFormattedComponent(const std::string& spec,
std::wstring GetCleanStringFromUrl(const GURL& url,
const std::wstring& languages,
- url_parse::Parsed* new_parsed) {
+ url_parse::Parsed* new_parsed,
+ size_t* prefix_end) {
std::wstring url_string;
// Check for empty URLs or 0 available text width.
- if (url.is_empty())
+ if (url.is_empty()) {
+ if (prefix_end)
+ *prefix_end = 0;
return url_string;
+ }
// We handle both valid and invalid URLs (this will give us the spec
// regardless of validity).
@@ -377,10 +388,12 @@ std::wstring GetCleanStringFromUrl(const GURL& url,
//
// Copy everything before the host name we want (the scheme and the
// separators), minus the username start we computed above. These are ASCII.
- int prefix_end = parsed.CountCharactersBefore(
+ int pre_end = parsed.CountCharactersBefore(
url_parse::Parsed::USERNAME, true);
- for (int i = 0; i < prefix_end; i++)
+ for (int i = 0; i < pre_end; i++)
url_string.push_back(spec[i]);
+ if (prefix_end)
+ *prefix_end = static_cast<size_t>(pre_end);
new_parsed->scheme = parsed.scheme;
new_parsed->username.reset();
new_parsed->password.reset();
@@ -411,5 +424,66 @@ std::wstring GetCleanStringFromUrl(const GURL& url,
return url_string;
}
-} // namespace gfx.
+SortedDisplayURL::SortedDisplayURL(const GURL& url,
+ const std::wstring& languages) {
+ AppendFormattedHost(url, languages, &sort_host_, NULL);
+ std::wstring host_minus_www = net::StripWWW(sort_host_);
+ url_parse::Parsed parsed;
+ display_url_ = GetCleanStringFromUrl(url, languages, &parsed, &prefix_end_);
+ if (sort_host_.length() > host_minus_www.length()) {
+ prefix_end_ += sort_host_.length() - host_minus_www.length();
+ sort_host_.swap(host_minus_www);
+ }
+}
+int SortedDisplayURL::Compare(const SortedDisplayURL& other,
+ Collator* collator) const {
+ // Compare on hosts first. The host won't contain 'www.'.
+ UErrorCode compare_status = U_ZERO_ERROR;
+ UCollationResult host_compare_result = collator->compare(
+ static_cast<const UChar*>(sort_host_.c_str()),
+ static_cast<int>(sort_host_.length()),
+ static_cast<const UChar*>(other.sort_host_.c_str()),
+ static_cast<int>(other.sort_host_.length()),
+ compare_status);
+ DCHECK(U_SUCCESS(compare_status));
+ if (host_compare_result != 0)
+ return host_compare_result;
+
+ // Hosts match, compare on the portion of the url after the host.
+ std::wstring path = this->AfterHost();
+ std::wstring o_path = other.AfterHost();
+ compare_status = U_ZERO_ERROR;
+ UCollationResult path_compare_result = collator->compare(
+ static_cast<const UChar*>(path.c_str()),
+ static_cast<int>(path.length()),
+ static_cast<const UChar*>(o_path.c_str()),
+ static_cast<int>(o_path.length()),
+ compare_status);
+ DCHECK(U_SUCCESS(compare_status));
+ if (path_compare_result != 0)
+ return path_compare_result;
+
+ // Hosts and paths match, compare on the complete url. This'll push the www.
+ // ones to the end.
+ compare_status = U_ZERO_ERROR;
+ UCollationResult display_url_compare_result = collator->compare(
+ static_cast<const UChar*>(display_url_.c_str()),
+ static_cast<int>(display_url_.length()),
+ static_cast<const UChar*>(other.display_url_.c_str()),
+ static_cast<int>(other.display_url_.length()),
+ compare_status);
+ DCHECK(U_SUCCESS(compare_status));
+ return display_url_compare_result;
+}
+
+std::wstring SortedDisplayURL::AfterHost() const {
+ size_t slash_index = display_url_.find(sort_host_, prefix_end_);
+ if (slash_index == std::wstring::npos) {
+ NOTREACHED();
+ return std::wstring();
+ }
+ return display_url_.substr(slash_index + sort_host_.length());
+}
+
+} // namespace gfx.
diff --git a/chrome/common/gfx/url_elider.h b/chrome/common/gfx/url_elider.h
index 85e5ddf..83815f0 100644
--- a/chrome/common/gfx/url_elider.h
+++ b/chrome/common/gfx/url_elider.h
@@ -2,9 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CHROME_COMMON_GFX_URL_ELIDER_H__
-#define CHROME_COMMON_GFX_URL_ELIDER_H__
+#ifndef CHROME_COMMON_GFX_URL_ELIDER_H_
+#define CHROME_COMMON_GFX_URL_ELIDER_H_
+#include <unicode/coll.h>
+#include <unicode/uchar.h>
#include <windows.h>
#include "base/basictypes.h"
@@ -30,7 +32,38 @@ std::wstring ElideText(const std::wstring& text,
const ChromeFont& font,
int available_pixel_width);
-} // namespace gfx.
+// SortedDisplayURL maintains a string from a URL suitable for display to the
+// use. SortedDisplayURL also provides a function used for comparing two
+// SortedDisplayURLs for use in visually ordering the SortedDisplayURLs.
+//
+// SortedDisplayURL is relatively cheap and supports value semantics.
+class SortedDisplayURL {
+ public:
+ SortedDisplayURL(const GURL& url, const std::wstring& languages);
+ SortedDisplayURL() {}
+
+ // Compares this SortedDisplayURL to |url| using |collator|. Returns a value
+ // < 0, = 1 or > 0 as to whether this url is less then, equal to or greater
+ // than the supplied url.
+ int Compare(const SortedDisplayURL& other, Collator* collator) const;
+
+ // Returns the display string for the URL.
+ const std::wstring& display_url() const { return display_url_; }
+
+ private:
+ // Returns everything after the host. This is used by Compare if the hosts
+ // match.
+ std::wstring AfterHost() const;
-#endif // #ifndef CHROME_COMMON_GFX_URL_ELIDER_H__
+ // Host name minus 'www.'. Used by Compare.
+ std::wstring sort_host_;
+
+ // End of the prefix (spec and separator) in display_url_.
+ size_t prefix_end_;
+
+ std::wstring display_url_;
+};
+
+} // namespace gfx.
+#endif // #ifndef CHROME_COMMON_GFX_URL_ELIDER_H_
diff --git a/chrome/common/gfx/url_elider_unittest.cc b/chrome/common/gfx/url_elider_unittest.cc
index b6ca38b..4f1a3c9 100644
--- a/chrome/common/gfx/url_elider_unittest.cc
+++ b/chrome/common/gfx/url_elider_unittest.cc
@@ -163,3 +163,50 @@ TEST(URLEliderTest, ElideTextLongStrings) {
}
}
+// Verifies display_url is set correctly.
+TEST(URLEliderTest, SortedDisplayURL) {
+ gfx::SortedDisplayURL d_url(GURL("http://www.google.com/"), std::wstring());
+ EXPECT_EQ(L"http://www.google.com/", d_url.display_url());
+}
+
+// Verifies DisplayURL::Compare works correctly.
+TEST(URLEliderTest, SortedDisplayURLCompare) {
+ UErrorCode create_status = U_ZERO_ERROR;
+ Collator* collator = Collator::createInstance(create_status);
+ if (!U_SUCCESS(create_status))
+ return;
+
+ struct TestData {
+ const std::string a;
+ const std::string b;
+ const int compare_result;
+ } tests[] = {
+ // IDN comparison. Hosts equal, so compares on path.
+ { "http://xn--1lq90i.cn/a", "http://xn--1lq90i.cn/b", -1},
+
+ // Because the host and after host match, this compares the full url.
+ { "http://www.x/b", "http://x/b", -1 },
+
+ // Because the host and after host match, this compares the full url.
+ { "http://www.a:1/b", "http://a:1/b", 1 },
+
+ // The hosts match, so these end up comparing on the after host portion.
+ { "http://www.x:0/b", "http://x:1/b", -1 },
+ { "http://www.x/a", "http://x/b", -1 },
+ { "http://x/b", "http://www.x/a", 1 },
+
+ // Trivial Equality.
+ { "http://a/", "http://a/", 0 },
+
+ // Compares just hosts.
+ { "http://www.a/", "http://b/", -1 },
+ };
+
+
+ for (size_t i = 0; i < arraysize(tests); ++i) {
+ gfx::SortedDisplayURL url1(GURL(tests[i].a), std::wstring());
+ gfx::SortedDisplayURL url2(GURL(tests[i].b), std::wstring());
+ EXPECT_EQ(tests[i].compare_result, url1.Compare(url2, collator));
+ EXPECT_EQ(-tests[i].compare_result, -url1.Compare(url2, collator));
+ }
+}