上一次說到需要調用這個
OpenURLFromTab
函數,那么這個函數是做什么的呢?從名稱上可能猜到它是打開網頁,但是是從目前
TAB
頁里打開呢?還是新建一個?或者使用每個
TAB
頁一個進程呢?這些疑惑,只能通過代碼的分析來理解它的實現,代碼如下:
這個函數的參數意思:
source
是
TAB
內容。
url
是網絡連接地址。
disposition
是窗口打開的位置。
transition
是連接傳送的類型。
override_encoding
是編碼類型。
#001
?
void Browser::OpenURLFromTab(TabContents* source,
#002
??????????????????????????????
const GURL& url,
#003
??????????????????????????????
WindowOpenDisposition disposition,
#004
??????????????????????????????
PageTransition::Type transition,
#005
??????????????????????????????
const std::string& override_encoding) {
調試時檢查代碼。
#006
???
// No code for these yet
#007
???
DCHECK((disposition != NEW_POPUP) && (disposition != SAVE_TO_DISK));
#008
?
獲取當前的
TAB
頁。
#009
???
TabContents* current_tab = source ? source : GetSelectedTabContents();
判斷是否當前
TAB
頁選中。
#010
???
bool source_tab_was_frontmost = (current_tab == GetSelectedTabContents());
#011
???
TabContents* new_contents = NULL;
#012
?
#013
???
// If the URL is part of the same web site, then load it in the same
#014
???
// SiteInstance (and thus the same process).
?
This is an optimization to
#015
???
// reduce process overhead; it is not necessary for compatibility.
?
(That is,
#016
???
// the new tab will not have script connections to the previous tab, so it
#017
??
?
// does not need to be part of the same SiteInstance or BrowsingInstance.)
#018
???
// Default to loading in a new SiteInstance and BrowsingInstance.
#019
???
// TODO(creis): should this apply to applications?
保存打開連接的實例指針。
#020
???
SiteInstance* instance = NULL;
如果不使用每個
TAB
頁一個進程的方式,就不需要進行下面的處理。因為同一個連接在一個進程里打開是比較快,這里主要做優化。
#021
???
// Don't use this logic when "--process-per-tab" is specified.
判斷是否有每一個
TAB
一個進程的方式。
#022
???
if (!CommandLine().HasSwitch(switches::kProcessPerTab)) {
有當前進程頁。
#023
?????
if (current_tab) {
#024
???????
const WebContents* const web_contents = current_tab->AsWebContents();
判斷是否相同的網絡連接地址。
#025
???????
if (web_contents) {
#026
?????????
const GURL& current_url = web_contents->GetURL();
如果相同的網絡地址,并且有實例打開,就返回這個實例在
instance
。
#027
?????????
if (SiteInstance::IsSameWebSite(current_url, url))
#028
???????????
instance = web_contents->site_instance();
#029
???????
}
#030
?????
}
#031
???
}
#032
?
#033
???
// If this is an application we can only have one tab so a new tab always
#034
???
// goes into a tabbed browser window.
下面進行不打開新窗口的處理。
#035
???
if (disposition != NEW_WINDOW && type_ == BrowserType::APPLICATION) {
#036
?????
// If the disposition is OFF_THE_RECORD we don't want to create a new
#037
?????
// browser that will itself create another OTR browser. This will result in
#038
?????
// a browser leak (and crash below because no tab is created or selected).
#039
?????
if (disposition == OFF_THE_RECORD) {
#040
???
????
OpenURLOffTheRecord(profile_, url);
#041
???????
return;
#042
?????
}
#043
?
#044
?????
Browser* b = GetOrCreateTabbedBrowser();
#045
?????
DCHECK(b);
#046
?
#047
?????
// If we have just created a new browser window, make sure we select the
#048
?????
// tab.
#049
?????
if (b->tab_count() == 0 && disposition == NEW_BACKGROUND_TAB)
#050
???????
disposition = NEW_FOREGROUND_TAB;
#051
?
#052
?????
b->OpenURL(url, disposition, transition);
#053
?????
b->Show();
#054
?????
b->MoveToFront(true);
#055
?????
return;
#056
???
}
#057
?
#058
???
if (profile_->IsOffTheRecord() && disposition == OFF_THE_RECORD)
#059
?????
disposition = NEW_FOREGROUND_TAB;
#060
?
這里開始處理打開一個新窗口顯示網絡連接。
#061
???
if (disposition == NEW_WINDOW) {
創建一個新的
Browser
瀏覽器對象。
#062
?????
Browser* new_browser = new Browser(gfx::Rect(), SW_SHOWNORMAL, profile_,
#063
????????????????????????????????????????
BrowserType::TABBED_BROWSER, L"");
創建一個
TAB
內容。
#064
?????
new_contents = new_browser->AddTabWithURL(url, transition, true, instance);
這里開始顯示這個網絡連接的內容。
#065
?????
new_browser->Show();
#066
???
} else if ((disposition == CURRENT_TAB) && current_tab) {
下面開始在當前
TAB
頁里打開連接,同時判斷處理的類型。
#067
?????
if (transition == PageTransition::TYPED ||
#068
?????????
transition == PageTransition::AUTO_BOOKMARK ||
#069
?????????
transition == PageTransition::GENERATED ||
#070
?????????
transition == PageTransition::START_PAGE) {
#071
??????
?
// Don't forget the openers if this tab is a New Tab page opened at the
#072
???????
// end of the TabStrip (e.g. by pressing Ctrl+T). Give the user one
#073
???????
// navigation of one of these transition types before resetting the
#074
???????
// opener relationships (this allows for the use case of opening a new
#075
???????
// tab to do a quick look-up of something while viewing a tab earlier in
#076
???????
// the strip). We can make this heuristic more permissive if need be.
#077
???????
// TODO(beng): (http://b/1306495) write unit tests for this once this
#078
???????
//
????????????
object is unit-testable.
#079
???????
int current_tab_index =
#080
???????????
tabstrip_model_.GetIndexOfTabContents(current_tab);
#081
???????
bool forget_openers =
#082
???????
????
!(current_tab->type() == TAB_CONTENTS_NEW_TAB_UI &&
#083
???????????
current_tab_index == (tab_count() - 1) &&
#084
???????????
current_tab->controller()->GetEntryCount() == 1);
#085
???????
if (forget_openers) {
#086
?????????
// If the user navigates the current tab to another page in any way
#087
?????????
// other than by clicking a link, we want to pro-actively forget all
#088
?????????
// TabStrip opener relationships since we assume they're beginning a
#089
???
??????
// different task by reusing the current tab.
#090
?????????
tabstrip_model_.ForgetAllOpeners();
#091
?????????
// In this specific case we also want to reset the group relationship,
#092
?????????
// since it is now technically invalid.
#093
?????????
tabstrip_model_.ForgetGroup(current_tab);
#094
???????
}
#095
?????
}
這里開始在當前
TAB
頁里加載網絡地址連接。
#096
?????
current_tab->controller()->LoadURL(url, transition);
#097
?????
// The TabContents might have changed as part of the navigation (ex: new tab
#098
?????
// page can become WebContents).
獲取當前顯示的內容。
#099
?????
new_contents = current_tab->controller()->active_contents();
隱藏最下面狀態提示窗口。
#100
?????
GetStatusBubble()->Hide();
#101
?
#102
?????
// Synchronously update the location bar. This allows us to immediately
#103
?????
// have the URL bar update when the user types something, rather than
#104
?????
// going through the normal system of ScheduleUIUpdate which has a delay.
更新本地的工具條。
#105
?????
UpdateToolBar(false);
后面的內容先不分析,主要分析目前打開當前連接的內容。
#106
???
} else if (disposition == OFF_THE_RECORD) {
#107
?????
OpenURLOffTheRecord(profile_, url);
#108
?????
return;
#109
???
} else if (disposition != SUPPRESS_OPEN) {
#110
?????
new_contents =
#111
?????????
AddTabWithURL(url, transition, disposition != NEW_BACKGROUND_TAB,
#112
???????????????????????
instance);
#113
???
}
#114
?
#115
???
if (disposition != NEW_BACKGROUND_TAB && source_tab_was_frontmost) {
#116
?????
// Give the focus to the newly navigated tab, if the source tab was
#117
?????
// front-most.
#118
?????
new_contents->Focus();
#119
???
}
#120
?
#121
???
if (!override_encoding.empty()) {
#122
?????
// The new tab needs a special encoding, such as a view source page
#123
?????
// which should use the same encoding as the original page.
#124
?????
WebContents* web_contents = new_contents->AsWebContents();
#125
?????
if (web_contents)
#126
???????
web_contents->set_override_encoding(override_encoding);
#127
???
}
#128
?
}
#129
?
上面函數的過程是這樣的:主要根據打開網頁的方式來選擇窗口,比如是創建新窗口,還是只是打開一個
TAB
頁,然后在
TAB
頁顯示。在這里還做了同一個網頁地址的優化,不讓它打開兩個相同的進程來處理。
Browser
對象是創建一個瀏覽器對象,接著調用
LoadURL
函數來加載輸入的網頁連接,隱藏當前窗口最下面的加載狀態條,更新當前窗口的狀態條,就完成了這個函數對當前
TAB
頁加載網頁的功能。下一次再來分析
LoadURL
函數是怎么樣打開網頁連接了。
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
