File: location_bar_model_impl.cc

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (281 lines) | stat: -rw-r--r-- 10,729 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/omnibox/browser/location_bar_model_impl.h"

#include "base/check.h"
#include "base/feature_list.h"
#include "base/metrics/field_trial_params.h"
#include "base/notreached.h"
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "components/dom_distiller/core/url_constants.h"
#include "components/dom_distiller/core/url_utils.h"
#include "components/omnibox/browser/buildflags.h"
#include "components/omnibox/browser/location_bar_model_delegate.h"
#include "components/omnibox/browser/location_bar_model_util.h"
#include "components/omnibox/common/omnibox_features.h"
#include "components/search_engines/template_url_service.h"
#include "components/security_state/core/security_state.h"
#include "components/strings/grit/components_strings.h"
#include "net/cert/cert_status_flags.h"
#include "net/cert/x509_certificate.h"
#include "net/ssl/ssl_connection_status_flags.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/gfx/text_elider.h"
#include "ui/gfx/vector_icon_types.h"
#include "url/origin.h"

#if (!BUILDFLAG(IS_ANDROID) || BUILDFLAG(ENABLE_VR)) && !BUILDFLAG(IS_IOS)
#include "components/omnibox/browser/vector_icons.h"  // nogncheck
#endif

using metrics::OmniboxEventProto;

LocationBarModelImpl::LocationBarModelImpl(LocationBarModelDelegate* delegate,
                                           size_t max_url_display_chars)
    : delegate_(delegate), max_url_display_chars_(max_url_display_chars) {
  DCHECK(delegate_);
}

LocationBarModelImpl::~LocationBarModelImpl() = default;

// LocationBarModelImpl Implementation.
std::u16string LocationBarModelImpl::GetFormattedFullURL() const {
  return GetFormattedURL(url_formatter::kFormatUrlOmitDefaults);
}

std::u16string LocationBarModelImpl::GetURLForDisplay() const {
  url_formatter::FormatUrlTypes format_types =
      url_formatter::kFormatUrlOmitDefaults;
  if (delegate_->ShouldTrimDisplayUrlAfterHostName()) {
    format_types |= url_formatter::kFormatUrlTrimAfterHost;
  }

#if BUILDFLAG(IS_IOS)
  format_types |= url_formatter::kFormatUrlTrimAfterHost;
#endif

  format_types |= url_formatter::kFormatUrlOmitHTTPS;
  format_types |= url_formatter::kFormatUrlOmitTrivialSubdomains;

#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS)
  // On desktop, the File chip makes the scheme redundant in the steady state.
  format_types |= url_formatter::kFormatUrlOmitFileScheme;
#endif

  if (dom_distiller::url_utils::IsDistilledPage(GetURL())) {
    // We explicitly elide the scheme here to ensure that HTTPS and HTTP will
    // be removed for display: Reader mode pages should not display a scheme,
    // and should only run on HTTP/HTTPS pages.
    // Users will be able to see the scheme when the URL is focused or being
    // edited in the omnibox.
    format_types |= url_formatter::kFormatUrlOmitHTTP;
    format_types |= url_formatter::kFormatUrlOmitHTTPS;
  }

  return GetFormattedURL(format_types);
}

std::u16string LocationBarModelImpl::GetFormattedURL(
    url_formatter::FormatUrlTypes format_types) const {
  if (!ShouldDisplayURL())
    return std::u16string{};

  // Reset |format_types| to prevent elision of URLs when relevant extension or
  // pref is enabled.
  if (delegate_->ShouldPreventElision()) {
    format_types = url_formatter::kFormatUrlOmitDefaults &
                   ~url_formatter::kFormatUrlOmitHTTP;
  }

  GURL url(GetURL());

#if BUILDFLAG(IS_IOS)
  // On iOS, the blob: display URLs should be simply the domain name. However,
  // url_formatter parses everything past blob: as path, not domain, so swap
  // the url here to be just origin.
  if (url.SchemeIsBlob()) {
    url::Origin origin = url::Origin::Create(url);
    if (!origin.host().empty()) {
      url = origin.GetURL();
    }
  }
#endif  // BUILDFLAG(IS_IOS)

  // Special handling for dom-distiller:. Instead of showing internal reader
  // mode URLs, show the original article URL in the omnibox.
  // Note that this does not disallow the user from seeing the distilled page
  // URL in the view-source url or devtools. Note that this also impacts
  // GetFormattedFullURL which uses GetFormattedURL as a helper.
  // Virtual URLs were not a good solution for Reader Mode URLs because some
  // security UI is based off of the virtual URL rather than the original URL,
  // and Reader Mode has its own security chip. In addition virtual URLs would
  // add a lot of complexity around passing necessary URL parameters to the
  // Reader Mode pages.
  // Note: if the URL begins with dom-distiller:// but is invalid we display it
  // as-is because it cannot be transformed into an article URL.
  if (dom_distiller::url_utils::IsDistilledPage(url))
    url = dom_distiller::url_utils::GetOriginalUrlFromDistillerUrl(url);

  // Note that we can't unescape spaces here, because if the user copies this
  // and pastes it into another program, that program may think the URL ends at
  // the space.
  const std::u16string formatted_text =
      delegate_->FormattedStringWithEquivalentMeaning(
          url, url_formatter::FormatUrl(url, format_types,
                                        base::UnescapeRule::NORMAL, nullptr,
                                        nullptr, nullptr));

  // Truncating the URL breaks editing and then pressing enter, but hopefully
  // people won't try to do much with such enormous URLs anyway. If this becomes
  // a real problem, we could perhaps try to keep some sort of different "elided
  // visible URL" where editing affects and reloads the "real underlying URL",
  // but this seems very tricky for little gain.
  return gfx::TruncateString(formatted_text, max_url_display_chars_,
                             gfx::CHARACTER_BREAK);
}

GURL LocationBarModelImpl::GetURL() const {
  GURL url;
  return (ShouldDisplayURL() && delegate_->GetURL(&url))
             ? url
             : GURL(url::kAboutBlankURL);
}

security_state::SecurityLevel LocationBarModelImpl::GetSecurityLevel() const {
  // When empty, assume no security style.
  if (!ShouldDisplayURL())
    return security_state::NONE;

  return delegate_->GetSecurityLevel();
}

net::CertStatus LocationBarModelImpl::GetCertStatus() const {
  // When empty, assume no cert status.
  if (!ShouldDisplayURL())
    return 0;

  return delegate_->GetCertStatus();
}

OmniboxEventProto::PageClassification
LocationBarModelImpl::GetPageClassification(bool is_prefetch) const {
  // We may be unable to fetch the current URL during startup or shutdown when
  // the omnibox exists but there is no attached page.
  GURL gurl;
  if (!delegate_->GetURL(&gurl)) {
    return OmniboxEventProto::OTHER;
  }
  if (delegate_->IsNewTabPage()) {
    return is_prefetch ? OmniboxEventProto::NTP_ZPS_PREFETCH
               : OmniboxEventProto::INSTANT_NTP_WITH_OMNIBOX_AS_STARTING_FOCUS;
  }
  if (!gurl.is_valid()) {
    return OmniboxEventProto::INVALID_SPEC;
  }
  if (delegate_->IsNewTabPageURL(gurl)) {
    return is_prefetch ? OmniboxEventProto::NTP_ZPS_PREFETCH
                       : OmniboxEventProto::NTP;
  }
  if (gurl.spec() == url::kAboutBlankURL) {
    return OmniboxEventProto::BLANK;
  }
  if (delegate_->IsHomePage(gurl)) {
    return OmniboxEventProto::HOME_PAGE;
  }

  TemplateURLService* template_url_service = delegate_->GetTemplateURLService();
  if (template_url_service &&
      template_url_service->IsSearchResultsPageFromDefaultSearchProvider(
          gurl)) {
    return is_prefetch ? OmniboxEventProto::SRP_ZPS_PREFETCH
                       : OmniboxEventProto::
                             SEARCH_RESULT_PAGE_NO_SEARCH_TERM_REPLACEMENT;
  }

  return is_prefetch ? OmniboxEventProto::OTHER_ZPS_PREFETCH
                     : OmniboxEventProto::OTHER;
}

const gfx::VectorIcon& LocationBarModelImpl::GetVectorIcon() const {
#if (!BUILDFLAG(IS_ANDROID) || BUILDFLAG(ENABLE_VR)) && !BUILDFLAG(IS_IOS)
  auto* const icon_override = delegate_->GetVectorIconOverride();
  if (icon_override)
    return *icon_override;

  if (IsOfflinePage())
    return omnibox::kOfflinePinIcon;
#endif

  return location_bar_model::GetSecurityVectorIcon(
      GetSecurityLevel(),
      delegate_->GetVisibleSecurityState()->malicious_content_status);
}

std::u16string LocationBarModelImpl::GetSecureDisplayText() const {
  // Note that display text will be implicitly used as the accessibility text.
  // GetSecureAccessibilityText() handles special cases when no display text is
  // set.

  if (IsOfflinePage())
    return l10n_util::GetStringUTF16(IDS_OFFLINE_VERBOSE_STATE);

  switch (GetSecurityLevel()) {
    case security_state::WARNING:
      return l10n_util::GetStringUTF16(IDS_NOT_SECURE_VERBOSE_STATE);
    case security_state::SECURE:
      return std::u16string();
    case security_state::DANGEROUS: {
      std::unique_ptr<security_state::VisibleSecurityState>
          visible_security_state = delegate_->GetVisibleSecurityState();

      // Don't show any text in the security indicator for sites on the billing
      // interstitial list or blocked by the enterprise administrator.
      if (visible_security_state->malicious_content_status ==
              security_state::MALICIOUS_CONTENT_STATUS_BILLING ||
          visible_security_state->malicious_content_status ==
              security_state::MALICIOUS_CONTENT_STATUS_MANAGED_POLICY_BLOCK ||
          visible_security_state->malicious_content_status ==
              security_state::MALICIOUS_CONTENT_STATUS_MANAGED_POLICY_WARN) {
        return std::u16string();
      }

      bool fails_malware_check =
          visible_security_state->malicious_content_status !=
          security_state::MALICIOUS_CONTENT_STATUS_NONE;
      return l10n_util::GetStringUTF16(fails_malware_check
                                           ? IDS_DANGEROUS_VERBOSE_STATE
                                           : IDS_NOT_SECURE_VERBOSE_STATE);
    }
    default:
      return std::u16string();
  }
}

std::u16string LocationBarModelImpl::GetSecureAccessibilityText() const {
  auto display_text = GetSecureDisplayText();
  if (!display_text.empty())
    return display_text;

  switch (GetSecurityLevel()) {
    case security_state::SECURE:
      return l10n_util::GetStringUTF16(IDS_SECURE_VERBOSE_STATE);
    default:
      return std::u16string();
  }
}

bool LocationBarModelImpl::ShouldDisplayURL() const {
  return delegate_->ShouldDisplayURL();
}

bool LocationBarModelImpl::IsOfflinePage() const {
  return delegate_->IsOfflinePage();
}

bool LocationBarModelImpl::ShouldPreventElision() const {
  return delegate_->ShouldPreventElision();
}