OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "ios/chrome/browser/ui/omnibox/omnibox_view_ios.h" | 5 #include "ios/chrome/browser/ui/omnibox/omnibox_view_ios.h" |
6 | 6 |
7 #import <CoreText/CoreText.h> | 7 #import <CoreText/CoreText.h> |
8 #import <MobileCoreServices/MobileCoreServices.h> | 8 #import <MobileCoreServices/MobileCoreServices.h> |
9 | 9 |
| 10 #include "base/auto_reset.h" |
10 #include "base/command_line.h" | 11 #include "base/command_line.h" |
11 #include "base/ios/device_util.h" | 12 #include "base/ios/device_util.h" |
12 #include "base/memory/ptr_util.h" | 13 #include "base/memory/ptr_util.h" |
13 #include "base/metrics/user_metrics.h" | 14 #include "base/metrics/user_metrics.h" |
14 #include "base/metrics/user_metrics_action.h" | 15 #include "base/metrics/user_metrics_action.h" |
15 #include "base/strings/string16.h" | 16 #include "base/strings/string16.h" |
16 #include "base/strings/sys_string_conversions.h" | 17 #include "base/strings/sys_string_conversions.h" |
17 #include "components/omnibox/browser/autocomplete_input.h" | 18 #include "components/omnibox/browser/autocomplete_input.h" |
18 #include "components/omnibox/browser/autocomplete_match.h" | 19 #include "components/omnibox/browser/autocomplete_match.h" |
19 #include "components/omnibox/browser/omnibox_edit_model.h" | 20 #include "components/omnibox/browser/omnibox_edit_model.h" |
(...skipping 23 matching lines...) Expand all Loading... |
43 // The color of the rest of the URL (i.e. after the TLD) in the omnibox. | 44 // The color of the rest of the URL (i.e. after the TLD) in the omnibox. |
44 UIColor* BaseTextColor() { | 45 UIColor* BaseTextColor() { |
45 return [UIColor colorWithWhite:(161 / 255.0) alpha:1.0]; | 46 return [UIColor colorWithWhite:(161 / 255.0) alpha:1.0]; |
46 } | 47 } |
47 | 48 |
48 // The color of the https when there is an error. | 49 // The color of the https when there is an error. |
49 UIColor* ErrorTextColor() { | 50 UIColor* ErrorTextColor() { |
50 return skia::UIColorFromSkColor(gfx::kGoogleRed700); | 51 return skia::UIColorFromSkColor(gfx::kGoogleRed700); |
51 } | 52 } |
52 | 53 |
53 // The color of the https when there is a warning. | |
54 UIColor* WarningTextColor() { | |
55 return skia::UIColorFromSkColor(gfx::kGoogleYellow700); | |
56 } | |
57 | |
58 // The color of the https when there is not an error. | 54 // The color of the https when there is not an error. |
59 UIColor* SecureTextColor() { | 55 UIColor* SecureTextColor() { |
60 return skia::UIColorFromSkColor(gfx::kGoogleGreen700); | 56 return skia::UIColorFromSkColor(gfx::kGoogleGreen700); |
61 } | 57 } |
62 | 58 |
63 // The color of the https when highlighted in incognito. | 59 // The color of the https when highlighted in incognito. |
64 UIColor* IncognitoSecureTextColor() { | 60 UIColor* IncognitoSecureTextColor() { |
65 return [UIColor colorWithWhite:(255 / 255.0) alpha:1.0]; | 61 return [UIColor colorWithWhite:(255 / 255.0) alpha:1.0]; |
66 } | 62 } |
67 | 63 |
68 // Helper to make converting url_parse ranges to NSRange easier to | |
69 // read. | |
70 NSRange ComponentToNSRange(const url::Component& component) { | |
71 return NSMakeRange(static_cast<NSInteger>(component.begin), | |
72 static_cast<NSInteger>(component.len)); | |
73 } | |
74 | |
75 } // namespace | 64 } // namespace |
76 | 65 |
77 // Simple Obj-C object to forward UITextFieldDelegate method calls back to the | 66 // Simple Obj-C object to forward UITextFieldDelegate method calls back to the |
78 // OmniboxViewIOS. | 67 // OmniboxViewIOS. |
79 @interface AutocompleteTextFieldDelegate : NSObject<OmniboxTextFieldDelegate> { | 68 @interface AutocompleteTextFieldDelegate : NSObject<OmniboxTextFieldDelegate> { |
80 @private | 69 @private |
81 OmniboxViewIOS* editView_; // weak, owns us | 70 OmniboxViewIOS* editView_; // weak, owns us |
82 | 71 |
83 // YES if we are already forwarding an OnDidChange() message to the edit view. | 72 // YES if we are already forwarding an OnDidChange() message to the edit view. |
84 // Needed to prevent infinite recursion. | 73 // Needed to prevent infinite recursion. |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
178 ios::ChromeBrowserState* browser_state, | 167 ios::ChromeBrowserState* browser_state, |
179 id<PreloadProvider> preloader, | 168 id<PreloadProvider> preloader, |
180 id<OmniboxPopupPositioner> positioner) | 169 id<OmniboxPopupPositioner> positioner) |
181 : OmniboxView( | 170 : OmniboxView( |
182 controller, | 171 controller, |
183 base::MakeUnique<ChromeOmniboxClientIOS>(controller, browser_state)), | 172 base::MakeUnique<ChromeOmniboxClientIOS>(controller, browser_state)), |
184 browser_state_(browser_state), | 173 browser_state_(browser_state), |
185 field_([field retain]), | 174 field_([field retain]), |
186 controller_(controller), | 175 controller_(controller), |
187 preloader_(preloader), | 176 preloader_(preloader), |
188 ignore_popup_updates_(false) { | 177 ignore_popup_updates_(false), |
| 178 attributing_display_string_(nil) { |
189 popup_view_.reset(new OmniboxPopupViewIOS(this, model(), positioner)); | 179 popup_view_.reset(new OmniboxPopupViewIOS(this, model(), positioner)); |
190 field_delegate_.reset( | 180 field_delegate_.reset( |
191 [[AutocompleteTextFieldDelegate alloc] initWithEditView:this]); | 181 [[AutocompleteTextFieldDelegate alloc] initWithEditView:this]); |
192 [field_ setDelegate:field_delegate_]; | 182 [field_ setDelegate:field_delegate_]; |
193 [field_ addTarget:field_delegate_ | 183 [field_ addTarget:field_delegate_ |
194 action:@selector(textFieldDidChange:) | 184 action:@selector(textFieldDidChange:) |
195 forControlEvents:UIControlEventEditingChanged]; | 185 forControlEvents:UIControlEventEditingChanged]; |
196 } | 186 } |
197 | 187 |
198 OmniboxViewIOS::~OmniboxViewIOS() { | 188 OmniboxViewIOS::~OmniboxViewIOS() { |
(...skipping 428 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
627 } | 617 } |
628 | 618 |
629 bool OmniboxViewIOS::CanCopyURL() { | 619 bool OmniboxViewIOS::CanCopyURL() { |
630 return false; | 620 return false; |
631 } | 621 } |
632 | 622 |
633 void OmniboxViewIOS::WillPaste() { | 623 void OmniboxViewIOS::WillPaste() { |
634 model()->OnPaste(); | 624 model()->OnPaste(); |
635 } | 625 } |
636 | 626 |
| 627 // static |
| 628 UIColor* OmniboxViewIOS::GetSecureTextColor( |
| 629 security_state::SecurityLevel security_level, |
| 630 bool in_dark_mode) { |
| 631 if (security_level == security_state::EV_SECURE || |
| 632 security_level == security_state::SECURE) { |
| 633 return in_dark_mode ? IncognitoSecureTextColor() : SecureTextColor(); |
| 634 } |
| 635 |
| 636 // Don't color strikethrough in dark mode. See https://crbug.com/635004#c6 |
| 637 if (security_level == security_state::DANGEROUS && !in_dark_mode) |
| 638 return ErrorTextColor(); |
| 639 |
| 640 return nil; |
| 641 } |
| 642 |
| 643 void OmniboxViewIOS::SetEmphasis(bool emphasize, const gfx::Range& range) { |
| 644 NSRange ns_range = range.IsValid() |
| 645 ? range.ToNSRange() |
| 646 : NSMakeRange(0, [attributing_display_string_ length]); |
| 647 |
| 648 [attributing_display_string_ |
| 649 addAttribute:NSForegroundColorAttributeName |
| 650 value:(emphasize) ? [field_ displayedTextColor] : BaseTextColor() |
| 651 range:ns_range]; |
| 652 } |
| 653 |
| 654 void OmniboxViewIOS::UpdateSchemeStyle(const gfx::Range& range) { |
| 655 if (!range.IsValid()) |
| 656 return; |
| 657 |
| 658 const security_state::SecurityLevel security_level = |
| 659 controller()->GetToolbarModel()->GetSecurityLevel(false); |
| 660 |
| 661 if ((security_level == security_state::NONE) || |
| 662 (security_level == security_state::HTTP_SHOW_WARNING)) { |
| 663 return; |
| 664 } |
| 665 |
| 666 DCHECK_NE(security_state::SECURITY_WARNING, security_level); |
| 667 DCHECK_NE(security_state::SECURE_WITH_POLICY_INSTALLED_CERT, security_level); |
| 668 |
| 669 if (security_level == security_state::DANGEROUS) { |
| 670 // Add a strikethrough through the scheme. |
| 671 [attributing_display_string_ |
| 672 addAttribute:NSStrikethroughStyleAttributeName |
| 673 value:[NSNumber numberWithInteger:NSUnderlineStyleSingle] |
| 674 range:range.ToNSRange()]; |
| 675 } |
| 676 |
| 677 UIColor* color = GetSecureTextColor(security_level, [field_ incognito]); |
| 678 if (color) { |
| 679 [attributing_display_string_ addAttribute:NSForegroundColorAttributeName |
| 680 value:color |
| 681 range:range.ToNSRange()]; |
| 682 } |
| 683 } |
| 684 |
637 NSAttributedString* OmniboxViewIOS::ApplyTextAttributes( | 685 NSAttributedString* OmniboxViewIOS::ApplyTextAttributes( |
638 const base::string16& text) { | 686 const base::string16& text) { |
639 NSMutableAttributedString* as = [[[NSMutableAttributedString alloc] | 687 NSMutableAttributedString* as = [[[NSMutableAttributedString alloc] |
640 initWithString:base::SysUTF16ToNSString(text)] autorelease]; | 688 initWithString:base::SysUTF16ToNSString(text)] autorelease]; |
641 url::Component scheme, host; | 689 // Cache a pointer to the attributed string to allow the superclass' |
642 AutocompleteInput::ParseForEmphasizeComponents( | 690 // virtual method invocations to add attributes. |
643 text, AutocompleteSchemeClassifierImpl(), &scheme, &host); | 691 DCHECK(attributing_display_string_ == nil); |
644 | 692 base::AutoReset<NSMutableAttributedString*> resetter( |
645 const bool emphasize = model()->CurrentTextIsURL() && (host.len > 0); | 693 &attributing_display_string_, as); |
646 if (emphasize) { | 694 UpdateTextStyle(text, AutocompleteSchemeClassifierImpl()); |
647 [as addAttribute:NSForegroundColorAttributeName | |
648 value:BaseTextColor() | |
649 range:NSMakeRange(0, [as length])]; | |
650 | |
651 [as addAttribute:NSForegroundColorAttributeName | |
652 value:[field_ displayedTextColor] | |
653 range:ComponentToNSRange(host)]; | |
654 | |
655 if (scheme.len > 0) { | |
656 UIColor* color = nil; | |
657 switch (controller_->GetToolbarModel()->GetSecurityLevel(false)) { | |
658 case security_state::NONE: | |
659 case security_state::HTTP_SHOW_WARNING: | |
660 break; | |
661 case security_state::SECURITY_WARNING: | |
662 // Don't color strikethrough schemes. See https://crbug.com/635004#c6 | |
663 if (![field_ incognito]) | |
664 color = WarningTextColor(); | |
665 [as addAttribute:NSStrikethroughStyleAttributeName | |
666 value:[NSNumber numberWithInteger:NSUnderlineStyleSingle] | |
667 range:ComponentToNSRange(scheme)]; | |
668 break; | |
669 case security_state::SECURE: | |
670 case security_state::EV_SECURE: | |
671 color = [field_ incognito] ? IncognitoSecureTextColor() | |
672 : SecureTextColor(); | |
673 break; | |
674 case security_state::DANGEROUS: | |
675 // Don't color strikethrough schemes. See https://crbug.com/635004#c6 | |
676 if (![field_ incognito]) | |
677 color = ErrorTextColor(); | |
678 [as addAttribute:NSStrikethroughStyleAttributeName | |
679 value:[NSNumber numberWithInteger:NSUnderlineStyleSingle] | |
680 range:ComponentToNSRange(scheme)]; | |
681 break; | |
682 case security_state::SECURE_WITH_POLICY_INSTALLED_CERT: | |
683 NOTREACHED(); | |
684 } | |
685 if (color) { | |
686 [as addAttribute:NSForegroundColorAttributeName | |
687 value:color | |
688 range:ComponentToNSRange(scheme)]; | |
689 } | |
690 } | |
691 } | |
692 return as; | 695 return as; |
693 } | 696 } |
694 | 697 |
695 void OmniboxViewIOS::UpdateAppearance() { | 698 void OmniboxViewIOS::UpdateAppearance() { |
696 // If Siri is thinking, treat that as user input being in progress. It is | 699 // If Siri is thinking, treat that as user input being in progress. It is |
697 // unsafe to modify the text field while voice entry is pending. | 700 // unsafe to modify the text field while voice entry is pending. |
698 if (model()->UpdatePermanentText()) { | 701 if (model()->UpdatePermanentText()) { |
699 // Revert everything to the baseline look. | 702 // Revert everything to the baseline look. |
700 RevertAll(); | 703 RevertAll(); |
701 } else if (!model()->has_focus() && | 704 } else if (!model()->has_focus() && |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
866 // is being left out for now because it was not present before the OmniboxView | 869 // is being left out for now because it was not present before the OmniboxView |
867 // rewrite. | 870 // rewrite. |
868 #if 0 | 871 #if 0 |
869 // When editing is in progress, the url text is not colored, so there is | 872 // When editing is in progress, the url text is not colored, so there is |
870 // nothing to emphasize. (Calling SetText() in that situation would also be | 873 // nothing to emphasize. (Calling SetText() in that situation would also be |
871 // harmful, as it would reset the carat position to the end of the text.) | 874 // harmful, as it would reset the carat position to the end of the text.) |
872 if (!IsEditingOrEmpty()) | 875 if (!IsEditingOrEmpty()) |
873 SetText(GetText()); | 876 SetText(GetText()); |
874 #endif | 877 #endif |
875 } | 878 } |
OLD | NEW |