Fix bugs and improve perf in Touch Bar text suggestions.
- The old implementation recreated the Touch Bar on each keystroke (including
when hidden, I believe), which burns a significant amount of power while
typing. This new implementation updates the existing candidate list, if it
exists and isn't collapsed.
- Removes a bunch of support code for a behavior that was disabled in r590669.
It moves the remaining code into RWHV itself instead of a dedicated
controller class, which I have mixed feelings about, but ultimately picked
because after the support code was removed, most of what was left was
plumbing between RWHV and TextSuggestionsTouchBarController.
- [Bigish change] Moves text suggestions out of the window and into the RWHV,
so that hiding and showing as focus and web contents change is left to AppKit
and the responder chain.
- Fixes small lifecyle-ish bugs around when use this kind of Touch Bar — now
it's tied to the RWHV's input type instead of using a special
WebContentsTextObserver.
Bug: 717553, 881545
Change-Id: I8e1eff6da7918f92cfdb47465196d5841a88a7e4
Reviewed-on: https://chromium-review.googlesource.com/c/1212004
Commit-Queue: Sidney San Martín <sdy@chromium.org>
Reviewed-by: Avi Drissman <avi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#597371}
diff --git a/base/mac/sdk_forward_declarations.h b/base/mac/sdk_forward_declarations.h
index 86de4d83..a4549e1 100644
--- a/base/mac/sdk_forward_declarations.h
+++ b/base/mac/sdk_forward_declarations.h
@@ -360,4 +360,10 @@
// ----------------------------------------------------------------------------
BASE_EXPORT extern "C" NSString* const kCWSSIDDidChangeNotification;
+// Once Chrome is built with at least the macOS 10.13 SDK, everything within
+// this preprocessor block can be removed.
+#if !defined(MAC_OS_X_VERSION_10_13)
+typedef NSString* NSTextCheckingOptionKey;
+#endif
+
#endif // BASE_MAC_SDK_FORWARD_DECLARATIONS_H_
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn
index b632b5e..cde0af8 100644
--- a/chrome/browser/ui/BUILD.gn
+++ b/chrome/browser/ui/BUILD.gn
@@ -132,8 +132,6 @@
"cocoa/themed_window.mm",
"cocoa/touchbar/credit_card_autofill_touch_bar_controller.h",
"cocoa/touchbar/credit_card_autofill_touch_bar_controller.mm",
- "cocoa/touchbar/text_suggestions_touch_bar_controller.h",
- "cocoa/touchbar/text_suggestions_touch_bar_controller.mm",
"cocoa/touchbar/web_textfield_touch_bar_controller.h",
"cocoa/touchbar/web_textfield_touch_bar_controller.mm",
"cocoa/url_drop_target.h",
diff --git a/chrome/browser/ui/cocoa/touchbar/browser_window_touch_bar_controller.mm b/chrome/browser/ui/cocoa/touchbar/browser_window_touch_bar_controller.mm
index c81dbbf..711e219d 100644
--- a/chrome/browser/ui/cocoa/touchbar/browser_window_touch_bar_controller.mm
+++ b/chrome/browser/ui/cocoa/touchbar/browser_window_touch_bar_controller.mm
@@ -117,7 +117,6 @@
- (void)updateWebContents:(content::WebContents*)contents {
[defaultTouchBar_ updateWebContents:contents];
- [webTextfieldTouchBar_ updateWebContents:contents];
[self invalidateTouchBar];
}
diff --git a/chrome/browser/ui/cocoa/touchbar/text_suggestions_touch_bar_controller.h b/chrome/browser/ui/cocoa/touchbar/text_suggestions_touch_bar_controller.h
deleted file mode 100644
index 288fb93..0000000
--- a/chrome/browser/ui/cocoa/touchbar/text_suggestions_touch_bar_controller.h
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_UI_COCOA_TOUCHBAR_TEXT_SUGGESTIONS_TOUCH_BAR_CONTROLLER_H_
-#define CHROME_BROWSER_UI_COCOA_TOUCHBAR_TEXT_SUGGESTIONS_TOUCH_BAR_CONTROLLER_H_
-
-#import <Cocoa/Cocoa.h>
-
-#include <memory>
-
-#import "base/mac/scoped_nsobject.h"
-#include "chrome/browser/ui/cocoa/touchbar/web_textfield_touch_bar_controller.h"
-#import "ui/base/cocoa/touch_bar_forward_declarations.h"
-
-@class WebTextfieldTouchBarController;
-
-namespace content {
-class WebContents;
-} // namespace content
-
-namespace gfx {
-class Range;
-} // namespace gfx
-
-API_AVAILABLE(macos(10.12.2))
-@interface TextSuggestionsTouchBarController
- : NSObject<NSTouchBarDelegate, NSCandidateListTouchBarItemDelegate>
-
-- (instancetype)initWithWebContents:(content::WebContents*)webContents
- controller:(WebTextfieldTouchBarController*)controller;
-
-- (NSTouchBar*)makeTouchBar;
-
-- (NSTouchBarItem*)touchBar:(NSTouchBar*)touchBar
- makeItemForIdentifier:(NSTouchBarItemIdentifier)identifier;
-
-// Creates a NSCandidateListTouchBarItem that contains text suggestions
-// based on the current text selection.
-- (NSCandidateListTouchBarItem*)makeCandidateListItem;
-
-- (void)candidateListTouchBarItem:(NSCandidateListTouchBarItem*)anItem
- endSelectingCandidateAtIndex:(NSInteger)index;
-
-- (void)updateTextSelection:(const base::string16&)text
- range:(const gfx::Range&)range
- offset:(size_t)offset;
-
-// Returns a range from start to the end of the word that the cursor is
-// currently in.
-- (NSRange)editingWordRangeFromText:(const base::string16&)text
- cursorPosition:(size_t)cursor;
-
-- (void)requestSuggestions;
-
-// Select the range of the editing word and replace it with a suggestion
-// from the touch bar.
-- (void)replaceEditingWordWithSuggestion:(NSString*)text;
-
-@end
-
-@interface TextSuggestionsTouchBarController (ExposedForTesting)
-
-- (void)setWebContents:(content::WebContents*)webContents;
-- (content::WebContents*)webContents;
-- (void)setText:(NSString*)text;
-- (NSString*)text;
-- (void)setSelectionRange:(const gfx::Range&)range;
-- (gfx::Range)selectionRange;
-- (void)setSuggestions:(NSArray*)suggestions;
-- (NSArray*)suggestions;
-- (WebTextfieldTouchBarController*)controller;
-- (void)setShouldIgnoreReplacementSelection:(BOOL)shouldIgnore;
-- (void)setEditingWordRange:(const gfx::Range&)range offset:(size_t)offset;
-
-@end
-
-#endif // CHROME_BROWSER_UI_COCOA_TOUCHBAR_SUGGESTED_TEXT_TOUCH_BAR_CONTROLLER_H_
diff --git a/chrome/browser/ui/cocoa/touchbar/text_suggestions_touch_bar_controller.mm b/chrome/browser/ui/cocoa/touchbar/text_suggestions_touch_bar_controller.mm
deleted file mode 100644
index 7f3fb1b..0000000
--- a/chrome/browser/ui/cocoa/touchbar/text_suggestions_touch_bar_controller.mm
+++ /dev/null
@@ -1,322 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#import "chrome/browser/ui/cocoa/touchbar/text_suggestions_touch_bar_controller.h"
-
-#include "base/i18n/break_iterator.h"
-#include "base/strings/sys_string_conversions.h"
-#include "content/public/browser/render_widget_host_view.h"
-#include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_observer.h"
-#import "ui/base/cocoa/touch_bar_util.h"
-#include "ui/gfx/range/range.h"
-
-namespace {
-// Touch bar identifier.
-NSString* const kTextSuggestionsTouchBarId = @"text-suggestions";
-
-// Touch bar item identifiers.
-NSString* const kTextSuggestionsItemsTouchId = @"TEXT-SUGGESTIONS-ITEMS";
-} // namespace
-
-namespace text_observer {
-class API_AVAILABLE(macos(10.12.2)) WebContentsTextObserver
- : public content::WebContentsObserver {
- public:
- WebContentsTextObserver(content::WebContents* web_contents,
- TextSuggestionsTouchBarController* owner)
- : WebContentsObserver(web_contents), owner_(owner) {}
-
- void UpdateWebContents(content::WebContents* web_contents) {
- Observe(web_contents);
- }
-
- void DidChangeTextSelection(const base::string16& text,
- const gfx::Range& range,
- size_t offset) override {
- [owner_ updateTextSelection:text range:range offset:offset];
- }
-
- void DidFinishLoad(content::RenderFrameHost* render_frame_host,
- const GURL& validated_url) override {
- [owner_ updateTextSelection:base::string16() range:gfx::Range() offset:0];
- }
-
- private:
- TextSuggestionsTouchBarController* owner_; // weak
-};
-} // namespace text_observer
-
-@interface TextSuggestionsTouchBarController () {
- // An observer for text selection changes.
- std::unique_ptr<text_observer::WebContentsTextObserver> observer_;
-
- // The WebContents in which text is being selected and replaced.
- content::WebContents* webContents_; // weak
-
- // The WebTextfieldTouchBarController that invalidates the touch bar.
- WebTextfieldTouchBarController* controller_; // weak
-
- // The text on which suggestions are based.
- base::scoped_nsobject<NSString> text_;
-
- // A list of NSTextCheckingResults containing text suggestions for |text_| at
- // |selectionRange_|.
- base::scoped_nsobject<NSArray> suggestions_;
-
- // The currently selected range. If the range has length = 0, it is simply a
- // cursor position.
- NSRange selectionRange_;
-
- // The range of the word that's currently being edited. Used when replacing
- // the current editing word with a selected suggestion. If length = 0, there
- // is no word currently being edited and the suggestion will be placed at the
- // cursor.
- NSRange editingWordRange_;
-
- // The location of |editingWordRange_| within the total text, which may be
- // longer than the text received on text selection update. Used for checking
- // when to ignore replacement text selections.
- NSRange offsetEditingWordRange_;
-
- // When YES, -updateTextSelection:range: should ignore a text selection that
- // is equal to the editing word range. Set to YES when
- // -replaceEditingWordWithSuggestion: modifies the current text selection.
- // Reset to NO when the text selection for replacing the editing word reaches
- // -updateTextSelection:range:.
- BOOL shouldIgnoreReplacementSelection_;
-}
-@end
-
-@implementation TextSuggestionsTouchBarController
-
-- (BOOL)isTextfieldFocused {
- return webContents_ && webContents_->IsFocusedElementEditable();
-}
-
-- (instancetype)initWithWebContents:(content::WebContents*)webContents
- controller:
- (WebTextfieldTouchBarController*)controller {
- if ((self = [super init])) {
- webContents_ = webContents;
- controller_ = controller;
- observer_.reset(
- new text_observer::WebContentsTextObserver(webContents_, self));
- shouldIgnoreReplacementSelection_ = NO;
- }
-
- return self;
-}
-
-- (NSTouchBar*)makeTouchBar {
- if (![self isTextfieldFocused] || ![suggestions_ count])
- return nil;
-
- base::scoped_nsobject<NSTouchBar> touchBar([[ui::NSTouchBar() alloc] init]);
- [touchBar
- setCustomizationIdentifier:ui::GetTouchBarId(kTextSuggestionsTouchBarId)];
- [touchBar setDelegate:self];
-
- [touchBar setDefaultItemIdentifiers:@[ kTextSuggestionsItemsTouchId ]];
- return touchBar.autorelease();
-}
-
-- (NSTouchBarItem*)touchBar:(NSTouchBar*)touchBar
- makeItemForIdentifier:(NSTouchBarItemIdentifier)identifier {
- if (![identifier hasSuffix:kTextSuggestionsItemsTouchId])
- return nil;
-
- return [self makeCandidateListItem];
-}
-
-- (NSCandidateListTouchBarItem*)makeCandidateListItem {
- base::scoped_nsobject<NSCandidateListTouchBarItem> candidateListItem(
- [[NSCandidateListTouchBarItem alloc]
- initWithIdentifier:kTextSuggestionsItemsTouchId]);
-
- [candidateListItem setDelegate:self];
- if (selectionRange_.length)
- [candidateListItem setCollapsed:YES];
-
- [candidateListItem setCandidates:suggestions_
- forSelectedRange:selectionRange_
- inString:text_];
-
- return candidateListItem.autorelease();
-}
-
-- (void)candidateListTouchBarItem:(NSCandidateListTouchBarItem*)anItem
- endSelectingCandidateAtIndex:(NSInteger)index {
- if (index == NSNotFound)
- return;
-
- if (anItem) {
- NSTextCheckingResult* selectedResult = anItem.candidates[index];
- [self replaceEditingWordWithSuggestion:[selectedResult replacementString]];
- }
-
- ui::LogTouchBarUMA(ui::TouchBarAction::TEXT_SUGGESTION);
-}
-
-- (void)updateTextSelection:(const base::string16&)text
- range:(const gfx::Range&)range
- offset:(size_t)offset {
- if (shouldIgnoreReplacementSelection_ &&
- range == gfx::Range(offsetEditingWordRange_)) {
- shouldIgnoreReplacementSelection_ = NO;
- return;
- }
-
- if (![self isTextfieldFocused]) {
- [controller_ invalidateTouchBar];
- return;
- }
-
- // TODO(crbug.com/880642): It's possible for a range out of the text bounds
- // to be passed in. Investigate this.
- if (range.start() - offset > text.length() ||
- range.end() - offset > text.length()) {
- text_.reset([[NSString alloc] init]);
- selectionRange_ = NSMakeRange(0, 0);
- editingWordRange_ = NSMakeRange(0, 0);
- offsetEditingWordRange_ = NSMakeRange(0, 0);
- return;
- }
-
- text_.reset([base::SysUTF16ToNSString(text) retain]);
- selectionRange_ = range.ToNSRange();
- selectionRange_.location -= offset;
-
- editingWordRange_ = [self editingWordRangeFromText:text
- cursorPosition:selectionRange_.location];
-
- offsetEditingWordRange_ = editingWordRange_;
- offsetEditingWordRange_.location += offset;
- [self requestSuggestions];
-}
-
-- (NSRange)editingWordRangeFromText:(const base::string16&)text
- cursorPosition:(size_t)cursor {
- // The cursor should not be off the end of the text.
- DCHECK(cursor <= text.length());
-
- // Default range is just the cursor position. This is used if BreakIterator
- // cannot be initialized, there is no text in the textfield, or the cursor is
- // at the front of a word.
- size_t location = cursor;
- size_t length = 0;
-
- base::i18n::BreakIterator iter(text, base::i18n::BreakIterator::BREAK_WORD);
-
- if (iter.Init()) {
- // Repeat iter.Advance() until end of line is reached or
- // current iterator position passes cursor position.
- while (iter.pos() < cursor && iter.Advance()) {
- }
-
- // If BreakIterator stopped at the end of a word, the cursor is in/at the
- // end of a word so the editing word range is [word start, word end].
- if (iter.IsWord()) {
- location = iter.prev();
- length = cursor - iter.prev();
- }
- }
-
- return NSMakeRange(location, length);
-}
-
-- (void)requestSuggestions {
- NSSpellChecker* spell_checker = [NSSpellChecker sharedSpellChecker];
- [spell_checker
- requestCandidatesForSelectedRange:selectionRange_
- inString:text_
- types:NSTextCheckingAllSystemTypes
- options:nil
- inSpellDocumentWithTag:0
- completionHandler:^(
- NSInteger sequenceNumber,
- NSArray<NSTextCheckingResult*>* candidates) {
- dispatch_async(dispatch_get_main_queue(), ^{
- suggestions_.reset([candidates copy]);
- [controller_ invalidateTouchBar];
- });
- }];
-}
-
-- (void)replaceEditingWordWithSuggestion:(NSString*)text {
- // If the editing word is not selected in its entirety, modify the selection
- // to cover the current editing word.
- if (!NSEqualRanges(editingWordRange_, selectionRange_)) {
- shouldIgnoreReplacementSelection_ = YES;
- int start_adjust = editingWordRange_.location - selectionRange_.location;
- int end_adjust = (editingWordRange_.location + editingWordRange_.length) -
- (selectionRange_.location + selectionRange_.length);
- webContents_->AdjustSelectionByCharacterOffset(start_adjust, end_adjust,
- false);
- }
- webContents_->Replace(base::SysNSStringToUTF16(text));
-}
-
-- (void)setWebContents:(content::WebContents*)webContents {
- webContents_ = webContents;
- observer_->UpdateWebContents(webContents);
-
- if (![self isTextfieldFocused]) {
- [controller_ invalidateTouchBar];
- return;
- }
-
- const base::string16 text =
- webContents_->GetTopLevelRenderWidgetHostView()->GetSurroundingText();
- const gfx::Range range =
- webContents_->GetTopLevelRenderWidgetHostView()->GetSelectedRange();
- const size_t offset = webContents_->GetTopLevelRenderWidgetHostView()
- ->GetOffsetForSurroundingText();
-
- [self updateTextSelection:text range:range offset:offset];
-}
-
-- (content::WebContents*)webContents {
- return webContents_;
-}
-
-- (void)setText:(NSString*)text {
- text_.reset([text copy]);
-}
-
-- (NSString*)text {
- return text_;
-}
-
-- (void)setSelectionRange:(const gfx::Range&)range {
- selectionRange_ = range.ToNSRange();
-}
-
-- (gfx::Range)selectionRange {
- return gfx::Range(selectionRange_);
-}
-
-- (void)setSuggestions:(NSArray*)suggestions {
- suggestions_.reset([suggestions copy]);
-}
-
-- (NSArray*)suggestions {
- return suggestions_;
-}
-
-- (WebTextfieldTouchBarController*)controller {
- return controller_;
-}
-
-- (void)setShouldIgnoreReplacementSelection:(BOOL)shouldIgnore {
- shouldIgnoreReplacementSelection_ = shouldIgnore;
-}
-
-- (void)setEditingWordRange:(const gfx::Range&)range offset:(size_t)offset {
- editingWordRange_ = range.ToNSRange();
- offsetEditingWordRange_ = NSMakeRange(editingWordRange_.location + offset,
- editingWordRange_.length);
-}
-
-@end
diff --git a/chrome/browser/ui/cocoa/touchbar/text_suggestions_touch_bar_controller_browsertest.mm b/chrome/browser/ui/cocoa/touchbar/text_suggestions_touch_bar_controller_browsertest.mm
deleted file mode 100644
index bc5949f..0000000
--- a/chrome/browser/ui/cocoa/touchbar/text_suggestions_touch_bar_controller_browsertest.mm
+++ /dev/null
@@ -1,327 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#import <Cocoa/Cocoa.h>
-
-#include "base/mac/mac_util.h"
-#include "base/mac/scoped_nsobject.h"
-#include "base/strings/sys_string_conversions.h"
-#include "base/strings/utf_string_conversions.h"
-#include "base/test/scoped_feature_list.h"
-#include "build/build_config.h"
-#include "chrome/browser/ui/browser.h"
-#import "chrome/browser/ui/cocoa/test/cocoa_test_helper.h"
-#import "chrome/browser/ui/cocoa/touchbar/text_suggestions_touch_bar_controller.h"
-#include "chrome/browser/ui/cocoa/touchbar/web_textfield_touch_bar_controller.h"
-#include "chrome/common/chrome_features.h"
-#include "chrome/test/base/in_process_browser_test.h"
-#include "chrome/test/base/ui_test_utils.h"
-#include "content/public/browser/notification_service.h"
-#include "content/public/browser/notification_types.h"
-#include "content/public/test/test_utils.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#import "ui/base/cocoa/touch_bar_util.h"
-
-API_AVAILABLE(macos(10.12.2))
-@interface MockWebTextfieldTouchBarController : WebTextfieldTouchBarController {
- // Counter for the number of times invalidateTouchBar is called.
- int numInvalidations_;
-}
-- (int)numInvalidations;
-
-- (void)resetNumInvalidations;
-
-@end
-
-@implementation MockWebTextfieldTouchBarController
-
-- (void)invalidateTouchBar {
- numInvalidations_++;
-}
-
-- (int)numInvalidations {
- return numInvalidations_;
-}
-
-- (void)resetNumInvalidations {
- numInvalidations_ = 0;
-}
-
-@end
-
-API_AVAILABLE(macos(10.12.2))
-@interface MockTextSuggestionsTouchBarController
- : TextSuggestionsTouchBarController
-- (NSString*)firstSuggestion;
-@end
-
-@implementation MockTextSuggestionsTouchBarController
-
-- (void)requestSuggestions {
- [self setSuggestions:@[ [self text] ]];
- [[self controller] invalidateTouchBar];
-}
-
-- (NSString*)firstSuggestion {
- return [self suggestions][0];
-}
-
-@end
-
-namespace {
-
-class TextSuggestionsTouchBarControllerTest : public InProcessBrowserTest {
- public:
- void SetUp() override {
- InProcessBrowserTest::SetUp();
- feature_list_.InitAndEnableFeature(features::kTextSuggestionsTouchBar);
- }
-
- void SetUpOnMainThread() override {
- if (@available(macOS 10.12.2, *)) {
- web_textfield_controller_.reset(
- [[MockWebTextfieldTouchBarController alloc] init]);
- [web_textfield_controller_ resetNumInvalidations];
- touch_bar_controller_.reset([[MockTextSuggestionsTouchBarController alloc]
- initWithWebContents:GetActiveWebContents()
- controller:web_textfield_controller_]);
- }
- }
-
- void FocusTextfield() {
- content::WindowedNotificationObserver focus_observer(
- content::NOTIFICATION_FOCUS_CHANGED_IN_PAGE,
- content::NotificationService::AllSources());
- ui_test_utils::NavigateToURL(
- browser(),
- GURL("data:text/html;charset=utf-8,<input type=\"text\" autofocus>"));
- focus_observer.Wait();
- }
-
- void UnfocusTextfield() {
- ui_test_utils::NavigateToURL(browser(), GURL("about:blank"));
- }
-
- content::WebContents* GetActiveWebContents() {
- return browser()->tab_strip_model()->GetActiveWebContents();
- }
-
- API_AVAILABLE(macos(10.12.2))
- base::scoped_nsobject<MockWebTextfieldTouchBarController>
- web_textfield_controller_;
-
- API_AVAILABLE(macos(10.12.2))
- base::scoped_nsobject<MockTextSuggestionsTouchBarController>
- touch_bar_controller_;
- base::test::ScopedFeatureList feature_list_;
-};
-
-// Tests to check if the touch bar shows up properly.
-IN_PROC_BROWSER_TEST_F(TextSuggestionsTouchBarControllerTest, MakeTouchBar) {
- if (@available(macOS 10.12.2, *)) {
- NSString* const kTextSuggestionsTouchBarId = @"text-suggestions";
- NSArray* const kSuggestions = @[ @"text" ];
-
- // Touch bar shouldn't appear if the focused element is not a textfield.
- UnfocusTextfield();
- [touch_bar_controller_ setSuggestions:kSuggestions];
- EXPECT_FALSE([touch_bar_controller_ makeTouchBar]);
-
- // Touch bar shouldn't appear if there are no suggestions.
- FocusTextfield();
- [touch_bar_controller_ setSuggestions:[NSArray array]];
- EXPECT_FALSE([touch_bar_controller_ makeTouchBar]);
-
- // Touch bar should appear if textfield is focused and there are
- // suggestions.
- [touch_bar_controller_ setSuggestions:kSuggestions];
- NSTouchBar* touch_bar = [touch_bar_controller_ makeTouchBar];
- EXPECT_TRUE(touch_bar);
- EXPECT_TRUE([[touch_bar customizationIdentifier]
- isEqual:ui::GetTouchBarId(kTextSuggestionsTouchBarId)]);
- }
-}
-
-// Tests that a change in text selection is handled properly.
-IN_PROC_BROWSER_TEST_F(TextSuggestionsTouchBarControllerTest,
- UpdateTextSelection) {
- if (@available(macOS 10.12.2, *)) {
- NSString* const kText = @"text";
- NSString* const kEmptyText = @"";
- const gfx::Range kRange = gfx::Range(0, 4);
- const gfx::Range kEmptyRange = gfx::Range();
-
- // If not in a textfield,
- // 1. Textfield text should not be saved.
- // 2. Selected range should not be saved.
- // 3. Touch bar should be invalidated (if on MacOS 10.12.2 or later).
- UnfocusTextfield();
- [touch_bar_controller_ setText:kEmptyText];
- [touch_bar_controller_ setSelectionRange:kEmptyRange];
- [web_textfield_controller_ resetNumInvalidations];
-
- [touch_bar_controller_ updateTextSelection:base::SysNSStringToUTF16(kText)
- range:kRange
- offset:0];
- EXPECT_STREQ(kEmptyText.UTF8String,
- [touch_bar_controller_ text].UTF8String);
- EXPECT_EQ(kEmptyRange, [touch_bar_controller_ selectionRange]);
- EXPECT_EQ(1, [web_textfield_controller_ numInvalidations]);
-
- // If in a textfield and on MacOS 10.12.2 or later,
- // 1. Textfield text should be saved.
- // 2. Selected range should be saved.
- // 3. Suggestions should be generated based on text selection.
- // 4. Touch bar should be invalidated.
- FocusTextfield();
- [touch_bar_controller_ setText:kEmptyText];
- [touch_bar_controller_ setSelectionRange:kEmptyRange];
- [web_textfield_controller_ resetNumInvalidations];
-
- [touch_bar_controller_ updateTextSelection:base::SysNSStringToUTF16(kText)
- range:kRange
- offset:0];
- EXPECT_STREQ(kText.UTF8String, [touch_bar_controller_ text].UTF8String);
- EXPECT_EQ(kRange, [touch_bar_controller_ selectionRange]);
- EXPECT_STREQ(kText.UTF8String,
- [touch_bar_controller_ firstSuggestion].UTF8String);
- EXPECT_EQ(1, [web_textfield_controller_ numInvalidations]);
- }
-}
-
-// Tests that a range outside of the text bounds will set the selection range
-// to empty.
-IN_PROC_BROWSER_TEST_F(TextSuggestionsTouchBarControllerTest,
- RangeOutOfTextBounds) {
- if (@available(macOS 10.12.2, *)) {
- FocusTextfield();
- [touch_bar_controller_ setText:@""];
- [touch_bar_controller_ setSelectionRange:gfx::Range()];
-
- [touch_bar_controller_
- updateTextSelection:base::string16(base::ASCIIToUTF16("text"))
- range:gfx::Range(4, 5)
- offset:0];
- EXPECT_STREQ("", [touch_bar_controller_ text].UTF8String);
- EXPECT_EQ(gfx::Range(), [touch_bar_controller_ selectionRange]);
-
- [touch_bar_controller_
- updateTextSelection:base::string16(base::ASCIIToUTF16("text"))
- range:gfx::Range(2, 5)
- offset:0];
- EXPECT_STREQ("", [touch_bar_controller_ text].UTF8String);
- EXPECT_EQ(gfx::Range(), [touch_bar_controller_ selectionRange]);
- }
-}
-
-// Tests that a change in WebContents is handled properly.
-IN_PROC_BROWSER_TEST_F(TextSuggestionsTouchBarControllerTest, SetWebContents) {
- if (@available(macOS 10.12.2, *)) {
- NSString* const kText = @"text";
- const gfx::Range kRange = gfx::Range(1, 1);
-
- FocusTextfield();
-
- // A null-pointer should not break the controller.
- [touch_bar_controller_ setWebContents:nullptr];
- EXPECT_FALSE([touch_bar_controller_ webContents]);
-
- [touch_bar_controller_ setText:kText];
- [touch_bar_controller_ setSelectionRange:kRange];
-
- // The text selection should change on MacOS 10.12.2 and later if the
- // WebContents pointer is not null.
- [touch_bar_controller_ setWebContents:GetActiveWebContents()];
- EXPECT_EQ(GetActiveWebContents(), [touch_bar_controller_ webContents]);
- EXPECT_STRNE(kText.UTF8String, [touch_bar_controller_ text].UTF8String);
- EXPECT_NE(kRange, [touch_bar_controller_ selectionRange]);
- }
-}
-
-// Tests that the selection created when replacing the editing word with a
-// suggestion is ignored.
-IN_PROC_BROWSER_TEST_F(TextSuggestionsTouchBarControllerTest,
- IgnoreReplacementSelection) {
- if (@available(macOS 10.12.2, *)) {
- NSString* const kText = @"text";
- const base::string16 kEmptyText = base::string16();
- const gfx::Range kRange = gfx::Range(0, 4);
- const gfx::Range kEmptyRange = gfx::Range();
-
- FocusTextfield();
- [touch_bar_controller_ setText:kText];
- [touch_bar_controller_ setSelectionRange:kRange];
-
- // If ignoreReplacementSelection is YES and new selection range is equal to
- // editing word range, ignore text selection update.
- [touch_bar_controller_ setShouldIgnoreReplacementSelection:YES];
- [touch_bar_controller_ setEditingWordRange:kEmptyRange offset:0];
- [touch_bar_controller_ updateTextSelection:kEmptyText
- range:kEmptyRange
- offset:0];
- EXPECT_STREQ(kText.UTF8String, [touch_bar_controller_ text].UTF8String);
- EXPECT_EQ(kRange, [touch_bar_controller_ selectionRange]);
-
- // If ignoreReplacementSelection is YES but new selection range is not equal
- // to editing word range, do not ignore text selection update.
- [touch_bar_controller_ setShouldIgnoreReplacementSelection:YES];
- [touch_bar_controller_ setEditingWordRange:kRange offset:0];
- [touch_bar_controller_ updateTextSelection:kEmptyText
- range:kEmptyRange
- offset:0];
- EXPECT_STREQ("", [touch_bar_controller_ text].UTF8String);
- EXPECT_EQ(gfx::Range(), [touch_bar_controller_ selectionRange]);
-
- [touch_bar_controller_ setText:kText];
- [touch_bar_controller_ setSelectionRange:kRange];
-
- // If ignoreReplacementSelection is NO and new selection range is equal to
- // editing word range, do not ignore text selection update.
- [touch_bar_controller_ setShouldIgnoreReplacementSelection:NO];
- [touch_bar_controller_ setEditingWordRange:kEmptyRange offset:0];
- [touch_bar_controller_ updateTextSelection:kEmptyText
- range:kEmptyRange
- offset:0];
- EXPECT_STREQ("", [touch_bar_controller_ text].UTF8String);
- EXPECT_EQ(gfx::Range(), [touch_bar_controller_ selectionRange]);
- }
-}
-
-// Tests that offsets are properly handled.
-IN_PROC_BROWSER_TEST_F(TextSuggestionsTouchBarControllerTest, Offset) {
- if (@available(macOS 10.12.2, *)) {
- const base::string16 kText =
- base::string16(base::ASCIIToUTF16("hello world"));
- const gfx::Range kRange = gfx::Range(3, 3);
- const size_t kOffset = 1;
- const gfx::Range kOffsetRange =
- gfx::Range(kRange.start() - kOffset, kRange.end() - kOffset);
-
- FocusTextfield();
- [touch_bar_controller_ setSelectionRange:gfx::Range()];
-
- // |selectionRange_| should include offset.
- [touch_bar_controller_ updateTextSelection:kText
- range:kRange
- offset:kOffset];
- if (@available(macOS 10.12.2, *))
- EXPECT_EQ(kOffsetRange, [touch_bar_controller_ selectionRange]);
- else
- EXPECT_EQ(gfx::Range(), [touch_bar_controller_ selectionRange]);
-
- // The check for ignoring text selection updates should still work with
- // offsets.
- [touch_bar_controller_ setShouldIgnoreReplacementSelection:YES];
- [touch_bar_controller_ updateTextSelection:kText
- range:gfx::Range(1, 7)
- offset:kOffset];
- if (@available(macOS 10.12.2, *))
- EXPECT_EQ(gfx::Range(0, 6), [touch_bar_controller_ selectionRange]);
- else
- EXPECT_EQ(gfx::Range(), [touch_bar_controller_ selectionRange]);
- }
-}
-
-} // namespace
diff --git a/chrome/browser/ui/cocoa/touchbar/text_suggestions_touch_bar_controller_unittest.mm b/chrome/browser/ui/cocoa/touchbar/text_suggestions_touch_bar_controller_unittest.mm
deleted file mode 100644
index feb982f..0000000
--- a/chrome/browser/ui/cocoa/touchbar/text_suggestions_touch_bar_controller_unittest.mm
+++ /dev/null
@@ -1,155 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#import <Cocoa/Cocoa.h>
-
-#include "base/strings/utf_string_conversions.h"
-#include "base/test/metrics/histogram_tester.h"
-#import "chrome/browser/ui/cocoa/test/cocoa_test_helper.h"
-#import "chrome/browser/ui/cocoa/touchbar/text_suggestions_touch_bar_controller.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#import "ui/base/cocoa/touch_bar_util.h"
-#include "ui/gfx/range/range.h"
-
-const base::string16 kEmptyText(base::ASCIIToUTF16(""));
-const base::string16 kWord(base::ASCIIToUTF16("hello"));
-const base::string16 kWordWithTrailingWhitespace(base::ASCIIToUTF16("hello "));
-const base::string16 kWordWithLeadingWhitespace(base::ASCIIToUTF16(" hello"));
-const base::string16 kMultipleWords(base::ASCIIToUTF16("hello world"));
-const base::string16 kWhitespace(base::ASCIIToUTF16(" "));
-
-class TextSuggestionsTouchBarControllerTest : public CocoaTest {
- public:
- void SetUp() override {
- CocoaTest::SetUp();
- if (@available(macOS 10.12.2, *))
- controller_.reset([[TextSuggestionsTouchBarController alloc] init]);
- }
-
- gfx::Range GetEditingWordRange(const base::string16& text, size_t cursor)
- API_AVAILABLE(macos(10.12.2)) {
- NSRange range =
- [controller_.get() editingWordRangeFromText:text cursorPosition:cursor];
- return gfx::Range(range);
- }
-
- API_AVAILABLE(macos(10.12.2))
- base::scoped_nsobject<TextSuggestionsTouchBarController> controller_;
-};
-
-// Tests that the NSCandidateListTouchBarItem collapses properly.
-TEST_F(TextSuggestionsTouchBarControllerTest, CollapsedCandidateList) {
- if (@available(macOS 10.12.2, *)) {
- [controller_ setSelectionRange:gfx::Range()];
- EXPECT_FALSE([[controller_ makeCandidateListItem] isCollapsed]);
-
- [controller_ setSelectionRange:gfx::Range(0, 1)];
- EXPECT_TRUE([[controller_ makeCandidateListItem] isCollapsed]);
- }
-}
-
-// Tests that the editing word range is simply the cursor position if there
-// is no text.
-TEST_F(TextSuggestionsTouchBarControllerTest, EmptyTextEditingWordRange) {
- if (@available(macOS 10.12.2, *))
- EXPECT_EQ(gfx::Range(0, 0), GetEditingWordRange(kEmptyText, 0));
-}
-
-// Tests that the editing word range contains the full word as the cursor
-// moves through a word without breaks.
-TEST_F(TextSuggestionsTouchBarControllerTest, WordEditingWordRange) {
- if (@available(macOS 10.12.2, *)) {
- EXPECT_EQ(gfx::Range(0, 0), GetEditingWordRange(kWord, 0));
- EXPECT_EQ(gfx::Range(0, 1), GetEditingWordRange(kWord, 1));
- EXPECT_EQ(gfx::Range(0, 2), GetEditingWordRange(kWord, 2));
- EXPECT_EQ(gfx::Range(0, 3), GetEditingWordRange(kWord, 3));
- EXPECT_EQ(gfx::Range(0, 4), GetEditingWordRange(kWord, 4));
- }
-}
-
-// Tests that the editing word range is properly calculated as the cursor moves
-// through non-word characters.
-TEST_F(TextSuggestionsTouchBarControllerTest, WhitespaceEditingWordRange) {
- if (@available(macOS 10.12.2, *)) {
- EXPECT_EQ(gfx::Range(0, 0), GetEditingWordRange(kWhitespace, 0));
- EXPECT_EQ(gfx::Range(1, 1), GetEditingWordRange(kWhitespace, 1));
- EXPECT_EQ(gfx::Range(2, 2), GetEditingWordRange(kWhitespace, 2));
- EXPECT_EQ(gfx::Range(3, 3), GetEditingWordRange(kWhitespace, 3));
- EXPECT_EQ(gfx::Range(4, 4), GetEditingWordRange(kWhitespace, 4));
- EXPECT_EQ(gfx::Range(5, 5), GetEditingWordRange(kWhitespace, 5));
- }
-}
-
-// Tests that the editing word range changes properly as the cursor moves
-// from word to non-word characters.
-TEST_F(TextSuggestionsTouchBarControllerTest,
- TrailingWhitespaceEditingWordRange) {
- if (@available(macOS 10.12.2, *)) {
- EXPECT_EQ(gfx::Range(0, 0),
- GetEditingWordRange(kWordWithTrailingWhitespace, 0));
- EXPECT_EQ(gfx::Range(0, 1),
- GetEditingWordRange(kWordWithTrailingWhitespace, 1));
- EXPECT_EQ(gfx::Range(0, 2),
- GetEditingWordRange(kWordWithTrailingWhitespace, 2));
- EXPECT_EQ(gfx::Range(0, 3),
- GetEditingWordRange(kWordWithTrailingWhitespace, 3));
- EXPECT_EQ(gfx::Range(0, 4),
- GetEditingWordRange(kWordWithTrailingWhitespace, 4));
- EXPECT_EQ(gfx::Range(0, 5),
- GetEditingWordRange(kWordWithTrailingWhitespace, 5));
- EXPECT_EQ(gfx::Range(6, 6),
- GetEditingWordRange(kWordWithTrailingWhitespace, 6));
- }
-}
-
-// Tests that the editing word range changes properly as the cursor moves
-// from non-word to word characters.
-TEST_F(TextSuggestionsTouchBarControllerTest,
- LeadingWhitespaceEditingWordRange) {
- if (@available(macOS 10.12.2, *)) {
- EXPECT_EQ(gfx::Range(0, 0),
- GetEditingWordRange(kWordWithLeadingWhitespace, 0));
- EXPECT_EQ(gfx::Range(1, 1),
- GetEditingWordRange(kWordWithLeadingWhitespace, 1));
- EXPECT_EQ(gfx::Range(1, 2),
- GetEditingWordRange(kWordWithLeadingWhitespace, 2));
- EXPECT_EQ(gfx::Range(1, 3),
- GetEditingWordRange(kWordWithLeadingWhitespace, 3));
- EXPECT_EQ(gfx::Range(1, 4),
- GetEditingWordRange(kWordWithLeadingWhitespace, 4));
- EXPECT_EQ(gfx::Range(1, 5),
- GetEditingWordRange(kWordWithLeadingWhitespace, 5));
- EXPECT_EQ(gfx::Range(1, 6),
- GetEditingWordRange(kWordWithLeadingWhitespace, 6));
- }
-}
-
-// Tests that the editing word range is properly calculated as the cursor moves
-// from word to non-word and back to word characters.
-TEST_F(TextSuggestionsTouchBarControllerTest, MultipleWordsEditingWordRange) {
- if (@available(macOS 10.12.2, *)) {
- EXPECT_EQ(gfx::Range(0, 0), GetEditingWordRange(kMultipleWords, 0));
- EXPECT_EQ(gfx::Range(0, 1), GetEditingWordRange(kMultipleWords, 1));
- EXPECT_EQ(gfx::Range(0, 2), GetEditingWordRange(kMultipleWords, 2));
- EXPECT_EQ(gfx::Range(0, 3), GetEditingWordRange(kMultipleWords, 3));
- EXPECT_EQ(gfx::Range(0, 4), GetEditingWordRange(kMultipleWords, 4));
- EXPECT_EQ(gfx::Range(0, 5), GetEditingWordRange(kMultipleWords, 5));
- EXPECT_EQ(gfx::Range(6, 6), GetEditingWordRange(kMultipleWords, 6));
- EXPECT_EQ(gfx::Range(6, 7), GetEditingWordRange(kMultipleWords, 7));
- EXPECT_EQ(gfx::Range(6, 8), GetEditingWordRange(kMultipleWords, 8));
- EXPECT_EQ(gfx::Range(6, 9), GetEditingWordRange(kMultipleWords, 9));
- EXPECT_EQ(gfx::Range(6, 10), GetEditingWordRange(kMultipleWords, 10));
- EXPECT_EQ(gfx::Range(6, 11), GetEditingWordRange(kMultipleWords, 11));
- }
-}
-
-// Tests that touch bar usage is properly logged.
-TEST_F(TextSuggestionsTouchBarControllerTest, TouchBarMetrics) {
- if (@available(macOS 10.12.2, *)) {
- base::HistogramTester histogram_tester;
- [controller_ candidateListTouchBarItem:nil endSelectingCandidateAtIndex:1];
- histogram_tester.ExpectBucketCount("TouchBar.Default.Metrics",
- ui::TouchBarAction::TEXT_SUGGESTION, 1);
- }
-}
diff --git a/chrome/browser/ui/cocoa/touchbar/web_textfield_touch_bar_controller.h b/chrome/browser/ui/cocoa/touchbar/web_textfield_touch_bar_controller.h
index 622cd75..d5fb4be6 100644
--- a/chrome/browser/ui/cocoa/touchbar/web_textfield_touch_bar_controller.h
+++ b/chrome/browser/ui/cocoa/touchbar/web_textfield_touch_bar_controller.h
@@ -14,7 +14,6 @@
@class BrowserWindowTouchBarController;
@class CreditCardAutofillTouchBarController;
-@class TextSuggestionsTouchBarController;
@class TabContentsController;
namespace autofill {
@@ -32,8 +31,6 @@
BrowserWindowTouchBarController* controller_; // weak.
base::scoped_nsobject<CreditCardAutofillTouchBarController>
autofillTouchBarController_;
- base::scoped_nsobject<TextSuggestionsTouchBarController>
- textSuggestionsTouchBarController_;
}
+ (WebTextfieldTouchBarController*)controllerForWindow:(NSWindow*)window;
@@ -46,8 +43,6 @@
- (void)hideCreditCardAutofillTouchBar;
-- (void)updateWebContents:(content::WebContents*)contents;
-
- (void)invalidateTouchBar;
// Creates and returns a touch bar.
diff --git a/chrome/browser/ui/cocoa/touchbar/web_textfield_touch_bar_controller.mm b/chrome/browser/ui/cocoa/touchbar/web_textfield_touch_bar_controller.mm
index 76a9101..b8f98d68 100644
--- a/chrome/browser/ui/cocoa/touchbar/web_textfield_touch_bar_controller.mm
+++ b/chrome/browser/ui/cocoa/touchbar/web_textfield_touch_bar_controller.mm
@@ -12,13 +12,10 @@
#import "chrome/browser/ui/cocoa/tab_contents/tab_contents_controller.h"
#import "chrome/browser/ui/cocoa/touchbar/browser_window_touch_bar_controller.h"
#import "chrome/browser/ui/cocoa/touchbar/credit_card_autofill_touch_bar_controller.h"
-#import "chrome/browser/ui/cocoa/touchbar/text_suggestions_touch_bar_controller.h"
#include "chrome/browser/ui/views/frame/browser_frame_mac.h"
#include "chrome/browser/ui/views/frame/browser_view.h"
-#include "chrome/common/chrome_features.h"
#include "content/public/browser/web_contents.h"
#import "ui/base/cocoa/touch_bar_util.h"
-#include "ui/base/ui_base_features.h"
@implementation WebTextfieldTouchBarController
@@ -37,14 +34,6 @@
(BrowserWindowTouchBarController*)controller {
if ((self = [super init])) {
controller_ = controller;
-
- if (base::FeatureList::IsEnabled(features::kTextSuggestionsTouchBar) ||
- base::FeatureList::IsEnabled(features::kExperimentalUi)) {
- textSuggestionsTouchBarController_.reset(
- [[TextSuggestionsTouchBarController alloc]
- initWithWebContents:[controller_ webContents]
- controller:self]);
- }
}
return self;
@@ -68,10 +57,6 @@
[self invalidateTouchBar];
}
-- (void)updateWebContents:(content::WebContents*)contents {
- [textSuggestionsTouchBarController_ setWebContents:contents];
-}
-
- (void)invalidateTouchBar {
[controller_ invalidateTouchBar];
}
@@ -79,10 +64,6 @@
- (NSTouchBar*)makeTouchBar {
if (autofillTouchBarController_)
return [autofillTouchBarController_ makeTouchBar];
-
- if (textSuggestionsTouchBarController_)
- return [textSuggestionsTouchBarController_ makeTouchBar];
-
return nil;
}
diff --git a/chrome/browser/ui/passwords/password_generation_popup_controller_impl.cc b/chrome/browser/ui/passwords/password_generation_popup_controller_impl.cc
index 730e43c..e16693e 100644
--- a/chrome/browser/ui/passwords/password_generation_popup_controller_impl.cc
+++ b/chrome/browser/ui/passwords/password_generation_popup_controller_impl.cc
@@ -37,6 +37,7 @@
#include "ui/base/l10n/l10n_util.h"
#include "ui/events/keycodes/keyboard_codes.h"
#include "ui/gfx/geometry/rect_conversions.h"
+#include "ui/gfx/range/range.h"
#include "ui/gfx/text_utils.h"
#if defined(OS_ANDROID)
diff --git a/chrome/common/chrome_features.cc b/chrome/common/chrome_features.cc
index 9a06154..e8099d1 100644
--- a/chrome/common/chrome_features.cc
+++ b/chrome/common/chrome_features.cc
@@ -138,12 +138,6 @@
base::FEATURE_ENABLED_BY_DEFAULT};
#endif
-#if defined(OS_MACOSX)
-// Enables the suggested text touch bar for autocomplete in textfields.
-const base::Feature kTextSuggestionsTouchBar{"TextSuggestionsTouchBar",
- base::FEATURE_DISABLED_BY_DEFAULT};
-#endif
-
#if defined(OS_WIN) && defined(GOOGLE_CHROME_BUILD)
// Enables the blocking of third-party modules.
// Note: Due to a limitation in the implementation of this feature, it is
diff --git a/chrome/common/chrome_features.h b/chrome/common/chrome_features.h
index f137fb4..94821af 100644
--- a/chrome/common/chrome_features.h
+++ b/chrome/common/chrome_features.h
@@ -371,11 +371,6 @@
COMPONENT_EXPORT(CHROME_FEATURES) extern const base::Feature kTabMetricsLogging;
#endif
-#if defined(OS_MACOSX)
-COMPONENT_EXPORT(CHROME_FEATURES)
-extern const base::Feature kTextSuggestionsTouchBar;
-#endif
-
#if defined(OS_WIN) && defined(GOOGLE_CHROME_BUILD)
COMPONENT_EXPORT(CHROME_FEATURES)
extern const base::Feature kThirdPartyModulesBlocking;
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index c719239a..54b519f9 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -1968,7 +1968,6 @@
"../browser/ui/cocoa/renderer_context_menu/render_view_context_menu_mac_cocoa_browsertest.mm",
"../browser/ui/cocoa/ssl_client_certificate_selector_cocoa_browsertest.mm",
"../browser/ui/cocoa/touchbar/browser_window_touch_bar_controller_browsertest.mm",
- "../browser/ui/cocoa/touchbar/text_suggestions_touch_bar_controller_browsertest.mm",
## TODO(crbug/845389): Re-Enable the following, which were temporarily
## omitted from the build, but still in use by the Cocoa browser.
@@ -4149,7 +4148,6 @@
"../browser/ui/cocoa/test/run_loop_testing_unittest.mm",
"../browser/ui/cocoa/touchbar/browser_window_default_touch_bar_unittest.mm",
"../browser/ui/cocoa/touchbar/credit_card_autofill_touch_bar_controller_unittest.mm",
- "../browser/ui/cocoa/touchbar/text_suggestions_touch_bar_controller_unittest.mm",
"../browser/ui/cocoa/url_drop_target_unittest.mm",
"../browser/ui/cocoa/view_resizer_pong.h",
"../browser/ui/cocoa/view_resizer_pong.mm",
diff --git a/content/browser/frame_host/render_widget_host_view_guest.cc b/content/browser/frame_host/render_widget_host_view_guest.cc
index 96c9cd1..66f1270 100644
--- a/content/browser/frame_host/render_widget_host_view_guest.cc
+++ b/content/browser/frame_host/render_widget_host_view_guest.cc
@@ -338,18 +338,6 @@
return platform_view_->GetSelectedText();
}
-base::string16 RenderWidgetHostViewGuest::GetSurroundingText() {
- return platform_view_->GetSurroundingText();
-}
-
-gfx::Range RenderWidgetHostViewGuest::GetSelectedRange() {
- return platform_view_->GetSelectedRange();
-}
-
-size_t RenderWidgetHostViewGuest::GetOffsetForSurroundingText() {
- return platform_view_->GetOffsetForSurroundingText();
-}
-
void RenderWidgetHostViewGuest::SetNeedsBeginFrames(bool needs_begin_frames) {
if (platform_view_)
platform_view_->SetNeedsBeginFrames(needs_begin_frames);
diff --git a/content/browser/frame_host/render_widget_host_view_guest.h b/content/browser/frame_host/render_widget_host_view_guest.h
index dae838f..b3353f56 100644
--- a/content/browser/frame_host/render_widget_host_view_guest.h
+++ b/content/browser/frame_host/render_widget_host_view_guest.h
@@ -80,9 +80,6 @@
gfx::Rect GetBoundsInRootWindow() override;
gfx::Size GetCompositorViewportPixelSize() const override;
base::string16 GetSelectedText() override;
- base::string16 GetSurroundingText() override;
- gfx::Range GetSelectedRange() override;
- size_t GetOffsetForSurroundingText() override;
void SetNeedsBeginFrames(bool needs_begin_frames) override;
TouchSelectionControllerClientManager*
GetTouchSelectionControllerClientManager() override;
diff --git a/content/browser/renderer_host/render_widget_host_delegate.h b/content/browser/renderer_host/render_widget_host_delegate.h
index 88340958..e34de9d 100644
--- a/content/browser/renderer_host/render_widget_host_delegate.h
+++ b/content/browser/renderer_host/render_widget_host_delegate.h
@@ -20,7 +20,6 @@
#include "third_party/blink/public/platform/web_drag_operation.h"
#include "third_party/blink/public/platform/web_input_event.h"
#include "ui/gfx/native_widget_types.h"
-#include "ui/gfx/range/range.h"
namespace blink {
class WebMouseEvent;
@@ -156,12 +155,6 @@
// currently focused frame.
virtual void SelectRange(const gfx::Point& base, const gfx::Point& extent) {}
-#if defined(OS_MACOSX)
- virtual void DidChangeTextSelection(const base::string16& text,
- const gfx::Range& range,
- size_t offset) {}
-#endif
-
// Request the renderer to Move the caret to the new position.
virtual void MoveCaret(const gfx::Point& extent) {}
diff --git a/content/browser/renderer_host/render_widget_host_view_base.cc b/content/browser/renderer_host/render_widget_host_view_base.cc
index e155153..72f5b4178 100644
--- a/content/browser/renderer_host/render_widget_host_view_base.cc
+++ b/content/browser/renderer_host/render_widget_host_view_base.cc
@@ -299,24 +299,6 @@
return GetTextInputManager()->GetTextSelection(this)->selected_text();
}
-base::string16 RenderWidgetHostViewBase::GetSurroundingText() {
- if (!GetTextInputManager())
- return base::string16();
- return GetTextInputManager()->GetTextSelection(this)->text();
-}
-
-gfx::Range RenderWidgetHostViewBase::GetSelectedRange() {
- if (!GetTextInputManager())
- return gfx::Range();
- return GetTextInputManager()->GetTextSelection(this)->range();
-}
-
-size_t RenderWidgetHostViewBase::GetOffsetForSurroundingText() {
- if (!GetTextInputManager())
- return 0;
- return GetTextInputManager()->GetTextSelection(this)->offset();
-}
-
void RenderWidgetHostViewBase::SetBackgroundColor(SkColor color) {
DCHECK(SkColorGetA(color) == SK_AlphaOPAQUE ||
SkColorGetA(color) == SK_AlphaTRANSPARENT);
diff --git a/content/browser/renderer_host/render_widget_host_view_base.h b/content/browser/renderer_host/render_widget_host_view_base.h
index becc63fa..404d277 100644
--- a/content/browser/renderer_host/render_widget_host_view_base.h
+++ b/content/browser/renderer_host/render_widget_host_view_base.h
@@ -116,9 +116,6 @@
void WasOccluded() override {}
void SetIsInVR(bool is_in_vr) override;
base::string16 GetSelectedText() override;
- base::string16 GetSurroundingText() override;
- gfx::Range GetSelectedRange() override;
- size_t GetOffsetForSurroundingText() override;
bool IsMouseLocked() override;
bool LockKeyboard(base::Optional<base::flat_set<ui::DomCode>> codes) override;
void SetBackgroundColor(SkColor color) override;
diff --git a/content/browser/renderer_host/render_widget_host_view_cocoa.h b/content/browser/renderer_host/render_widget_host_view_cocoa.h
index fc0105d..12e531d 100644
--- a/content/browser/renderer_host/render_widget_host_view_cocoa.h
+++ b/content/browser/renderer_host/render_widget_host_view_cocoa.h
@@ -55,6 +55,7 @@
@interface RenderWidgetHostViewCocoa
: ToolTipBaseView<CommandDispatcherTarget,
RenderWidgetHostNSViewClientOwner,
+ NSCandidateListTouchBarItemDelegate,
NSTextInputClient> {
@private
// The communications channel to the RenderWidgetHostViewMac. This pointer is
@@ -198,6 +199,8 @@
@property(nonatomic, assign) NSRange markedRange;
@property(nonatomic, assign) ui::TextInputType textInputType;
+@property(nonatomic, assign) NSSpellChecker* spellCheckerForTesting;
+
// Common code path for handling begin gesture events. This helper method is
// called via different codepaths based on OS version and SDK:
// - On 10.11 and later, when linking with the 10.11 SDK, it is called from
diff --git a/content/browser/renderer_host/render_widget_host_view_cocoa.mm b/content/browser/renderer_host/render_widget_host_view_cocoa.mm
index ee6cde81..7730617 100644
--- a/content/browser/renderer_host/render_widget_host_view_cocoa.mm
+++ b/content/browser/renderer_host/render_widget_host_view_cocoa.mm
@@ -21,10 +21,12 @@
#include "content/browser/renderer_host/render_widget_host_view_mac.h"
#import "content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper.h"
#import "content/public/browser/render_widget_host_view_mac_delegate.h"
+#include "content/public/common/content_features.h"
#include "ui/accessibility/platform/ax_platform_node.h"
#import "ui/base/clipboard/clipboard_util_mac.h"
#import "ui/base/cocoa/appkit_utils.h"
#include "ui/base/cocoa/cocoa_base_utils.h"
+#import "ui/base/cocoa/touch_bar_util.h"
#include "ui/base/ui_base_features.h"
#include "ui/display/screen.h"
#include "ui/events/event_utils.h"
@@ -52,6 +54,9 @@
namespace {
+// Touch bar identifier.
+NSString* const kWebContentTouchBarId = @"web-content";
+
// Whether a keyboard event has been reserved by OSX.
BOOL EventIsReservedBySystem(NSEvent* event) {
content::SystemHotkeyHelperMac* helper =
@@ -119,6 +124,10 @@
@interface RenderWidgetHostViewCocoa () {
bool keyboardLockActive_;
base::Optional<base::flat_set<ui::DomCode>> lockedKeys_;
+
+ API_AVAILABLE(macos(10.12.2))
+ base::scoped_nsobject<NSCandidateListTouchBarItem> candidateListTouchBarItem_;
+ NSInteger textSuggestionsSequenceNumber_;
}
- (void)processedWheelEvent:(const blink::WebMouseWheelEvent&)event
consumed:(BOOL)consumed;
@@ -128,13 +137,21 @@
- (void)windowDidBecomeKey:(NSNotification*)notification;
- (void)windowDidResignKey:(NSNotification*)notification;
- (void)sendViewBoundsInWindowToClient;
+- (void)requestTextSuggestions;
- (void)sendWindowFrameInScreenToClient;
- (bool)clientIsDisconnected;
+- (void)invalidateTouchBar API_AVAILABLE(macos(10.12.2));
+
+// NSCandidateListTouchBarItemDelegate implementation
+- (void)candidateListTouchBarItem:(NSCandidateListTouchBarItem*)anItem
+ endSelectingCandidateAtIndex:(NSInteger)index
+ API_AVAILABLE(macos(10.12.2));
@end
@implementation RenderWidgetHostViewCocoa
@synthesize markedRange = markedRange_;
@synthesize textInputType = textInputType_;
+@synthesize spellCheckerForTesting = spellCheckerForTesting_;
- (id)initWithClient:(RenderWidgetHostNSViewClient*)client
withClientHelper:(RenderWidgetHostNSViewClientHelper*)clientHelper {
@@ -191,12 +208,65 @@
client_->OnBoundsInWindowChanged(gfxViewBoundsInWindow, true);
}
+- (void)requestTextSuggestions {
+ if (@available(macOS 10.12.2, *)) {
+ auto* touchBarItem = candidateListTouchBarItem_.get();
+ if (!touchBarItem)
+ return;
+ NSRange selectionRange = textSelectionRange_.ToNSRange();
+ NSString* selectionText = base::SysUTF16ToNSString(textSelectionText_);
+ selectionRange.location -= textSelectionOffset_;
+ NSSpellChecker* spell_checker = spellCheckerForTesting_
+ ? spellCheckerForTesting_
+ : [NSSpellChecker sharedSpellChecker];
+ textSuggestionsSequenceNumber_ = [spell_checker
+ requestCandidatesForSelectedRange:selectionRange
+ inString:selectionText
+ types:NSTextCheckingAllSystemTypes
+ options:nil
+ inSpellDocumentWithTag:0
+ completionHandler:^(
+ NSInteger sequenceNumber,
+ NSArray<NSTextCheckingResult*>* candidates) {
+ dispatch_async(dispatch_get_main_queue(), ^{
+ if (sequenceNumber !=
+ textSuggestionsSequenceNumber_)
+ return;
+ [touchBarItem setCandidates:candidates
+ forSelectedRange:selectionRange
+ inString:selectionText];
+ });
+ }];
+ }
+}
+
- (void)setTextSelectionText:(base::string16)text
offset:(size_t)offset
range:(gfx::Range)range {
textSelectionText_ = text;
textSelectionOffset_ = offset;
textSelectionRange_ = range;
+ [self requestTextSuggestions];
+}
+
+- (void)candidateListTouchBarItem:(NSCandidateListTouchBarItem*)anItem
+ endSelectingCandidateAtIndex:(NSInteger)index {
+ if (index == NSNotFound)
+ return;
+ NSTextCheckingResult* selectedResult = anItem.candidates[index];
+ NSRange replacementRange = selectedResult.range;
+ replacementRange.location += textSelectionOffset_;
+ [self insertText:selectedResult.replacementString
+ replacementRange:replacementRange];
+}
+
+- (void)setTextInputType:(ui::TextInputType)textInputType {
+ if (textInputType_ == textInputType)
+ return;
+ textInputType_ = textInputType;
+
+ if (@available(macOS 10.12.2, *))
+ [self invalidateTouchBar];
}
- (base::string16)selectedText {
@@ -1842,6 +1912,36 @@
client_->RequestShutdown();
}
+- (void)invalidateTouchBar {
+ candidateListTouchBarItem_.reset();
+ self.touchBar = nil;
+}
+
+- (NSTouchBar*)makeTouchBar {
+ if (textInputType_ != ui::TEXT_INPUT_TYPE_NONE &&
+ textInputType_ != ui::TEXT_INPUT_TYPE_PASSWORD &&
+ (base::FeatureList::IsEnabled(features::kTextSuggestionsTouchBar) ||
+ base::FeatureList::IsEnabled(features::kExperimentalUi))) {
+ candidateListTouchBarItem_.reset([[NSCandidateListTouchBarItem alloc]
+ initWithIdentifier:NSTouchBarItemIdentifierCandidateList]);
+ auto* candidateListItem = candidateListTouchBarItem_.get();
+
+ candidateListItem.delegate = self;
+ candidateListItem.client = self;
+ [self requestTextSuggestions];
+
+ base::scoped_nsobject<NSTouchBar> scopedTouchBar([[NSTouchBar alloc] init]);
+ auto* touchBar = scopedTouchBar.get();
+ touchBar.customizationIdentifier = ui::GetTouchBarId(kWebContentTouchBarId);
+ touchBar.templateItems = [NSSet setWithObject:candidateListTouchBarItem_];
+ touchBar.defaultItemIdentifiers =
+ @[ NSTouchBarItemIdentifierCandidateList ];
+ return scopedTouchBar.autorelease();
+ }
+
+ return [super makeTouchBar];
+}
+
@end
//
diff --git a/content/browser/renderer_host/render_widget_host_view_mac.mm b/content/browser/renderer_host/render_widget_host_view_mac.mm
index 94d6e793..455a6ccb 100644
--- a/content/browser/renderer_host/render_widget_host_view_mac.mm
+++ b/content/browser/renderer_host/render_widget_host_view_mac.mm
@@ -627,9 +627,6 @@
return;
ns_view_bridge_->SetTextSelection(selection->text(), selection->offset(),
selection->range());
- if (host() && host()->delegate())
- host()->delegate()->DidChangeTextSelection(
- selection->text(), selection->range(), selection->offset());
}
bool RenderWidgetHostViewMac::ShouldWaitInPreCommit() {
diff --git a/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm b/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm
index ed5984e8..f6549b3 100644
--- a/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm
+++ b/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm
@@ -127,6 +127,72 @@
@end
+@interface FakeTextCheckingResult : NSObject<NSCopying>
+@property(readonly) NSRange range;
+@property(readonly) NSString* replacementString;
+@end
+
+@implementation FakeTextCheckingResult {
+ base::scoped_nsobject<NSString> replacementString_;
+}
+@synthesize range = range_;
+
++ (FakeTextCheckingResult*)resultWithRange:(NSRange)range
+ replacementString:(NSString*)replacementString {
+ FakeTextCheckingResult* result =
+ [[[FakeTextCheckingResult alloc] init] autorelease];
+ result->range_ = range;
+ result->replacementString_.reset([replacementString retain]);
+ return result;
+}
+
+- (id)copyWithZone:(NSZone*)zone {
+ return
+ [[FakeTextCheckingResult resultWithRange:self.range
+ replacementString:self.replacementString] retain];
+}
+
+- (NSString*)replacementString {
+ return replacementString_;
+}
+@end
+
+@interface FakeSpellChecker : NSObject
+@property NSInteger sequenceNumber;
+@end
+
+@implementation FakeSpellChecker {
+ base::mac::ScopedBlock<void (^)(NSInteger sequenceNumber,
+ NSArray<NSTextCheckingResult*>* candidates)>
+ lastCompletionHandler_;
+}
+@synthesize sequenceNumber = sequenceNumber_;
+
+- (NSInteger)
+requestCandidatesForSelectedRange:(NSRange)selectedRange
+ inString:(NSString*)stringToCheck
+ types:(NSTextCheckingTypes)checkingTypes
+ options:
+ (nullable NSDictionary<NSTextCheckingOptionKey,
+ id>*)options
+ inSpellDocumentWithTag:(NSInteger)tag
+ completionHandler:
+ (void (^__nullable)(NSInteger sequenceNumber,
+ NSArray<NSTextCheckingResult*>*
+ candidates))completionHandler
+ NS_AVAILABLE_MAC(10_12_2) {
+ sequenceNumber_ += 1;
+ lastCompletionHandler_.reset([completionHandler copy]);
+ return sequenceNumber_;
+}
+
+- (void (^)(NSInteger sequenceNumber,
+ NSArray<NSTextCheckingResult*>* candidates))lastCompletionHandler {
+ return lastCompletionHandler_;
+}
+
+@end
+
namespace content {
namespace {
@@ -1669,6 +1735,12 @@
RenderWidgetHostImpl* tab_widget() { return widget_; }
RenderWidgetHostViewCocoa* tab_cocoa_view() { return view_->cocoa_view(); }
+ API_AVAILABLE(macos(10.12.2))
+ NSCandidateListTouchBarItem* candidate_list_item() {
+ return [tab_cocoa_view().touchBar
+ itemForIdentifier:NSTouchBarItemIdentifierCandidateList];
+ }
+
protected:
MockRenderProcessHost* process_host_;
MockRenderWidgetHostImpl* widget_;
@@ -1955,6 +2027,90 @@
EXPECT_FALSE(message->monitor_request());
}
+TEST_F(InputMethodMacTest, TouchBarTextSuggestionsDisabled) {
+ base::test::ScopedFeatureList feature_list;
+ feature_list.InitAndDisableFeature(features::kTextSuggestionsTouchBar);
+ if (@available(macOS 10.12.2, *)) {
+ EXPECT_NSEQ(nil, candidate_list_item());
+ SetTextInputType(tab_view(), ui::TEXT_INPUT_TYPE_TEXT);
+ EXPECT_NSEQ(nil, candidate_list_item());
+ }
+}
+
+TEST_F(InputMethodMacTest, TouchBarTextSuggestionsPresence) {
+ base::test::ScopedFeatureList feature_list;
+ feature_list.InitAndEnableFeature(features::kTextSuggestionsTouchBar);
+ if (@available(macOS 10.12.2, *)) {
+ EXPECT_NSEQ(nil, candidate_list_item());
+ SetTextInputType(tab_view(), ui::TEXT_INPUT_TYPE_PASSWORD);
+ EXPECT_NSEQ(nil, candidate_list_item());
+ SetTextInputType(tab_view(), ui::TEXT_INPUT_TYPE_TEXT);
+ EXPECT_NSNE(nil, candidate_list_item());
+ }
+}
+
+TEST_F(InputMethodMacTest, TouchBarTextSuggestionsReplacement) {
+ base::test::ScopedFeatureList feature_list;
+ feature_list.InitAndEnableFeature(features::kTextSuggestionsTouchBar);
+ if (@available(macOS 10.12.2, *)) {
+ base::scoped_nsobject<FakeSpellChecker> spellChecker(
+ [[FakeSpellChecker alloc] init]);
+ tab_cocoa_view().spellCheckerForTesting =
+ static_cast<NSSpellChecker*>(spellChecker.get());
+
+ SetTextInputType(tab_view(), ui::TEXT_INPUT_TYPE_TEXT);
+ EXPECT_NSNE(nil, candidate_list_item());
+
+ FakeTextCheckingResult* fakeResult =
+ [FakeTextCheckingResult resultWithRange:NSMakeRange(0, 3)
+ replacementString:@"foo"];
+
+ const base::string16 kOriginalString = base::UTF8ToUTF16("abcxxxghi");
+
+ // Change the selection once; requests completions from the spell checker.
+ tab_view()->SelectionChanged(kOriginalString, 3, gfx::Range(0, 0));
+
+ NSInteger firstSequenceNumber = [spellChecker sequenceNumber];
+ base::mac::ScopedBlock<void (^)(NSInteger sequenceNumber,
+ NSArray<NSTextCheckingResult*>* candidates)>
+ firstCompletionHandler([[spellChecker lastCompletionHandler] retain]);
+
+ EXPECT_NE(nil, (id)firstCompletionHandler.get());
+ EXPECT_EQ(0U, candidate_list_item().candidates.count);
+
+ // Instead of replying right away, change the selection again!
+ tab_view()->SelectionChanged(kOriginalString, 3, gfx::Range(3, 3));
+
+ EXPECT_NE(firstSequenceNumber, [spellChecker sequenceNumber]);
+
+ // Make sure that calling the stale completion handler is a no-op.
+ firstCompletionHandler.get()(
+ firstSequenceNumber,
+ @[ static_cast<NSTextCheckingResult*>(fakeResult) ]);
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(0U, candidate_list_item().candidates.count);
+
+ // But calling the current handler should work.
+ [spellChecker lastCompletionHandler](
+ [spellChecker sequenceNumber],
+ @[ static_cast<NSTextCheckingResult*>(fakeResult) ]);
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(1U, candidate_list_item().candidates.count);
+
+ base::RunLoop().RunUntilIdle();
+ MockWidgetInputHandler::MessageVector events =
+ host_->GetAndResetDispatchedMessages();
+ ASSERT_EQ("", GetMessageNames(events));
+
+ // Now, select that result.
+ [tab_cocoa_view() candidateListTouchBarItem:candidate_list_item()
+ endSelectingCandidateAtIndex:0];
+ base::RunLoop().RunUntilIdle();
+ events = widget_->GetAndResetDispatchedMessages();
+ ASSERT_EQ("CommitText", GetMessageNames(events));
+ }
+}
+
TEST_F(RenderWidgetHostViewMacTest, ClearCompositorFrame) {
BrowserCompositorMac* browser_compositor = rwhv_mac_->BrowserCompositor();
ui::Compositor* ui_compositor = browser_compositor->GetCompositor();
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index 13a53b4..50c8c00 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -3248,15 +3248,6 @@
focused_frame->GetFrameInputHandler()->SelectRange(base, extent);
}
-#if defined(OS_MACOSX)
-void WebContentsImpl::DidChangeTextSelection(const base::string16& text,
- const gfx::Range& range,
- size_t offset) {
- for (auto& observer : observers_)
- observer.DidChangeTextSelection(text, range, offset);
-}
-#endif
-
void WebContentsImpl::MoveCaret(const gfx::Point& extent) {
RenderFrameHostImpl* focused_frame = GetFocusedFrame();
if (!focused_frame)
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h
index 83f2875..ccd1485 100644
--- a/content/browser/web_contents/web_contents_impl.h
+++ b/content/browser/web_contents/web_contents_impl.h
@@ -729,11 +729,6 @@
const base::Optional<base::string16>& value) override;
void MoveRangeSelectionExtent(const gfx::Point& extent) override;
void SelectRange(const gfx::Point& base, const gfx::Point& extent) override;
-#if defined(OS_MACOSX)
- void DidChangeTextSelection(const base::string16& text,
- const gfx::Range& range,
- size_t offset) override;
-#endif
void MoveCaret(const gfx::Point& extent) override;
void AdjustSelectionByCharacterOffset(int start_adjust,
int end_adjust,
diff --git a/content/public/browser/render_widget_host_view.h b/content/public/browser/render_widget_host_view.h
index c662115..b691dd6 100644
--- a/content/public/browser/render_widget_host_view.h
+++ b/content/public/browser/render_widget_host_view.h
@@ -141,16 +141,6 @@
// Returns the currently selected text.
virtual base::string16 GetSelectedText() = 0;
- // Returns part of the text on the page which includes the selected text plus
- // possibly several characters before and after it.
- virtual base::string16 GetSurroundingText() = 0;
-
- // Returns the range of the selection in the page.
- virtual gfx::Range GetSelectedRange() = 0;
-
- // The offset of the surrounding text relative to the start of the total text.
- virtual size_t GetOffsetForSurroundingText() = 0;
-
// This only returns non-null on platforms that implement touch
// selection editing (TSE), currently Aura and (soon) Android.
// TODO(wjmaclean): update this comment when OOPIF TSE is implemented on
diff --git a/content/public/browser/web_contents_observer.h b/content/public/browser/web_contents_observer.h
index 89ff658d..3cb21f57 100644
--- a/content/public/browser/web_contents_observer.h
+++ b/content/public/browser/web_contents_observer.h
@@ -25,7 +25,6 @@
#include "third_party/skia/include/core/SkColor.h"
#include "ui/base/page_transition_types.h"
#include "ui/base/window_open_disposition.h"
-#include "ui/gfx/range/range.h"
namespace blink {
namespace mojom {
@@ -455,11 +454,6 @@
// Invoked when theme color is changed to |theme_color|.
virtual void DidChangeThemeColor(SkColor theme_color) {}
- // Invoked when text selection is changed.
- virtual void DidChangeTextSelection(const base::string16& text,
- const gfx::Range& range,
- size_t offset) {}
-
// Invoked when media is playing or paused. |id| is unique per player and per
// RenderFrameHost. There may be multiple players within a RenderFrameHost
// and subsequently within a WebContents. MediaStartedPlaying() will always
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc
index cc603a60..963de01 100644
--- a/content/public/common/content_features.cc
+++ b/content/public/common/content_features.cc
@@ -665,6 +665,10 @@
// entire life of the process.
const base::Feature kMacV2Sandbox{"MacV2Sandbox",
base::FEATURE_ENABLED_BY_DEFAULT};
+//
+// Enables the suggested text touch bar for autocomplete in textfields.
+const base::Feature kTextSuggestionsTouchBar{"TextSuggestionsTouchBar",
+ base::FEATURE_DISABLED_BY_DEFAULT};
#endif // defined(OS_MACOSX)
enum class VideoCaptureServiceConfiguration {
diff --git a/content/public/common/content_features.h b/content/public/common/content_features.h
index 874fc98f..95b77a7 100644
--- a/content/public/common/content_features.h
+++ b/content/public/common/content_features.h
@@ -161,6 +161,7 @@
CONTENT_EXPORT extern const base::Feature kDeviceMonitorMac;
CONTENT_EXPORT extern const base::Feature kIOSurfaceCapturer;
CONTENT_EXPORT extern const base::Feature kMacV2Sandbox;
+CONTENT_EXPORT extern const base::Feature kTextSuggestionsTouchBar;
#endif // defined(OS_MACOSX)
// DON'T ADD RANDOM STUFF HERE. Put it in the main section above in