1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef COMPONENTS_OMNIBOX_BROWSER_OMNIBOX_EDIT_MODEL_H_
6 #define COMPONENTS_OMNIBOX_BROWSER_OMNIBOX_EDIT_MODEL_H_
7 
8 #include <stddef.h>
9 
10 #include <memory>
11 
12 #include "base/compiler_specific.h"
13 #include "base/strings/string16.h"
14 #include "base/time/time.h"
15 #include "components/omnibox/browser/autocomplete_controller.h"
16 #include "components/omnibox/browser/autocomplete_input.h"
17 #include "components/omnibox/browser/autocomplete_match.h"
18 #include "components/omnibox/browser/omnibox_controller.h"
19 #include "components/omnibox/browser/omnibox_view.h"
20 #include "components/omnibox/common/omnibox_focus_state.h"
21 #include "third_party/metrics_proto/omnibox_event.pb.h"
22 #include "ui/base/window_open_disposition.h"
23 #include "ui/gfx/native_widget_types.h"
24 #include "url/gurl.h"
25 
26 class AutocompleteResult;
27 class OmniboxClient;
28 class OmniboxEditController;
29 class OmniboxPopupModel;
30 class OmniboxView;
31 
32 namespace gfx {
33 class Image;
34 }
35 
36 class OmniboxEditModel {
37  public:
38   struct State {
39     State(bool user_input_in_progress,
40           const base::string16& user_text,
41           const base::string16& keyword,
42           bool is_keyword_hint,
43           metrics::OmniboxEventProto::KeywordModeEntryMethod
44               keyword_mode_entry_method,
45           OmniboxFocusState focus_state,
46           OmniboxFocusSource focus_source,
47           const AutocompleteInput& autocomplete_input);
48     State(const State& other);
49     ~State();
50     State& operator=(const State&) = delete;
51 
52     bool user_input_in_progress;
53     const base::string16 user_text;
54     const base::string16 keyword;
55     const bool is_keyword_hint;
56     metrics::OmniboxEventProto::KeywordModeEntryMethod
57         keyword_mode_entry_method;
58     OmniboxFocusState focus_state;
59     OmniboxFocusSource focus_source;
60     const AutocompleteInput autocomplete_input;
61   };
62 
63   OmniboxEditModel(OmniboxView* view,
64                    OmniboxEditController* controller,
65                    std::unique_ptr<OmniboxClient> client);
66   virtual ~OmniboxEditModel();
67   OmniboxEditModel(const OmniboxEditModel&) = delete;
68   OmniboxEditModel& operator=(const OmniboxEditModel&) = delete;
69 
70   // TODO(jdonnelly): Remove this accessor when the AutocompleteController has
71   //     completely moved to OmniboxController.
autocomplete_controller()72   AutocompleteController* autocomplete_controller() const {
73     return omnibox_controller_->autocomplete_controller();
74   }
75 
set_popup_model(OmniboxPopupModel * popup_model)76   void set_popup_model(OmniboxPopupModel* popup_model) {
77     omnibox_controller_->set_popup_model(popup_model);
78   }
79 
80   // TODO(jdonnelly): The edit and popup should be siblings owned by the
81   // LocationBarView, making this accessor unnecessary.
82   // NOTE: popup_model() can be NULL for testing.
popup_model()83   OmniboxPopupModel* popup_model() const {
84     return omnibox_controller_->popup_model();
85   }
86 
controller()87   OmniboxEditController* controller() const { return controller_; }
88 
client()89   OmniboxClient* client() const { return client_.get(); }
90 
91   metrics::OmniboxEventProto::PageClassification GetPageClassification() const;
92 
93   // Returns the current state.  This assumes we are switching tabs, and changes
94   // the internal state appropriately.
95   State GetStateForTabSwitch() const;
96 
97   // Resets the tab state, then restores local state from |state|. |state| may
98   // be nullptr if there is no saved state.
99   void RestoreState(const State* state);
100 
101   // Returns the match for the current text. If the user has not edited the text
102   // this is the match corresponding to the permanent text. Returns the
103   // alternate nav URL, if |alternate_nav_url| is non-NULL and there is such a
104   // URL. Virtual for testing.
105   virtual AutocompleteMatch CurrentMatch(GURL* alternate_nav_url) const;
106 
107   // Called when the user wants to export the entire current text as a URL.
108   // Sets the url, and if known, the title and favicon.
109   void GetDataForURLExport(GURL* url,
110                            base::string16* title,
111                            gfx::Image* favicon);
112 
113   // Returns true if the current edit contents will be treated as a
114   // URL/navigation, as opposed to a search.
115   bool CurrentTextIsURL() const;
116 
117   // Adjusts the copied text before writing it to the clipboard. If the copied
118   // text is a URL with the scheme elided, this method reattaches the scheme.
119   // Copied text that looks like a search query will not be modified.
120   //
121   // |sel_min| gives the minimum of the selection, e.g. min(sel_start, sel_end).
122   // |text| is the currently selected text, and may be modified by this method.
123   // |url_from_text| is the GURL interpretation of the selected text, and may
124   // be used for drag-and-drop models or writing hyperlink data types to
125   // system clipboards.
126   //
127   // If the copied text is interpreted as a URL:
128   //  - |write_url| is set to true.
129   //  - |url_from_text| is set to the URL.
130   //  - |text| is set to the URL's spec. The output will be pure ASCII and
131   //    %-escaped, since canonical URLs are always encoded to ASCII.
132   //
133   // If the copied text is *NOT* interpreted as a URL:
134   //  - |write_url| is set to false.
135   //  - |url_from_text| may be modified, but might not contain a valid GURL.
136   //  - |text| is full UTF-16 and not %-escaped. This is because we are not
137   //    interpreting |text| as a URL, so we leave the Unicode characters as-is.
138   void AdjustTextForCopy(int sel_min,
139                          base::string16* text,
140                          GURL* url_from_text,
141                          bool* write_url);
142 
user_input_in_progress()143   bool user_input_in_progress() const { return user_input_in_progress_; }
144 
145   // Encapsulates all the varied conditions for whether to override the
146   // permanent page icon (associated with the currently displayed page),
147   // with a temporary icon (associated with the current match or user text).
148   bool ShouldShowCurrentPageIcon() const;
149 
150   // Sets the state of user_input_in_progress_, and notifies the observer if
151   // that state has changed.
152   void SetInputInProgress(bool in_progress);
153 
154   // Calls SetInputInProgress, via SetInputInProgressNoNotify and
155   // NotifyObserversInputInProgress, calling the latter after
156   // StartAutocomplete, so that the result is only updated once.
157   void UpdateInput(bool has_selected_text,
158                    bool prevent_inline_autocomplete);
159 
160   // Resets the permanent display texts (display_text_ and url_for_editing_)
161   // to those provided by the controller. Returns true if the display texts
162   // have changed and the change should be immediately user-visible, because
163   // either the user is not editing or the edit does not have focus.
164   bool ResetDisplayTexts();
165 
166   // Returns the permanent display text for the current page and Omnibox state.
167   base::string16 GetPermanentDisplayText() const;
168 
169   // Sets the user_text_ to |text|. Also enters user-input-in-progress mode.
170   void SetUserText(const base::string16& text);
171 
172   // If the omnibox is currently displaying elided text, this method will
173   // restore the full URL into the user text. After unelision, this selects-all,
174   // enters user-input-in-progress mode, and then returns true.
175   //
176   // If the omnibox is not currently displaying elided text, this method will
177   // no-op and return false.
178   bool Unelide();
179 
180   // Invoked any time the text may have changed in the edit. Notifies the
181   // controller.
182   void OnChanged();
183 
184   // Reverts the edit model back to its unedited state (permanent text showing,
185   // no user input in progress).
186   void Revert();
187 
188   // Directs the popup to start autocomplete.  Makes use of the |view_| text and
189   // selection, so make sure to set those before calling StartAutocomplete().
190   void StartAutocomplete(bool has_selected_text,
191                          bool prevent_inline_autocomplete);
192 
193   // Closes the popup and cancels any pending asynchronous queries.
194   void StopAutocomplete();
195 
196   // Determines whether the user can "paste and go", given the specified text.
197   bool CanPasteAndGo(const base::string16& text) const;
198 
199   // Navigates to the destination last supplied to CanPasteAndGo.
200   void PasteAndGo(
201       const base::string16& text,
202       base::TimeTicks match_selection_timestamp = base::TimeTicks());
203 
204   // Sets |match| and |alternate_nav_url| based on classifying |text|.
205   // |alternate_nav_url| may be nullptr.
206   void ClassifyString(const base::string16& text,
207                       AutocompleteMatch* match,
208                       GURL* alternate_nav_url) const;
209 
210   // Asks the browser to load the popup's currently selected item, using the
211   // supplied disposition.  This may close the popup.
212   void AcceptInput(
213       WindowOpenDisposition disposition,
214       base::TimeTicks match_selection_timestamp = base::TimeTicks());
215 
216   // Executes the |pedal| associated with given match.
217   void ExecutePedal(const AutocompleteMatch& match,
218                     base::TimeTicks match_selection_timestamp);
219 
220   // Asks the browser to load |match|. |index| is only used for logging, and
221   // can be kNoMatch if the popup was closed, or if none of the suggestions
222   // in the popup were used (in the unusual no-default-match case). In that
223   // case, an artificial result set with only |match| will be logged.
224   //
225   // OpenMatch() needs to know the original text that drove this action.  If
226   // |pasted_text| is non-empty, this is a Paste-And-Go/Search action, and
227   // that's the relevant input text.  Otherwise, the relevant input text is
228   // either the user text or the display URL, depending on if user input is
229   // in progress.
230   //
231   // |match| is passed by value for two reasons:
232   // (1) This function needs to modify |match|, so a const ref isn't
233   //     appropriate.  Callers don't actually care about the modifications, so a
234   //     pointer isn't required.
235   // (2) The passed-in match is, on the caller side, typically coming from data
236   //     associated with the popup.  Since this call can close the popup, that
237   //     could clear that data, leaving us with a pointer-to-garbage.  So at
238   //     some point someone needs to make a copy of the match anyway, to
239   //     preserve it past the popup closure.
240   void OpenMatch(AutocompleteMatch match,
241                  WindowOpenDisposition disposition,
242                  const GURL& alternate_nav_url,
243                  const base::string16& pasted_text,
244                  size_t index,
245                  base::TimeTicks match_selection_timestamp = base::TimeTicks());
246 
focus_state()247   OmniboxFocusState focus_state() const { return focus_state_; }
has_focus()248   bool has_focus() const { return focus_state_ != OMNIBOX_FOCUS_NONE; }
249 
250   // This is the same as when the Omnibox is visibly focused.
is_caret_visible()251   bool is_caret_visible() const {
252     return focus_state_ == OMNIBOX_FOCUS_VISIBLE;
253   }
254 
focus_source()255   OmniboxFocusSource focus_source() const { return focus_source_; }
set_focus_source(OmniboxFocusSource focus_source)256   void set_focus_source(OmniboxFocusSource focus_source) {
257     focus_source_ = focus_source;
258   }
259 
260   // Accessors for keyword-related state (see comments on keyword_ and
261   // is_keyword_hint_).
keyword()262   const base::string16& keyword() const { return keyword_; }
is_keyword_hint()263   bool is_keyword_hint() const { return is_keyword_hint_; }
is_keyword_selected()264   bool is_keyword_selected() const {
265     return !is_keyword_hint_ && !keyword_.empty();
266   }
267 
268   // A stronger version of is_keyword_selected(), which depends on there
269   // being input after the keyword.
270   bool InExplicitExperimentalKeywordMode();
271 
272   // Accepts the current keyword hint as a keyword. It always returns true for
273   // caller convenience. |entry_method| indicates how the user entered
274   // keyword mode.
275   bool AcceptKeyword(
276       metrics::OmniboxEventProto::KeywordModeEntryMethod entry_method);
277 
278   // Sets the current keyword to that of the user's default search provider and
279   // updates the view so the user sees the keyword chip in the omnibox.  Adjusts
280   // user_text_ and the selection based on the display text and the keyword
281   // entry method.
282   void EnterKeywordModeForDefaultSearchProvider(
283       metrics::OmniboxEventProto::KeywordModeEntryMethod entry_method);
284 
285   // Accepts the current temporary text as the user text.
286   void AcceptTemporaryTextAsUserText();
287 
288   // Clears the current keyword.
289   void ClearKeyword();
290 
291   // Returns the current autocomplete result.  This logic should in the future
292   // live in AutocompleteController but resides here for now.  This method is
293   // used by AutomationProvider::AutocompleteEditGetMatches.
result()294   const AutocompleteResult& result() const {
295     return omnibox_controller_->result();
296   }
297 
298   // Called when the view is gaining focus.  |control_down| is whether the
299   // control key is down (at the time we're gaining focus).
300   void OnSetFocus(bool control_down);
301 
302   // Starts a request for zero-prefix suggestions if no query is currently
303   // running and the popup is closed. This can be called multiple times without
304   // harm, since it will early-exit if an earlier request is in progress or
305   // done.
306   void StartZeroSuggestRequest(bool user_clobbered_permanent_text = false);
307 
308   // Sets the visibility of the caret in the omnibox, if it has focus. The
309   // visibility of the caret is reset to visible if either
310   //   - The user starts typing, or
311   //   - We explicitly focus the omnibox again.
312   // The latter case must be handled in three separate places--OnSetFocus(),
313   // OmniboxView::SetFocus(), and the mouse handlers in OmniboxView. See
314   // accompanying comments for why each of these is necessary.
315   //
316   // Caret visibility is tracked per-tab and updates automatically upon
317   // switching tabs.
318   void SetCaretVisibility(bool visible);
319 
320   // If the ctrl key is down, marks it as consumed to prevent it from triggering
321   // ctrl-enter behavior unless it is released and re-pressed.
322   void ConsumeCtrlKey();
323 
324   // Sent before |OnKillFocus| and before the popup is closed.
325   void OnWillKillFocus();
326 
327   // Called when the view is losing focus.  Resets some state.
328   void OnKillFocus();
329 
330   // Returns whether the omnibox will handle a press of the escape key.  The
331   // caller can use this to decide whether the browser should process escape as
332   // "stop current page load".
333   bool WillHandleEscapeKey() const;
334 
335   // Called when the user presses the escape key.  Decides what, if anything, to
336   // revert about any current edits.  Returns whether the key was handled.
337   bool OnEscapeKeyPressed();
338 
339   // Called when the user presses or releases the control key.  Changes state as
340   // necessary.
341   void OnControlKeyChanged(bool pressed);
342 
343   // Called when the user pastes in text.
344   void OnPaste();
345 
346   // Returns true if pasting is in progress.
is_pasting()347   bool is_pasting() const { return paste_state_ == PASTING; }
348 
349   // Called when the user presses up or down.  |count| is a repeat count,
350   // negative for moving up, positive for moving down. Virtual for testing.
351   virtual void OnUpOrDownKeyPressed(int count);
352 
353   // If no query is in progress, starts working on an autocomplete query.
354   // Returns true if started; false otherwise.
355   bool MaybeStartQueryForPopup();
356 
357   // Called when any relevant data changes.  This rolls together several
358   // separate pieces of data into one call so we can update all the UI
359   // efficiently. Specifically, it's invoked for temporary text, autocompletion,
360   // and keyword changes.
361   //   |temporary_text| is the new temporary text from the user selecting a
362   //   different match. This will be empty when selecting a suggestion
363   //   without a |fill_into_edit| (e.g. FOCUSED_BUTTON_HEADER) and when
364   //   |is_temporary_test| is false.
365   //   |is_temporary_text| is true if invoked because of a temporary text change
366   //     or false if |temporary_text| should be ignored.
367   //   |inline_autocompletion|, |prefix_autocompletion|, and
368   //     |split_autocompletion| are the autocompletion.
369   //   |destination_for_temporary_text_change| is NULL (if temporary text should
370   //     not change) or the pre-change destination URL (if temporary text should
371   //     change) so we can save it off to restore later.
372   //   |keyword| is the keyword to show a hint for if |is_keyword_hint| is true,
373   //     or the currently selected keyword if |is_keyword_hint| is false (see
374   //     comments on keyword_ and is_keyword_hint_).
375   //   |additional_text| is additional omnibox text to be displayed adjacent to
376   //     the omnibox view.
377   // Virtual to allow testing.
378   virtual void OnPopupDataChanged(
379       const base::string16& temporary_text,
380       bool is_temporary_text,
381       const base::string16& inline_autocompletion,
382       const base::string16& prefix_autocompletion,
383       const SplitAutocompletion& split_autocompletion,
384       const base::string16& keyword,
385       bool is_keyword_hint,
386       const base::string16& additional_text);
387 
388   // Called by the OmniboxView after something changes, with details about what
389   // state changes occurred.  Updates internal state, updates the popup if
390   // necessary, and returns true if any significant changes occurred.  Note that
391   // |text_change.text_differs| may be set even if |text_change.old_text| ==
392   // |text_change.new_text|, e.g. if we've just committed an IME composition.
393   //
394   // If |allow_keyword_ui_change| is false then the change should not affect
395   // keyword ui state, even if the text matches a keyword exactly. This value
396   // may be false when the user is composing a text with an IME.
397   bool OnAfterPossibleChange(const OmniboxView::StateChanges& state_changes,
398                              bool allow_keyword_ui_change);
399 
400   // Called when the current match has changed in the OmniboxController.
401   void OnCurrentMatchChanged();
402 
403   // Used for testing purposes only.
GetUserTextForTesting()404   base::string16 GetUserTextForTesting() const { return user_text_; }
405 
406   // Name of the histogram tracking cut or copy omnibox commands.
407   static const char kCutOrCopyAllTextHistogram[];
408 
409   // Just forwards the call to the OmniboxView referred within.
410   void SetAccessibilityLabel(const AutocompleteMatch& match);
411 
412   // Reverts the edit box from a temporary text back to the original user text.
413   // Also resets the popup to the initial state.
414   void RevertTemporaryTextAndPopup();
415 
416   // Returns whether to prevent elision of the display URL.
417   bool ShouldPreventElision() const;
418 
419  private:
420   friend class OmniboxControllerTest;
421   FRIEND_TEST_ALL_PREFIXES(OmniboxEditModelTest, ConsumeCtrlKey);
422   FRIEND_TEST_ALL_PREFIXES(OmniboxEditModelTest, ConsumeCtrlKeyOnRequestFocus);
423   FRIEND_TEST_ALL_PREFIXES(OmniboxEditModelTest, ConsumeCtrlKeyOnCtrlAction);
424 
425   enum PasteState {
426     NONE,           // Most recent edit was not a paste.
427     PASTING,        // In the middle of doing a paste. We need this intermediate
428                     // state because OnPaste() does the actual detection of
429                     // paste, but OnAfterPossibleChange() has to update the
430                     // paste state for every edit. If OnPaste() set the state
431                     // directly to PASTED, OnAfterPossibleChange() wouldn't know
432                     // whether that represented the current edit or a past one.
433     PASTED,         // Most recent edit was a paste.
434   };
435 
436   enum ControlKeyState {
437     UP,                // The control key is not depressed.
438     DOWN,              // The control key is depressed and should trigger the
439                        // "ctrl-enter" behavior when the user hits enter.
440     DOWN_AND_CONSUMED  // The control key is depressed, but has been consumed
441                        // and should not trigger the "ctrl-enter" behavior.
442                        // The control key becomes consumed if it has been used
443                        // for another action such as focusing the location bar
444                        // with ctrl-l or copying the selected text with ctrl-c.
445   };
446 
447   // Returns true if a query to an autocomplete provider is currently
448   // in progress.  This logic should in the future live in
449   // AutocompleteController but resides here for now.  This method is used by
450   // AutomationProvider::AutocompleteEditIsQueryInProgress.
query_in_progress()451   bool query_in_progress() const { return !autocomplete_controller()->done(); }
452 
453   // Returns true if the popup exists and is open.  (This is a convenience
454   // wrapper for the benefit of test code, which may not have a popup model.)
455   // Virtual for testing.
456   virtual bool PopupIsOpen() const;
457 
458   // An internal method to set the user text. Notably, this differs from
459   // SetUserText because it does not change the user-input-in-progress state.
460   void InternalSetUserText(const base::string16& text);
461 
462   // Conversion between user text and display text. User text is the text the
463   // user has input. Display text is the text being shown in the edit. The
464   // two are different if a keyword is selected.
465   base::string16 MaybeStripKeyword(const base::string16& text) const;
466   base::string16 MaybePrependKeyword(const base::string16& text) const;
467 
468   // Copies a match corresponding to the current text into |match|, and
469   // populates |alternate_nav_url| as well if it's not nullptr. If the popup
470   // is closed, the match is generated from the autocomplete classifier.
471   void GetInfoForCurrentText(AutocompleteMatch* match,
472                              GURL* alternate_nav_url) const;
473 
474   // Accepts current keyword if the user just typed a space at the end of
475   // |new_text|.  This handles both of the following cases:
476   //   (assume "foo" is a keyword, | is the input caret, [] is selected text)
477   //   foo| -> foo |      (a space was appended to a keyword)
478   //   foo[bar] -> foo |  (a space replaced other text after a keyword)
479   // Returns true if the current keyword is accepted.
480   bool MaybeAcceptKeywordBySpace(const base::string16& new_text);
481 
482   // Checks whether the user inserted a space into |old_text| and by doing so
483   // created a |new_text| that looks like "<keyword> <search phrase>".
484   bool CreatedKeywordSearchByInsertingSpaceInMiddle(
485       const base::string16& old_text,
486       const base::string16& new_text,
487       size_t caret_position) const;
488 
489   // Checks if a given character is a valid space character for accepting
490   // keyword.
491   static bool IsSpaceCharForAcceptingKeyword(wchar_t c);
492 
493   // Sets the state of user_input_in_progress_. Returns whether said state
494   // changed, so that the caller can evoke NotifyObserversInputInProgress().
495   bool SetInputInProgressNoNotify(bool in_progress);
496 
497   // Notifies the observers that the state has changed.
498   void NotifyObserversInputInProgress(bool in_progress);
499 
500   // If focus_state_ does not match |state|, we update it and notify the
501   // InstantController about the change (passing along the |reason| for the
502   // change). If the caret visibility changes, we call ApplyCaretVisibility() on
503   // the view.
504   void SetFocusState(OmniboxFocusState state, OmniboxFocusChangeReason reason);
505 
506   // NOTE: |client_| must outlive |omnibox_controller_|, as the latter has a
507   // reference to the former.
508   std::unique_ptr<OmniboxClient> client_;
509 
510   std::unique_ptr<OmniboxController> omnibox_controller_;
511 
512   OmniboxView* view_;
513 
514   OmniboxEditController* controller_;
515 
516   OmniboxFocusState focus_state_;
517 
518   // Used to keep track whether the input currently in progress originated by
519   // focusing in the Omnibox, Fakebox or Search button. This will be INVALID if
520   // no input is in progress or the Omnibox is not focused.
521   OmniboxFocusSource focus_source_ = OmniboxFocusSource::INVALID;
522 
523   // Display-only text representing the current page. This could either:
524   //  - The same as |url_for_editing_| if Steady State Elisions is OFF.
525   //  - A simplified version of |url_for_editing_| with some destructive
526   //    elisions applied. This is the case if Steady State Elisions is ON.
527   //
528   // This should not be considered suitable for editing.
529   base::string16 display_text_;
530 
531   // The initial text representing the current URL suitable for editing.
532   // This should fully represent the current URL without any meaning-changing
533   // elisions applied - and is suitable for user editing.
534   base::string16 url_for_editing_;
535 
536   // This flag is true when the user has modified the contents of the edit, but
537   // not yet accepted them.  We use this to determine when we need to save
538   // state (on switching tabs) and whether changes to the page URL should be
539   // immediately displayed.
540   // This flag will be true in a superset of the cases where the popup is open.
541   bool user_input_in_progress_;
542 
543   // The text that the user has entered.  This does not include inline
544   // autocomplete text that has not yet been accepted.  |user_text_| can
545   // contain a string without |user_input_in_progress_| being true.
546   // For instance, this is the case when the user has unelided a URL without
547   // modifying its contents.
548   base::string16 user_text_;
549 
550   // We keep track of when the user last focused on the omnibox.
551   base::TimeTicks last_omnibox_focus_;
552 
553   // Whether any user input has occurred since focusing on the omnibox. This is
554   // used along with |last_omnibox_focus_| to calculate the time between a user
555   // focusing on the omnibox and editing. It is initialized to true since
556   // there was no focus event.
557   bool user_input_since_focus_;
558 
559   // Indicates whether the current interaction with the Omnibox resulted in
560   // navigation (true), or user leaving the omnibox without taking any action
561   // (false).
562   // The value is initialized when the Omnibox receives focus and available for
563   // use when the focus is about to be cleared.
564   bool focus_resulted_in_navigation_;
565 
566   // We keep track of when the user began modifying the omnibox text.
567   // This should be valid whenever user_input_in_progress_ is true.
568   base::TimeTicks time_user_first_modified_omnibox_;
569 
570   // When the user closes the popup, we need to remember the URL for their
571   // desired choice, so that if they hit enter without reopening the popup we
572   // know where to go.  We could simply rerun autocomplete in this case, but
573   // we'd need to either wait for all results to come in (unacceptably slow) or
574   // do the wrong thing when the user had chosen some provider whose results
575   // were not returned instantaneously.
576   //
577   // This variable is only valid when user_input_in_progress_ is true, since
578   // when it is false the user has either never input anything (so there won't
579   // be a value here anyway) or has canceled their input, which should be
580   // treated the same way.  Also, since this is for preserving a desired URL
581   // after the popup has been closed, we ignore this if the popup is open, and
582   // simply ask the popup for the desired URL directly.  As a result, the
583   // contents of this variable only need to be updated when the popup is closed
584   // but user_input_in_progress_ is not being cleared.
585   base::string16 url_for_remembered_user_selection_;
586 
587   // Inline autocomplete is allowed if the user has not just deleted text, and
588   // no temporary text is showing.  In this case, inline_autocompletion_ is
589   // appended to the user_text_ and displayed selected (at least initially).
590   //
591   // NOTE: When the popup is closed there should never be inline autocomplete
592   // text (actions that close the popup should either accept the text, convert
593   // it to a normal selection, or change the edit entirely).
594   bool just_deleted_text_;
595   base::string16 inline_autocompletion_;
596   base::string16 prefix_autocompletion_;
597   SplitAutocompletion split_autocompletion_;
598 
599   // Used by OnPopupDataChanged to keep track of whether there is currently a
600   // temporary text.
601   //
602   // Example of use: If the user types "goog", then arrows down in the
603   // autocomplete popup until, say, "google.com" appears in the edit box, then
604   // the user_text_ is still "goog", and "google.com" is "temporary text".
605   // When the user hits <esc>, the edit box reverts to "goog".  Hit <esc> again
606   // and the popup is closed and "goog" is replaced by the permanent display
607   // URL, which is the URL of the current page.
608   //
609   // original_user_text_with_keyword_ tracks the user_text_ before keywords are
610   // removed. When accepting a keyword (from either a default match or another
611   // lower in the dropdown), the user_text_ is destructively trimmed of its 1st
612   // word. In order to restore the user_text_ properly when the omnibox reverts,
613   // e.g. by pressing <escape> or pressing <up> until the first result is
614   // selected, we track original_user_text_with_keyword_.
615   // original_user_text_with_keyword_ is null if a keyword has not been
616   // accepted.
617   bool has_temporary_text_;
618   base::string16 original_user_text_with_keyword_;
619 
620   // When the user's last action was to paste, we disallow inline autocomplete
621   // (on the theory that the user is trying to paste in a new URL or part of
622   // one, and in either case inline autocomplete would get in the way).
623   PasteState paste_state_;
624 
625   // Whether the control key is depressed.  We track this to avoid calling
626   // UpdatePopup() repeatedly if the user holds down the key, and to know
627   // whether to trigger "ctrl-enter" behavior.
628   ControlKeyState control_key_state_;
629 
630   // The keyword associated with the current match.  The user may have an actual
631   // selected keyword, or just some input text that looks like a keyword (so we
632   // can show a hint to press <tab>).  This is the keyword in either case;
633   // is_keyword_hint_ (below) distinguishes the two cases.
634   base::string16 keyword_;
635 
636   // True if the keyword associated with this match is merely a hint, i.e. the
637   // user hasn't actually selected a keyword yet.  When this is true, we can use
638   // keyword_ to show a "Press <tab> to search" sort of hint.
639   bool is_keyword_hint_;
640 
641   // Indicates how the user entered keyword mode if the user is actually in
642   // keyword mode.  Otherwise, the value of this variable is INVALID.  This
643   // is used to restore the user's search terms upon a call to ClearKeyword().
644   metrics::OmniboxEventProto::KeywordModeEntryMethod keyword_mode_entry_method_;
645 
646   // This is needed to properly update the SearchModel state when the user
647   // presses escape.
648   bool in_revert_;
649 
650   // Indicates if the upcoming autocomplete search is allowed to be treated as
651   // an exact keyword match.  If this is true then keyword mode will be
652   // triggered automatically if the input is "<keyword> <search string>".  We
653   // allow this when CreatedKeywordSearchByInsertingSpaceInMiddle() is true.
654   // This has no effect if we're already in keyword mode.
655   bool allow_exact_keyword_match_;
656 
657   // The input that was sent to the AutocompleteController. Since no
658   // autocomplete query is started after a tab switch, it is possible for this
659   // |input_| to differ from the one currently stored in AutocompleteController.
660   AutocompleteInput input_;
661 };
662 
663 #endif  // COMPONENTS_OMNIBOX_BROWSER_OMNIBOX_EDIT_MODEL_H_
664