1. 程式人生 > >谷歌瀏覽器的源碼分析 9

谷歌瀏覽器的源碼分析 9

void replace ces sting name reset flag href art

為了處理字符消息實現自動完成的功能,這是怎麽樣實現的呢?其實是先記錄字符消息響應前的字符串以及選中狀態,接著再處理消息,最後才查詢可能的輸入,做出智能提示。<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

#001 void AutocompleteEdit::OnBeforePossibleChange() {

#002 // Record our state.

記錄當前已經輸入的字符串。

#003 text_before_change_ = GetText();

記錄當前選中的字符位置。

#004 GetSelection(sel_before_change_);

#005 select_all_before_change_ = IsSelectAll(sel_before_change_);

#006 }

上面就保存字符消息響應前的狀態,接著下來就是消息響應後的處理了,如下:

#001 bool AutocompleteEdit::OnAfterPossibleChange() {

#002 // Prevent the user from selecting the "phantom newline" at the end of the

#003 // edit. If they try, we just silently move the end of the selection back to

#004 // the end of the real text.

判斷用戶新選中狀態。

#005 CHARRANGE new_sel;

#006 GetSelection(new_sel);

#007 const int length = GetTextLength();

#008 if ((new_sel.cpMin > length) || (new_sel.cpMax > length)) {

#009 if (new_sel.cpMin > length)

#010 new_sel.cpMin = length;

#011 if (new_sel.cpMax > length)

#012 new_sel.cpMax = length;

#013 SetSelectionRange(new_sel);

#014 }

判斷用戶是否輸入字符有變化。

#015 const bool selection_differs = (new_sel.cpMin != sel_before_change_.cpMin) ||

#016 (new_sel.cpMax != sel_before_change_.cpMax);

#017

#018 // See if the text or selection have changed since OnBeforePossibleChange().

#019 const std::wstring new_text(GetText());

#020 const bool text_differs = (new_text != text_before_change_);

#021

#022 // Update the paste state as appropriate: if we‘re just finishing a paste

#023 // that replaced all the text, preserve that information; otherwise, if we‘ve

#024 // made some other edit, clear paste tracking.

#025 if (paste_state_ == REPLACING_ALL)

#026 paste_state_ = REPLACED_ALL;

#027 else if (text_differs)

#028 paste_state_ = NONE;

#029

如果輸入沒有任何變化,就返回去。

#030 // If something has changed while the control key is down, prevent

#031 // "ctrl-enter" until the control key is released. When we do this, we need

#032 // to update the popup if it‘s open, since the desired_tld will have changed.

#033 if ((text_differs || selection_differs) &&

#034 (control_key_state_ == DOWN_WITHOUT_CHANGE)) {

#035 control_key_state_ = DOWN_WITH_CHANGE;

#036 if (!text_differs && !popup_->is_open())

#037 return false; // Don‘t open the popup for no reason.

#038 } else if (!text_differs &&

#039 (inline_autocomplete_text_.empty() || !selection_differs)) {

#040 return false;

#041 }

#042

#043 const bool had_keyword = !is_keyword_hint_ && !keyword_.empty();

#044

下面開始設置新的顯示字符串。

#045 // Modifying the selection counts as accepting the autocompleted text.

#046 InternalSetUserText(UserTextFromDisplayText(new_text));

#047 has_temporary_text_ = false;

#048

#049 if (text_differs) {

#050 // When the user has deleted text, don‘t allow inline autocomplete. Make

#051 // sure to not flag cases like selecting part of the text and then pasting

#052 // (or typing) the prefix of that selection. (We detect these by making

#053 // sure the caret, which should be after any insertion, hasn‘t moved

#054 // forward of the old selection start.)

#055 just_deleted_text_ = (text_before_change_.length() > new_text.length()) &&

#056 (new_sel.cpMin <= std::min(sel_before_change_.cpMin,

#057 sel_before_change_.cpMax));

#058

#059 // When the user doesn‘t have a selected keyword, deleting text or replacing

#060 // all of it with something else should reset the provider affinity. The

#061 // typical use case for deleting is that the user starts typing, sees that

#062 // some entry is close to what he wants, arrows to it, and then deletes some

#063 // unnecessary bit from the end of the string. In this case the user didn‘t

#064 // actually want "provider X", he wanted the string from that entry for

#065 // editing purposes, and he‘s no longer looking at the popup to notice that,

#066 // despite deleting some text, the action we‘ll take on enter hasn‘t changed

#067 // at all.

這裏刪除已經選擇的提示。

#068 if (!had_keyword && (just_deleted_text_ || select_all_before_change_)) {

#069 popup_->manually_selected_match_.Clear();

#070 }

#071 }

#072

#073 // Disable the fancy keyword UI if the user didn‘t already have a visible

#074 // keyword and is not at the end of the edit. This prevents us from showing

#075 // the fancy UI (and interrupting the user‘s editing) if the user happens to

#076 // have a keyword for ‘a‘, types ‘ab‘ then puts a space between the ‘a‘ and

#077 // the ‘b‘.

#078 disable_keyword_ui_ = (is_keyword_hint_ || keyword_.empty()) &&

#079 ((new_sel.cpMax != length) || (new_sel.cpMin != length));

#080

更新智能提示菜單。

#081 UpdatePopup();

#082

#083 if (!had_keyword && !is_keyword_hint_ && !keyword_.empty()) {

#084 // Went from no selected keyword to a selected keyword. Set the affinity to

#085 // the keyword provider. This forces the selected keyword to persist even

#086 // if the user deletes all the text.

#087 popup_->manually_selected_match_.Clear();

#088 popup_->manually_selected_match_.provider_affinity =

#089 popup_->autocomplete_controller()->keyword_provider();

#090 }

#091

當自動完成框字符串發生變化,就需要更新URL重點顯示。

#092 if (text_differs)

#093 TextChanged();

#094

#095 return true;

#096 }

在這個函數裏,先判斷字符串是否發生變化,然後根據變化來決定是否更新編輯框的顯示,同時還需要UpdatePopup更新智能提示菜單,最後判斷是否有一個URL地址,如果有就重點顯示出來。

其實這裏最關鍵的問題就是智能菜單的數據從那裏來的呢?怎麽樣根據用戶的輸入查找到最合適的提示呢?下一次我們再來分析這方面的問題。

再分享一下我老師大神的人工智能教程吧。零基礎!通俗易懂!風趣幽默!還帶黃段子!希望你也加入到我們人工智能的隊伍中來!https://blog.csdn.net/jiangjunshow

谷歌瀏覽器的源碼分析 9