Movatterモバイル変換


[0]ホーム

URL:


project logoChromium Docs

Tab Helpers

Thecontent/ layer of Chromium has a class calledWebContents, which is one of the most basic building blocks of all of Chromium. This document describes howWebContentses are used to build tabs in browser windows.

Tab helpers are in the process of being deprecated. When possible prefer to use TabFeatures over TabHelpers. Seedesign principles.

Contents

Introduction

What is a “tab helper”? It is aWebContentsObserver owned by theWebContents itself. Let's break that down.

WebContentsObserver

WebContentsObserver is asimple interface that allows an object to observe events in the life of aWebContents. As an example, if we look at theTabStripModel, there are times when it need to watch out for WebContents being deleted. So it creates aTabStripModel::WebContentsData. That object overridesWebContentsDestroyed(), and when aWebContents gets destroyed, the callback is called and the object processes the message. Note thatTabStripModel::WebContentsData object is not owned by theWebContents. It is owned indirectly by theTabStripModel.

SupportsUserData and WebContentsUserData

There is a mechanism used in Chromium calledSupportsUserData that allows attaching of arbitrary objects to an object. The mechanism is simple: host objects derive fromSupportsUserData, and owned objects derive fromSupportsUserData::Data. There are three calls to attach and detach the data.

WebContents derives fromSupportsUserData, so that mechanism works for attaching objects to aWebContents, but theSupportsUserData mechanism is a bit low-level. A higher level abstraction isWebContentsUserData, which is easy to derive from and has easy-to-use functionality inCreateForWebContents() andFromWebContents().

Adding a feature to a browser tab

Let's combineWebContentsObserver andWebContentsUserData together, to log whenever the title of a tab changes.

class TitleLoggerTabHelper    : public content::WebContentsObserver,      public content::WebContentsUserData<TitleLoggerTabHelper> { public:  TitleLoggerTabHelper(const TitleLoggerTabHelper&) = delete;  TitleLoggerTabHelper& operator=(const TitleLoggerTabHelper&) = delete;  ~TitleLoggerTabHelper() override;  // content::WebContentsObserver  void TitleWasSet(NavigationEntry* entry) override {      LOG(INFO) << "Title: " << entry->GetTitle();  } private:  explicit TitleLoggerTabHelper(content::WebContents* web_contents);  friend class content::WebContentsUserData<TitleLoggerTabHelper>;};

We want each tab to have thisWebContentsObserver attached to it, so that it will properly handle the events it's looking for, and when the tab goes away, then this tab helper will go away too.

But how do you hook in to browser tab creation? How can we attach this tab helper to theWebContentses that are used for the browser tabs?

AttachTabHelpers

There is a function calledAttachTabHelpers(). Whenever aWebContents is created for use as a browser tab,AttachTabHelpers() is called. Every tab helper from around Chromium, from ContentSettings to Favicons to History to Prefs, all take this opportunity to hook into thoseWebContents used as tabs.

If you are writing a feature that needs to deal with browser tabs, this is where you go. Create a tab helper, and add it (in alphabetical order, please!) toAttachTabHelpers(). Note, though, that you arenever allowed to callAttachTabHelpers() yourself.AttachTabHelpers() is only forWebContents that are in browser tabs, and all of those code paths are already written.

Reusing tab helpers with non-browser tab WebContentses

Sometimes it‘s useful to re-use tab helpers forWebContentses that aren’t browser tabs. For example, the Chrome Apps code wants to be able to print, and wants to use the printing code that browser tabs use. So inChromeAppDelegate::InitWebContents() we see that whenever the Apps code creates a newWebContents, it attaches a carefully-chosen subset of tab helpers, including two printing ones.

You can do that too. If you are creating aWebContents, make a very deliberate decision about which tab helpers you need. Chances are, you don't need them all; you probably only need a handful. In fact, most tab helpers assume they are attached to browser tabs, so only add the bare minimum.

Not every WebContents has every tab helper

The other consequence of this design is that you can't make the assumption that an arbitraryWebContents will have an arbitrary tab helper. TheWebContentses used as browser tabs likely will have most tab helpers (though not necessarily all of them!) but aWebContents only has a tab helper if it is installed on it.

The deeper (false and dangerous) assumption is that everyWebContents is a browser tab. Do not assume that either!

If your code handlesWebContentses, be aware of their source. It is extremely rare to have to be able to handle arbitraryWebContentses. Know where they come from and what tab helpers are on them, and you'll be fine.


[8]ページ先頭

©2009-2025 Movatter.jp