Home | History | Annotate | Download | only in browser
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef CONTENT_PUBLIC_BROWSER_WEB_CONTENTS_USER_DATA_H_
      6 #define CONTENT_PUBLIC_BROWSER_WEB_CONTENTS_USER_DATA_H_
      7 
      8 #include "base/logging.h"
      9 #include "base/supports_user_data.h"
     10 #include "content/public/browser/web_contents.h"
     11 
     12 namespace content {
     13 
     14 // A base class for classes attached to, and scoped to, the lifetime of a
     15 // WebContents. For example:
     16 //
     17 // --- in foo_tab_helper.h ---
     18 // class FooTabHelper : public content::WebContentsUserData<FooTabHelper> {
     19 //  public:
     20 //   virtual ~FooTabHelper();
     21 //   // ... more public stuff here ...
     22 //  private:
     23 //   explicit FooTabHelper(content::WebContents* contents);
     24 //   friend class content::WebContentsUserData<FooTabHelper>;
     25 //   // ... more private stuff here ...
     26 // }
     27 // --- in foo_tab_helper.cc ---
     28 // DEFINE_WEB_CONTENTS_USER_DATA_KEY(FooTabHelper);
     29 //
     30 template <typename T>
     31 class WebContentsUserData : public base::SupportsUserData::Data {
     32  public:
     33   // Creates an object of type T, and attaches it to the specified WebContents.
     34   // If an instance is already attached, does nothing.
     35   static void CreateForWebContents(WebContents* contents) {
     36     DCHECK(contents);
     37     if (!FromWebContents(contents))
     38       contents->SetUserData(UserDataKey(), new T(contents));
     39   }
     40 
     41   // Retrieves the instance of type T that was attached to the specified
     42   // WebContents (via CreateForWebContents above) and returns it. If no instance
     43   // of the type was attached, returns NULL.
     44   static T* FromWebContents(WebContents* contents) {
     45     DCHECK(contents);
     46     return static_cast<T*>(contents->GetUserData(UserDataKey()));
     47   }
     48   static const T* FromWebContents(const WebContents* contents) {
     49     DCHECK(contents);
     50     return static_cast<const T*>(contents->GetUserData(UserDataKey()));
     51   }
     52 
     53  protected:
     54   static inline void* UserDataKey() {
     55     return &kLocatorKey;
     56   }
     57 
     58  private:
     59   // The user data key.
     60   static int kLocatorKey;
     61 };
     62 
     63 // The macro to define the locator key. This key must be defined in the .cc file
     64 // of the tab helper otherwise different instances for different template types
     65 // will be collapsed by the Visual Studio linker.
     66 //
     67 // The "= 0" is surprising, but is required to effect a definition rather than
     68 // a declaration. Without it, this would be merely a declaration of a template
     69 // specialization. (C++98: 14.7.3.15; C++11: 14.7.3.13)
     70 //
     71 #define DEFINE_WEB_CONTENTS_USER_DATA_KEY(TYPE) \
     72 template<>                                      \
     73 int content::WebContentsUserData<TYPE>::kLocatorKey = 0
     74 
     75 }  // namespace content
     76 
     77 #endif  // CONTENT_PUBLIC_BROWSER_WEB_CONTENTS_USER_DATA_H_
     78