谷歌浏览器的源码分析(16)

系统 2165 0
 

上一次说到需要调用这个 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 函数是怎么样打开网页连接了。

 

谷歌浏览器的源码分析(16)


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论