refactor: move devtools from brightray to atom (#15234)
This commit is contained in:
parent
122017e6fa
commit
6f3c46cc7e
58 changed files with 315 additions and 400 deletions
|
@ -82,7 +82,7 @@ class BrowserWindow : public TopLevelWindow,
|
|||
|
||||
private:
|
||||
#if defined(OS_MACOSX)
|
||||
void OverrideNSWindowContentView(brightray::InspectableWebContents* iwc);
|
||||
void OverrideNSWindowContentView(InspectableWebContents* iwc);
|
||||
#endif
|
||||
|
||||
// Helpers.
|
||||
|
|
|
@ -8,9 +8,9 @@
|
|||
|
||||
#include "atom/browser/native_browser_view.h"
|
||||
#include "atom/browser/native_window_mac.h"
|
||||
#include "atom/browser/ui/inspectable_web_contents_view.h"
|
||||
#include "atom/common/draggable_region.h"
|
||||
#include "base/mac/scoped_nsobject.h"
|
||||
#include "brightray/browser/inspectable_web_contents_view.h"
|
||||
|
||||
@interface NSView (WebContentsView)
|
||||
- (void)setMouseDownCanMoveWindow:(BOOL)can_move;
|
||||
|
@ -55,8 +55,7 @@ std::vector<gfx::Rect> CalculateNonDraggableRegions(
|
|||
|
||||
} // namespace
|
||||
|
||||
void BrowserWindow::OverrideNSWindowContentView(
|
||||
brightray::InspectableWebContents* iwc) {
|
||||
void BrowserWindow::OverrideNSWindowContentView(InspectableWebContents* iwc) {
|
||||
// Make NativeWindow use a NSView as content view.
|
||||
static_cast<NativeWindowMac*>(window())->OverrideNSWindowContentView();
|
||||
// Add webview to contentView.
|
||||
|
|
|
@ -22,6 +22,8 @@
|
|||
#include "atom/browser/native_window.h"
|
||||
#include "atom/browser/net/atom_network_delegate.h"
|
||||
#include "atom/browser/ui/drag_util.h"
|
||||
#include "atom/browser/ui/inspectable_web_contents.h"
|
||||
#include "atom/browser/ui/inspectable_web_contents_view.h"
|
||||
#include "atom/browser/web_contents_permission_helper.h"
|
||||
#include "atom/browser/web_contents_preferences.h"
|
||||
#include "atom/browser/web_contents_zoom_controller.h"
|
||||
|
@ -48,8 +50,6 @@
|
|||
#include "base/threading/thread_restrictions.h"
|
||||
#include "base/threading/thread_task_runner_handle.h"
|
||||
#include "base/values.h"
|
||||
#include "brightray/browser/inspectable_web_contents.h"
|
||||
#include "brightray/browser/inspectable_web_contents_view.h"
|
||||
#include "chrome/browser/browser_process.h"
|
||||
#include "chrome/browser/ssl/security_state_tab_helper.h"
|
||||
#include "content/browser/frame_host/frame_tree_node.h"
|
||||
|
|
|
@ -29,10 +29,6 @@ namespace blink {
|
|||
struct WebDeviceEmulationParams;
|
||||
}
|
||||
|
||||
namespace brightray {
|
||||
class InspectableWebContents;
|
||||
}
|
||||
|
||||
namespace mate {
|
||||
class Arguments;
|
||||
class Dictionary;
|
||||
|
@ -46,6 +42,7 @@ namespace atom {
|
|||
|
||||
class AtomBrowserContext;
|
||||
class AtomJavaScriptDialogManager;
|
||||
class InspectableWebContents;
|
||||
class WebContentsZoomController;
|
||||
class WebViewGuestDelegate;
|
||||
class FrameSubscriber;
|
||||
|
@ -419,10 +416,10 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
|||
content::WebContentsObserver::MediaStoppedReason reason) override;
|
||||
void DidChangeThemeColor(SkColor theme_color) override;
|
||||
|
||||
// brightray::InspectableWebContentsDelegate:
|
||||
// InspectableWebContentsDelegate:
|
||||
void DevToolsReloadPage() override;
|
||||
|
||||
// brightray::InspectableWebContentsViewDelegate:
|
||||
// InspectableWebContentsViewDelegate:
|
||||
void DevToolsFocused() override;
|
||||
void DevToolsOpened() override;
|
||||
void DevToolsClosed() override;
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
#include "atom/browser/api/atom_api_web_contents_view.h"
|
||||
|
||||
#include "atom/browser/api/atom_api_web_contents.h"
|
||||
#include "atom/browser/ui/inspectable_web_contents_view.h"
|
||||
#include "atom/common/api/constructor.h"
|
||||
#include "brightray/browser/inspectable_web_contents_view.h"
|
||||
#include "content/public/browser/web_contents_user_data.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
|
||||
|
@ -43,7 +43,7 @@ namespace api {
|
|||
|
||||
WebContentsView::WebContentsView(v8::Isolate* isolate,
|
||||
mate::Handle<WebContents> web_contents,
|
||||
brightray::InspectableWebContents* iwc)
|
||||
InspectableWebContents* iwc)
|
||||
#if defined(OS_MACOSX)
|
||||
: View(new DelayedNativeViewHost(iwc->GetView()->GetNativeView())),
|
||||
#else
|
||||
|
|
|
@ -9,12 +9,10 @@
|
|||
#include "content/public/browser/web_contents_observer.h"
|
||||
#include "native_mate/handle.h"
|
||||
|
||||
namespace brightray {
|
||||
class InspectableWebContents;
|
||||
}
|
||||
|
||||
namespace atom {
|
||||
|
||||
class InspectableWebContents;
|
||||
|
||||
namespace api {
|
||||
|
||||
class WebContents;
|
||||
|
@ -30,7 +28,7 @@ class WebContentsView : public View, public content::WebContentsObserver {
|
|||
protected:
|
||||
WebContentsView(v8::Isolate* isolate,
|
||||
mate::Handle<WebContents> web_contents,
|
||||
brightray::InspectableWebContents* iwc);
|
||||
InspectableWebContents* iwc);
|
||||
~WebContentsView() override;
|
||||
|
||||
// content::WebContentsObserver:
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "atom/browser/notifications/notification_presenter.h"
|
||||
#include "atom/browser/notifications/platform_notification_service.h"
|
||||
#include "atom/browser/session_preferences.h"
|
||||
#include "atom/browser/ui/devtools_manager_delegate.h"
|
||||
#include "atom/browser/web_contents_permission_helper.h"
|
||||
#include "atom/browser/web_contents_preferences.h"
|
||||
#include "atom/browser/window_list.h"
|
||||
|
@ -494,6 +495,11 @@ void AtomBrowserClient::GetAdditionalAllowedSchemesForFileSystem(
|
|||
additional_schemes->push_back(content::kChromeDevToolsScheme);
|
||||
}
|
||||
|
||||
void AtomBrowserClient::GetAdditionalWebUISchemes(
|
||||
std::vector<std::string>* additional_schemes) {
|
||||
additional_schemes->push_back(content::kChromeDevToolsScheme);
|
||||
}
|
||||
|
||||
void AtomBrowserClient::SiteInstanceDeleting(
|
||||
content::SiteInstance* site_instance) {
|
||||
// We are storing weak_ptr, is it fundamental to maintain the map up-to-date
|
||||
|
@ -677,6 +683,11 @@ AtomBrowserClient::CreateThrottlesForNavigation(
|
|||
return throttles;
|
||||
}
|
||||
|
||||
content::DevToolsManagerDelegate*
|
||||
AtomBrowserClient::GetDevToolsManagerDelegate() {
|
||||
return new DevToolsManagerDelegate;
|
||||
}
|
||||
|
||||
NotificationPresenter* AtomBrowserClient::GetNotificationPresenter() {
|
||||
if (!notification_presenter_) {
|
||||
notification_presenter_.reset(NotificationPresenter::Create());
|
||||
|
|
|
@ -111,7 +111,9 @@ class AtomBrowserClient : public brightray::BrowserClient,
|
|||
bool opener_suppressed,
|
||||
bool* no_javascript_access) override;
|
||||
void GetAdditionalAllowedSchemesForFileSystem(
|
||||
std::vector<std::string>* schemes) override;
|
||||
std::vector<std::string>* additional_schemes) override;
|
||||
void GetAdditionalWebUISchemes(
|
||||
std::vector<std::string>* additional_schemes) override;
|
||||
void SiteInstanceDeleting(content::SiteInstance* site_instance) override;
|
||||
std::unique_ptr<net::ClientCertStore> CreateClientCertStore(
|
||||
content::ResourceContext* resource_context) override;
|
||||
|
@ -125,6 +127,7 @@ class AtomBrowserClient : public brightray::BrowserClient,
|
|||
std::unique_ptr<base::Value> GetServiceManifestOverlay(
|
||||
base::StringPiece name) override;
|
||||
net::NetLog* GetNetLog() override;
|
||||
content::DevToolsManagerDelegate* GetDevToolsManagerDelegate() override;
|
||||
content::PlatformNotificationService* GetPlatformNotificationService()
|
||||
override;
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "atom/browser/net/resolve_proxy_helper.h"
|
||||
#include "atom/browser/pref_store_delegate.h"
|
||||
#include "atom/browser/special_storage_policy.h"
|
||||
#include "atom/browser/ui/inspectable_web_contents_impl.h"
|
||||
#include "atom/browser/web_view_manager.h"
|
||||
#include "atom/common/atom_version.h"
|
||||
#include "atom/common/chrome_version.h"
|
||||
|
@ -27,7 +28,6 @@
|
|||
#include "base/threading/sequenced_task_runner_handle.h"
|
||||
#include "base/threading/thread_restrictions.h"
|
||||
#include "brightray/browser/brightray_paths.h"
|
||||
#include "brightray/browser/inspectable_web_contents_impl.h"
|
||||
#include "brightray/browser/zoom_level_delegate.h"
|
||||
#include "brightray/common/application_info.h"
|
||||
#include "chrome/common/chrome_paths.h"
|
||||
|
@ -152,7 +152,7 @@ void AtomBrowserContext::InitPrefs() {
|
|||
registry->RegisterFilePathPref(prefs::kDownloadDefaultDirectory,
|
||||
download_dir);
|
||||
registry->RegisterDictionaryPref(prefs::kDevToolsFileSystemPaths);
|
||||
brightray::InspectableWebContentsImpl::RegisterPrefs(registry.get());
|
||||
InspectableWebContentsImpl::RegisterPrefs(registry.get());
|
||||
brightray::MediaDeviceIDSalt::RegisterPrefs(registry.get());
|
||||
brightray::ZoomLevelDelegate::RegisterPrefs(registry.get());
|
||||
PrefProxyConfigTrackerImpl::RegisterPrefs(registry.get());
|
||||
|
|
|
@ -10,10 +10,12 @@
|
|||
#include "atom/browser/api/trackable_object.h"
|
||||
#include "atom/browser/atom_browser_client.h"
|
||||
#include "atom/browser/atom_browser_context.h"
|
||||
#include "atom/browser/atom_web_ui_controller_factory.h"
|
||||
#include "atom/browser/browser.h"
|
||||
#include "atom/browser/io_thread.h"
|
||||
#include "atom/browser/javascript_environment.h"
|
||||
#include "atom/browser/node_debugger.h"
|
||||
#include "atom/browser/ui/devtools_manager_delegate.h"
|
||||
#include "atom/common/api/atom_bindings.h"
|
||||
#include "atom/common/asar/asar_util.h"
|
||||
#include "atom/common/node_bindings.h"
|
||||
|
@ -25,6 +27,8 @@
|
|||
#include "components/net_log/chrome_net_log.h"
|
||||
#include "components/net_log/net_export_file_writer.h"
|
||||
#include "content/public/browser/child_process_security_policy.h"
|
||||
#include "content/public/browser/web_ui_controller_factory.h"
|
||||
#include "content/public/common/content_switches.h"
|
||||
#include "content/public/common/result_codes.h"
|
||||
#include "content/public/common/service_manager_connection.h"
|
||||
#include "electron/buildflags/buildflags.h"
|
||||
|
@ -39,14 +43,10 @@
|
|||
#include "ui/events/devices/x11/touch_factory_x11.h"
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(ENABLE_PDF_VIEWER)
|
||||
#include "atom/browser/atom_web_ui_controller_factory.h"
|
||||
#endif // BUILDFLAG(ENABLE_PDF_VIEWER)
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
#include "atom/browser/ui/cocoa/views_delegate_mac.h"
|
||||
#else
|
||||
#include "brightray/browser/views/views_delegate.h"
|
||||
#include "atom/browser/ui/views/atom_views_delegate.h"
|
||||
#endif
|
||||
|
||||
// Must be included after all other headers.
|
||||
|
@ -212,7 +212,7 @@ void AtomBrowserMainParts::ToolkitInitialized() {
|
|||
#if defined(OS_MACOSX)
|
||||
views_delegate_.reset(new ViewsDelegateMac);
|
||||
#else
|
||||
views_delegate_.reset(new brightray::ViewsDelegate);
|
||||
views_delegate_.reset(new ViewsDelegate);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -231,12 +231,13 @@ void AtomBrowserMainParts::PreMainMessageLoopRun() {
|
|||
base::Bind(&v8::Isolate::LowMemoryNotification,
|
||||
base::Unretained(js_env_->isolate())));
|
||||
|
||||
#if BUILDFLAG(ENABLE_PDF_VIEWER)
|
||||
content::WebUIControllerFactory::RegisterFactory(
|
||||
AtomWebUIControllerFactory::GetInstance());
|
||||
#endif // BUILDFLAG(ENABLE_PDF_VIEWER)
|
||||
|
||||
brightray::BrowserMainParts::PreMainMessageLoopRun();
|
||||
// --remote-debugging-port
|
||||
auto* command_line = base::CommandLine::ForCurrentProcess();
|
||||
if (command_line->HasSwitch(switches::kRemoteDebuggingPort))
|
||||
DevToolsManagerDelegate::StartHttpHandler();
|
||||
|
||||
#if defined(USE_X11)
|
||||
libgtkui::GtkInitFromCommandLine(*base::CommandLine::ForCurrentProcess());
|
||||
|
|
|
@ -19,12 +19,6 @@
|
|||
class BrowserProcess;
|
||||
class IconManager;
|
||||
|
||||
#if defined(TOOLKIT_VIEWS)
|
||||
namespace brightray {
|
||||
class ViewsDelegate;
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace net_log {
|
||||
class ChromeNetLog;
|
||||
}
|
||||
|
@ -40,6 +34,10 @@ class NodeDebugger;
|
|||
class NodeEnvironment;
|
||||
class BridgeTaskRunner;
|
||||
|
||||
#if defined(TOOLKIT_VIEWS)
|
||||
class ViewsDelegate;
|
||||
#endif
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
class ViewsDelegateMac;
|
||||
#endif
|
||||
|
@ -103,7 +101,7 @@ class AtomBrowserMainParts : public brightray::BrowserMainParts {
|
|||
#if defined(OS_MACOSX)
|
||||
std::unique_ptr<ViewsDelegateMac> views_delegate_;
|
||||
#else
|
||||
std::unique_ptr<brightray::ViewsDelegate> views_delegate_;
|
||||
std::unique_ptr<ViewsDelegate> views_delegate_;
|
||||
#endif
|
||||
|
||||
// A fake BrowserProcess object that used to feed the source code from chrome.
|
||||
|
|
|
@ -13,12 +13,20 @@
|
|||
#include "atom/common/atom_constants.h"
|
||||
#include "base/strings/string_split.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "content/public/browser/web_contents.h"
|
||||
#include "net/base/escape.h"
|
||||
#endif // BUILDFLAG(ENABLE_PDF_VIEWER)
|
||||
|
||||
#include "atom/browser/ui/devtools_ui.h"
|
||||
#include "content/public/browser/web_contents.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace {
|
||||
|
||||
const char kChromeUIDevToolsBundledHost[] = "devtools";
|
||||
|
||||
} // namespace
|
||||
|
||||
// static
|
||||
AtomWebUIControllerFactory* AtomWebUIControllerFactory::GetInstance() {
|
||||
return base::Singleton<AtomWebUIControllerFactory>::get();
|
||||
|
@ -36,6 +44,9 @@ content::WebUI::TypeID AtomWebUIControllerFactory::GetWebUIType(
|
|||
return const_cast<AtomWebUIControllerFactory*>(this);
|
||||
}
|
||||
#endif // BUILDFLAG(ENABLE_PDF_VIEWER)
|
||||
if (url.host() == kChromeUIDevToolsBundledHost) {
|
||||
return const_cast<AtomWebUIControllerFactory*>(this);
|
||||
}
|
||||
|
||||
return content::WebUI::kNoWebUI;
|
||||
}
|
||||
|
@ -78,6 +89,10 @@ AtomWebUIControllerFactory::CreateWebUIControllerForURL(content::WebUI* web_ui,
|
|||
return new PdfViewerUI(browser_context, web_ui, src);
|
||||
}
|
||||
#endif // BUILDFLAG(ENABLE_PDF_VIEWER)
|
||||
if (url.host() == kChromeUIDevToolsBundledHost) {
|
||||
auto* browser_context = web_ui->GetWebContents()->GetBrowserContext();
|
||||
return std::make_unique<DevToolsUI>(browser_context, web_ui);
|
||||
}
|
||||
return std::unique_ptr<content::WebUIController>();
|
||||
}
|
||||
|
||||
|
|
|
@ -188,7 +188,7 @@ void CommonWebContentsDelegate::InitWithWebContents(
|
|||
!web_preferences || web_preferences->IsEnabled(options::kOffscreen);
|
||||
|
||||
// Create InspectableWebContents.
|
||||
web_contents_.reset(brightray::InspectableWebContents::Create(
|
||||
web_contents_.reset(InspectableWebContents::Create(
|
||||
web_contents, browser_context->prefs(), is_guest));
|
||||
web_contents_->SetDelegate(this);
|
||||
}
|
||||
|
@ -229,11 +229,12 @@ void CommonWebContentsDelegate::ResetManagedWebContents(bool async) {
|
|||
// is required to get the right quit closure for the main message loop.
|
||||
base::ThreadTaskRunnerHandle::Get()->PostNonNestableTask(
|
||||
FROM_HERE,
|
||||
base::BindOnce([](scoped_refptr<AtomBrowserContext> browser_context,
|
||||
std::unique_ptr<brightray::InspectableWebContents>
|
||||
web_contents) { web_contents.reset(); },
|
||||
base::RetainedRef(browser_context_),
|
||||
std::move(web_contents_)));
|
||||
base::BindOnce(
|
||||
[](scoped_refptr<AtomBrowserContext> browser_context,
|
||||
std::unique_ptr<InspectableWebContents> web_contents) {
|
||||
web_contents.reset();
|
||||
},
|
||||
base::RetainedRef(browser_context_), std::move(web_contents_)));
|
||||
} else {
|
||||
web_contents_.reset();
|
||||
}
|
||||
|
|
|
@ -10,10 +10,10 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "atom/browser/ui/inspectable_web_contents_delegate.h"
|
||||
#include "atom/browser/ui/inspectable_web_contents_impl.h"
|
||||
#include "atom/browser/ui/inspectable_web_contents_view_delegate.h"
|
||||
#include "base/memory/weak_ptr.h"
|
||||
#include "brightray/browser/inspectable_web_contents_delegate.h"
|
||||
#include "brightray/browser/inspectable_web_contents_impl.h"
|
||||
#include "brightray/browser/inspectable_web_contents_view_delegate.h"
|
||||
#include "chrome/browser/devtools/devtools_file_system_indexer.h"
|
||||
#include "content/public/browser/web_contents_delegate.h"
|
||||
#include "electron/buildflags/buildflags.h"
|
||||
|
@ -36,10 +36,9 @@ class WebDialogHelper;
|
|||
class OffScreenRenderWidgetHostView;
|
||||
#endif
|
||||
|
||||
class CommonWebContentsDelegate
|
||||
: public content::WebContentsDelegate,
|
||||
public brightray::InspectableWebContentsDelegate,
|
||||
public brightray::InspectableWebContentsViewDelegate {
|
||||
class CommonWebContentsDelegate : public content::WebContentsDelegate,
|
||||
public InspectableWebContentsDelegate,
|
||||
public InspectableWebContentsViewDelegate {
|
||||
public:
|
||||
CommonWebContentsDelegate();
|
||||
~CommonWebContentsDelegate() override;
|
||||
|
@ -61,7 +60,7 @@ class CommonWebContentsDelegate
|
|||
// Returns the WebContents of devtools.
|
||||
content::WebContents* GetDevToolsWebContents() const;
|
||||
|
||||
brightray::InspectableWebContents* managed_web_contents() const {
|
||||
InspectableWebContents* managed_web_contents() const {
|
||||
return web_contents_.get();
|
||||
}
|
||||
|
||||
|
@ -115,7 +114,7 @@ class CommonWebContentsDelegate
|
|||
void HideAutofillPopup();
|
||||
#endif
|
||||
|
||||
// brightray::InspectableWebContentsDelegate:
|
||||
// InspectableWebContentsDelegate:
|
||||
void DevToolsSaveToFile(const std::string& url,
|
||||
const std::string& content,
|
||||
bool save_as) override;
|
||||
|
@ -134,7 +133,7 @@ class CommonWebContentsDelegate
|
|||
const std::string& file_system_path,
|
||||
const std::string& query) override;
|
||||
|
||||
// brightray::InspectableWebContentsViewDelegate:
|
||||
// InspectableWebContentsViewDelegate:
|
||||
#if defined(TOOLKIT_VIEWS) && !defined(OS_MACOSX)
|
||||
gfx::ImageSkia GetDevToolsWindowIcon() override;
|
||||
#endif
|
||||
|
@ -189,7 +188,7 @@ class CommonWebContentsDelegate
|
|||
// Notice that web_contents_ must be placed after dialog_manager_, so we can
|
||||
// make sure web_contents_ is destroyed before dialog_manager_, otherwise a
|
||||
// crash would happen.
|
||||
std::unique_ptr<brightray::InspectableWebContents> web_contents_;
|
||||
std::unique_ptr<InspectableWebContents> web_contents_;
|
||||
|
||||
// Maps url to file path, used by the file requests sent from devtools.
|
||||
typedef std::map<std::string, base::FilePath> PathsMap;
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
#include "atom/browser/ui/cocoa/event_dispatching_window.h"
|
||||
#include "atom/browser/web_contents_preferences.h"
|
||||
#include "brightray/browser/mac/event_dispatching_window.h"
|
||||
#include "content/public/browser/native_web_keyboard_event.h"
|
||||
#include "ui/events/keycodes/keyboard_codes.h"
|
||||
|
||||
|
|
|
@ -7,18 +7,17 @@
|
|||
#include "atom/browser/native_browser_view.h"
|
||||
|
||||
#include "atom/browser/api/atom_api_web_contents.h"
|
||||
#include "brightray/browser/inspectable_web_contents.h"
|
||||
#include "atom/browser/ui/inspectable_web_contents.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
NativeBrowserView::NativeBrowserView(
|
||||
brightray::InspectableWebContents* inspectable_web_contents)
|
||||
InspectableWebContents* inspectable_web_contents)
|
||||
: inspectable_web_contents_(inspectable_web_contents) {}
|
||||
|
||||
NativeBrowserView::~NativeBrowserView() {}
|
||||
|
||||
brightray::InspectableWebContentsView*
|
||||
NativeBrowserView::GetInspectableWebContentsView() {
|
||||
InspectableWebContentsView* NativeBrowserView::GetInspectableWebContentsView() {
|
||||
return inspectable_web_contents_->GetView();
|
||||
}
|
||||
|
||||
|
|
|
@ -12,11 +12,6 @@
|
|||
#include "content/public/browser/web_contents.h"
|
||||
#include "third_party/skia/include/core/SkColor.h"
|
||||
|
||||
namespace brightray {
|
||||
class InspectableWebContents;
|
||||
class InspectableWebContentsView;
|
||||
} // namespace brightray
|
||||
|
||||
namespace gfx {
|
||||
class Rect;
|
||||
}
|
||||
|
@ -28,18 +23,21 @@ enum AutoResizeFlags {
|
|||
kAutoResizeHeight = 0x2,
|
||||
};
|
||||
|
||||
class InspectableWebContents;
|
||||
class InspectableWebContentsView;
|
||||
|
||||
class NativeBrowserView {
|
||||
public:
|
||||
virtual ~NativeBrowserView();
|
||||
|
||||
static NativeBrowserView* Create(
|
||||
brightray::InspectableWebContents* inspectable_web_contents);
|
||||
InspectableWebContents* inspectable_web_contents);
|
||||
|
||||
brightray::InspectableWebContents* GetInspectableWebContents() {
|
||||
InspectableWebContents* GetInspectableWebContents() {
|
||||
return inspectable_web_contents_;
|
||||
}
|
||||
|
||||
brightray::InspectableWebContentsView* GetInspectableWebContentsView();
|
||||
InspectableWebContentsView* GetInspectableWebContentsView();
|
||||
content::WebContents* GetWebContents();
|
||||
|
||||
virtual void SetAutoResizeFlags(uint8_t flags) = 0;
|
||||
|
@ -51,10 +49,9 @@ class NativeBrowserView {
|
|||
const std::vector<gfx::Rect>& system_drag_exclude_areas) {}
|
||||
|
||||
protected:
|
||||
explicit NativeBrowserView(
|
||||
brightray::InspectableWebContents* inspectable_web_contents);
|
||||
explicit NativeBrowserView(InspectableWebContents* inspectable_web_contents);
|
||||
|
||||
brightray::InspectableWebContents* inspectable_web_contents_;
|
||||
InspectableWebContents* inspectable_web_contents_;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(NativeBrowserView);
|
||||
|
|
|
@ -17,7 +17,7 @@ namespace atom {
|
|||
class NativeBrowserViewMac : public NativeBrowserView {
|
||||
public:
|
||||
explicit NativeBrowserViewMac(
|
||||
brightray::InspectableWebContents* inspectable_web_contents);
|
||||
InspectableWebContents* inspectable_web_contents);
|
||||
~NativeBrowserViewMac() override;
|
||||
|
||||
void SetAutoResizeFlags(uint8_t flags) override;
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
|
||||
#include "atom/browser/native_browser_view_mac.h"
|
||||
|
||||
#include "brightray/browser/inspectable_web_contents.h"
|
||||
#include "brightray/browser/inspectable_web_contents_view.h"
|
||||
#include "atom/browser/ui/inspectable_web_contents.h"
|
||||
#include "atom/browser/ui/inspectable_web_contents_view.h"
|
||||
#include "skia/ext/skia_utils_mac.h"
|
||||
#include "ui/gfx/geometry/rect.h"
|
||||
|
||||
|
@ -158,7 +158,7 @@ const NSAutoresizingMaskOptions kDefaultAutoResizingMask =
|
|||
namespace atom {
|
||||
|
||||
NativeBrowserViewMac::NativeBrowserViewMac(
|
||||
brightray::InspectableWebContents* inspectable_web_contents)
|
||||
InspectableWebContents* inspectable_web_contents)
|
||||
: NativeBrowserView(inspectable_web_contents) {
|
||||
auto* view = GetInspectableWebContentsView()->GetNativeView();
|
||||
view.autoresizingMask = kDefaultAutoResizingMask;
|
||||
|
@ -233,7 +233,7 @@ void NativeBrowserViewMac::UpdateDraggableRegions(
|
|||
|
||||
// static
|
||||
NativeBrowserView* NativeBrowserView::Create(
|
||||
brightray::InspectableWebContents* inspectable_web_contents) {
|
||||
InspectableWebContents* inspectable_web_contents) {
|
||||
return new NativeBrowserViewMac(inspectable_web_contents);
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
#include "atom/browser/native_browser_view_views.h"
|
||||
|
||||
#include "brightray/browser/inspectable_web_contents_view.h"
|
||||
#include "atom/browser/ui/inspectable_web_contents_view.h"
|
||||
#include "ui/gfx/geometry/rect.h"
|
||||
#include "ui/views/background.h"
|
||||
#include "ui/views/view.h"
|
||||
|
@ -12,7 +12,7 @@
|
|||
namespace atom {
|
||||
|
||||
NativeBrowserViewViews::NativeBrowserViewViews(
|
||||
brightray::InspectableWebContents* inspectable_web_contents)
|
||||
InspectableWebContents* inspectable_web_contents)
|
||||
: NativeBrowserView(inspectable_web_contents) {}
|
||||
|
||||
NativeBrowserViewViews::~NativeBrowserViewViews() {}
|
||||
|
@ -33,7 +33,7 @@ void NativeBrowserViewViews::SetBackgroundColor(SkColor color) {
|
|||
|
||||
// static
|
||||
NativeBrowserView* NativeBrowserView::Create(
|
||||
brightray::InspectableWebContents* inspectable_web_contents) {
|
||||
InspectableWebContents* inspectable_web_contents) {
|
||||
return new NativeBrowserViewViews(inspectable_web_contents);
|
||||
}
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ namespace atom {
|
|||
class NativeBrowserViewViews : public NativeBrowserView {
|
||||
public:
|
||||
explicit NativeBrowserViewViews(
|
||||
brightray::InspectableWebContents* inspectable_web_contents);
|
||||
InspectableWebContents* inspectable_web_contents);
|
||||
~NativeBrowserViewViews() override;
|
||||
|
||||
uint8_t GetAutoResizeFlags() { return auto_resize_flags_; }
|
||||
|
|
|
@ -16,13 +16,13 @@
|
|||
#include "atom/browser/ui/cocoa/atom_preview_item.h"
|
||||
#include "atom/browser/ui/cocoa/atom_touch_bar.h"
|
||||
#include "atom/browser/ui/cocoa/root_view_mac.h"
|
||||
#include "atom/browser/ui/inspectable_web_contents.h"
|
||||
#include "atom/browser/ui/inspectable_web_contents_view.h"
|
||||
#include "atom/browser/window_list.h"
|
||||
#include "atom/common/options_switches.h"
|
||||
#include "base/mac/mac_util.h"
|
||||
#include "base/mac/scoped_cftyperef.h"
|
||||
#include "base/strings/sys_string_conversions.h"
|
||||
#include "brightray/browser/inspectable_web_contents.h"
|
||||
#include "brightray/browser/inspectable_web_contents_view.h"
|
||||
#include "content/public/browser/browser_accessibility_state.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "skia/ext/skia_utils_mac.h"
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
|
||||
#include "atom/browser/api/atom_api_web_contents.h"
|
||||
#include "atom/browser/native_browser_view_views.h"
|
||||
#include "atom/browser/ui/inspectable_web_contents.h"
|
||||
#include "atom/browser/ui/inspectable_web_contents_view.h"
|
||||
#include "atom/browser/ui/views/root_view.h"
|
||||
#include "atom/browser/web_contents_preferences.h"
|
||||
#include "atom/browser/web_view_manager.h"
|
||||
|
@ -23,8 +25,6 @@
|
|||
#include "atom/common/native_mate_converters/image_converter.h"
|
||||
#include "atom/common/options_switches.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "brightray/browser/inspectable_web_contents.h"
|
||||
#include "brightray/browser/inspectable_web_contents_view.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "ui/aura/window_tree_host.h"
|
||||
|
|
47
atom/browser/ui/cocoa/atom_inspectable_web_contents_view.h
Normal file
47
atom/browser/ui/cocoa/atom_inspectable_web_contents_view.h
Normal file
|
@ -0,0 +1,47 @@
|
|||
// Copyright (c) 2014 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-CHROMIUM file.
|
||||
|
||||
#ifndef ATOM_BROWSER_UI_COCOA_BRY_INSPECTABLE_WEB_CONTENTS_VIEW_H_
|
||||
#define ATOM_BROWSER_UI_COCOA_BRY_INSPECTABLE_WEB_CONTENTS_VIEW_H_
|
||||
|
||||
#import <AppKit/AppKit.h>
|
||||
|
||||
#include "base/mac/scoped_nsobject.h"
|
||||
#include "chrome/browser/devtools/devtools_contents_resizing_strategy.h"
|
||||
#include "ui/base/cocoa/base_view.h"
|
||||
|
||||
namespace atom {
|
||||
class InspectableWebContentsViewMac;
|
||||
}
|
||||
|
||||
using atom::InspectableWebContentsViewMac;
|
||||
|
||||
@interface AtomInspectableWebContentsView : BaseView <NSWindowDelegate> {
|
||||
@private
|
||||
atom::InspectableWebContentsViewMac* inspectableWebContentsView_;
|
||||
|
||||
base::scoped_nsobject<NSView> fake_view_;
|
||||
base::scoped_nsobject<NSWindow> devtools_window_;
|
||||
BOOL devtools_visible_;
|
||||
BOOL devtools_docked_;
|
||||
BOOL devtools_is_first_responder_;
|
||||
|
||||
DevToolsContentsResizingStrategy strategy_;
|
||||
}
|
||||
|
||||
- (instancetype)initWithInspectableWebContentsViewMac:
|
||||
(InspectableWebContentsViewMac*)view;
|
||||
- (void)removeObservers;
|
||||
- (void)notifyDevToolsFocused;
|
||||
- (void)setDevToolsVisible:(BOOL)visible;
|
||||
- (BOOL)isDevToolsVisible;
|
||||
- (BOOL)isDevToolsFocused;
|
||||
- (void)setIsDocked:(BOOL)docked;
|
||||
- (void)setContentsResizingStrategy:
|
||||
(const DevToolsContentsResizingStrategy&)strategy;
|
||||
- (void)setTitle:(NSString*)title;
|
||||
|
||||
@end
|
||||
|
||||
#endif // ATOM_BROWSER_UI_COCOA_BRY_INSPECTABLE_WEB_CONTENTS_VIEW_H_
|
273
atom/browser/ui/cocoa/atom_inspectable_web_contents_view.mm
Normal file
273
atom/browser/ui/cocoa/atom_inspectable_web_contents_view.mm
Normal file
|
@ -0,0 +1,273 @@
|
|||
// Copyright (c) 2014 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-CHROMIUM file.
|
||||
|
||||
#include "atom/browser/ui/cocoa/atom_inspectable_web_contents_view.h"
|
||||
|
||||
#include "atom/browser/ui/cocoa/event_dispatching_window.h"
|
||||
#include "atom/browser/ui/inspectable_web_contents_impl.h"
|
||||
#include "atom/browser/ui/inspectable_web_contents_view_delegate.h"
|
||||
#include "atom/browser/ui/inspectable_web_contents_view_mac.h"
|
||||
#include "content/public/browser/render_widget_host_view.h"
|
||||
#include "ui/gfx/mac/scoped_cocoa_disable_screen_updates.h"
|
||||
|
||||
@implementation AtomInspectableWebContentsView
|
||||
|
||||
- (instancetype)initWithInspectableWebContentsViewMac:
|
||||
(InspectableWebContentsViewMac*)view {
|
||||
self = [super init];
|
||||
if (!self)
|
||||
return nil;
|
||||
|
||||
inspectableWebContentsView_ = view;
|
||||
devtools_visible_ = NO;
|
||||
devtools_docked_ = NO;
|
||||
devtools_is_first_responder_ = NO;
|
||||
|
||||
[[NSNotificationCenter defaultCenter]
|
||||
addObserver:self
|
||||
selector:@selector(viewDidBecomeFirstResponder:)
|
||||
name:kViewDidBecomeFirstResponder
|
||||
object:nil];
|
||||
|
||||
[[NSNotificationCenter defaultCenter]
|
||||
addObserver:self
|
||||
selector:@selector(parentWindowBecameMain:)
|
||||
name:NSWindowDidBecomeMainNotification
|
||||
object:nil];
|
||||
|
||||
if (inspectableWebContentsView_->inspectable_web_contents()->IsGuest()) {
|
||||
fake_view_.reset([[NSView alloc] init]);
|
||||
[fake_view_ setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
|
||||
[self addSubview:fake_view_];
|
||||
} else {
|
||||
auto* contents = inspectableWebContentsView_->inspectable_web_contents()
|
||||
->GetWebContents();
|
||||
auto contentsView = contents->GetNativeView();
|
||||
[contentsView setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
|
||||
[self addSubview:contentsView];
|
||||
}
|
||||
|
||||
// See https://code.google.com/p/chromium/issues/detail?id=348490.
|
||||
[self setWantsLayer:YES];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)removeObservers {
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
}
|
||||
|
||||
- (void)resizeSubviewsWithOldSize:(NSSize)oldBoundsSize {
|
||||
[self adjustSubviews];
|
||||
}
|
||||
|
||||
- (IBAction)showDevTools:(id)sender {
|
||||
inspectableWebContentsView_->inspectable_web_contents()->ShowDevTools();
|
||||
}
|
||||
|
||||
- (void)notifyDevToolsFocused {
|
||||
if (inspectableWebContentsView_->GetDelegate())
|
||||
inspectableWebContentsView_->GetDelegate()->DevToolsFocused();
|
||||
}
|
||||
|
||||
- (void)setDevToolsVisible:(BOOL)visible {
|
||||
if (visible == devtools_visible_)
|
||||
return;
|
||||
|
||||
auto* inspectable_web_contents =
|
||||
inspectableWebContentsView_->inspectable_web_contents();
|
||||
auto* webContents = inspectable_web_contents->GetWebContents();
|
||||
auto* devToolsWebContents =
|
||||
inspectable_web_contents->GetDevToolsWebContents();
|
||||
auto devToolsView = devToolsWebContents->GetNativeView();
|
||||
|
||||
if (visible && devtools_docked_) {
|
||||
webContents->SetAllowOtherViews(true);
|
||||
devToolsWebContents->SetAllowOtherViews(true);
|
||||
} else if (!inspectable_web_contents->IsGuest()) {
|
||||
webContents->SetAllowOtherViews(false);
|
||||
}
|
||||
|
||||
devtools_visible_ = visible;
|
||||
if (devtools_docked_) {
|
||||
if (visible) {
|
||||
// Place the devToolsView under contentsView, notice that we didn't set
|
||||
// sizes for them until the setContentsResizingStrategy message.
|
||||
[self addSubview:devToolsView positioned:NSWindowBelow relativeTo:nil];
|
||||
[self adjustSubviews];
|
||||
|
||||
// Focus on web view.
|
||||
devToolsWebContents->RestoreFocus();
|
||||
} else {
|
||||
gfx::ScopedCocoaDisableScreenUpdates disabler;
|
||||
[devToolsView removeFromSuperview];
|
||||
[self adjustSubviews];
|
||||
}
|
||||
} else {
|
||||
if (visible) {
|
||||
[devtools_window_ makeKeyAndOrderFront:nil];
|
||||
} else {
|
||||
[devtools_window_ setDelegate:nil];
|
||||
[devtools_window_ close];
|
||||
devtools_window_.reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)isDevToolsVisible {
|
||||
return devtools_visible_;
|
||||
}
|
||||
|
||||
- (BOOL)isDevToolsFocused {
|
||||
if (devtools_docked_) {
|
||||
return [[self window] isKeyWindow] && devtools_is_first_responder_;
|
||||
} else {
|
||||
return [devtools_window_ isKeyWindow];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setIsDocked:(BOOL)docked {
|
||||
// Revert to no-devtools state.
|
||||
[self setDevToolsVisible:NO];
|
||||
|
||||
// Switch to new state.
|
||||
devtools_docked_ = docked;
|
||||
if (!docked) {
|
||||
auto* inspectable_web_contents =
|
||||
inspectableWebContentsView_->inspectable_web_contents();
|
||||
auto* devToolsWebContents =
|
||||
inspectable_web_contents->GetDevToolsWebContents();
|
||||
auto devToolsView = devToolsWebContents->GetNativeView();
|
||||
|
||||
auto styleMask = NSWindowStyleMaskTitled | NSWindowStyleMaskClosable |
|
||||
NSMiniaturizableWindowMask | NSWindowStyleMaskResizable |
|
||||
NSTexturedBackgroundWindowMask |
|
||||
NSWindowStyleMaskUnifiedTitleAndToolbar;
|
||||
devtools_window_.reset([[EventDispatchingWindow alloc]
|
||||
initWithContentRect:NSMakeRect(0, 0, 800, 600)
|
||||
styleMask:styleMask
|
||||
backing:NSBackingStoreBuffered
|
||||
defer:YES]);
|
||||
[devtools_window_ setDelegate:self];
|
||||
[devtools_window_ setFrameAutosaveName:@"brightray.devtools"];
|
||||
[devtools_window_ setTitle:@"Developer Tools"];
|
||||
[devtools_window_ setReleasedWhenClosed:NO];
|
||||
[devtools_window_ setAutorecalculatesContentBorderThickness:NO
|
||||
forEdge:NSMaxYEdge];
|
||||
[devtools_window_ setContentBorderThickness:24 forEdge:NSMaxYEdge];
|
||||
|
||||
NSView* contentView = [devtools_window_ contentView];
|
||||
devToolsView.frame = contentView.bounds;
|
||||
devToolsView.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable;
|
||||
|
||||
[contentView addSubview:devToolsView];
|
||||
}
|
||||
[self setDevToolsVisible:YES];
|
||||
}
|
||||
|
||||
- (void)setContentsResizingStrategy:
|
||||
(const DevToolsContentsResizingStrategy&)strategy {
|
||||
strategy_.CopyFrom(strategy);
|
||||
[self adjustSubviews];
|
||||
}
|
||||
|
||||
- (void)adjustSubviews {
|
||||
if (![[self subviews] count])
|
||||
return;
|
||||
|
||||
if (![self isDevToolsVisible] || devtools_window_) {
|
||||
DCHECK_EQ(1u, [[self subviews] count]);
|
||||
NSView* contents = [[self subviews] objectAtIndex:0];
|
||||
[contents setFrame:[self bounds]];
|
||||
return;
|
||||
}
|
||||
|
||||
NSView* devToolsView = [[self subviews] objectAtIndex:0];
|
||||
NSView* contentsView = [[self subviews] objectAtIndex:1];
|
||||
|
||||
DCHECK_EQ(2u, [[self subviews] count]);
|
||||
|
||||
gfx::Rect new_devtools_bounds;
|
||||
gfx::Rect new_contents_bounds;
|
||||
ApplyDevToolsContentsResizingStrategy(
|
||||
strategy_, gfx::Size(NSSizeToCGSize([self bounds].size)),
|
||||
&new_devtools_bounds, &new_contents_bounds);
|
||||
[devToolsView setFrame:[self flipRectToNSRect:new_devtools_bounds]];
|
||||
[contentsView setFrame:[self flipRectToNSRect:new_contents_bounds]];
|
||||
}
|
||||
|
||||
- (void)setTitle:(NSString*)title {
|
||||
[devtools_window_ setTitle:title];
|
||||
}
|
||||
|
||||
- (void)viewDidBecomeFirstResponder:(NSNotification*)notification {
|
||||
auto* inspectable_web_contents =
|
||||
inspectableWebContentsView_->inspectable_web_contents();
|
||||
if (!inspectable_web_contents || inspectable_web_contents->IsGuest())
|
||||
return;
|
||||
auto* webContents = inspectable_web_contents->GetWebContents();
|
||||
auto webContentsView = webContents->GetNativeView();
|
||||
|
||||
NSView* view = [notification object];
|
||||
if ([[webContentsView subviews] containsObject:view]) {
|
||||
devtools_is_first_responder_ = NO;
|
||||
return;
|
||||
}
|
||||
|
||||
auto* devToolsWebContents =
|
||||
inspectable_web_contents->GetDevToolsWebContents();
|
||||
if (!devToolsWebContents)
|
||||
return;
|
||||
auto devToolsView = devToolsWebContents->GetNativeView();
|
||||
|
||||
if ([[devToolsView subviews] containsObject:view]) {
|
||||
devtools_is_first_responder_ = YES;
|
||||
[self notifyDevToolsFocused];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)parentWindowBecameMain:(NSNotification*)notification {
|
||||
NSWindow* parentWindow = [notification object];
|
||||
if ([self window] == parentWindow && devtools_docked_ &&
|
||||
devtools_is_first_responder_)
|
||||
[self notifyDevToolsFocused];
|
||||
}
|
||||
|
||||
#pragma mark - NSWindowDelegate
|
||||
|
||||
- (void)windowWillClose:(NSNotification*)notification {
|
||||
inspectableWebContentsView_->inspectable_web_contents()->CloseDevTools();
|
||||
}
|
||||
|
||||
- (void)windowDidBecomeMain:(NSNotification*)notification {
|
||||
content::WebContents* web_contents =
|
||||
inspectableWebContentsView_->inspectable_web_contents()
|
||||
->GetDevToolsWebContents();
|
||||
if (!web_contents)
|
||||
return;
|
||||
|
||||
web_contents->RestoreFocus();
|
||||
|
||||
content::RenderWidgetHostView* rwhv = web_contents->GetRenderWidgetHostView();
|
||||
if (rwhv)
|
||||
rwhv->SetActive(true);
|
||||
|
||||
[self notifyDevToolsFocused];
|
||||
}
|
||||
|
||||
- (void)windowDidResignMain:(NSNotification*)notification {
|
||||
content::WebContents* web_contents =
|
||||
inspectableWebContentsView_->inspectable_web_contents()
|
||||
->GetDevToolsWebContents();
|
||||
if (!web_contents)
|
||||
return;
|
||||
|
||||
web_contents->StoreFocus();
|
||||
|
||||
content::RenderWidgetHostView* rwhv = web_contents->GetRenderWidgetHostView();
|
||||
if (rwhv)
|
||||
rwhv->SetActive(false);
|
||||
}
|
||||
|
||||
@end
|
|
@ -5,7 +5,7 @@
|
|||
#ifndef ATOM_BROWSER_UI_COCOA_ATOM_NS_WINDOW_H_
|
||||
#define ATOM_BROWSER_UI_COCOA_ATOM_NS_WINDOW_H_
|
||||
|
||||
#include "brightray/browser/mac/event_dispatching_window.h"
|
||||
#include "atom/browser/ui/cocoa/event_dispatching_window.h"
|
||||
#include "ui/views/cocoa/native_widget_mac_nswindow.h"
|
||||
#include "ui/views/widget/native_widget_mac.h"
|
||||
|
||||
|
|
19
atom/browser/ui/cocoa/event_dispatching_window.h
Normal file
19
atom/browser/ui/cocoa/event_dispatching_window.h
Normal file
|
@ -0,0 +1,19 @@
|
|||
// Copyright (c) 2016 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_BROWSER_UI_COCOA_EVENT_DISPATCHING_WINDOW_H_
|
||||
#define ATOM_BROWSER_UI_COCOA_EVENT_DISPATCHING_WINDOW_H_
|
||||
|
||||
#import "ui/base/cocoa/underlay_opengl_hosting_window.h"
|
||||
|
||||
@interface EventDispatchingWindow : UnderlayOpenGLHostingWindow {
|
||||
@private
|
||||
BOOL redispatchingEvent_;
|
||||
}
|
||||
|
||||
- (void)redispatchKeyEvent:(NSEvent*)event;
|
||||
|
||||
@end
|
||||
|
||||
#endif // ATOM_BROWSER_UI_COCOA_EVENT_DISPATCHING_WINDOW_H_
|
34
atom/browser/ui/cocoa/event_dispatching_window.mm
Normal file
34
atom/browser/ui/cocoa/event_dispatching_window.mm
Normal file
|
@ -0,0 +1,34 @@
|
|||
// Copyright (c) 2016 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/ui/cocoa/event_dispatching_window.h"
|
||||
|
||||
@implementation EventDispatchingWindow
|
||||
|
||||
- (void)sendEvent:(NSEvent*)event {
|
||||
if (!redispatchingEvent_)
|
||||
[super sendEvent:event];
|
||||
}
|
||||
|
||||
- (BOOL)performKeyEquivalent:(NSEvent*)event {
|
||||
if (redispatchingEvent_)
|
||||
return NO;
|
||||
else
|
||||
return [super performKeyEquivalent:event];
|
||||
}
|
||||
|
||||
- (void)redispatchKeyEvent:(NSEvent*)event {
|
||||
NSEventType eventType = [event type];
|
||||
if (eventType != NSKeyDown && eventType != NSKeyUp &&
|
||||
eventType != NSFlagsChanged) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Redispatch the event.
|
||||
redispatchingEvent_ = YES;
|
||||
[NSApp sendEvent:event];
|
||||
redispatchingEvent_ = NO;
|
||||
}
|
||||
|
||||
@end
|
119
atom/browser/ui/devtools_manager_delegate.cc
Normal file
119
atom/browser/ui/devtools_manager_delegate.cc
Normal file
|
@ -0,0 +1,119 @@
|
|||
// Copyright (c) 2014 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-CHROMIUM file.
|
||||
|
||||
#include "atom/browser/ui/devtools_manager_delegate.h"
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "base/bind.h"
|
||||
#include "base/command_line.h"
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/strings/string_number_conversions.h"
|
||||
#include "base/strings/stringprintf.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "brightray/common/content_client.h"
|
||||
#include "content/public/browser/devtools_agent_host.h"
|
||||
#include "content/public/browser/devtools_frontend_host.h"
|
||||
#include "content/public/browser/devtools_socket_factory.h"
|
||||
#include "content/public/browser/favicon_status.h"
|
||||
#include "content/public/browser/navigation_entry.h"
|
||||
#include "content/public/common/content_switches.h"
|
||||
#include "content/public/common/url_constants.h"
|
||||
#include "content/public/common/user_agent.h"
|
||||
#include "content/shell/grit/shell_resources.h"
|
||||
#include "net/base/net_errors.h"
|
||||
#include "net/socket/stream_socket.h"
|
||||
#include "net/socket/tcp_server_socket.h"
|
||||
#include "ui/base/resource/resource_bundle.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace {
|
||||
|
||||
class TCPServerSocketFactory : public content::DevToolsSocketFactory {
|
||||
public:
|
||||
TCPServerSocketFactory(const std::string& address, int port)
|
||||
: address_(address), port_(port) {}
|
||||
|
||||
private:
|
||||
// content::ServerSocketFactory.
|
||||
std::unique_ptr<net::ServerSocket> CreateForHttpServer() override {
|
||||
std::unique_ptr<net::ServerSocket> socket(
|
||||
new net::TCPServerSocket(nullptr, net::NetLogSource()));
|
||||
if (socket->ListenWithAddressAndPort(address_, port_, 10) != net::OK)
|
||||
return std::unique_ptr<net::ServerSocket>();
|
||||
|
||||
return socket;
|
||||
}
|
||||
std::unique_ptr<net::ServerSocket> CreateForTethering(
|
||||
std::string* name) override {
|
||||
return std::unique_ptr<net::ServerSocket>();
|
||||
}
|
||||
|
||||
std::string address_;
|
||||
uint16_t port_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(TCPServerSocketFactory);
|
||||
};
|
||||
|
||||
std::unique_ptr<content::DevToolsSocketFactory> CreateSocketFactory() {
|
||||
auto& command_line = *base::CommandLine::ForCurrentProcess();
|
||||
// See if the user specified a port on the command line (useful for
|
||||
// automation). If not, use an ephemeral port by specifying 0.
|
||||
int port = 0;
|
||||
if (command_line.HasSwitch(switches::kRemoteDebuggingPort)) {
|
||||
int temp_port;
|
||||
std::string port_str =
|
||||
command_line.GetSwitchValueASCII(switches::kRemoteDebuggingPort);
|
||||
if (base::StringToInt(port_str, &temp_port) && temp_port > 0 &&
|
||||
temp_port < 65535) {
|
||||
port = temp_port;
|
||||
} else {
|
||||
DLOG(WARNING) << "Invalid http debugger port number " << temp_port;
|
||||
}
|
||||
}
|
||||
return std::unique_ptr<content::DevToolsSocketFactory>(
|
||||
new TCPServerSocketFactory("127.0.0.1", port));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// DevToolsManagerDelegate ---------------------------------------------------
|
||||
|
||||
// static
|
||||
void DevToolsManagerDelegate::StartHttpHandler() {
|
||||
content::DevToolsAgentHost::StartRemoteDebuggingServer(
|
||||
CreateSocketFactory(), base::FilePath(), base::FilePath());
|
||||
}
|
||||
|
||||
DevToolsManagerDelegate::DevToolsManagerDelegate() {}
|
||||
|
||||
DevToolsManagerDelegate::~DevToolsManagerDelegate() {}
|
||||
|
||||
void DevToolsManagerDelegate::Inspect(content::DevToolsAgentHost* agent_host) {}
|
||||
|
||||
bool DevToolsManagerDelegate::HandleCommand(
|
||||
content::DevToolsAgentHost* agent_host,
|
||||
content::DevToolsAgentHostClient* client,
|
||||
base::DictionaryValue* command) {
|
||||
return false;
|
||||
}
|
||||
|
||||
scoped_refptr<content::DevToolsAgentHost>
|
||||
DevToolsManagerDelegate::CreateNewTarget(const GURL& url) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::string DevToolsManagerDelegate::GetDiscoveryPageHTML() {
|
||||
return ui::ResourceBundle::GetSharedInstance()
|
||||
.GetRawDataResource(IDR_CONTENT_SHELL_DEVTOOLS_DISCOVERY_PAGE)
|
||||
.as_string();
|
||||
}
|
||||
|
||||
bool DevToolsManagerDelegate::HasBundledFrontendResources() {
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace atom
|
39
atom/browser/ui/devtools_manager_delegate.h
Normal file
39
atom/browser/ui/devtools_manager_delegate.h
Normal file
|
@ -0,0 +1,39 @@
|
|||
// Copyright (c) 2014 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-CHROMIUM file.
|
||||
|
||||
#ifndef ATOM_BROWSER_UI_DEVTOOLS_MANAGER_DELEGATE_H_
|
||||
#define ATOM_BROWSER_UI_DEVTOOLS_MANAGER_DELEGATE_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "base/compiler_specific.h"
|
||||
#include "base/macros.h"
|
||||
#include "content/public/browser/devtools_manager_delegate.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
class DevToolsManagerDelegate : public content::DevToolsManagerDelegate {
|
||||
public:
|
||||
static void StartHttpHandler();
|
||||
|
||||
DevToolsManagerDelegate();
|
||||
~DevToolsManagerDelegate() override;
|
||||
|
||||
// DevToolsManagerDelegate implementation.
|
||||
void Inspect(content::DevToolsAgentHost* agent_host) override;
|
||||
bool HandleCommand(content::DevToolsAgentHost* agent_host,
|
||||
content::DevToolsAgentHostClient* client,
|
||||
base::DictionaryValue* command) override;
|
||||
scoped_refptr<content::DevToolsAgentHost> CreateNewTarget(
|
||||
const GURL& url) override;
|
||||
std::string GetDiscoveryPageHTML() override;
|
||||
bool HasBundledFrontendResources() override;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(DevToolsManagerDelegate);
|
||||
};
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_UI_DEVTOOLS_MANAGER_DELEGATE_H_
|
120
atom/browser/ui/devtools_ui.cc
Normal file
120
atom/browser/ui/devtools_ui.cc
Normal file
|
@ -0,0 +1,120 @@
|
|||
// Copyright (c) 2012 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-CHROMIUM file.
|
||||
|
||||
#include "atom/browser/ui/devtools_ui.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "base/memory/ref_counted_memory.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/strings/stringprintf.h"
|
||||
#include "content/public/browser/devtools_frontend_host.h"
|
||||
#include "content/public/browser/url_data_source.h"
|
||||
#include "content/public/browser/web_contents.h"
|
||||
#include "content/public/browser/web_ui.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace {
|
||||
|
||||
const char kChromeUIDevToolsHost[] = "devtools";
|
||||
const char kChromeUIDevToolsBundledPath[] = "bundled";
|
||||
|
||||
std::string PathWithoutParams(const std::string& path) {
|
||||
return GURL(std::string("chrome-devtools://devtools/") + path)
|
||||
.path()
|
||||
.substr(1);
|
||||
}
|
||||
|
||||
std::string GetMimeTypeForPath(const std::string& path) {
|
||||
std::string filename = PathWithoutParams(path);
|
||||
if (base::EndsWith(filename, ".html", base::CompareCase::INSENSITIVE_ASCII)) {
|
||||
return "text/html";
|
||||
} else if (base::EndsWith(filename, ".css",
|
||||
base::CompareCase::INSENSITIVE_ASCII)) {
|
||||
return "text/css";
|
||||
} else if (base::EndsWith(filename, ".js",
|
||||
base::CompareCase::INSENSITIVE_ASCII)) {
|
||||
return "application/javascript";
|
||||
} else if (base::EndsWith(filename, ".png",
|
||||
base::CompareCase::INSENSITIVE_ASCII)) {
|
||||
return "image/png";
|
||||
} else if (base::EndsWith(filename, ".gif",
|
||||
base::CompareCase::INSENSITIVE_ASCII)) {
|
||||
return "image/gif";
|
||||
} else if (base::EndsWith(filename, ".svg",
|
||||
base::CompareCase::INSENSITIVE_ASCII)) {
|
||||
return "image/svg+xml";
|
||||
} else if (base::EndsWith(filename, ".manifest",
|
||||
base::CompareCase::INSENSITIVE_ASCII)) {
|
||||
return "text/cache-manifest";
|
||||
}
|
||||
return "text/html";
|
||||
}
|
||||
|
||||
class BundledDataSource : public content::URLDataSource {
|
||||
public:
|
||||
BundledDataSource() {}
|
||||
|
||||
// content::URLDataSource implementation.
|
||||
std::string GetSource() const override { return kChromeUIDevToolsHost; }
|
||||
|
||||
void StartDataRequest(
|
||||
const std::string& path,
|
||||
const content::ResourceRequestInfo::WebContentsGetter& wc_getter,
|
||||
const GotDataCallback& callback) override {
|
||||
// Serve request from local bundle.
|
||||
std::string bundled_path_prefix(kChromeUIDevToolsBundledPath);
|
||||
bundled_path_prefix += "/";
|
||||
if (base::StartsWith(path, bundled_path_prefix,
|
||||
base::CompareCase::INSENSITIVE_ASCII)) {
|
||||
StartBundledDataRequest(path.substr(bundled_path_prefix.length()),
|
||||
callback);
|
||||
return;
|
||||
}
|
||||
|
||||
// We do not handle remote and custom requests.
|
||||
callback.Run(nullptr);
|
||||
}
|
||||
|
||||
std::string GetMimeType(const std::string& path) const override {
|
||||
return GetMimeTypeForPath(path);
|
||||
}
|
||||
|
||||
bool ShouldAddContentSecurityPolicy() const override { return false; }
|
||||
|
||||
bool ShouldDenyXFrameOptions() const override { return false; }
|
||||
|
||||
bool ShouldServeMimeTypeAsContentTypeHeader() const override { return true; }
|
||||
|
||||
void StartBundledDataRequest(const std::string& path,
|
||||
const GotDataCallback& callback) {
|
||||
std::string filename = PathWithoutParams(path);
|
||||
base::StringPiece resource =
|
||||
content::DevToolsFrontendHost::GetFrontendResource(filename);
|
||||
|
||||
DLOG_IF(WARNING, resource.empty())
|
||||
<< "Unable to find dev tool resource: " << filename
|
||||
<< ". If you compiled with debug_devtools=1, try running with "
|
||||
"--debug-devtools.";
|
||||
scoped_refptr<base::RefCountedStaticMemory> bytes(
|
||||
new base::RefCountedStaticMemory(resource.data(), resource.length()));
|
||||
callback.Run(bytes.get());
|
||||
}
|
||||
|
||||
private:
|
||||
~BundledDataSource() override {}
|
||||
DISALLOW_COPY_AND_ASSIGN(BundledDataSource);
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
DevToolsUI::DevToolsUI(content::BrowserContext* browser_context,
|
||||
content::WebUI* web_ui)
|
||||
: WebUIController(web_ui) {
|
||||
web_ui->SetBindings(0);
|
||||
content::URLDataSource::Add(browser_context, new BundledDataSource());
|
||||
}
|
||||
|
||||
} // namespace atom
|
27
atom/browser/ui/devtools_ui.h
Normal file
27
atom/browser/ui/devtools_ui.h
Normal file
|
@ -0,0 +1,27 @@
|
|||
// Copyright (c) 2011 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-CHROMIUM file.
|
||||
|
||||
#ifndef ATOM_BROWSER_UI_DEVTOOLS_UI_H_
|
||||
#define ATOM_BROWSER_UI_DEVTOOLS_UI_H_
|
||||
|
||||
#include "base/compiler_specific.h"
|
||||
#include "content/public/browser/browser_context.h"
|
||||
#include "content/public/browser/web_ui_controller.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
class BrowserContext;
|
||||
|
||||
class DevToolsUI : public content::WebUIController {
|
||||
public:
|
||||
explicit DevToolsUI(content::BrowserContext* browser_context,
|
||||
content::WebUI* web_ui);
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(DevToolsUI);
|
||||
};
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_UI_DEVTOOLS_UI_H_
|
19
atom/browser/ui/inspectable_web_contents.cc
Normal file
19
atom/browser/ui/inspectable_web_contents.cc
Normal file
|
@ -0,0 +1,19 @@
|
|||
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
||||
// Copyright (c) 2013 Adam Roben <adam@roben.org>. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE-CHROMIUM file.
|
||||
|
||||
#include "atom/browser/ui/inspectable_web_contents.h"
|
||||
|
||||
#include "atom/browser/ui/inspectable_web_contents_impl.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
InspectableWebContents* InspectableWebContents::Create(
|
||||
content::WebContents* web_contents,
|
||||
PrefService* pref_service,
|
||||
bool is_guest) {
|
||||
return new InspectableWebContentsImpl(web_contents, pref_service, is_guest);
|
||||
}
|
||||
|
||||
} // namespace atom
|
64
atom/browser/ui/inspectable_web_contents.h
Normal file
64
atom/browser/ui/inspectable_web_contents.h
Normal file
|
@ -0,0 +1,64 @@
|
|||
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
||||
// Copyright (c) 2013 Adam Roben <adam@roben.org>. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE-CHROMIUM file.
|
||||
|
||||
#ifndef ATOM_BROWSER_UI_INSPECTABLE_WEB_CONTENTS_H_
|
||||
#define ATOM_BROWSER_UI_INSPECTABLE_WEB_CONTENTS_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "content/public/browser/web_contents.h"
|
||||
|
||||
namespace base {
|
||||
class Value;
|
||||
}
|
||||
|
||||
namespace content {
|
||||
class DevToolsAgentHost;
|
||||
}
|
||||
|
||||
class PrefService;
|
||||
|
||||
namespace atom {
|
||||
|
||||
class InspectableWebContentsDelegate;
|
||||
class InspectableWebContentsView;
|
||||
|
||||
class InspectableWebContents {
|
||||
public:
|
||||
// The returned InspectableWebContents takes ownership of the passed-in
|
||||
// WebContents.
|
||||
static InspectableWebContents* Create(content::WebContents* web_contents,
|
||||
PrefService* pref_service,
|
||||
bool is_guest);
|
||||
|
||||
virtual ~InspectableWebContents() {}
|
||||
|
||||
virtual InspectableWebContentsView* GetView() const = 0;
|
||||
virtual content::WebContents* GetWebContents() const = 0;
|
||||
virtual content::WebContents* GetDevToolsWebContents() const = 0;
|
||||
|
||||
// The delegate manages its own life.
|
||||
virtual void SetDelegate(InspectableWebContentsDelegate* delegate) = 0;
|
||||
virtual InspectableWebContentsDelegate* GetDelegate() const = 0;
|
||||
|
||||
virtual bool IsGuest() const = 0;
|
||||
virtual void ReleaseWebContents() = 0;
|
||||
virtual void SetDevToolsWebContents(content::WebContents* devtools) = 0;
|
||||
virtual void SetDockState(const std::string& state) = 0;
|
||||
virtual void ShowDevTools() = 0;
|
||||
virtual void CloseDevTools() = 0;
|
||||
virtual bool IsDevToolsViewShowing() = 0;
|
||||
virtual void AttachTo(scoped_refptr<content::DevToolsAgentHost>) = 0;
|
||||
virtual void Detach() = 0;
|
||||
virtual void CallClientFunction(const std::string& function_name,
|
||||
const base::Value* arg1 = nullptr,
|
||||
const base::Value* arg2 = nullptr,
|
||||
const base::Value* arg3 = nullptr) = 0;
|
||||
virtual void InspectElement(int x, int y) = 0;
|
||||
};
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_UI_INSPECTABLE_WEB_CONTENTS_H_
|
42
atom/browser/ui/inspectable_web_contents_delegate.h
Normal file
42
atom/browser/ui/inspectable_web_contents_delegate.h
Normal file
|
@ -0,0 +1,42 @@
|
|||
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
||||
// Copyright (c) 2013 Adam Roben <adam@roben.org>. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE-CHROMIUM file.
|
||||
|
||||
#ifndef ATOM_BROWSER_UI_INSPECTABLE_WEB_CONTENTS_DELEGATE_H_
|
||||
#define ATOM_BROWSER_UI_INSPECTABLE_WEB_CONTENTS_DELEGATE_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "base/files/file_path.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
class InspectableWebContentsDelegate {
|
||||
public:
|
||||
virtual ~InspectableWebContentsDelegate() {}
|
||||
|
||||
// Requested by WebContents of devtools.
|
||||
virtual void DevToolsReloadPage() {}
|
||||
virtual void DevToolsSaveToFile(const std::string& url,
|
||||
const std::string& content,
|
||||
bool save_as) {}
|
||||
virtual void DevToolsAppendToFile(const std::string& url,
|
||||
const std::string& content) {}
|
||||
virtual void DevToolsRequestFileSystems() {}
|
||||
virtual void DevToolsAddFileSystem(const std::string& type,
|
||||
const base::FilePath& file_system_path) {}
|
||||
virtual void DevToolsRemoveFileSystem(
|
||||
const base::FilePath& file_system_path) {}
|
||||
virtual void DevToolsIndexPath(int request_id,
|
||||
const std::string& file_system_path,
|
||||
const std::string& excluded_folders) {}
|
||||
virtual void DevToolsStopIndexing(int request_id) {}
|
||||
virtual void DevToolsSearchInPath(int request_id,
|
||||
const std::string& file_system_path,
|
||||
const std::string& query) {}
|
||||
};
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_UI_INSPECTABLE_WEB_CONTENTS_DELEGATE_H_
|
897
atom/browser/ui/inspectable_web_contents_impl.cc
Normal file
897
atom/browser/ui/inspectable_web_contents_impl.cc
Normal file
|
@ -0,0 +1,897 @@
|
|||
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
||||
// Copyright (c) 2013 Adam Roben <adam@roben.org>. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE-CHROMIUM file.
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#include "atom/browser/ui/inspectable_web_contents_impl.h"
|
||||
|
||||
#include "atom/browser/ui/inspectable_web_contents_delegate.h"
|
||||
#include "atom/browser/ui/inspectable_web_contents_view.h"
|
||||
#include "atom/browser/ui/inspectable_web_contents_view_delegate.h"
|
||||
#include "atom/common/platform_util.h"
|
||||
#include "base/guid.h"
|
||||
#include "base/json/json_reader.h"
|
||||
#include "base/json/json_writer.h"
|
||||
#include "base/metrics/histogram.h"
|
||||
#include "base/strings/pattern.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/strings/stringprintf.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "base/values.h"
|
||||
#include "components/prefs/pref_registry_simple.h"
|
||||
#include "components/prefs/pref_service.h"
|
||||
#include "components/prefs/scoped_user_pref_update.h"
|
||||
#include "content/public/browser/browser_context.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/browser/host_zoom_map.h"
|
||||
#include "content/public/browser/navigation_handle.h"
|
||||
#include "content/public/browser/render_frame_host.h"
|
||||
#include "content/public/browser/render_view_host.h"
|
||||
#include "content/public/browser/storage_partition.h"
|
||||
#include "content/public/common/user_agent.h"
|
||||
#include "ipc/ipc_channel.h"
|
||||
#include "net/base/io_buffer.h"
|
||||
#include "net/http/http_response_headers.h"
|
||||
#include "net/url_request/url_fetcher.h"
|
||||
#include "net/url_request/url_fetcher_response_writer.h"
|
||||
#include "ui/display/display.h"
|
||||
#include "ui/display/screen.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace {
|
||||
|
||||
const double kPresetZoomFactors[] = {0.25, 0.333, 0.5, 0.666, 0.75, 0.9,
|
||||
1.0, 1.1, 1.25, 1.5, 1.75, 2.0,
|
||||
2.5, 3.0, 4.0, 5.0};
|
||||
|
||||
const char kChromeUIDevToolsURL[] =
|
||||
"chrome-devtools://devtools/bundled/devtools_app.html?"
|
||||
"remoteBase=%s&"
|
||||
"can_dock=%s&"
|
||||
"toolbarColor=rgba(223,223,223,1)&"
|
||||
"textColor=rgba(0,0,0,1)&"
|
||||
"experiments=true";
|
||||
const char kChromeUIDevToolsRemoteFrontendBase[] =
|
||||
"https://chrome-devtools-frontend.appspot.com/";
|
||||
const char kChromeUIDevToolsRemoteFrontendPath[] = "serve_file";
|
||||
|
||||
const char kDevToolsBoundsPref[] = "brightray.devtools.bounds";
|
||||
const char kDevToolsZoomPref[] = "brightray.devtools.zoom";
|
||||
const char kDevToolsPreferences[] = "brightray.devtools.preferences";
|
||||
|
||||
const char kFrontendHostId[] = "id";
|
||||
const char kFrontendHostMethod[] = "method";
|
||||
const char kFrontendHostParams[] = "params";
|
||||
const char kTitleFormat[] = "Developer Tools - %s";
|
||||
|
||||
const size_t kMaxMessageChunkSize = IPC::Channel::kMaximumMessageSize / 4;
|
||||
|
||||
void RectToDictionary(const gfx::Rect& bounds, base::DictionaryValue* dict) {
|
||||
dict->SetInteger("x", bounds.x());
|
||||
dict->SetInteger("y", bounds.y());
|
||||
dict->SetInteger("width", bounds.width());
|
||||
dict->SetInteger("height", bounds.height());
|
||||
}
|
||||
|
||||
void DictionaryToRect(const base::DictionaryValue& dict, gfx::Rect* bounds) {
|
||||
int x = 0, y = 0, width = 800, height = 600;
|
||||
dict.GetInteger("x", &x);
|
||||
dict.GetInteger("y", &y);
|
||||
dict.GetInteger("width", &width);
|
||||
dict.GetInteger("height", &height);
|
||||
*bounds = gfx::Rect(x, y, width, height);
|
||||
}
|
||||
|
||||
bool IsPointInRect(const gfx::Point& point, const gfx::Rect& rect) {
|
||||
return point.x() > rect.x() && point.x() < (rect.width() + rect.x()) &&
|
||||
point.y() > rect.y() && point.y() < (rect.height() + rect.y());
|
||||
}
|
||||
|
||||
bool IsPointInScreen(const gfx::Point& point) {
|
||||
for (const auto& display : display::Screen::GetScreen()->GetAllDisplays()) {
|
||||
if (IsPointInRect(point, display.bounds()))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void SetZoomLevelForWebContents(content::WebContents* web_contents,
|
||||
double level) {
|
||||
content::HostZoomMap::SetZoomLevel(web_contents, level);
|
||||
}
|
||||
|
||||
double GetNextZoomLevel(double level, bool out) {
|
||||
double factor = content::ZoomLevelToZoomFactor(level);
|
||||
size_t size = arraysize(kPresetZoomFactors);
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
if (!content::ZoomValuesEqual(kPresetZoomFactors[i], factor))
|
||||
continue;
|
||||
if (out && i > 0)
|
||||
return content::ZoomFactorToZoomLevel(kPresetZoomFactors[i - 1]);
|
||||
if (!out && i != size - 1)
|
||||
return content::ZoomFactorToZoomLevel(kPresetZoomFactors[i + 1]);
|
||||
}
|
||||
return level;
|
||||
}
|
||||
|
||||
GURL GetRemoteBaseURL() {
|
||||
return GURL(base::StringPrintf("%s%s/%s/",
|
||||
kChromeUIDevToolsRemoteFrontendBase,
|
||||
kChromeUIDevToolsRemoteFrontendPath,
|
||||
content::GetWebKitRevision().c_str()));
|
||||
}
|
||||
|
||||
GURL GetDevToolsURL(bool can_dock) {
|
||||
auto url_string = base::StringPrintf(kChromeUIDevToolsURL,
|
||||
GetRemoteBaseURL().spec().c_str(),
|
||||
can_dock ? "true" : "");
|
||||
return GURL(url_string);
|
||||
}
|
||||
|
||||
// ResponseWriter -------------------------------------------------------------
|
||||
|
||||
class ResponseWriter : public net::URLFetcherResponseWriter {
|
||||
public:
|
||||
ResponseWriter(base::WeakPtr<InspectableWebContentsImpl> bindings,
|
||||
int stream_id);
|
||||
~ResponseWriter() override;
|
||||
|
||||
// URLFetcherResponseWriter overrides:
|
||||
int Initialize(const net::CompletionCallback& callback) override;
|
||||
int Write(net::IOBuffer* buffer,
|
||||
int num_bytes,
|
||||
const net::CompletionCallback& callback) override;
|
||||
int Finish(int net_error, const net::CompletionCallback& callback) override;
|
||||
|
||||
private:
|
||||
base::WeakPtr<InspectableWebContentsImpl> bindings_;
|
||||
int stream_id_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(ResponseWriter);
|
||||
};
|
||||
|
||||
ResponseWriter::ResponseWriter(
|
||||
base::WeakPtr<InspectableWebContentsImpl> bindings,
|
||||
int stream_id)
|
||||
: bindings_(bindings), stream_id_(stream_id) {}
|
||||
|
||||
ResponseWriter::~ResponseWriter() {}
|
||||
|
||||
int ResponseWriter::Initialize(const net::CompletionCallback& callback) {
|
||||
return net::OK;
|
||||
}
|
||||
|
||||
int ResponseWriter::Write(net::IOBuffer* buffer,
|
||||
int num_bytes,
|
||||
const net::CompletionCallback& callback) {
|
||||
std::string chunk = std::string(buffer->data(), num_bytes);
|
||||
if (!base::IsStringUTF8(chunk))
|
||||
return num_bytes;
|
||||
|
||||
base::Value* id = new base::Value(stream_id_);
|
||||
base::Value* chunk_value = new base::Value(chunk);
|
||||
|
||||
content::BrowserThread::PostTask(
|
||||
content::BrowserThread::UI, FROM_HERE,
|
||||
base::BindOnce(&InspectableWebContentsImpl::CallClientFunction, bindings_,
|
||||
"DevToolsAPI.streamWrite", base::Owned(id),
|
||||
base::Owned(chunk_value), nullptr));
|
||||
return num_bytes;
|
||||
}
|
||||
|
||||
int ResponseWriter::Finish(int net_error,
|
||||
const net::CompletionCallback& callback) {
|
||||
return net::OK;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// Implemented separately on each platform.
|
||||
InspectableWebContentsView* CreateInspectableContentsView(
|
||||
InspectableWebContentsImpl* inspectable_web_contents_impl);
|
||||
|
||||
void InspectableWebContentsImpl::RegisterPrefs(PrefRegistrySimple* registry) {
|
||||
std::unique_ptr<base::DictionaryValue> bounds_dict(new base::DictionaryValue);
|
||||
RectToDictionary(gfx::Rect(0, 0, 800, 600), bounds_dict.get());
|
||||
registry->RegisterDictionaryPref(kDevToolsBoundsPref, std::move(bounds_dict));
|
||||
registry->RegisterDoublePref(kDevToolsZoomPref, 0.);
|
||||
registry->RegisterDictionaryPref(kDevToolsPreferences);
|
||||
}
|
||||
|
||||
InspectableWebContentsImpl::InspectableWebContentsImpl(
|
||||
content::WebContents* web_contents,
|
||||
PrefService* pref_service,
|
||||
bool is_guest)
|
||||
: frontend_loaded_(false),
|
||||
can_dock_(true),
|
||||
delegate_(nullptr),
|
||||
pref_service_(pref_service),
|
||||
web_contents_(web_contents),
|
||||
is_guest_(is_guest),
|
||||
view_(CreateInspectableContentsView(this)),
|
||||
weak_factory_(this) {
|
||||
auto* bounds_dict = pref_service_->GetDictionary(kDevToolsBoundsPref);
|
||||
if (bounds_dict) {
|
||||
DictionaryToRect(*bounds_dict, &devtools_bounds_);
|
||||
// Sometimes the devtools window is out of screen or has too small size.
|
||||
if (devtools_bounds_.height() < 100 || devtools_bounds_.width() < 100) {
|
||||
devtools_bounds_.set_height(600);
|
||||
devtools_bounds_.set_width(800);
|
||||
}
|
||||
if (!IsPointInScreen(devtools_bounds_.origin())) {
|
||||
gfx::Rect display;
|
||||
if (!is_guest && web_contents->GetNativeView()) {
|
||||
display = display::Screen::GetScreen()
|
||||
->GetDisplayNearestView(web_contents->GetNativeView())
|
||||
.bounds();
|
||||
} else {
|
||||
display = display::Screen::GetScreen()->GetPrimaryDisplay().bounds();
|
||||
}
|
||||
|
||||
devtools_bounds_.set_x(display.x() +
|
||||
(display.width() - devtools_bounds_.width()) / 2);
|
||||
devtools_bounds_.set_y(
|
||||
display.y() + (display.height() - devtools_bounds_.height()) / 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
InspectableWebContentsImpl::~InspectableWebContentsImpl() {
|
||||
// Unsubscribe from devtools and Clean up resources.
|
||||
if (GetDevToolsWebContents()) {
|
||||
if (managed_devtools_web_contents_)
|
||||
managed_devtools_web_contents_->SetDelegate(nullptr);
|
||||
// Calling this also unsubscribes the observer, so WebContentsDestroyed
|
||||
// won't be called again.
|
||||
WebContentsDestroyed();
|
||||
}
|
||||
// Let destructor destroy managed_devtools_web_contents_.
|
||||
}
|
||||
|
||||
InspectableWebContentsView* InspectableWebContentsImpl::GetView() const {
|
||||
return view_.get();
|
||||
}
|
||||
|
||||
content::WebContents* InspectableWebContentsImpl::GetWebContents() const {
|
||||
return web_contents_.get();
|
||||
}
|
||||
|
||||
content::WebContents* InspectableWebContentsImpl::GetDevToolsWebContents()
|
||||
const {
|
||||
if (external_devtools_web_contents_)
|
||||
return external_devtools_web_contents_;
|
||||
else
|
||||
return managed_devtools_web_contents_.get();
|
||||
}
|
||||
|
||||
void InspectableWebContentsImpl::InspectElement(int x, int y) {
|
||||
if (agent_host_)
|
||||
agent_host_->InspectElement(web_contents_->GetMainFrame(), x, y);
|
||||
}
|
||||
|
||||
void InspectableWebContentsImpl::SetDelegate(
|
||||
InspectableWebContentsDelegate* delegate) {
|
||||
delegate_ = delegate;
|
||||
}
|
||||
|
||||
InspectableWebContentsDelegate* InspectableWebContentsImpl::GetDelegate()
|
||||
const {
|
||||
return delegate_;
|
||||
}
|
||||
|
||||
bool InspectableWebContentsImpl::IsGuest() const {
|
||||
return is_guest_;
|
||||
}
|
||||
|
||||
void InspectableWebContentsImpl::ReleaseWebContents() {
|
||||
web_contents_.release();
|
||||
}
|
||||
|
||||
void InspectableWebContentsImpl::SetDockState(const std::string& state) {
|
||||
if (state == "detach") {
|
||||
can_dock_ = false;
|
||||
} else {
|
||||
can_dock_ = true;
|
||||
dock_state_ = state;
|
||||
}
|
||||
}
|
||||
|
||||
void InspectableWebContentsImpl::SetDevToolsWebContents(
|
||||
content::WebContents* devtools) {
|
||||
if (!managed_devtools_web_contents_)
|
||||
external_devtools_web_contents_ = devtools;
|
||||
}
|
||||
|
||||
void InspectableWebContentsImpl::ShowDevTools() {
|
||||
if (embedder_message_dispatcher_) {
|
||||
if (managed_devtools_web_contents_)
|
||||
view_->ShowDevTools();
|
||||
return;
|
||||
}
|
||||
|
||||
// Show devtools only after it has done loading, this is to make sure the
|
||||
// SetIsDocked is called *BEFORE* ShowDevTools.
|
||||
embedder_message_dispatcher_.reset(
|
||||
DevToolsEmbedderMessageDispatcher::CreateForDevToolsFrontend(this));
|
||||
|
||||
if (!external_devtools_web_contents_) { // no external devtools
|
||||
managed_devtools_web_contents_ = content::WebContents::Create(
|
||||
content::WebContents::CreateParams(web_contents_->GetBrowserContext()));
|
||||
managed_devtools_web_contents_->SetDelegate(this);
|
||||
}
|
||||
|
||||
Observe(GetDevToolsWebContents());
|
||||
AttachTo(content::DevToolsAgentHost::GetOrCreateFor(web_contents_.get()));
|
||||
|
||||
GetDevToolsWebContents()->GetController().LoadURL(
|
||||
GetDevToolsURL(can_dock_), content::Referrer(),
|
||||
ui::PAGE_TRANSITION_AUTO_TOPLEVEL, std::string());
|
||||
}
|
||||
|
||||
void InspectableWebContentsImpl::CloseDevTools() {
|
||||
if (GetDevToolsWebContents()) {
|
||||
frontend_loaded_ = false;
|
||||
if (managed_devtools_web_contents_) {
|
||||
view_->CloseDevTools();
|
||||
managed_devtools_web_contents_.reset();
|
||||
}
|
||||
embedder_message_dispatcher_.reset();
|
||||
if (!IsGuest())
|
||||
web_contents_->Focus();
|
||||
}
|
||||
}
|
||||
|
||||
bool InspectableWebContentsImpl::IsDevToolsViewShowing() {
|
||||
return managed_devtools_web_contents_ && view_->IsDevToolsViewShowing();
|
||||
}
|
||||
|
||||
void InspectableWebContentsImpl::AttachTo(
|
||||
scoped_refptr<content::DevToolsAgentHost> host) {
|
||||
Detach();
|
||||
agent_host_ = std::move(host);
|
||||
// We could use ForceAttachClient here if problem arises with
|
||||
// devtools multiple session support.
|
||||
agent_host_->AttachClient(this);
|
||||
}
|
||||
|
||||
void InspectableWebContentsImpl::Detach() {
|
||||
if (agent_host_)
|
||||
agent_host_->DetachClient(this);
|
||||
agent_host_ = nullptr;
|
||||
}
|
||||
|
||||
void InspectableWebContentsImpl::Reattach(const DispatchCallback& callback) {
|
||||
if (agent_host_) {
|
||||
agent_host_->DetachClient(this);
|
||||
agent_host_->AttachClient(this);
|
||||
}
|
||||
callback.Run(nullptr);
|
||||
}
|
||||
|
||||
void InspectableWebContentsImpl::CallClientFunction(
|
||||
const std::string& function_name,
|
||||
const base::Value* arg1,
|
||||
const base::Value* arg2,
|
||||
const base::Value* arg3) {
|
||||
if (!GetDevToolsWebContents())
|
||||
return;
|
||||
|
||||
std::string javascript = function_name + "(";
|
||||
if (arg1) {
|
||||
std::string json;
|
||||
base::JSONWriter::Write(*arg1, &json);
|
||||
javascript.append(json);
|
||||
if (arg2) {
|
||||
base::JSONWriter::Write(*arg2, &json);
|
||||
javascript.append(", ").append(json);
|
||||
if (arg3) {
|
||||
base::JSONWriter::Write(*arg3, &json);
|
||||
javascript.append(", ").append(json);
|
||||
}
|
||||
}
|
||||
}
|
||||
javascript.append(");");
|
||||
GetDevToolsWebContents()->GetMainFrame()->ExecuteJavaScript(
|
||||
base::UTF8ToUTF16(javascript));
|
||||
}
|
||||
|
||||
gfx::Rect InspectableWebContentsImpl::GetDevToolsBounds() const {
|
||||
return devtools_bounds_;
|
||||
}
|
||||
|
||||
void InspectableWebContentsImpl::SaveDevToolsBounds(const gfx::Rect& bounds) {
|
||||
base::DictionaryValue bounds_dict;
|
||||
RectToDictionary(bounds, &bounds_dict);
|
||||
pref_service_->Set(kDevToolsBoundsPref, bounds_dict);
|
||||
devtools_bounds_ = bounds;
|
||||
}
|
||||
|
||||
double InspectableWebContentsImpl::GetDevToolsZoomLevel() const {
|
||||
return pref_service_->GetDouble(kDevToolsZoomPref);
|
||||
}
|
||||
|
||||
void InspectableWebContentsImpl::UpdateDevToolsZoomLevel(double level) {
|
||||
pref_service_->SetDouble(kDevToolsZoomPref, level);
|
||||
}
|
||||
|
||||
void InspectableWebContentsImpl::ActivateWindow() {
|
||||
// Set the zoom level.
|
||||
SetZoomLevelForWebContents(GetDevToolsWebContents(), GetDevToolsZoomLevel());
|
||||
}
|
||||
|
||||
void InspectableWebContentsImpl::CloseWindow() {
|
||||
GetDevToolsWebContents()->DispatchBeforeUnload();
|
||||
}
|
||||
|
||||
void InspectableWebContentsImpl::LoadCompleted() {
|
||||
frontend_loaded_ = true;
|
||||
if (managed_devtools_web_contents_)
|
||||
view_->ShowDevTools();
|
||||
|
||||
// If the devtools can dock, "SetIsDocked" will be called by devtools itself.
|
||||
if (!can_dock_) {
|
||||
SetIsDocked(DispatchCallback(), false);
|
||||
} else {
|
||||
if (dock_state_.empty()) {
|
||||
const base::DictionaryValue* prefs =
|
||||
pref_service_->GetDictionary(kDevToolsPreferences);
|
||||
std::string current_dock_state;
|
||||
prefs->GetString("currentDockState", ¤t_dock_state);
|
||||
base::RemoveChars(current_dock_state, "\"", &dock_state_);
|
||||
}
|
||||
base::string16 javascript = base::UTF8ToUTF16(
|
||||
"Components.dockController.setDockSide(\"" + dock_state_ + "\");");
|
||||
GetDevToolsWebContents()->GetMainFrame()->ExecuteJavaScript(javascript);
|
||||
}
|
||||
|
||||
if (view_->GetDelegate())
|
||||
view_->GetDelegate()->DevToolsOpened();
|
||||
}
|
||||
|
||||
void InspectableWebContentsImpl::SetInspectedPageBounds(const gfx::Rect& rect) {
|
||||
DevToolsContentsResizingStrategy strategy(rect);
|
||||
if (contents_resizing_strategy_.Equals(strategy))
|
||||
return;
|
||||
|
||||
contents_resizing_strategy_.CopyFrom(strategy);
|
||||
if (managed_devtools_web_contents_)
|
||||
view_->SetContentsResizingStrategy(contents_resizing_strategy_);
|
||||
}
|
||||
|
||||
void InspectableWebContentsImpl::InspectElementCompleted() {}
|
||||
|
||||
void InspectableWebContentsImpl::InspectedURLChanged(const std::string& url) {
|
||||
if (managed_devtools_web_contents_)
|
||||
view_->SetTitle(
|
||||
base::UTF8ToUTF16(base::StringPrintf(kTitleFormat, url.c_str())));
|
||||
}
|
||||
|
||||
void InspectableWebContentsImpl::LoadNetworkResource(
|
||||
const DispatchCallback& callback,
|
||||
const std::string& url,
|
||||
const std::string& headers,
|
||||
int stream_id) {
|
||||
GURL gurl(url);
|
||||
if (!gurl.is_valid()) {
|
||||
base::DictionaryValue response;
|
||||
response.SetInteger("statusCode", 404);
|
||||
callback.Run(&response);
|
||||
return;
|
||||
}
|
||||
|
||||
auto* browser_context = GetDevToolsWebContents()->GetBrowserContext();
|
||||
|
||||
net::URLFetcher* fetcher =
|
||||
(net::URLFetcher::Create(gurl, net::URLFetcher::GET, this)).release();
|
||||
pending_requests_[fetcher] = callback;
|
||||
fetcher->SetRequestContext(
|
||||
content::BrowserContext::GetDefaultStoragePartition(browser_context)
|
||||
->GetURLRequestContext());
|
||||
fetcher->SetExtraRequestHeaders(headers);
|
||||
fetcher->SaveResponseWithWriter(
|
||||
std::unique_ptr<net::URLFetcherResponseWriter>(
|
||||
new ResponseWriter(weak_factory_.GetWeakPtr(), stream_id)));
|
||||
fetcher->Start();
|
||||
}
|
||||
|
||||
void InspectableWebContentsImpl::SetIsDocked(const DispatchCallback& callback,
|
||||
bool docked) {
|
||||
if (managed_devtools_web_contents_)
|
||||
view_->SetIsDocked(docked);
|
||||
if (!callback.is_null())
|
||||
callback.Run(nullptr);
|
||||
}
|
||||
|
||||
void InspectableWebContentsImpl::OpenInNewTab(const std::string& url) {}
|
||||
|
||||
void InspectableWebContentsImpl::ShowItemInFolder(
|
||||
const std::string& file_system_path) {
|
||||
if (file_system_path.empty())
|
||||
return;
|
||||
base::FilePath path = base::FilePath::FromUTF8Unsafe(file_system_path);
|
||||
platform_util::ShowItemInFolder(path);
|
||||
}
|
||||
|
||||
void InspectableWebContentsImpl::SaveToFile(const std::string& url,
|
||||
const std::string& content,
|
||||
bool save_as) {
|
||||
if (delegate_)
|
||||
delegate_->DevToolsSaveToFile(url, content, save_as);
|
||||
}
|
||||
|
||||
void InspectableWebContentsImpl::AppendToFile(const std::string& url,
|
||||
const std::string& content) {
|
||||
if (delegate_)
|
||||
delegate_->DevToolsAppendToFile(url, content);
|
||||
}
|
||||
|
||||
void InspectableWebContentsImpl::RequestFileSystems() {
|
||||
if (delegate_)
|
||||
delegate_->DevToolsRequestFileSystems();
|
||||
}
|
||||
|
||||
void InspectableWebContentsImpl::AddFileSystem(const std::string& type) {
|
||||
if (delegate_)
|
||||
delegate_->DevToolsAddFileSystem(type, base::FilePath());
|
||||
}
|
||||
|
||||
void InspectableWebContentsImpl::RemoveFileSystem(
|
||||
const std::string& file_system_path) {
|
||||
if (delegate_)
|
||||
delegate_->DevToolsRemoveFileSystem(
|
||||
base::FilePath::FromUTF8Unsafe(file_system_path));
|
||||
}
|
||||
|
||||
void InspectableWebContentsImpl::UpgradeDraggedFileSystemPermissions(
|
||||
const std::string& file_system_url) {}
|
||||
|
||||
void InspectableWebContentsImpl::IndexPath(
|
||||
int request_id,
|
||||
const std::string& file_system_path,
|
||||
const std::string& excluded_folders) {
|
||||
if (delegate_)
|
||||
delegate_->DevToolsIndexPath(request_id, file_system_path,
|
||||
excluded_folders);
|
||||
}
|
||||
|
||||
void InspectableWebContentsImpl::StopIndexing(int request_id) {
|
||||
if (delegate_)
|
||||
delegate_->DevToolsStopIndexing(request_id);
|
||||
}
|
||||
|
||||
void InspectableWebContentsImpl::SearchInPath(
|
||||
int request_id,
|
||||
const std::string& file_system_path,
|
||||
const std::string& query) {
|
||||
if (delegate_)
|
||||
delegate_->DevToolsSearchInPath(request_id, file_system_path, query);
|
||||
}
|
||||
|
||||
void InspectableWebContentsImpl::SetWhitelistedShortcuts(
|
||||
const std::string& message) {}
|
||||
|
||||
void InspectableWebContentsImpl::SetEyeDropperActive(bool active) {}
|
||||
void InspectableWebContentsImpl::ShowCertificateViewer(
|
||||
const std::string& cert_chain) {}
|
||||
|
||||
void InspectableWebContentsImpl::ZoomIn() {
|
||||
double new_level = GetNextZoomLevel(GetDevToolsZoomLevel(), false);
|
||||
SetZoomLevelForWebContents(GetDevToolsWebContents(), new_level);
|
||||
UpdateDevToolsZoomLevel(new_level);
|
||||
}
|
||||
|
||||
void InspectableWebContentsImpl::ZoomOut() {
|
||||
double new_level = GetNextZoomLevel(GetDevToolsZoomLevel(), true);
|
||||
SetZoomLevelForWebContents(GetDevToolsWebContents(), new_level);
|
||||
UpdateDevToolsZoomLevel(new_level);
|
||||
}
|
||||
|
||||
void InspectableWebContentsImpl::ResetZoom() {
|
||||
SetZoomLevelForWebContents(GetDevToolsWebContents(), 0.);
|
||||
UpdateDevToolsZoomLevel(0.);
|
||||
}
|
||||
|
||||
void InspectableWebContentsImpl::SetDevicesDiscoveryConfig(
|
||||
bool discover_usb_devices,
|
||||
bool port_forwarding_enabled,
|
||||
const std::string& port_forwarding_config,
|
||||
bool network_discovery_enabled,
|
||||
const std::string& network_discovery_config) {}
|
||||
|
||||
void InspectableWebContentsImpl::SetDevicesUpdatesEnabled(bool enabled) {}
|
||||
|
||||
void InspectableWebContentsImpl::PerformActionOnRemotePage(
|
||||
const std::string& page_id,
|
||||
const std::string& action) {}
|
||||
|
||||
void InspectableWebContentsImpl::OpenRemotePage(const std::string& browser_id,
|
||||
const std::string& url) {}
|
||||
|
||||
void InspectableWebContentsImpl::OpenNodeFrontend() {}
|
||||
|
||||
void InspectableWebContentsImpl::DispatchProtocolMessageFromDevToolsFrontend(
|
||||
const std::string& message) {
|
||||
// If the devtools wants to reload the page, hijack the message and handle it
|
||||
// to the delegate.
|
||||
if (base::MatchPattern(message,
|
||||
"{\"id\":*,"
|
||||
"\"method\":\"Page.reload\","
|
||||
"\"params\":*}")) {
|
||||
if (delegate_)
|
||||
delegate_->DevToolsReloadPage();
|
||||
return;
|
||||
}
|
||||
|
||||
if (agent_host_)
|
||||
agent_host_->DispatchProtocolMessage(this, message);
|
||||
}
|
||||
|
||||
void InspectableWebContentsImpl::SendJsonRequest(
|
||||
const DispatchCallback& callback,
|
||||
const std::string& browser_id,
|
||||
const std::string& url) {
|
||||
callback.Run(nullptr);
|
||||
}
|
||||
|
||||
void InspectableWebContentsImpl::GetPreferences(
|
||||
const DispatchCallback& callback) {
|
||||
const base::DictionaryValue* prefs =
|
||||
pref_service_->GetDictionary(kDevToolsPreferences);
|
||||
callback.Run(prefs);
|
||||
}
|
||||
|
||||
void InspectableWebContentsImpl::SetPreference(const std::string& name,
|
||||
const std::string& value) {
|
||||
DictionaryPrefUpdate update(pref_service_, kDevToolsPreferences);
|
||||
update.Get()->SetKey(name, base::Value(value));
|
||||
}
|
||||
|
||||
void InspectableWebContentsImpl::RemovePreference(const std::string& name) {
|
||||
DictionaryPrefUpdate update(pref_service_, kDevToolsPreferences);
|
||||
update.Get()->RemoveWithoutPathExpansion(name, nullptr);
|
||||
}
|
||||
|
||||
void InspectableWebContentsImpl::ClearPreferences() {
|
||||
DictionaryPrefUpdate update(pref_service_, kDevToolsPreferences);
|
||||
update.Get()->Clear();
|
||||
}
|
||||
|
||||
void InspectableWebContentsImpl::ConnectionReady() {}
|
||||
|
||||
void InspectableWebContentsImpl::RegisterExtensionsAPI(
|
||||
const std::string& origin,
|
||||
const std::string& script) {
|
||||
extensions_api_[origin + "/"] = script;
|
||||
}
|
||||
|
||||
void InspectableWebContentsImpl::HandleMessageFromDevToolsFrontend(
|
||||
const std::string& message) {
|
||||
// TODO(alexeykuzmin): Should we expect it to exist?
|
||||
if (!embedder_message_dispatcher_) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::string method;
|
||||
base::ListValue empty_params;
|
||||
base::ListValue* params = &empty_params;
|
||||
|
||||
base::DictionaryValue* dict = nullptr;
|
||||
std::unique_ptr<base::Value> parsed_message(base::JSONReader::Read(message));
|
||||
if (!parsed_message || !parsed_message->GetAsDictionary(&dict) ||
|
||||
!dict->GetString(kFrontendHostMethod, &method) ||
|
||||
(dict->HasKey(kFrontendHostParams) &&
|
||||
!dict->GetList(kFrontendHostParams, ¶ms))) {
|
||||
LOG(ERROR) << "Invalid message was sent to embedder: " << message;
|
||||
return;
|
||||
}
|
||||
int id = 0;
|
||||
dict->GetInteger(kFrontendHostId, &id);
|
||||
embedder_message_dispatcher_->Dispatch(
|
||||
base::Bind(&InspectableWebContentsImpl::SendMessageAck,
|
||||
weak_factory_.GetWeakPtr(), id),
|
||||
method, params);
|
||||
}
|
||||
|
||||
void InspectableWebContentsImpl::DispatchProtocolMessage(
|
||||
content::DevToolsAgentHost* agent_host,
|
||||
const std::string& message) {
|
||||
if (!frontend_loaded_)
|
||||
return;
|
||||
|
||||
if (message.length() < kMaxMessageChunkSize) {
|
||||
base::string16 javascript =
|
||||
base::UTF8ToUTF16("DevToolsAPI.dispatchMessage(" + message + ");");
|
||||
GetDevToolsWebContents()->GetMainFrame()->ExecuteJavaScript(javascript);
|
||||
return;
|
||||
}
|
||||
|
||||
base::Value total_size(static_cast<int>(message.length()));
|
||||
for (size_t pos = 0; pos < message.length(); pos += kMaxMessageChunkSize) {
|
||||
base::Value message_value(message.substr(pos, kMaxMessageChunkSize));
|
||||
CallClientFunction("DevToolsAPI.dispatchMessageChunk", &message_value,
|
||||
pos ? nullptr : &total_size, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void InspectableWebContentsImpl::AgentHostClosed(
|
||||
content::DevToolsAgentHost* agent_host) {}
|
||||
|
||||
void InspectableWebContentsImpl::RenderFrameHostChanged(
|
||||
content::RenderFrameHost* old_host,
|
||||
content::RenderFrameHost* new_host) {
|
||||
if (new_host->GetParent())
|
||||
return;
|
||||
frontend_host_.reset(content::DevToolsFrontendHost::Create(
|
||||
new_host,
|
||||
base::Bind(&InspectableWebContentsImpl::HandleMessageFromDevToolsFrontend,
|
||||
weak_factory_.GetWeakPtr())));
|
||||
}
|
||||
|
||||
void InspectableWebContentsImpl::WebContentsDestroyed() {
|
||||
frontend_loaded_ = false;
|
||||
external_devtools_web_contents_ = nullptr;
|
||||
Observe(nullptr);
|
||||
Detach();
|
||||
embedder_message_dispatcher_.reset();
|
||||
|
||||
for (const auto& pair : pending_requests_)
|
||||
delete pair.first;
|
||||
|
||||
if (view_ && view_->GetDelegate())
|
||||
view_->GetDelegate()->DevToolsClosed();
|
||||
}
|
||||
|
||||
bool InspectableWebContentsImpl::DidAddMessageToConsole(
|
||||
content::WebContents* source,
|
||||
int32_t level,
|
||||
const base::string16& message,
|
||||
int32_t line_no,
|
||||
const base::string16& source_id) {
|
||||
logging::LogMessage("CONSOLE", line_no, level).stream()
|
||||
<< "\"" << message << "\", source: " << source_id << " (" << line_no
|
||||
<< ")";
|
||||
return true;
|
||||
}
|
||||
|
||||
bool InspectableWebContentsImpl::ShouldCreateWebContents(
|
||||
content::WebContents* web_contents,
|
||||
content::RenderFrameHost* opener,
|
||||
content::SiteInstance* source_site_instance,
|
||||
int32_t route_id,
|
||||
int32_t main_frame_route_id,
|
||||
int32_t main_frame_widget_route_id,
|
||||
content::mojom::WindowContainerType window_container_type,
|
||||
const GURL& opener_url,
|
||||
const std::string& frame_name,
|
||||
const GURL& target_url,
|
||||
const std::string& partition_id,
|
||||
content::SessionStorageNamespace* session_storage_namespace) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void InspectableWebContentsImpl::HandleKeyboardEvent(
|
||||
content::WebContents* source,
|
||||
const content::NativeWebKeyboardEvent& event) {
|
||||
auto* delegate = web_contents_->GetDelegate();
|
||||
if (delegate)
|
||||
delegate->HandleKeyboardEvent(source, event);
|
||||
}
|
||||
|
||||
void InspectableWebContentsImpl::CloseContents(content::WebContents* source) {
|
||||
// This is where the devtools closes itself (by clicking the x button).
|
||||
CloseDevTools();
|
||||
}
|
||||
|
||||
content::ColorChooser* InspectableWebContentsImpl::OpenColorChooser(
|
||||
content::WebContents* source,
|
||||
SkColor color,
|
||||
const std::vector<blink::mojom::ColorSuggestionPtr>& suggestions) {
|
||||
auto* delegate = web_contents_->GetDelegate();
|
||||
if (delegate)
|
||||
return delegate->OpenColorChooser(source, color, suggestions);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void InspectableWebContentsImpl::RunFileChooser(
|
||||
content::RenderFrameHost* render_frame_host,
|
||||
const content::FileChooserParams& params) {
|
||||
auto* delegate = web_contents_->GetDelegate();
|
||||
if (delegate)
|
||||
delegate->RunFileChooser(render_frame_host, params);
|
||||
}
|
||||
|
||||
void InspectableWebContentsImpl::EnumerateDirectory(
|
||||
content::WebContents* source,
|
||||
int request_id,
|
||||
const base::FilePath& path) {
|
||||
auto* delegate = web_contents_->GetDelegate();
|
||||
if (delegate)
|
||||
delegate->EnumerateDirectory(source, request_id, path);
|
||||
}
|
||||
|
||||
void InspectableWebContentsImpl::OnWebContentsFocused(
|
||||
content::RenderWidgetHost* render_widget_host) {
|
||||
#if defined(TOOLKIT_VIEWS)
|
||||
if (view_->GetDelegate())
|
||||
view_->GetDelegate()->DevToolsFocused();
|
||||
#endif
|
||||
}
|
||||
|
||||
void InspectableWebContentsImpl::ReadyToCommitNavigation(
|
||||
content::NavigationHandle* navigation_handle) {
|
||||
if (navigation_handle->IsInMainFrame()) {
|
||||
if (navigation_handle->GetRenderFrameHost() ==
|
||||
GetDevToolsWebContents()->GetMainFrame() &&
|
||||
frontend_host_) {
|
||||
return;
|
||||
}
|
||||
frontend_host_.reset(content::DevToolsFrontendHost::Create(
|
||||
web_contents()->GetMainFrame(),
|
||||
base::Bind(
|
||||
&InspectableWebContentsImpl::HandleMessageFromDevToolsFrontend,
|
||||
base::Unretained(this))));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void InspectableWebContentsImpl::DidFinishNavigation(
|
||||
content::NavigationHandle* navigation_handle) {
|
||||
if (navigation_handle->IsInMainFrame() ||
|
||||
!navigation_handle->GetURL().SchemeIs("chrome-extension") ||
|
||||
!navigation_handle->HasCommitted())
|
||||
return;
|
||||
content::RenderFrameHost* frame = navigation_handle->GetRenderFrameHost();
|
||||
auto origin = navigation_handle->GetURL().GetOrigin().spec();
|
||||
auto it = extensions_api_.find(origin);
|
||||
if (it == extensions_api_.end())
|
||||
return;
|
||||
// Injected Script from devtools frontend doesn't expose chrome,
|
||||
// most likely bug in chromium.
|
||||
base::ReplaceFirstSubstringAfterOffset(&it->second, 0, "var chrome",
|
||||
"var chrome = window.chrome ");
|
||||
auto script = base::StringPrintf("%s(\"%s\")", it->second.c_str(),
|
||||
base::GenerateGUID().c_str());
|
||||
// Invoking content::DevToolsFrontendHost::SetupExtensionsAPI(frame, script);
|
||||
// should be enough, but it seems to be a noop currently.
|
||||
frame->ExecuteJavaScriptForTests(base::UTF8ToUTF16(script));
|
||||
}
|
||||
|
||||
void InspectableWebContentsImpl::OnURLFetchComplete(
|
||||
const net::URLFetcher* source) {
|
||||
DCHECK(source);
|
||||
auto it = pending_requests_.find(source);
|
||||
DCHECK(it != pending_requests_.end());
|
||||
|
||||
base::DictionaryValue response;
|
||||
|
||||
net::HttpResponseHeaders* rh = source->GetResponseHeaders();
|
||||
response.SetInteger("statusCode", rh ? rh->response_code() : 200);
|
||||
|
||||
{
|
||||
auto headers = std::make_unique<base::DictionaryValue>();
|
||||
|
||||
size_t iterator = 0;
|
||||
std::string name;
|
||||
std::string value;
|
||||
while (rh && rh->EnumerateHeaderLines(&iterator, &name, &value))
|
||||
headers->SetString(name, value);
|
||||
|
||||
response.Set("headers", std::move(headers));
|
||||
}
|
||||
|
||||
it->second.Run(&response);
|
||||
pending_requests_.erase(it);
|
||||
delete source;
|
||||
}
|
||||
|
||||
void InspectableWebContentsImpl::SendMessageAck(int request_id,
|
||||
const base::Value* arg) {
|
||||
base::Value id_value(request_id);
|
||||
CallClientFunction("DevToolsAPI.embedderMessageAck", &id_value, arg, nullptr);
|
||||
}
|
||||
|
||||
} // namespace atom
|
242
atom/browser/ui/inspectable_web_contents_impl.h
Normal file
242
atom/browser/ui/inspectable_web_contents_impl.h
Normal file
|
@ -0,0 +1,242 @@
|
|||
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
||||
// Copyright (c) 2013 Adam Roben <adam@roben.org>. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE-CHROMIUM file.
|
||||
|
||||
#ifndef ATOM_BROWSER_UI_INSPECTABLE_WEB_CONTENTS_IMPL_H_
|
||||
#define ATOM_BROWSER_UI_INSPECTABLE_WEB_CONTENTS_IMPL_H_
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "atom/browser/ui/inspectable_web_contents.h"
|
||||
#include "base/memory/weak_ptr.h"
|
||||
#include "chrome/browser/devtools/devtools_contents_resizing_strategy.h"
|
||||
#include "chrome/browser/devtools/devtools_embedder_message_dispatcher.h"
|
||||
#include "content/public/browser/devtools_agent_host.h"
|
||||
#include "content/public/browser/devtools_frontend_host.h"
|
||||
#include "content/public/browser/web_contents_delegate.h"
|
||||
#include "content/public/browser/web_contents_observer.h"
|
||||
#include "net/url_request/url_fetcher_delegate.h"
|
||||
#include "ui/gfx/geometry/rect.h"
|
||||
|
||||
class PrefService;
|
||||
class PrefRegistrySimple;
|
||||
|
||||
namespace atom {
|
||||
|
||||
class InspectableWebContentsDelegate;
|
||||
class InspectableWebContentsView;
|
||||
|
||||
class InspectableWebContentsImpl
|
||||
: public InspectableWebContents,
|
||||
public content::DevToolsAgentHostClient,
|
||||
public content::WebContentsObserver,
|
||||
public content::WebContentsDelegate,
|
||||
public DevToolsEmbedderMessageDispatcher::Delegate,
|
||||
public net::URLFetcherDelegate {
|
||||
public:
|
||||
static void RegisterPrefs(PrefRegistrySimple* pref_registry);
|
||||
|
||||
InspectableWebContentsImpl(content::WebContents* web_contents,
|
||||
PrefService* pref_service,
|
||||
bool is_guest);
|
||||
~InspectableWebContentsImpl() override;
|
||||
|
||||
InspectableWebContentsView* GetView() const override;
|
||||
content::WebContents* GetWebContents() const override;
|
||||
content::WebContents* GetDevToolsWebContents() const override;
|
||||
|
||||
void SetDelegate(InspectableWebContentsDelegate* delegate) override;
|
||||
InspectableWebContentsDelegate* GetDelegate() const override;
|
||||
bool IsGuest() const override;
|
||||
void ReleaseWebContents() override;
|
||||
void SetDevToolsWebContents(content::WebContents* devtools) override;
|
||||
void SetDockState(const std::string& state) override;
|
||||
void ShowDevTools() override;
|
||||
void CloseDevTools() override;
|
||||
bool IsDevToolsViewShowing() override;
|
||||
void AttachTo(scoped_refptr<content::DevToolsAgentHost>) override;
|
||||
void Detach() override;
|
||||
void CallClientFunction(const std::string& function_name,
|
||||
const base::Value* arg1,
|
||||
const base::Value* arg2,
|
||||
const base::Value* arg3) override;
|
||||
void InspectElement(int x, int y) override;
|
||||
|
||||
// Return the last position and size of devtools window.
|
||||
gfx::Rect GetDevToolsBounds() const;
|
||||
void SaveDevToolsBounds(const gfx::Rect& bounds);
|
||||
|
||||
// Return the last set zoom level of devtools window.
|
||||
double GetDevToolsZoomLevel() const;
|
||||
void UpdateDevToolsZoomLevel(double level);
|
||||
|
||||
private:
|
||||
// DevToolsEmbedderMessageDispacher::Delegate
|
||||
void ActivateWindow() override;
|
||||
void CloseWindow() override;
|
||||
void LoadCompleted() override;
|
||||
void SetInspectedPageBounds(const gfx::Rect& rect) override;
|
||||
void InspectElementCompleted() override;
|
||||
void InspectedURLChanged(const std::string& url) override;
|
||||
void LoadNetworkResource(const DispatchCallback& callback,
|
||||
const std::string& url,
|
||||
const std::string& headers,
|
||||
int stream_id) override;
|
||||
void SetIsDocked(const DispatchCallback& callback, bool is_docked) override;
|
||||
void OpenInNewTab(const std::string& url) override;
|
||||
void ShowItemInFolder(const std::string& file_system_path) override;
|
||||
void SaveToFile(const std::string& url,
|
||||
const std::string& content,
|
||||
bool save_as) override;
|
||||
void AppendToFile(const std::string& url,
|
||||
const std::string& content) override;
|
||||
void RequestFileSystems() override;
|
||||
void AddFileSystem(const std::string& type) override;
|
||||
void RemoveFileSystem(const std::string& file_system_path) override;
|
||||
void UpgradeDraggedFileSystemPermissions(
|
||||
const std::string& file_system_url) override;
|
||||
void IndexPath(int index_request_id,
|
||||
const std::string& file_system_path,
|
||||
const std::string& excluded_folders) override;
|
||||
void StopIndexing(int index_request_id) override;
|
||||
void SearchInPath(int search_request_id,
|
||||
const std::string& file_system_path,
|
||||
const std::string& query) override;
|
||||
void SetWhitelistedShortcuts(const std::string& message) override;
|
||||
void SetEyeDropperActive(bool active) override;
|
||||
void ShowCertificateViewer(const std::string& cert_chain) override;
|
||||
void ZoomIn() override;
|
||||
void ZoomOut() override;
|
||||
void ResetZoom() override;
|
||||
void SetDevicesDiscoveryConfig(
|
||||
bool discover_usb_devices,
|
||||
bool port_forwarding_enabled,
|
||||
const std::string& port_forwarding_config,
|
||||
bool network_discovery_enabled,
|
||||
const std::string& network_discovery_config) override;
|
||||
void SetDevicesUpdatesEnabled(bool enabled) override;
|
||||
void PerformActionOnRemotePage(const std::string& page_id,
|
||||
const std::string& action) override;
|
||||
void OpenRemotePage(const std::string& browser_id,
|
||||
const std::string& url) override;
|
||||
void OpenNodeFrontend() override;
|
||||
void DispatchProtocolMessageFromDevToolsFrontend(
|
||||
const std::string& message) override;
|
||||
void SendJsonRequest(const DispatchCallback& callback,
|
||||
const std::string& browser_id,
|
||||
const std::string& url) override;
|
||||
void GetPreferences(const DispatchCallback& callback) override;
|
||||
void SetPreference(const std::string& name,
|
||||
const std::string& value) override;
|
||||
void RemovePreference(const std::string& name) override;
|
||||
void ClearPreferences() override;
|
||||
void ConnectionReady() override;
|
||||
void RegisterExtensionsAPI(const std::string& origin,
|
||||
const std::string& script) override;
|
||||
void Reattach(const DispatchCallback& callback) override;
|
||||
void RecordEnumeratedHistogram(const std::string& name,
|
||||
int sample,
|
||||
int boundary_value) override {}
|
||||
void ReadyForTest() override {}
|
||||
void SetOpenNewWindowForPopups(bool value) override {}
|
||||
|
||||
// content::DevToolsFrontendHostDelegate:
|
||||
void HandleMessageFromDevToolsFrontend(const std::string& message);
|
||||
|
||||
// content::DevToolsAgentHostClient:
|
||||
void DispatchProtocolMessage(content::DevToolsAgentHost* agent_host,
|
||||
const std::string& message) override;
|
||||
void AgentHostClosed(content::DevToolsAgentHost* agent_host) override;
|
||||
|
||||
// content::WebContentsObserver:
|
||||
void RenderFrameHostChanged(content::RenderFrameHost* old_host,
|
||||
content::RenderFrameHost* new_host) override;
|
||||
void WebContentsDestroyed() override;
|
||||
void OnWebContentsFocused(
|
||||
content::RenderWidgetHost* render_widget_host) override;
|
||||
void ReadyToCommitNavigation(
|
||||
content::NavigationHandle* navigation_handle) override;
|
||||
void DidFinishNavigation(
|
||||
content::NavigationHandle* navigation_handle) override;
|
||||
|
||||
// content::WebContentsDelegate:
|
||||
bool DidAddMessageToConsole(content::WebContents* source,
|
||||
int32_t level,
|
||||
const base::string16& message,
|
||||
int32_t line_no,
|
||||
const base::string16& source_id) override;
|
||||
bool ShouldCreateWebContents(
|
||||
content::WebContents* web_contents,
|
||||
content::RenderFrameHost* opener,
|
||||
content::SiteInstance* source_site_instance,
|
||||
int32_t route_id,
|
||||
int32_t main_frame_route_id,
|
||||
int32_t main_frame_widget_route_id,
|
||||
content::mojom::WindowContainerType window_container_type,
|
||||
const GURL& opener_url,
|
||||
const std::string& frame_name,
|
||||
const GURL& target_url,
|
||||
const std::string& partition_id,
|
||||
content::SessionStorageNamespace* session_storage_namespace) override;
|
||||
void HandleKeyboardEvent(content::WebContents*,
|
||||
const content::NativeWebKeyboardEvent&) override;
|
||||
void CloseContents(content::WebContents* source) override;
|
||||
content::ColorChooser* OpenColorChooser(
|
||||
content::WebContents* source,
|
||||
SkColor color,
|
||||
const std::vector<blink::mojom::ColorSuggestionPtr>& suggestions)
|
||||
override;
|
||||
void RunFileChooser(content::RenderFrameHost* render_frame_host,
|
||||
const content::FileChooserParams& params) override;
|
||||
void EnumerateDirectory(content::WebContents* source,
|
||||
int request_id,
|
||||
const base::FilePath& path) override;
|
||||
|
||||
// net::URLFetcherDelegate:
|
||||
void OnURLFetchComplete(const net::URLFetcher* source) override;
|
||||
|
||||
void SendMessageAck(int request_id, const base::Value* arg1);
|
||||
|
||||
bool frontend_loaded_;
|
||||
scoped_refptr<content::DevToolsAgentHost> agent_host_;
|
||||
std::unique_ptr<content::DevToolsFrontendHost> frontend_host_;
|
||||
std::unique_ptr<DevToolsEmbedderMessageDispatcher>
|
||||
embedder_message_dispatcher_;
|
||||
|
||||
DevToolsContentsResizingStrategy contents_resizing_strategy_;
|
||||
gfx::Rect devtools_bounds_;
|
||||
bool can_dock_;
|
||||
std::string dock_state_;
|
||||
|
||||
using PendingRequestsMap = std::map<const net::URLFetcher*, DispatchCallback>;
|
||||
PendingRequestsMap pending_requests_;
|
||||
InspectableWebContentsDelegate* delegate_; // weak references.
|
||||
|
||||
PrefService* pref_service_; // weak reference.
|
||||
|
||||
std::unique_ptr<content::WebContents> web_contents_;
|
||||
|
||||
// The default devtools created by this class when we don't have an external
|
||||
// one assigned by SetDevToolsWebContents.
|
||||
std::unique_ptr<content::WebContents> managed_devtools_web_contents_;
|
||||
// The external devtools assigned by SetDevToolsWebContents.
|
||||
content::WebContents* external_devtools_web_contents_ = nullptr;
|
||||
|
||||
bool is_guest_;
|
||||
std::unique_ptr<InspectableWebContentsView> view_;
|
||||
|
||||
using ExtensionsAPIs = std::map<std::string, std::string>;
|
||||
ExtensionsAPIs extensions_api_;
|
||||
|
||||
base::WeakPtrFactory<InspectableWebContentsImpl> weak_factory_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(InspectableWebContentsImpl);
|
||||
};
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_UI_INSPECTABLE_WEB_CONTENTS_IMPL_H_
|
62
atom/browser/ui/inspectable_web_contents_view.h
Normal file
62
atom/browser/ui/inspectable_web_contents_view.h
Normal file
|
@ -0,0 +1,62 @@
|
|||
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
||||
// Copyright (c) 2013 Adam Roben <adam@roben.org>. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE-CHROMIUM file.
|
||||
|
||||
#ifndef ATOM_BROWSER_UI_INSPECTABLE_WEB_CONTENTS_VIEW_H_
|
||||
#define ATOM_BROWSER_UI_INSPECTABLE_WEB_CONTENTS_VIEW_H_
|
||||
|
||||
#include "base/strings/string16.h"
|
||||
#include "ui/gfx/native_widget_types.h"
|
||||
|
||||
class DevToolsContentsResizingStrategy;
|
||||
|
||||
#if defined(TOOLKIT_VIEWS)
|
||||
namespace views {
|
||||
class View;
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace atom {
|
||||
|
||||
class InspectableWebContentsViewDelegate;
|
||||
|
||||
class InspectableWebContentsView {
|
||||
public:
|
||||
InspectableWebContentsView() : delegate_(nullptr) {}
|
||||
virtual ~InspectableWebContentsView() {}
|
||||
|
||||
// The delegate manages its own life.
|
||||
void SetDelegate(InspectableWebContentsViewDelegate* delegate) {
|
||||
delegate_ = delegate;
|
||||
}
|
||||
InspectableWebContentsViewDelegate* GetDelegate() const { return delegate_; }
|
||||
|
||||
#if defined(TOOLKIT_VIEWS) && !defined(OS_MACOSX)
|
||||
// Returns the container control, which has devtools view attached.
|
||||
virtual views::View* GetView() = 0;
|
||||
|
||||
// Returns the web view control, which can be used by the
|
||||
// GetInitiallyFocusedView() to set initial focus to web view.
|
||||
virtual views::View* GetWebView() = 0;
|
||||
#else
|
||||
virtual gfx::NativeView GetNativeView() const = 0;
|
||||
#endif
|
||||
|
||||
virtual void ShowDevTools() = 0;
|
||||
// Hide the DevTools view.
|
||||
virtual void CloseDevTools() = 0;
|
||||
virtual bool IsDevToolsViewShowing() = 0;
|
||||
virtual bool IsDevToolsViewFocused() = 0;
|
||||
virtual void SetIsDocked(bool docked) = 0;
|
||||
virtual void SetContentsResizingStrategy(
|
||||
const DevToolsContentsResizingStrategy& strategy) = 0;
|
||||
virtual void SetTitle(const base::string16& title) = 0;
|
||||
|
||||
private:
|
||||
InspectableWebContentsViewDelegate* delegate_; // weak references.
|
||||
};
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_UI_INSPECTABLE_WEB_CONTENTS_VIEW_H_
|
14
atom/browser/ui/inspectable_web_contents_view_delegate.cc
Normal file
14
atom/browser/ui/inspectable_web_contents_view_delegate.cc
Normal file
|
@ -0,0 +1,14 @@
|
|||
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
||||
// Copyright (c) 2013 Adam Roben <adam@roben.org>. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE-CHROMIUM file.
|
||||
|
||||
#include "atom/browser/ui/inspectable_web_contents_view_delegate.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
gfx::ImageSkia InspectableWebContentsViewDelegate::GetDevToolsWindowIcon() {
|
||||
return gfx::ImageSkia();
|
||||
}
|
||||
|
||||
} // namespace atom
|
35
atom/browser/ui/inspectable_web_contents_view_delegate.h
Normal file
35
atom/browser/ui/inspectable_web_contents_view_delegate.h
Normal file
|
@ -0,0 +1,35 @@
|
|||
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
||||
// Copyright (c) 2013 Adam Roben <adam@roben.org>. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE-CHROMIUM file.
|
||||
|
||||
#ifndef ATOM_BROWSER_UI_INSPECTABLE_WEB_CONTENTS_VIEW_DELEGATE_H_
|
||||
#define ATOM_BROWSER_UI_INSPECTABLE_WEB_CONTENTS_VIEW_DELEGATE_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "ui/gfx/image/image_skia.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
class InspectableWebContentsViewDelegate {
|
||||
public:
|
||||
virtual ~InspectableWebContentsViewDelegate() {}
|
||||
|
||||
virtual void DevToolsFocused() {}
|
||||
virtual void DevToolsOpened() {}
|
||||
virtual void DevToolsClosed() {}
|
||||
|
||||
// Returns the icon of devtools window.
|
||||
virtual gfx::ImageSkia GetDevToolsWindowIcon();
|
||||
|
||||
#if defined(USE_X11)
|
||||
// Called when creating devtools window.
|
||||
virtual void GetDevToolsWindowWMClass(std::string* name,
|
||||
std::string* class_name) {}
|
||||
#endif
|
||||
};
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_UI_INSPECTABLE_WEB_CONTENTS_VIEW_DELEGATE_H_
|
50
atom/browser/ui/inspectable_web_contents_view_mac.h
Normal file
50
atom/browser/ui/inspectable_web_contents_view_mac.h
Normal file
|
@ -0,0 +1,50 @@
|
|||
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
||||
// Copyright (c) 2013 Adam Roben <adam@roben.org>. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE-CHROMIUM file.
|
||||
|
||||
#ifndef ATOM_BROWSER_UI_INSPECTABLE_WEB_CONTENTS_VIEW_MAC_H_
|
||||
#define ATOM_BROWSER_UI_INSPECTABLE_WEB_CONTENTS_VIEW_MAC_H_
|
||||
|
||||
#include "atom/browser/ui/inspectable_web_contents_view.h"
|
||||
|
||||
#include "base/mac/scoped_nsobject.h"
|
||||
|
||||
@class AtomInspectableWebContentsView;
|
||||
|
||||
namespace atom {
|
||||
|
||||
class InspectableWebContentsImpl;
|
||||
|
||||
class InspectableWebContentsViewMac : public InspectableWebContentsView {
|
||||
public:
|
||||
explicit InspectableWebContentsViewMac(
|
||||
InspectableWebContentsImpl* inspectable_web_contents_impl);
|
||||
~InspectableWebContentsViewMac() override;
|
||||
|
||||
gfx::NativeView GetNativeView() const override;
|
||||
void ShowDevTools() override;
|
||||
void CloseDevTools() override;
|
||||
bool IsDevToolsViewShowing() override;
|
||||
bool IsDevToolsViewFocused() override;
|
||||
void SetIsDocked(bool docked) override;
|
||||
void SetContentsResizingStrategy(
|
||||
const DevToolsContentsResizingStrategy& strategy) override;
|
||||
void SetTitle(const base::string16& title) override;
|
||||
|
||||
InspectableWebContentsImpl* inspectable_web_contents() {
|
||||
return inspectable_web_contents_;
|
||||
}
|
||||
|
||||
private:
|
||||
// Owns us.
|
||||
InspectableWebContentsImpl* inspectable_web_contents_;
|
||||
|
||||
base::scoped_nsobject<AtomInspectableWebContentsView> view_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(InspectableWebContentsViewMac);
|
||||
};
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_UI_INSPECTABLE_WEB_CONTENTS_VIEW_MAC_H_
|
66
atom/browser/ui/inspectable_web_contents_view_mac.mm
Normal file
66
atom/browser/ui/inspectable_web_contents_view_mac.mm
Normal file
|
@ -0,0 +1,66 @@
|
|||
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
||||
// Copyright (c) 2013 Adam Roben <adam@roben.org>. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE-CHROMIUM file.
|
||||
|
||||
#include "atom/browser/ui/inspectable_web_contents_view_mac.h"
|
||||
|
||||
#import <AppKit/AppKit.h>
|
||||
|
||||
#import "atom/browser/ui/cocoa/atom_inspectable_web_contents_view.h"
|
||||
#include "atom/browser/ui/inspectable_web_contents.h"
|
||||
#include "atom/browser/ui/inspectable_web_contents_view_delegate.h"
|
||||
#include "base/strings/sys_string_conversions.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
InspectableWebContentsView* CreateInspectableContentsView(
|
||||
InspectableWebContentsImpl* inspectable_web_contents) {
|
||||
return new InspectableWebContentsViewMac(inspectable_web_contents);
|
||||
}
|
||||
|
||||
InspectableWebContentsViewMac::InspectableWebContentsViewMac(
|
||||
InspectableWebContentsImpl* inspectable_web_contents)
|
||||
: inspectable_web_contents_(inspectable_web_contents),
|
||||
view_([[AtomInspectableWebContentsView alloc]
|
||||
initWithInspectableWebContentsViewMac:this]) {}
|
||||
|
||||
InspectableWebContentsViewMac::~InspectableWebContentsViewMac() {
|
||||
[view_ removeObservers];
|
||||
CloseDevTools();
|
||||
}
|
||||
|
||||
gfx::NativeView InspectableWebContentsViewMac::GetNativeView() const {
|
||||
return view_.get();
|
||||
}
|
||||
|
||||
void InspectableWebContentsViewMac::ShowDevTools() {
|
||||
[view_ setDevToolsVisible:YES];
|
||||
}
|
||||
|
||||
void InspectableWebContentsViewMac::CloseDevTools() {
|
||||
[view_ setDevToolsVisible:NO];
|
||||
}
|
||||
|
||||
bool InspectableWebContentsViewMac::IsDevToolsViewShowing() {
|
||||
return [view_ isDevToolsVisible];
|
||||
}
|
||||
|
||||
bool InspectableWebContentsViewMac::IsDevToolsViewFocused() {
|
||||
return [view_ isDevToolsFocused];
|
||||
}
|
||||
|
||||
void InspectableWebContentsViewMac::SetIsDocked(bool docked) {
|
||||
[view_ setIsDocked:docked];
|
||||
}
|
||||
|
||||
void InspectableWebContentsViewMac::SetContentsResizingStrategy(
|
||||
const DevToolsContentsResizingStrategy& strategy) {
|
||||
[view_ setContentsResizingStrategy:strategy];
|
||||
}
|
||||
|
||||
void InspectableWebContentsViewMac::SetTitle(const base::string16& title) {
|
||||
[view_ setTitle:base::SysUTF16ToNSString(title)];
|
||||
}
|
||||
|
||||
} // namespace atom
|
118
atom/browser/ui/views/atom_views_delegate.cc
Normal file
118
atom/browser/ui/views/atom_views_delegate.cc
Normal file
|
@ -0,0 +1,118 @@
|
|||
// Copyright (c) 2014 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-CHROMIUM file.
|
||||
|
||||
#include "atom/browser/ui/views/atom_views_delegate.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h"
|
||||
#include "ui/views/widget/native_widget_aura.h"
|
||||
|
||||
#if defined(OS_LINUX)
|
||||
#include "base/environment.h"
|
||||
#include "base/nix/xdg_util.h"
|
||||
#include "ui/views/linux_ui/linux_ui.h"
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
|
||||
#if defined(OS_LINUX)
|
||||
bool IsDesktopEnvironmentUnity() {
|
||||
std::unique_ptr<base::Environment> env(base::Environment::Create());
|
||||
base::nix::DesktopEnvironment desktop_env =
|
||||
base::nix::GetDesktopEnvironment(env.get());
|
||||
return desktop_env == base::nix::DESKTOP_ENVIRONMENT_UNITY;
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace atom {
|
||||
|
||||
ViewsDelegate::ViewsDelegate() {}
|
||||
|
||||
ViewsDelegate::~ViewsDelegate() {}
|
||||
|
||||
void ViewsDelegate::SaveWindowPlacement(const views::Widget* window,
|
||||
const std::string& window_name,
|
||||
const gfx::Rect& bounds,
|
||||
ui::WindowShowState show_state) {}
|
||||
|
||||
bool ViewsDelegate::GetSavedWindowPlacement(
|
||||
const views::Widget* widget,
|
||||
const std::string& window_name,
|
||||
gfx::Rect* bounds,
|
||||
ui::WindowShowState* show_state) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
void ViewsDelegate::NotifyAccessibilityEvent(views::View* view,
|
||||
ax::mojom::Event event_type) {}
|
||||
|
||||
void ViewsDelegate::NotifyMenuItemFocused(const base::string16& menu_name,
|
||||
const base::string16& menu_item_name,
|
||||
int item_index,
|
||||
int item_count,
|
||||
bool has_submenu) {}
|
||||
|
||||
#if defined(OS_WIN)
|
||||
HICON ViewsDelegate::GetDefaultWindowIcon() const {
|
||||
// Use current exe's icon as default window icon.
|
||||
return LoadIcon(GetModuleHandle(NULL),
|
||||
MAKEINTRESOURCE(1 /* IDR_MAINFRAME */));
|
||||
}
|
||||
|
||||
HICON ViewsDelegate::GetSmallWindowIcon() const {
|
||||
return GetDefaultWindowIcon();
|
||||
}
|
||||
|
||||
bool ViewsDelegate::IsWindowInMetro(gfx::NativeWindow window) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
#elif defined(OS_LINUX) && !defined(OS_CHROMEOS)
|
||||
gfx::ImageSkia* ViewsDelegate::GetDefaultWindowIcon() const {
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
views::NonClientFrameView* ViewsDelegate::CreateDefaultNonClientFrameView(
|
||||
views::Widget* widget) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void ViewsDelegate::AddRef() {}
|
||||
|
||||
void ViewsDelegate::ReleaseRef() {}
|
||||
|
||||
void ViewsDelegate::OnBeforeWidgetInit(
|
||||
views::Widget::InitParams* params,
|
||||
views::internal::NativeWidgetDelegate* delegate) {
|
||||
// If we already have a native_widget, we don't have to try to come
|
||||
// up with one.
|
||||
if (params->native_widget)
|
||||
return;
|
||||
|
||||
if (params->parent && params->type != views::Widget::InitParams::TYPE_MENU &&
|
||||
params->type != views::Widget::InitParams::TYPE_TOOLTIP) {
|
||||
params->native_widget = new views::NativeWidgetAura(delegate);
|
||||
} else {
|
||||
params->native_widget = new views::DesktopNativeWidgetAura(delegate);
|
||||
}
|
||||
}
|
||||
|
||||
bool ViewsDelegate::WindowManagerProvidesTitleBar(bool maximized) {
|
||||
#if defined(OS_LINUX)
|
||||
// On Ubuntu Unity, the system always provides a title bar for maximized
|
||||
// windows.
|
||||
if (!maximized)
|
||||
return false;
|
||||
static bool is_desktop_environment_unity = IsDesktopEnvironmentUnity();
|
||||
return is_desktop_environment_unity;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace atom
|
60
atom/browser/ui/views/atom_views_delegate.h
Normal file
60
atom/browser/ui/views/atom_views_delegate.h
Normal file
|
@ -0,0 +1,60 @@
|
|||
// Copyright (c) 2014 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-CHROMIUM file.
|
||||
|
||||
#ifndef ATOM_BROWSER_UI_VIEWS_ATOM_VIEWS_DELEGATE_H_
|
||||
#define ATOM_BROWSER_UI_VIEWS_ATOM_VIEWS_DELEGATE_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "base/compiler_specific.h"
|
||||
#include "ui/views/views_delegate.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
class ViewsDelegate : public views::ViewsDelegate {
|
||||
public:
|
||||
ViewsDelegate();
|
||||
~ViewsDelegate() override;
|
||||
|
||||
protected:
|
||||
// views::ViewsDelegate:
|
||||
void SaveWindowPlacement(const views::Widget* window,
|
||||
const std::string& window_name,
|
||||
const gfx::Rect& bounds,
|
||||
ui::WindowShowState show_state) override;
|
||||
bool GetSavedWindowPlacement(const views::Widget* widget,
|
||||
const std::string& window_name,
|
||||
gfx::Rect* bounds,
|
||||
ui::WindowShowState* show_state) const override;
|
||||
void NotifyAccessibilityEvent(views::View* view,
|
||||
ax::mojom::Event event_type) override;
|
||||
void NotifyMenuItemFocused(const base::string16& menu_name,
|
||||
const base::string16& menu_item_name,
|
||||
int item_index,
|
||||
int item_count,
|
||||
bool has_submenu) override;
|
||||
|
||||
#if defined(OS_WIN)
|
||||
HICON GetDefaultWindowIcon() const override;
|
||||
HICON GetSmallWindowIcon() const override;
|
||||
bool IsWindowInMetro(gfx::NativeWindow window) const override;
|
||||
#elif defined(OS_LINUX) && !defined(OS_CHROMEOS)
|
||||
gfx::ImageSkia* GetDefaultWindowIcon() const override;
|
||||
#endif
|
||||
views::NonClientFrameView* CreateDefaultNonClientFrameView(
|
||||
views::Widget* widget) override;
|
||||
void AddRef() override;
|
||||
void ReleaseRef() override;
|
||||
void OnBeforeWidgetInit(
|
||||
views::Widget::InitParams* params,
|
||||
views::internal::NativeWidgetDelegate* delegate) override;
|
||||
bool WindowManagerProvidesTitleBar(bool maximized) override;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ViewsDelegate);
|
||||
};
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_UI_VIEWS_ATOM_VIEWS_DELEGATE_H_
|
231
atom/browser/ui/views/inspectable_web_contents_view_views.cc
Normal file
231
atom/browser/ui/views/inspectable_web_contents_view_views.cc
Normal file
|
@ -0,0 +1,231 @@
|
|||
// Copyright (c) 2014 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-CHROMIUM file.
|
||||
|
||||
#include "atom/browser/ui/views/inspectable_web_contents_view_views.h"
|
||||
|
||||
#include "atom/browser/ui/inspectable_web_contents_delegate.h"
|
||||
#include "atom/browser/ui/inspectable_web_contents_impl.h"
|
||||
#include "atom/browser/ui/inspectable_web_contents_view_delegate.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "ui/views/controls/label.h"
|
||||
#include "ui/views/controls/webview/webview.h"
|
||||
#include "ui/views/widget/widget.h"
|
||||
#include "ui/views/widget/widget_delegate.h"
|
||||
#include "ui/views/window/client_view.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace {
|
||||
|
||||
class DevToolsWindowDelegate : public views::ClientView,
|
||||
public views::WidgetDelegate {
|
||||
public:
|
||||
DevToolsWindowDelegate(InspectableWebContentsViewViews* shell,
|
||||
views::View* view,
|
||||
views::Widget* widget)
|
||||
: views::ClientView(widget, view),
|
||||
shell_(shell),
|
||||
view_(view),
|
||||
widget_(widget) {
|
||||
// A WidgetDelegate should be deleted on DeleteDelegate.
|
||||
set_owned_by_client();
|
||||
|
||||
if (shell->GetDelegate())
|
||||
icon_ = shell->GetDelegate()->GetDevToolsWindowIcon();
|
||||
}
|
||||
~DevToolsWindowDelegate() override {}
|
||||
|
||||
// views::WidgetDelegate:
|
||||
void DeleteDelegate() override { delete this; }
|
||||
views::View* GetInitiallyFocusedView() override { return view_; }
|
||||
bool CanResize() const override { return true; }
|
||||
bool CanMaximize() const override { return true; }
|
||||
bool CanMinimize() const override { return true; }
|
||||
base::string16 GetWindowTitle() const override { return shell_->GetTitle(); }
|
||||
gfx::ImageSkia GetWindowAppIcon() override { return GetWindowIcon(); }
|
||||
gfx::ImageSkia GetWindowIcon() override { return icon_; }
|
||||
views::Widget* GetWidget() override { return widget_; }
|
||||
const views::Widget* GetWidget() const override { return widget_; }
|
||||
views::View* GetContentsView() override { return view_; }
|
||||
views::ClientView* CreateClientView(views::Widget* widget) override {
|
||||
return this;
|
||||
}
|
||||
|
||||
// views::ClientView:
|
||||
bool CanClose() override {
|
||||
shell_->inspectable_web_contents()->CloseDevTools();
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
InspectableWebContentsViewViews* shell_;
|
||||
views::View* view_;
|
||||
views::Widget* widget_;
|
||||
gfx::ImageSkia icon_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(DevToolsWindowDelegate);
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
InspectableWebContentsView* CreateInspectableContentsView(
|
||||
InspectableWebContentsImpl* inspectable_web_contents) {
|
||||
return new InspectableWebContentsViewViews(inspectable_web_contents);
|
||||
}
|
||||
|
||||
InspectableWebContentsViewViews::InspectableWebContentsViewViews(
|
||||
InspectableWebContentsImpl* inspectable_web_contents)
|
||||
: inspectable_web_contents_(inspectable_web_contents),
|
||||
devtools_window_web_view_(nullptr),
|
||||
contents_web_view_(nullptr),
|
||||
devtools_web_view_(new views::WebView(nullptr)),
|
||||
devtools_visible_(false),
|
||||
devtools_window_delegate_(nullptr),
|
||||
title_(base::ASCIIToUTF16("Developer Tools")) {
|
||||
set_owned_by_client();
|
||||
|
||||
if (!inspectable_web_contents_->IsGuest() &&
|
||||
inspectable_web_contents_->GetWebContents()->GetNativeView()) {
|
||||
views::WebView* contents_web_view = new views::WebView(nullptr);
|
||||
contents_web_view->SetWebContents(
|
||||
inspectable_web_contents_->GetWebContents());
|
||||
contents_web_view_ = contents_web_view;
|
||||
} else {
|
||||
contents_web_view_ =
|
||||
new views::Label(base::ASCIIToUTF16("No content under offscreen mode"));
|
||||
}
|
||||
|
||||
devtools_web_view_->SetVisible(false);
|
||||
AddChildView(devtools_web_view_);
|
||||
AddChildView(contents_web_view_);
|
||||
}
|
||||
|
||||
InspectableWebContentsViewViews::~InspectableWebContentsViewViews() {
|
||||
if (devtools_window_)
|
||||
inspectable_web_contents()->SaveDevToolsBounds(
|
||||
devtools_window_->GetWindowBoundsInScreen());
|
||||
}
|
||||
|
||||
views::View* InspectableWebContentsViewViews::GetView() {
|
||||
return this;
|
||||
}
|
||||
|
||||
views::View* InspectableWebContentsViewViews::GetWebView() {
|
||||
return contents_web_view_;
|
||||
}
|
||||
|
||||
void InspectableWebContentsViewViews::ShowDevTools() {
|
||||
if (devtools_visible_)
|
||||
return;
|
||||
|
||||
devtools_visible_ = true;
|
||||
if (devtools_window_) {
|
||||
devtools_window_web_view_->SetWebContents(
|
||||
inspectable_web_contents_->GetDevToolsWebContents());
|
||||
devtools_window_->SetBounds(
|
||||
inspectable_web_contents()->GetDevToolsBounds());
|
||||
devtools_window_->Show();
|
||||
} else {
|
||||
devtools_web_view_->SetVisible(true);
|
||||
devtools_web_view_->SetWebContents(
|
||||
inspectable_web_contents_->GetDevToolsWebContents());
|
||||
devtools_web_view_->RequestFocus();
|
||||
Layout();
|
||||
}
|
||||
}
|
||||
|
||||
void InspectableWebContentsViewViews::CloseDevTools() {
|
||||
if (!devtools_visible_)
|
||||
return;
|
||||
|
||||
devtools_visible_ = false;
|
||||
if (devtools_window_) {
|
||||
inspectable_web_contents()->SaveDevToolsBounds(
|
||||
devtools_window_->GetWindowBoundsInScreen());
|
||||
devtools_window_.reset();
|
||||
devtools_window_web_view_ = nullptr;
|
||||
devtools_window_delegate_ = nullptr;
|
||||
} else {
|
||||
devtools_web_view_->SetVisible(false);
|
||||
devtools_web_view_->SetWebContents(NULL);
|
||||
Layout();
|
||||
}
|
||||
}
|
||||
|
||||
bool InspectableWebContentsViewViews::IsDevToolsViewShowing() {
|
||||
return devtools_visible_;
|
||||
}
|
||||
|
||||
bool InspectableWebContentsViewViews::IsDevToolsViewFocused() {
|
||||
if (devtools_window_web_view_)
|
||||
return devtools_window_web_view_->HasFocus();
|
||||
else if (devtools_web_view_)
|
||||
return devtools_web_view_->HasFocus();
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
void InspectableWebContentsViewViews::SetIsDocked(bool docked) {
|
||||
CloseDevTools();
|
||||
|
||||
if (!docked) {
|
||||
devtools_window_.reset(new views::Widget);
|
||||
devtools_window_web_view_ = new views::WebView(NULL);
|
||||
devtools_window_delegate_ = new DevToolsWindowDelegate(
|
||||
this, devtools_window_web_view_, devtools_window_.get());
|
||||
|
||||
views::Widget::InitParams params;
|
||||
params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
|
||||
params.delegate = devtools_window_delegate_;
|
||||
params.bounds = inspectable_web_contents()->GetDevToolsBounds();
|
||||
|
||||
#if defined(USE_X11)
|
||||
params.wm_role_name = "devtools";
|
||||
if (GetDelegate())
|
||||
GetDelegate()->GetDevToolsWindowWMClass(¶ms.wm_class_name,
|
||||
¶ms.wm_class_class);
|
||||
#endif
|
||||
|
||||
devtools_window_->Init(params);
|
||||
devtools_window_->UpdateWindowIcon();
|
||||
}
|
||||
|
||||
ShowDevTools();
|
||||
}
|
||||
|
||||
void InspectableWebContentsViewViews::SetContentsResizingStrategy(
|
||||
const DevToolsContentsResizingStrategy& strategy) {
|
||||
strategy_.CopyFrom(strategy);
|
||||
Layout();
|
||||
}
|
||||
|
||||
void InspectableWebContentsViewViews::SetTitle(const base::string16& title) {
|
||||
if (devtools_window_) {
|
||||
title_ = title;
|
||||
devtools_window_->UpdateWindowTitle();
|
||||
}
|
||||
}
|
||||
|
||||
void InspectableWebContentsViewViews::Layout() {
|
||||
if (!devtools_web_view_->visible()) {
|
||||
contents_web_view_->SetBoundsRect(GetContentsBounds());
|
||||
return;
|
||||
}
|
||||
|
||||
gfx::Size container_size(width(), height());
|
||||
gfx::Rect new_devtools_bounds;
|
||||
gfx::Rect new_contents_bounds;
|
||||
ApplyDevToolsContentsResizingStrategy(
|
||||
strategy_, container_size, &new_devtools_bounds, &new_contents_bounds);
|
||||
|
||||
// DevTools cares about the specific position, so we have to compensate RTL
|
||||
// layout here.
|
||||
new_devtools_bounds.set_x(GetMirroredXForRect(new_devtools_bounds));
|
||||
new_contents_bounds.set_x(GetMirroredXForRect(new_contents_bounds));
|
||||
|
||||
devtools_web_view_->SetBoundsRect(new_devtools_bounds);
|
||||
contents_web_view_->SetBoundsRect(new_contents_bounds);
|
||||
}
|
||||
|
||||
} // namespace atom
|
72
atom/browser/ui/views/inspectable_web_contents_view_views.h
Normal file
72
atom/browser/ui/views/inspectable_web_contents_view_views.h
Normal file
|
@ -0,0 +1,72 @@
|
|||
// Copyright (c) 2014 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-CHROMIUM file.
|
||||
|
||||
#ifndef ATOM_BROWSER_UI_VIEWS_INSPECTABLE_WEB_CONTENTS_VIEW_VIEWS_H_
|
||||
#define ATOM_BROWSER_UI_VIEWS_INSPECTABLE_WEB_CONTENTS_VIEW_VIEWS_H_
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "atom/browser/ui/inspectable_web_contents_view.h"
|
||||
#include "base/compiler_specific.h"
|
||||
#include "chrome/browser/devtools/devtools_contents_resizing_strategy.h"
|
||||
#include "ui/views/view.h"
|
||||
|
||||
namespace views {
|
||||
class WebView;
|
||||
class Widget;
|
||||
class WidgetDelegate;
|
||||
} // namespace views
|
||||
|
||||
namespace atom {
|
||||
|
||||
class InspectableWebContentsImpl;
|
||||
|
||||
class InspectableWebContentsViewViews : public InspectableWebContentsView,
|
||||
public views::View {
|
||||
public:
|
||||
explicit InspectableWebContentsViewViews(
|
||||
InspectableWebContentsImpl* inspectable_web_contents_impl);
|
||||
~InspectableWebContentsViewViews() override;
|
||||
|
||||
// InspectableWebContentsView:
|
||||
views::View* GetView() override;
|
||||
views::View* GetWebView() override;
|
||||
void ShowDevTools() override;
|
||||
void CloseDevTools() override;
|
||||
bool IsDevToolsViewShowing() override;
|
||||
bool IsDevToolsViewFocused() override;
|
||||
void SetIsDocked(bool docked) override;
|
||||
void SetContentsResizingStrategy(
|
||||
const DevToolsContentsResizingStrategy& strategy) override;
|
||||
void SetTitle(const base::string16& title) override;
|
||||
|
||||
InspectableWebContentsImpl* inspectable_web_contents() {
|
||||
return inspectable_web_contents_;
|
||||
}
|
||||
|
||||
const base::string16& GetTitle() const { return title_; }
|
||||
|
||||
private:
|
||||
// views::View:
|
||||
void Layout() override;
|
||||
|
||||
// Owns us.
|
||||
InspectableWebContentsImpl* inspectable_web_contents_;
|
||||
|
||||
std::unique_ptr<views::Widget> devtools_window_;
|
||||
views::WebView* devtools_window_web_view_;
|
||||
views::View* contents_web_view_;
|
||||
views::WebView* devtools_web_view_;
|
||||
|
||||
DevToolsContentsResizingStrategy strategy_;
|
||||
bool devtools_visible_;
|
||||
views::WidgetDelegate* devtools_window_delegate_;
|
||||
base::string16 title_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(InspectableWebContentsViewViews);
|
||||
};
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_UI_VIEWS_INSPECTABLE_WEB_CONTENTS_VIEW_VIEWS_H_
|
Loading…
Add table
Add a link
Reference in a new issue