summaryrefslogtreecommitdiffstats
path: root/chrome/browser/tab_contents_factory.cc
blob: 248822267451a3d02c58e66d496688b4fb7fd8e0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/tab_contents.h"

#include "chrome/browser/about_internets_status_view.h"
#include "chrome/browser/browser_about_handler.h"
#include "chrome/browser/browser_url_handler.h"
#include "chrome/browser/dom_ui/html_dialog_contents.h"
#include "chrome/browser/dom_ui/new_tab_ui.h"
#include "chrome/browser/ipc_status_view.h"
#include "chrome/browser/native_ui_contents.h"
#include "chrome/browser/network_status_view.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/render_process_host.h"
#include "chrome/browser/debugger/debugger_contents.h"
#include "chrome/browser/tab_contents_factory.h"
#include "chrome/browser/view_source_contents.h"
#include "chrome/browser/web_contents.h"
#include "base/string_util.h"
#include "net/base/net_util.h"

typedef std::map<TabContentsType, TabContentsFactory*> TabContentsFactoryMap;
static TabContentsFactoryMap* g_extra_types;  // Only allocated if needed.

// static
TabContentsType TabContentsFactory::NextUnusedType() {
  int type = static_cast<int>(TAB_CONTENTS_NUM_TYPES);
  if (g_extra_types) {
    for (TabContentsFactoryMap::iterator i = g_extra_types->begin();
         i != g_extra_types->end(); ++i) {
      type = std::max(type, static_cast<int>(i->first));
    }
  }
  return static_cast<TabContentsType>(type + 1);
}

/*static*/
TabContents* TabContents::CreateWithType(TabContentsType type,
                                         Profile* profile,
                                         SiteInstance* instance) {
  TabContents* contents;

  switch (type) {
    case TAB_CONTENTS_WEB:
      contents = new WebContents(profile, instance, NULL, MSG_ROUTING_NONE, NULL);
      break;
    case TAB_CONTENTS_NETWORK_STATUS_VIEW:
      contents = new NetworkStatusView();
      break;
#ifdef IPC_MESSAGE_LOG_ENABLED
    case TAB_CONTENTS_IPC_STATUS_VIEW:
      contents = new IPCStatusView();
      break;
#endif
    case TAB_CONTENTS_NEW_TAB_UI:
      contents = new NewTabUIContents(profile, instance, NULL);
      break;
    case TAB_CONTENTS_HTML_DIALOG:
      contents = new HtmlDialogContents(profile, instance, NULL);
      break;
    case TAB_CONTENTS_NATIVE_UI:
      contents = new NativeUIContents(profile);
      break;
    case TAB_CONTENTS_ABOUT_INTERNETS_STATUS_VIEW:
      contents = new AboutInternetsStatusView();
      break;
    case TAB_CONTENTS_VIEW_SOURCE:
      contents = new ViewSourceContents(profile, instance);
      break;
    case TAB_CONTENTS_ABOUT_UI:
      contents = new BrowserAboutHandler(profile, instance, NULL);
      break;
    case TAB_CONTENTS_DEBUGGER:
      contents = new DebuggerContents(profile, instance);
      break;
    default:
      if (g_extra_types) {
        TabContentsFactoryMap::const_iterator it = g_extra_types->find(type);
        if (it != g_extra_types->end()) {
          contents = it->second->CreateInstance();
          break;
        }
      }
      NOTREACHED() << "Don't know how to create tab contents of type " << type;
      contents = NULL;
  }

  if (contents)
    contents->CreateView();

  return contents;
}

/*static*/
TabContentsType TabContents::TypeForURL(GURL* url) {
  DCHECK(url);
  if (g_extra_types) {
    TabContentsFactoryMap::const_iterator it = g_extra_types->begin();
    for (; it != g_extra_types->end(); ++it) {
      if (it->second->CanHandleURL(*url))
        return it->first;
    }
  }

  // Try to handle as a browser URL. If successful, |url| will end up
  // containing the real url being loaded (browser url's are just an alias).
  TabContentsType type(TAB_CONTENTS_UNKNOWN_TYPE);
  if (BrowserURLHandler::HandleBrowserURL(url, &type))
    return type;

  if (url->SchemeIs(NativeUIContents::GetScheme().c_str()))
    return TAB_CONTENTS_NATIVE_UI;

  if (HtmlDialogContents::IsHtmlDialogUrl(*url))
    return TAB_CONTENTS_HTML_DIALOG;

  if (DebuggerContents::IsDebuggerUrl(*url))
    return TAB_CONTENTS_DEBUGGER;

  if (url->SchemeIs("view-source")) {
    // Load the inner URL instead, but render it using a ViewSourceContents.
    *url = GURL(url->path());
    return TAB_CONTENTS_VIEW_SOURCE;
  }

  // NOTE: Even the empty string can be loaded by a WebContents.
  return TAB_CONTENTS_WEB;
}

/*static*/
TabContentsFactory* TabContents::RegisterFactory(TabContentsType type,
                                                 TabContentsFactory* factory) {
  if (!g_extra_types)
    g_extra_types = new TabContentsFactoryMap;

  TabContentsFactory* prev_factory = NULL;
  TabContentsFactoryMap::const_iterator prev = g_extra_types->find(type);
  if (prev != g_extra_types->end())
    prev_factory = prev->second;

  if (factory) {
    g_extra_types->insert(TabContentsFactoryMap::value_type(type, factory));
  } else {
    g_extra_types->erase(type);
    if (g_extra_types->empty()) {
      delete g_extra_types;
      g_extra_types = NULL;
    }
  }

  return prev_factory;
}