Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(291)

Side by Side Diff: docs/tab_helpers.md

Issue 1324453005: Convert TabHelper design doc to Markdown. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « chrome/browser/ui/tab_helpers.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 # Tab Helpers
2
3 The `content/` layer of Chromium has a class called `WebContents`, which is one
4 of the most basic building blocks of all of Chromium. This document describes
5 how `WebContents`es are used to build tabs in browser windows.
6
7 [TOC]
8
9 ## Introduction
10
11 What is a "tab helper"? It is a `WebContentsObserver` owned by the `WebContents`
12 itself. Let's break that down.
13
14 ## `WebContentsObserver`
15
16 `WebContentsObserver` is a [simple interface](https://code.google.com/p/chromium /codesearch#chromium/src/content/public/browser/web_contents_observer.h&q=webcon tentsobserver)
17 that allows an object to observe events in the life of a `WebContents`. As an
18 example, if we look at the `TabStripModel`, there are times when it need to watc h
Bons 2015/08/31 18:50:52 this is over 80 char limit
Avi (use Gerrit) 2015/08/31 18:58:06 Done.
19 out for WebContents being deleted. So it creates a [DeletionObserver](https://co de.google.com/p/chromium/codesearch#chromium/src/chrome/browser/ui/tabs/tab_stri p_model.cc&q=DeletionObserver).
20 The `DeletionObserver` overrides `WebContentsDestroyed()`, and when a
21 `WebContents` gets destroyed, the callback is called and the `DeletionObserver`
22 processes the message. Note that `DeletionObserver` is not owned by the
23 `WebContents`. It is owned indirectly by the `TabStripModel`.
24
25 ## `SupportsUserData` and `WebContentsUserData`
26
27 There is a mechanism used in Chromium called [`SupportsUserData`](https://code.g oogle.com/p/chromium/codesearch#chromium/src/base/supports_user_data.h&q=Support sUserData)
Bons 2015/08/31 18:50:52 place long links on their own line There is a mec
Avi (use Gerrit) 2015/08/31 18:58:06 Done.
28 that allows attaching of arbitrary objects to an object. The mechanism is
29 simple: host objects derive from `SupportsUserData`, and owned objects derive
30 from `SupportsUserData::Data`. There are three calls to attach and detach the
31 data.
32
33 `WebContents` derives from `SupportsUserData`, so that mechanism works for
34 attaching objects to a `WebContents`, but the `SupportsUserData` mechanism is a
35 bit low-level. A higher level abstraction is [`WebContentsUserData`](https://cod e.google.com/p/chromium/codesearch#chromium/src/content/public/browser/web_conte nts_user_data.h&q=WebContentsUserData),
36 which is easy to derive from and has easy-to-use functionality in
37 `CreateForWebContents()` and `FromWebContents()`.
38
39 ## Adding a feature to a browser tab
40
41 Let's combine `WebContentsObserver` and `WebContentsUserData` together, to log
42 whenever the title of a tab changes.
43
44 ```
45 class TitleLoggerTabHelper
46 : public content::WebContentsObserver,
47 public content::WebContentsUserData<TitleLoggerTabHelper> {
48 public:
49 ~TitleLoggerTabHelper() override;
50
51 // content::WebContentsObserver
52 void TitleWasSet(NavigationEntry* entry, bool explicit_set) override {
53 LOG(INFO) << "Title: " << entry->GetTitle();
54 }
55
56 private:
57 explicit TitleLoggerTabHelper(content::WebContents* web_contents);
58 friend class content::WebContentsUserData<TitleLoggerTabHelper>;
59
60 DISALLOW_COPY_AND_ASSIGN(TitleLoggerTabHelper);
61 };
62
63 DEFINE_WEB_CONTENTS_USER_DATA_KEY(TitleLoggerTabHelper);
64 ```
65
66 We want each tab to have this `WebContentsObserver` attached to it, so that it
67 will properly handle the events it's looking for, and when the tab goes away,
68 then this tab helper will go away too.
69
70 But how do you hook in to browser tab creation? How can we attach this tab
71 helper to the `WebContents`es that are used for the browser tabs?
72
73 ## AttachTabHelpers
74
75 There is a function called [`AttachTabHelpers()`](https://code.google.com/p/chro mium/codesearch#chromium/src/chrome/browser/ui/tab_helpers.cc&q=AttachTabHelpers ).
76 Whenever a `WebContents` is created for use as a browser tab,
77 `AttachTabHelpers()` is called. Every tab helper from around Chromium,
78 from ContentSettings to Favicons to History to Prefs, all take this opportunity
79 to hook into those `WebContents` used as tabs.
80
81 If you are writing a feature that needs to deal with browser tabs, this is where
82 you go. Create a tab helper, and add it (in alphabetical order, please!) to
83 `AttachTabHelpers()`. Note, though, that you are _never_ allowed to call
84 `AttachTabHelpers()` yourself. `AttachTabHelpers()` is only for `WebContents`
85 that are in browser tabs, and all of those code paths are already written.
86
87 ## Reusing tab helpers with non-browser tab `WebContents`es
88
89 Sometimes it's useful to re-use tab helpers for `WebContents`es that aren't
90 browser tabs. For example, the Chrome Apps code wants to be able to print, and
91 wants to use the printing code that browser tabs use. So in
92 [`ChromeAppDelegate::InitWebContents()`](https://code.google.com/p/chromium/code search#chromium/src/chrome/browser/ui/apps/chrome_app_delegate.cc&q=ChromeAppDel egate::InitWebContents)
93 we see that whenever the Apps code creates a new `WebContents`, it attaches a
94 carefully-chosen subset of tab helpers, including two printing ones.
95
96 You can do that too. If you are creating a `WebContents`, make a very deliberate
97 decision about which tab helpers you need. Chances are, you don't need them all;
98 you probably only need a handful. In fact, most tab helpers assume they are
99 attached to browser tabs, so only add the bare minimum.
100
101 ## Not every `WebContents` has every tab helper
102
103 The other consequence of this design is that you can't make the assumption that
104 an arbitrary `WebContents` will have an arbitrary tab helper. The
105 `WebContents`es used as browser tabs likely will have most tab helpers (though
106 not necessarily all of them!) but a `WebContents` only has a tab helper if it is
107 installed on it.
108
109 The deeper (false and dangerous) assumption is that every `WebContents` is a
110 browser tab. Do not assume that either!
111
112 If your code handles `WebContents`es, be aware of their source. It is extremely
113 rare to have to be able to handle arbitrary `WebContents`es. Know where they
114 come from and what tab helpers are on them, and you'll be fine.
OLDNEW
« no previous file with comments | « chrome/browser/ui/tab_helpers.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698