OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/ui/elide_url.h" | 5 #include "chrome/browser/ui/elide_url.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/strings/string_split.h" | 8 #include "base/strings/string_split.h" |
9 #include "base/strings/utf_string_conversions.h" | 9 #include "base/strings/utf_string_conversions.h" |
10 #include "net/base/escape.h" | 10 #include "net/base/escape.h" |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
57 const gfx::FontList& font_list, | 57 const gfx::FontList& font_list, |
58 float available_pixel_width) { | 58 float available_pixel_width) { |
59 const size_t url_path_number_of_elements = url_path_elements.size(); | 59 const size_t url_path_number_of_elements = url_path_elements.size(); |
60 | 60 |
61 CHECK(url_path_number_of_elements); | 61 CHECK(url_path_number_of_elements); |
62 for (size_t i = url_path_number_of_elements - 1; i > 0; --i) { | 62 for (size_t i = url_path_number_of_elements - 1; i > 0; --i) { |
63 base::string16 elided_path = BuildPathFromComponents(url_path_prefix, | 63 base::string16 elided_path = BuildPathFromComponents(url_path_prefix, |
64 url_path_elements, url_filename, i); | 64 url_path_elements, url_filename, i); |
65 if (available_pixel_width >= GetStringWidthF(elided_path, font_list)) | 65 if (available_pixel_width >= GetStringWidthF(elided_path, font_list)) |
66 return ElideText(elided_path + url_query, font_list, | 66 return ElideText(elided_path + url_query, font_list, |
67 available_pixel_width, gfx::ELIDE_AT_END); | 67 available_pixel_width, gfx::ELIDE_TAIL); |
68 } | 68 } |
69 | 69 |
70 return base::string16(); | 70 return base::string16(); |
71 } | 71 } |
72 | 72 |
73 // Splits the hostname in the |url| into sub-strings for the full hostname, | 73 // Splits the hostname in the |url| into sub-strings for the full hostname, |
74 // the domain (TLD+1), and the subdomain (everything leading the domain). | 74 // the domain (TLD+1), and the subdomain (everything leading the domain). |
75 void SplitHost(const GURL& url, | 75 void SplitHost(const GURL& url, |
76 base::string16* url_host, | 76 base::string16* url_host, |
77 base::string16* url_domain, | 77 base::string16* url_domain, |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
117 url::Parsed parsed; | 117 url::Parsed parsed; |
118 const base::string16 url_string = | 118 const base::string16 url_string = |
119 net::FormatUrl(url, languages, net::kFormatUrlOmitAll, | 119 net::FormatUrl(url, languages, net::kFormatUrlOmitAll, |
120 net::UnescapeRule::SPACES, &parsed, NULL, NULL); | 120 net::UnescapeRule::SPACES, &parsed, NULL, NULL); |
121 if (available_pixel_width <= 0) | 121 if (available_pixel_width <= 0) |
122 return url_string; | 122 return url_string; |
123 | 123 |
124 // If non-standard, return plain eliding. | 124 // If non-standard, return plain eliding. |
125 if (!url.IsStandard()) | 125 if (!url.IsStandard()) |
126 return ElideText(url_string, font_list, available_pixel_width, | 126 return ElideText(url_string, font_list, available_pixel_width, |
127 gfx::ELIDE_AT_END); | 127 gfx::ELIDE_TAIL); |
128 | 128 |
129 // Now start eliding url_string to fit within available pixel width. | 129 // Now start eliding url_string to fit within available pixel width. |
130 // Fist pass - check to see whether entire url_string fits. | 130 // Fist pass - check to see whether entire url_string fits. |
131 const float pixel_width_url_string = GetStringWidthF(url_string, font_list); | 131 const float pixel_width_url_string = GetStringWidthF(url_string, font_list); |
132 if (available_pixel_width >= pixel_width_url_string) | 132 if (available_pixel_width >= pixel_width_url_string) |
133 return url_string; | 133 return url_string; |
134 | 134 |
135 // Get the path substring, including query and reference. | 135 // Get the path substring, including query and reference. |
136 const size_t path_start_index = parsed.path.begin; | 136 const size_t path_start_index = parsed.path.begin; |
137 const size_t path_len = parsed.path.len; | 137 const size_t path_len = parsed.path.len; |
138 base::string16 url_path_query_etc = url_string.substr(path_start_index); | 138 base::string16 url_path_query_etc = url_string.substr(path_start_index); |
139 base::string16 url_path = url_string.substr(path_start_index, path_len); | 139 base::string16 url_path = url_string.substr(path_start_index, path_len); |
140 | 140 |
141 // Return general elided text if url minus the query fits. | 141 // Return general elided text if url minus the query fits. |
142 const base::string16 url_minus_query = | 142 const base::string16 url_minus_query = |
143 url_string.substr(0, path_start_index + path_len); | 143 url_string.substr(0, path_start_index + path_len); |
144 if (available_pixel_width >= GetStringWidthF(url_minus_query, font_list)) | 144 if (available_pixel_width >= GetStringWidthF(url_minus_query, font_list)) |
145 return ElideText(url_string, font_list, available_pixel_width, | 145 return ElideText(url_string, font_list, available_pixel_width, |
146 gfx::ELIDE_AT_END); | 146 gfx::ELIDE_TAIL); |
147 | 147 |
148 base::string16 url_host; | 148 base::string16 url_host; |
149 base::string16 url_domain; | 149 base::string16 url_domain; |
150 base::string16 url_subdomain; | 150 base::string16 url_subdomain; |
151 SplitHost(url, &url_host, &url_domain, &url_subdomain); | 151 SplitHost(url, &url_host, &url_domain, &url_subdomain); |
152 | 152 |
153 // If this is a file type, the path is now defined as everything after ":". | 153 // If this is a file type, the path is now defined as everything after ":". |
154 // For example, "C:/aa/aa/bb", the path is "/aa/bb/cc". Interesting, the | 154 // For example, "C:/aa/aa/bb", the path is "/aa/bb/cc". Interesting, the |
155 // domain is now C: - this is a nice hack for eliding to work pleasantly. | 155 // domain is now C: - this is a nice hack for eliding to work pleasantly. |
156 if (url.SchemeIsFile()) { | 156 if (url.SchemeIsFile()) { |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
188 // Query element. | 188 // Query element. |
189 base::string16 url_query; | 189 base::string16 url_query; |
190 const float kPixelWidthDotsTrailer = GetStringWidthF( | 190 const float kPixelWidthDotsTrailer = GetStringWidthF( |
191 base::string16(kEllipsisUTF16), font_list); | 191 base::string16(kEllipsisUTF16), font_list); |
192 if (parsed.query.is_nonempty()) { | 192 if (parsed.query.is_nonempty()) { |
193 url_query = UTF8ToUTF16("?") + url_string.substr(parsed.query.begin); | 193 url_query = UTF8ToUTF16("?") + url_string.substr(parsed.query.begin); |
194 if (available_pixel_width >= | 194 if (available_pixel_width >= |
195 (pixel_width_url_subdomain + pixel_width_url_domain + | 195 (pixel_width_url_subdomain + pixel_width_url_domain + |
196 pixel_width_url_path - GetStringWidthF(url_query, font_list))) { | 196 pixel_width_url_path - GetStringWidthF(url_query, font_list))) { |
197 return ElideText(url_subdomain + url_domain + url_path_query_etc, | 197 return ElideText(url_subdomain + url_domain + url_path_query_etc, |
198 font_list, available_pixel_width, gfx::ELIDE_AT_END); | 198 font_list, available_pixel_width, gfx::ELIDE_TAIL); |
199 } | 199 } |
200 } | 200 } |
201 | 201 |
202 // Parse url_path using '/'. | 202 // Parse url_path using '/'. |
203 std::vector<base::string16> url_path_elements; | 203 std::vector<base::string16> url_path_elements; |
204 base::SplitString(url_path, kForwardSlash, &url_path_elements); | 204 base::SplitString(url_path, kForwardSlash, &url_path_elements); |
205 | 205 |
206 // Get filename - note that for a path ending with / | 206 // Get filename - note that for a path ending with / |
207 // such as www.google.com/intl/ads/, the file name is ads/. | 207 // such as www.google.com/intl/ads/, the file name is ads/. |
208 size_t url_path_number_of_elements = url_path_elements.size(); | 208 size_t url_path_number_of_elements = url_path_elements.size(); |
209 DCHECK(url_path_number_of_elements != 0); | 209 DCHECK(url_path_number_of_elements != 0); |
210 base::string16 url_filename; | 210 base::string16 url_filename; |
211 if ((url_path_elements.at(url_path_number_of_elements - 1)).length() > 0) { | 211 if ((url_path_elements.at(url_path_number_of_elements - 1)).length() > 0) { |
212 url_filename = *(url_path_elements.end() - 1); | 212 url_filename = *(url_path_elements.end() - 1); |
213 } else if (url_path_number_of_elements > 1) { // Path ends with a '/'. | 213 } else if (url_path_number_of_elements > 1) { // Path ends with a '/'. |
214 url_filename = url_path_elements.at(url_path_number_of_elements - 2) + | 214 url_filename = url_path_elements.at(url_path_number_of_elements - 2) + |
215 kForwardSlash; | 215 kForwardSlash; |
216 url_path_number_of_elements--; | 216 url_path_number_of_elements--; |
217 } | 217 } |
218 DCHECK(url_path_number_of_elements != 0); | 218 DCHECK(url_path_number_of_elements != 0); |
219 | 219 |
220 const size_t kMaxNumberOfUrlPathElementsAllowed = 1024; | 220 const size_t kMaxNumberOfUrlPathElementsAllowed = 1024; |
221 if (url_path_number_of_elements <= 1 || | 221 if (url_path_number_of_elements <= 1 || |
222 url_path_number_of_elements > kMaxNumberOfUrlPathElementsAllowed) { | 222 url_path_number_of_elements > kMaxNumberOfUrlPathElementsAllowed) { |
223 // No path to elide, or too long of a path (could overflow in loop below) | 223 // No path to elide, or too long of a path (could overflow in loop below) |
224 // Just elide this as a text string. | 224 // Just elide this as a text string. |
225 return ElideText(url_subdomain + url_domain + url_path_query_etc, font_list, | 225 return ElideText(url_subdomain + url_domain + url_path_query_etc, font_list, |
226 available_pixel_width, gfx::ELIDE_AT_END); | 226 available_pixel_width, gfx::ELIDE_TAIL); |
227 } | 227 } |
228 | 228 |
229 // Start eliding the path and replacing elements by ".../". | 229 // Start eliding the path and replacing elements by ".../". |
230 const base::string16 kEllipsisAndSlash = | 230 const base::string16 kEllipsisAndSlash = |
231 base::string16(kEllipsisUTF16) + kForwardSlash; | 231 base::string16(kEllipsisUTF16) + kForwardSlash; |
232 const float pixel_width_ellipsis_slash = | 232 const float pixel_width_ellipsis_slash = |
233 GetStringWidthF(kEllipsisAndSlash, font_list); | 233 GetStringWidthF(kEllipsisAndSlash, font_list); |
234 | 234 |
235 // Check with both subdomain and domain. | 235 // Check with both subdomain and domain. |
236 base::string16 elided_path = | 236 base::string16 elided_path = |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
269 if ((available_pixel_width - url_elided_domain_width) > | 269 if ((available_pixel_width - url_elided_domain_width) > |
270 pixel_width_ellipsis_slash + kPixelWidthDotsTrailer + | 270 pixel_width_ellipsis_slash + kPixelWidthDotsTrailer + |
271 GetStringWidthF(base::ASCIIToUTF16("UV"), font_list)) { | 271 GetStringWidthF(base::ASCIIToUTF16("UV"), font_list)) { |
272 final_elided_url_string += BuildPathFromComponents(base::string16(), | 272 final_elided_url_string += BuildPathFromComponents(base::string16(), |
273 url_path_elements, url_filename, 1); | 273 url_path_elements, url_filename, 1); |
274 } else { | 274 } else { |
275 final_elided_url_string += url_path; | 275 final_elided_url_string += url_path; |
276 } | 276 } |
277 | 277 |
278 return ElideText(final_elided_url_string, font_list, available_pixel_width, | 278 return ElideText(final_elided_url_string, font_list, available_pixel_width, |
279 gfx::ELIDE_AT_END); | 279 gfx::ELIDE_TAIL); |
280 } | 280 } |
281 | 281 |
282 base::string16 ElideHost(const GURL& url, | 282 base::string16 ElideHost(const GURL& url, |
283 const gfx::FontList& font_list, | 283 const gfx::FontList& font_list, |
284 float available_pixel_width) { | 284 float available_pixel_width) { |
285 base::string16 url_host; | 285 base::string16 url_host; |
286 base::string16 url_domain; | 286 base::string16 url_domain; |
287 base::string16 url_subdomain; | 287 base::string16 url_subdomain; |
288 SplitHost(url, &url_host, &url_domain, &url_subdomain); | 288 SplitHost(url, &url_host, &url_domain, &url_subdomain); |
289 | 289 |
290 const float pixel_width_url_host = GetStringWidthF(url_host, font_list); | 290 const float pixel_width_url_host = GetStringWidthF(url_host, font_list); |
291 if (available_pixel_width >= pixel_width_url_host) | 291 if (available_pixel_width >= pixel_width_url_host) |
292 return url_host; | 292 return url_host; |
293 | 293 |
294 if (url_subdomain.empty()) | 294 if (url_subdomain.empty()) |
295 return url_domain; | 295 return url_domain; |
296 | 296 |
297 const float pixel_width_url_domain = GetStringWidthF(url_domain, font_list); | 297 const float pixel_width_url_domain = GetStringWidthF(url_domain, font_list); |
298 float subdomain_width = available_pixel_width - pixel_width_url_domain; | 298 float subdomain_width = available_pixel_width - pixel_width_url_domain; |
299 if (subdomain_width <= 0) | 299 if (subdomain_width <= 0) |
300 return base::string16(kEllipsisUTF16) + kDot + url_domain; | 300 return base::string16(kEllipsisUTF16) + kDot + url_domain; |
301 | 301 |
302 base::string16 elided_subdomain = ElideText( | 302 const base::string16 elided_subdomain = ElideText( |
303 url_subdomain, font_list, subdomain_width, gfx::ELIDE_AT_BEGINNING); | 303 url_subdomain, font_list, subdomain_width, gfx::ELIDE_HEAD); |
304 return elided_subdomain + url_domain; | 304 return elided_subdomain + url_domain; |
305 } | 305 } |
OLD | NEW |