diff --git a/atom/browser/api/atom_api_app.cc b/atom/browser/api/atom_api_app.cc index 8224d2b7ae..b3ee8afdc5 100644 --- a/atom/browser/api/atom_api_app.cc +++ b/atom/browser/api/atom_api_app.cc @@ -32,7 +32,6 @@ #include "base/strings/string_util.h" #include "brave/browser/brave_content_browser_client.h" #include "brightray/browser/brightray_paths.h" -#include "chrome/browser/chrome_notification_types.h" #include "chrome/common/chrome_paths.h" #include "content/public/browser/browser_accessibility_state.h" #include "content/public/browser/browser_thread.h" @@ -40,7 +39,6 @@ #include "content/public/browser/gpu_data_manager.h" #include "content/public/browser/navigation_details.h" #include "content/public/browser/notification_service.h" -#include "content/public/browser/notification_types.h" #include "content/public/browser/render_frame_host.h" #include "content/public/common/content_switches.h" #include "native_mate/dictionary.h" @@ -55,6 +53,8 @@ #if defined(ENABLE_EXTENSIONS) #include "atom/browser/api/atom_api_extension.h" +#include "chrome/browser/chrome_notification_types.h" +#include "content/public/browser/notification_types.h" #endif using atom::Browser; @@ -239,18 +239,23 @@ App::App(v8::Isolate* isolate) { Browser::Get()->AddObserver(this); content::GpuDataManager::GetInstance()->AddObserver(this); Init(isolate); +#if defined(ENABLE_EXTENSIONS) registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_RENDER_VIEW_HOST_CREATED, content::NotificationService::AllBrowserContextsAndSources()); + registrar_.Add(this, + chrome::NOTIFICATION_PROFILE_CREATED, + content::NotificationService::AllBrowserContextsAndSources()); +#endif } // TOOD(bridiver) - move this to api_extension? void App::Observe( int type, const content::NotificationSource& source, const content::NotificationDetails& details) { +#if defined(ENABLE_EXTENSIONS) switch (type) { case content::NOTIFICATION_WEB_CONTENTS_RENDER_VIEW_HOST_CREATED: { -#if defined(ENABLE_EXTENSIONS) content::WebContents* web_contents = content::Source(source).ptr(); auto browser_context = web_contents->GetBrowserContext(); @@ -261,10 +266,17 @@ void App::Observe( if (Extension::IsBackgroundPageUrl(url, browser_context)) { WebContents::CreateFrom(isolate(), web_contents); } -#endif + break; + } + case chrome::NOTIFICATION_PROFILE_CREATED: { + AtomBrowserContext* browser_context = + content::Source(source).ptr(); + auto session = Session::CreateFrom(isolate(), browser_context); + Emit("browser-context-created", session); break; } } +#endif } App::~App() { diff --git a/atom/browser/api/atom_api_extension.cc b/atom/browser/api/atom_api_extension.cc index 4406589d11..5cac7a7b05 100644 --- a/atom/browser/api/atom_api_extension.cc +++ b/atom/browser/api/atom_api_extension.cc @@ -12,6 +12,7 @@ #include "atom/common/native_mate_converters/file_path_converter.h" #include "atom/common/native_mate_converters/string16_converter.h" #include "atom/common/native_mate_converters/value_converter.h" +#include "atom/common/native_mate_converters/v8_value_converter.h" #include "atom/common/node_includes.h" #include "base/files/file_path.h" #include "components/prefs/pref_service.h" @@ -124,7 +125,7 @@ Extension* Extension::GetInstance() { } // static -mate::Dictionary Extension::Load( +v8::Local Extension::Load( v8::Isolate* isolate, const base::FilePath& path, const base::DictionaryValue& manifest, @@ -133,32 +134,37 @@ mate::Dictionary Extension::Load( std::string error; scoped_refptr extension; - if (manifest.empty()) { - extension = extensions::file_util::LoadExtension(path, - manifest_location, - flags, - &error); - } else { + std::unique_ptr manifest_copy = + manifest.CreateDeepCopy(); + if (manifest_copy->empty()) { + manifest_copy = extensions::file_util::LoadManifest(path, &error); + } + + if (error.empty()) { extension = LoadExtension(path, - manifest, + *manifest_copy, manifest_location, flags, &error); } - mate::Dictionary install_info = mate::Dictionary::CreateEmpty(isolate); + std::unique_ptr + install_info(new base::DictionaryValue); if (error.empty()) { Install(extension); - install_info.Set("name", extension->non_localized_name()); - install_info.Set("id", extension->id()); - install_info.Set("url", extension->url().spec()); - install_info.Set("path", extension->path()); - install_info.Set("version", extension->VersionString()); - install_info.Set("description", extension->description()); + install_info->SetString("name", extension->non_localized_name()); + install_info->SetString("id", extension->id()); + install_info->SetString("url", extension->url().spec()); + install_info->SetString("base_path", extension->path().value()); + install_info->SetString("version", extension->VersionString()); + install_info->SetString("description", extension->description()); + install_info->Set("manifest", std::move(manifest_copy)); } else { - install_info.Set("error", error); + install_info->SetString("error", error); } - return install_info; + std::unique_ptr + converter(new atom::V8ValueConverter); + return converter->ToV8Value(install_info.get(), isolate->GetCurrentContext()); } // static diff --git a/atom/browser/api/atom_api_extension.h b/atom/browser/api/atom_api_extension.h index ccdf3912c0..92e484d02b 100644 --- a/atom/browser/api/atom_api_extension.h +++ b/atom/browser/api/atom_api_extension.h @@ -36,7 +36,7 @@ class Extension : public content::NotificationObserver { public: static Extension* GetInstance(); - static mate::Dictionary Load(v8::Isolate* isolate, + static v8::Local Load(v8::Isolate* isolate, const base::FilePath& path, const base::DictionaryValue& manifest, const extensions::Manifest::Location& manifest_location, diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index a238cb0965..1da99b55f9 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -739,6 +739,11 @@ std::unique_ptr WebContents::RunBluetoothChooser( return std::move(bluetooth_chooser); } +void WebContents::UpdatePreferredSize(content::WebContents* web_contents, + const gfx::Size& pref_size) { + Emit("preferred-size-changed", pref_size); +} + void WebContents::BeforeUnloadFired(const base::TimeTicks& proceed_time) { // Do nothing, we override this method just to avoid compilation error since // there are two virtual functions named BeforeUnloadFired. @@ -776,6 +781,14 @@ void WebContents::DidChangeThemeColor(SkColor theme_color) { Emit("did-change-theme-color", hex_theme_color); } +void WebContents::DocumentAvailableInMainFrame() { + Emit("document-available"); +} + +void WebContents::DocumentOnLoadCompletedInMainFrame() { + Emit("document-onload"); +} + void WebContents::DocumentLoadedInFrame( content::RenderFrameHost* render_frame_host) { if (!render_frame_host->GetParent()) @@ -1692,6 +1705,10 @@ void WebContents::CapturePage(mate::Arguments* args) { kBGRA_8888_SkColorType); } +gfx::Size WebContents::GetPreferredSize() { + return web_contents()->GetPreferredSize(); +} + void WebContents::OnCursorChange(const content::WebCursor& cursor) { content::WebCursor::CursorInfo info; cursor.GetCursorInfo(&info); @@ -1831,6 +1848,7 @@ void WebContents::OnMemoryPressure( web_contents()->GetController().ClearAllScreenshots(); } + // TODO(bridiver) only run once per render process if (!web_contents()->GetRenderWidgetHostView()->HasFocus()) { content::MemoryPressureController::SendPressureNotification( web_contents()->GetRenderProcessHost(), memory_pressure_level); @@ -1967,6 +1985,7 @@ void WebContents::BuildPrototype(v8::Isolate* isolate, &WebContents::ShowDefinitionForSelection) .SetMethod("copyImageAt", &WebContents::CopyImageAt) .SetMethod("capturePage", &WebContents::CapturePage) + .SetMethod("getPreferredSize", &WebContents::GetPreferredSize) .SetProperty("id", &WebContents::ID) .SetMethod("getContentWindowId", &WebContents::GetContentWindowId) .SetMethod("setActive", &WebContents::SetActive) diff --git a/atom/browser/api/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index 57dc0b9bc6..0d08a1a13b 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -33,6 +33,10 @@ namespace brightray { class InspectableWebContents; } +namespace gfx { +class Size; +} + namespace mate { template<> @@ -214,6 +218,8 @@ class WebContents : public mate::TrackableObject, // done. void CapturePage(mate::Arguments* args); + gfx::Size GetPreferredSize(); + // Methods for creating . void SetSize(const SetSizeParams& params); bool IsGuest() const; @@ -333,11 +339,15 @@ class WebContents : public mate::TrackableObject, std::unique_ptr RunBluetoothChooser( content::RenderFrameHost* frame, const content::BluetoothChooser::EventHandler& handler) override; + void UpdatePreferredSize(content::WebContents* web_contents, + const gfx::Size& pref_size) override; // content::WebContentsObserver: void BeforeUnloadFired(const base::TimeTicks& proceed_time) override; void RenderViewDeleted(content::RenderViewHost*) override; void RenderProcessGone(base::TerminationStatus status) override; + void DocumentAvailableInMainFrame() override; + void DocumentOnLoadCompletedInMainFrame() override; void DocumentLoadedInFrame( content::RenderFrameHost* render_frame_host) override; void DidStartProvisionalLoadForFrame( diff --git a/atom/common/api/resources/browser_action_bindings.js b/atom/common/api/resources/browser_action_bindings.js index b40b938b2e..e9b688511d 100644 --- a/atom/common/api/resources/browser_action_bindings.js +++ b/atom/common/api/resources/browser_action_bindings.js @@ -4,28 +4,71 @@ var manifest = runtimeNatives.GetManifest(); var process = requireNative('process'); var extensionId = process.GetExtensionId(); +var id = 0 + var binding = { onClicked: { addListener: function (cb) { - ipc.send('register-chrome-browser-action', extensionId, - manifest.browser_action.default_title) ipc.on('chrome-browser-action-clicked', function(evt, tab) { cb(tab) }) + }, + removeListener: function (cb) { + // TODO + // ipc.off('chrome-browser-action-clicked', cb) } }, setPopup: function (details) { ipc.send('chrome-browser-action-set-popup', extensionId, details) }, + getPopup: function (details, cb) { + var responseId = ++id + ipc.once('chrome-browser-action-get-popup-response-' + responseId, function(evt, details) { + cb(details) + }) + ipc.send('chrome-browser-action-get-popup', responseId, details) + }, setTitle: function (details) { ipc.send('chrome-browser-action-set-title', extensionId, details) }, + getTitle: function (details, cb) { + var responseId = ++id + ipc.once('chrome-browser-action-get-title-response-' + responseId, function(evt, result) { + cb(result) + }) + ipc.send('chrome-browser-action-get-title', responseId, details) + }, setIcon: function (details, cb) { - ipc.send('chrome-browser-action-set-icon', extensionId, details) - cb && cb() + if (details.imageData) { + // TODO(bridiver) - support imageData somehow + console.warn('chrome.browserAction.setIcon imageData is not supported yet') + return + } + var responseId = ++id + ipc.once('chrome-browser-action-set-icon-response-' + responseId, function(evt) { + cb && cb() + }) + ipc.send('chrome-browser-action-set-icon', responseId, extensionId, details) }, setBadgeText: function (details) { - ipc.send('chrome-browser-action-set-title', extensionId, details) + ipc.send('chrome-browser-action-set-badge-text', extensionId, details) + }, + getBadgeText: function (details, cb) { + var responseId = ++id + ipc.once('chrome-browser-action-get-badge-text-response-' + responseId, function(evt, details) { + cb(details) + }) + ipc.send('chrome-browser-action-get-badge-text', responseId, details) + }, + setBadgeBackgroundColor: function (details) { + ipc.send('chrome-browser-action-set-badge-background-color', extensionId, details) + }, + getBadgeBackgroundColor: function (details, cb) { + var responseId = ++id + ipc.once('chrome-browser-action-get-badge-text-response-' + responseId, function(evt, details) { + cb(details) + }) + ipc.send('chrome-browser-action-get-badge-text', responseId, details) } } diff --git a/atom/common/api/resources/content_settings_bindings.js b/atom/common/api/resources/content_settings_bindings.js index cd03e94c4a..8d37e3c347 100644 --- a/atom/common/api/resources/content_settings_bindings.js +++ b/atom/common/api/resources/content_settings_bindings.js @@ -1,6 +1,5 @@ -var atom = requireNative('atom').GetBinding(); +var contentSettings = requireNative('contentSettings'); var inIncognitoContext = requireNative('process').InIncognitoContext(); -var contentSettings = atom.content_settings; function getCurrent (contentType) { return contentSettings.getCurrent(contentType, inIncognitoContext) diff --git a/atom/common/javascript_bindings.cc b/atom/common/javascript_bindings.cc index edf539955c..e7cf6203ca 100644 --- a/atom/common/javascript_bindings.cc +++ b/atom/common/javascript_bindings.cc @@ -9,36 +9,59 @@ #include "atom/common/api/api_messages.h" #include "atom/common/native_mate_converters/string16_converter.h" #include "atom/common/native_mate_converters/value_converter.h" -#include "atom/renderer/content_settings_manager.h" +#include "content/public/renderer/render_frame.h" #include "content/public/renderer/render_view.h" #include "native_mate/dictionary.h" #include "third_party/WebKit/public/web/WebView.h" #include "third_party/WebKit/public/web/WebLocalFrame.h" -#include "third_party/WebKit/public/web/WebDocument.h" + +namespace atom { namespace { -content::RenderView* GetCurrentRenderView() { - blink::WebLocalFrame* frame = - blink::WebLocalFrame::frameForCurrentContext(); - if (!frame) - return NULL; +std::vector> ListValueToVector(v8::Isolate* isolate, + const base::ListValue& list) { + v8::Local array = mate::ConvertToV8(isolate, list); + std::vector> result; + mate::ConvertFromV8(isolate, array, &result); + return result; +} + +} // namespace + +JavascriptBindings::JavascriptBindings(content::RenderView* render_view, + extensions::ScriptContext* context) + : content::RenderViewObserver(render_view), + extensions::ObjectBackedNativeHandler(context) { + RouteFunction( + "GetBinding", + base::Bind(&JavascriptBindings::GetBinding, base::Unretained(this))); +} - blink::WebView* view = frame->view(); - if (!view) - return NULL; // can happen during closing. +JavascriptBindings::~JavascriptBindings() { + Observe(nullptr); +} - return content::RenderView::FromWebView(view); +void JavascriptBindings::OnDestruct() { + Observe(nullptr); } -v8::Local GetHiddenValue(v8::Isolate* isolate, +v8::Local JavascriptBindings::GetHiddenValue(v8::Isolate* isolate, v8::Local key) { - content::RenderView* render_view = GetCurrentRenderView(); + if (!is_valid() || !render_view()) + return v8::Local(); + v8::Local context = - render_view->GetWebView()->mainFrame()->mainWorldScriptContext(); + render_view()->GetWebView()->mainFrame()->mainWorldScriptContext(); v8::Local privateKey = v8::Private::ForApi(isolate, key); v8::Local value; v8::Local object = context->Global(); + + if (!ContextCanAccessObject(context, context->Global(), false)) { + LOG(ERROR) << "cannot access global main"; + return v8::Local(); + } + v8::Maybe result = object->HasPrivate(context, privateKey); if (!(result.IsJust() && result.FromJust())) return v8::Local(); @@ -47,44 +70,49 @@ v8::Local GetHiddenValue(v8::Isolate* isolate, return v8::Local(); } -void SetHiddenValue(v8::Isolate* isolate, +void JavascriptBindings::SetHiddenValue(v8::Isolate* isolate, v8::Local key, v8::Local value) { - if (value.IsEmpty()) + if (!is_valid() || !render_view() || value.IsEmpty()) return; - content::RenderView* render_view = GetCurrentRenderView(); + v8::Local context = - render_view->GetWebView()->mainFrame()->mainWorldScriptContext(); + render_view()->GetWebView()->mainFrame()->mainWorldScriptContext(); + + if (!ContextCanAccessObject(context, context->Global(), false)) { + LOG(ERROR) << "cannot access global main"; + return; + } + v8::Local privateKey = v8::Private::ForApi(isolate, key); context->Global()->SetPrivate(context, privateKey, value); } -void IPCSend(mate::Arguments* args, +void JavascriptBindings::IPCSend(mate::Arguments* args, const base::string16& channel, const base::ListValue& arguments) { - content::RenderView* render_view = GetCurrentRenderView(); - if (render_view == NULL) + if (!is_valid() || !render_view()) return; - bool success = render_view->Send(new AtomViewHostMsg_Message( - render_view->GetRoutingID(), channel, arguments)); + bool success = render_view()->Send(new AtomViewHostMsg_Message( + render_view()->GetRoutingID(), channel, arguments)); if (!success) args->ThrowError("Unable to send AtomViewHostMsg_Message"); } -base::string16 IPCSendSync(mate::Arguments* args, +base::string16 JavascriptBindings::IPCSendSync(mate::Arguments* args, const base::string16& channel, const base::ListValue& arguments) { base::string16 json; - content::RenderView* render_view = GetCurrentRenderView(); - if (render_view == NULL) + if (!is_valid() || !render_view()) { return json; + } IPC::SyncMessage* message = new AtomViewHostMsg_Message_Sync( - render_view->GetRoutingID(), channel, arguments, &json); - bool success = render_view->Send(message); + render_view()->GetRoutingID(), channel, arguments, &json); + bool success = render_view()->Send(message); if (!success) args->ThrowError("Unable to send AtomViewHostMsg_Message_Sync"); @@ -92,34 +120,6 @@ base::string16 IPCSendSync(mate::Arguments* args, return json; } -std::vector> ListValueToVector(v8::Isolate* isolate, - const base::ListValue& list) { - v8::Local array = mate::ConvertToV8(isolate, list); - std::vector> result; - mate::ConvertFromV8(isolate, array, &result); - return result; -} - -} // namespace - -namespace atom { - -JavascriptBindings::JavascriptBindings(content::RenderView* render_view, - extensions::ScriptContext* context) - : content::RenderViewObserver(render_view), - extensions::ObjectBackedNativeHandler(context) { - RouteFunction( - "GetBinding", - base::Bind(&JavascriptBindings::GetBinding, base::Unretained(this))); -} - -JavascriptBindings::~JavascriptBindings() { -} - -void JavascriptBindings::OnDestruct() { - // do nothing -} - void JavascriptBindings::GetBinding( const v8::FunctionCallbackInfo& args) { blink::WebLocalFrame* frame = context()->web_frame(); @@ -129,29 +129,19 @@ void JavascriptBindings::GetBinding( mate::Dictionary binding(isolate, v8::Object::New(isolate)); mate::Dictionary ipc(isolate, v8::Object::New(isolate)); - ipc.SetMethod("send", &IPCSend); - ipc.SetMethod("sendSync", &IPCSendSync); + ipc.SetMethod("send", base::Bind(&JavascriptBindings::IPCSend, + base::Unretained(this))); + ipc.SetMethod("sendSync", base::Bind(&JavascriptBindings::IPCSendSync, + base::Unretained(this))); binding.Set("ipc", ipc.GetHandle()); mate::Dictionary v8(isolate, v8::Object::New(isolate)); - v8.SetMethod("getHiddenValue", &GetHiddenValue); - v8.SetMethod("setHiddenValue", &SetHiddenValue); + v8.SetMethod("getHiddenValue", base::Bind(&JavascriptBindings::GetHiddenValue, + base::Unretained(this))); + v8.SetMethod("setHiddenValue", base::Bind(&JavascriptBindings::SetHiddenValue, + base::Unretained(this))); binding.Set("v8", v8.GetHandle()); - mate::Dictionary content_settings(isolate, v8::Object::New(isolate)); - content_settings.SetMethod("get", - base::Bind(&ContentSettingsManager::GetSetting, - base::Unretained(ContentSettingsManager::GetInstance()))); - content_settings.SetMethod("getContentTypes", - base::Bind(&ContentSettingsManager::GetContentTypes, - base::Unretained(ContentSettingsManager::GetInstance()))); - content_settings.SetMethod("getCurrent", - base::Bind(&ContentSettingsManager::GetSetting, - base::Unretained(ContentSettingsManager::GetInstance()), - render_view()->GetWebView()->mainFrame()->document().url(), - frame->document().url())); - binding.Set("content_settings", content_settings); - args.GetReturnValue().Set(binding.GetHandle()); } diff --git a/atom/common/javascript_bindings.h b/atom/common/javascript_bindings.h index 0fd8fffb39..496c3f1995 100644 --- a/atom/common/javascript_bindings.h +++ b/atom/common/javascript_bindings.h @@ -10,6 +10,10 @@ #include "extensions/renderer/script_context.h" #include "v8/include/v8.h" +namespace mate { +class Arguments; +} + namespace atom { class JavascriptBindings : public content::RenderViewObserver, @@ -22,6 +26,18 @@ class JavascriptBindings : public content::RenderViewObserver, void GetBinding(const v8::FunctionCallbackInfo& args); private: + base::string16 IPCSendSync(mate::Arguments* args, + const base::string16& channel, + const base::ListValue& arguments); + void IPCSend(mate::Arguments* args, + const base::string16& channel, + const base::ListValue& arguments); + v8::Local GetHiddenValue(v8::Isolate* isolate, + v8::Local key); + void SetHiddenValue(v8::Isolate* isolate, + v8::Local key, + v8::Local value); + void OnDestruct() override; bool OnMessageReceived(const IPC::Message& message) override; void OnBrowserMessage(bool all_frames, diff --git a/atom/renderer/extensions/atom_extensions_dispatcher_delegate.cc b/atom/renderer/extensions/atom_extensions_dispatcher_delegate.cc index 42cb21ec60..76edb68050 100644 --- a/atom/renderer/extensions/atom_extensions_dispatcher_delegate.cc +++ b/atom/renderer/extensions/atom_extensions_dispatcher_delegate.cc @@ -8,6 +8,7 @@ #include #include "atom/common/javascript_bindings.h" #include "atom/grit/atom_resources.h" // NOLINT: This file is generated +#include "brave/renderer/extensions/content_settings_bindings.h" #include "brave/renderer/extensions/web_frame_bindings.h" #include "chrome/grit/renderer_resources.h" // NOLINT: This file is generated #include "chrome/renderer/extensions/tabs_custom_bindings.h" @@ -36,6 +37,10 @@ void AtomExtensionsDispatcherDelegate::RegisterNativeHandlers( std::unique_ptr( new atom::JavascriptBindings( context->GetRenderFrame()->GetRenderView(), context))); + module_system->RegisterNativeHandler( + "contentSettings", + std::unique_ptr( + new brave::ContentSettingsBindings(context))); module_system->RegisterNativeHandler( "webFrame", std::unique_ptr( diff --git a/brave/browser/brave_browser_context.h b/brave/browser/brave_browser_context.h index 15ef6a3966..3f1e6444bc 100644 --- a/brave/browser/brave_browser_context.h +++ b/brave/browser/brave_browser_context.h @@ -85,6 +85,7 @@ class BraveBrowserContext : public atom::AtomBrowserContext { GetAutofillWebdataService(); base::FilePath GetPath() const override; + private: void OnPrefsLoaded(bool success); void TrackZoomLevelsFromParent(); diff --git a/brave/renderer/extensions/content_settings_bindings.cc b/brave/renderer/extensions/content_settings_bindings.cc new file mode 100644 index 0000000000..1dd8539df6 --- /dev/null +++ b/brave/renderer/extensions/content_settings_bindings.cc @@ -0,0 +1,71 @@ +// Copyright (c) 2013 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#include "brave/renderer/extensions/content_settings_bindings.h" + +#include +#include + +#include "atom/common/native_mate_converters/string16_converter.h" +#include "atom/common/native_mate_converters/value_converter.h" +#include "atom/renderer/content_settings_manager.h" +#include "content/public/renderer/render_frame.h" +#include "content/public/renderer/render_view.h" +#include "extensions/renderer/script_context.h" +#include "third_party/WebKit/public/web/WebView.h" +#include "third_party/WebKit/public/web/WebLocalFrame.h" +#include "third_party/WebKit/public/web/WebDocument.h" + + +namespace brave { + +ContentSettingsBindings::ContentSettingsBindings( + extensions::ScriptContext* context) + : extensions::ObjectBackedNativeHandler(context) { + RouteFunction( + "getCurrent", + base::Bind(&ContentSettingsBindings::GetCurrentSetting, + base::Unretained(this))); + RouteFunction( + "getContentTypes", + base::Bind(&ContentSettingsBindings::GetContentTypes, + base::Unretained(this))); +} + +ContentSettingsBindings::~ContentSettingsBindings() { +} + +void ContentSettingsBindings::GetCurrentSetting( + const v8::FunctionCallbackInfo& args) { + const std::string content_type = + mate::V8ToString(args[0].As()); + bool incognito = args[1].As()->Value(); + + auto render_view = context()->GetRenderFrame()->GetRenderView(); + GURL main_frame_url = + render_view->GetWebView()->mainFrame()->document().url(); + + ContentSetting setting = + atom::ContentSettingsManager::GetInstance()->GetSetting( + main_frame_url, + context()->web_frame()->document().url(), + content_type, + incognito); + + + args.GetReturnValue().Set( + mate::Converter::ToV8(context()->isolate(), setting)); +} + +void ContentSettingsBindings::GetContentTypes( + const v8::FunctionCallbackInfo& args) { + std::vector content_types = + atom::ContentSettingsManager::GetInstance()->GetContentTypes(); + + args.GetReturnValue().Set( + mate::Converter>::ToV8( + context()->isolate(), content_types)); +} + +} // namespace brave diff --git a/brave/renderer/extensions/content_settings_bindings.h b/brave/renderer/extensions/content_settings_bindings.h new file mode 100644 index 0000000000..dd22842c6d --- /dev/null +++ b/brave/renderer/extensions/content_settings_bindings.h @@ -0,0 +1,29 @@ +// Copyright (c) 2013 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#ifndef BRAVE_RENDERER_EXTENSIONS_CONTENT_SETTINGS_BINDINGS_H_ +#define BRAVE_RENDERER_EXTENSIONS_CONTENT_SETTINGS_BINDINGS_H_ + +#include "extensions/renderer/object_backed_native_handler.h" +#include "extensions/renderer/script_context.h" +#include "v8/include/v8.h" + +namespace brave { + +class ContentSettingsBindings : public extensions::ObjectBackedNativeHandler { + public: + explicit ContentSettingsBindings(extensions::ScriptContext* context); + virtual ~ContentSettingsBindings(); + + void GetCurrentSetting( + const v8::FunctionCallbackInfo& args); + void GetContentTypes( + const v8::FunctionCallbackInfo& args); + private: + DISALLOW_COPY_AND_ASSIGN(ContentSettingsBindings); +}; + +} // namespace brave + +#endif // BRAVE_RENDERER_EXTENSIONS_CONTENT_SETTINGS_BINDINGS_H_ diff --git a/brave/renderer/extensions/web_frame_bindings.cc b/brave/renderer/extensions/web_frame_bindings.cc index cfd9b61a01..178d5378da 100644 --- a/brave/renderer/extensions/web_frame_bindings.cc +++ b/brave/renderer/extensions/web_frame_bindings.cc @@ -99,6 +99,11 @@ void WebFrameBindings::SetGlobal( context()->web_frame()->mainWorldScriptContext(); v8::Context::Scope context_scope(main_context); + if (!ContextCanAccessObject(main_context, main_context->Global(), false)) { + LOG(ERROR) << "cannot access global main"; + return; + } + v8::Handle obj; for (std::vector>::const_iterator iter = path.begin(); diff --git a/extensions.gypi b/extensions.gypi index a0f1a1d602..d04aed6c3e 100644 --- a/extensions.gypi +++ b/extensions.gypi @@ -4,6 +4,7 @@ 'grit_out_dir%': '<(SHARED_INTERMEDIATE_DIR)/atom', 'grit_defines': [], 'extension_js_sources': [ + 'lib/browser/api/browser-actions.js', 'lib/browser/api/extensions.js', ], 'extension_sources': [ @@ -55,6 +56,8 @@ 'atom/renderer/extensions/atom_extensions_dispatcher_delegate.h', 'atom/renderer/extensions/atom_extensions_renderer_client.cc', 'atom/renderer/extensions/atom_extensions_renderer_client.h', + 'brave/renderer/extensions/content_settings_bindings.cc', + 'brave/renderer/extensions/content_settings_bindings.h', 'brave/renderer/extensions/web_frame_bindings.cc', 'brave/renderer/extensions/web_frame_bindings.h', 'chromium_src/chrome/browser/renderer_host/chrome_extension_message_filter.cc', diff --git a/lib/browser/api/browser-actions.js b/lib/browser/api/browser-actions.js new file mode 100644 index 0000000000..c95c96d718 --- /dev/null +++ b/lib/browser/api/browser-actions.js @@ -0,0 +1,66 @@ +const browserActions = {} + +const updateBrowserAction = (extensionId, details) => { + browserActions[extensionId] = browserActions[extensionId] || {} + if (details.tabId) { + browserActions[extensionId][tabId] = browserActions[extensionId][tabId] || {} + browserActions[extensionId][tabId] = Object.assign(browserActions[extensionId][tabId], details) + } else { + browserActions[extensionId] = Object.assign(browserActions[extensionId], details) + } +} + +const getBrowserAction = (extensionId, details) => { + if (details.tabId) { + if (browserActions[extensionId] && browserActions[extensionId][details.tabId]) { + return browserActions[extensionId][details.tabId] + } + } + return browserActions[extensionId] || {} +} + +module.exports = { + onDestroyed: (extensionId, tabId) => { + Object.keys(browserActions).forEach((extensionId) => { + if (browserActions[extensionId]) { + delete browserActions[extensionId][tabId] + } + }) + }, + + setDefaultBrowserAction: (extensionId, details) => { + updateBrowserAction(extensionId, details) + }, + + setTitle: (extensionId, details) => { + updateBrowserAction(extensionId, details) + }, + + getTitle: (extensionId, details) => { + return getBrowserAction(extensionId, details).title + }, + + setBadgeText: (extensionId, details) => { + updateBrowserAction(extensionId, details) + }, + + getBadgeText: (extensionId, details) => { + return getBrowserAction(extensionId, details).text + }, + + setBadgeBackgroundColor: (extensionId, details) => { + updateBrowserAction(extensionId, details) + }, + + getBadgeBackgroundColor: (extensionId, details) => { + return getBrowserAction(extensionId, details).color + }, + + setPopup: (extensionId, details) => { + updateBrowserAction(extensionId, details) + }, + + getPopup: (extensionId, details) => { + return getBrowserAction(extensionId, details).popup + } +} diff --git a/lib/browser/api/extensions.js b/lib/browser/api/extensions.js index 6885bda0c2..e197753ae2 100644 --- a/lib/browser/api/extensions.js +++ b/lib/browser/api/extensions.js @@ -1,6 +1,7 @@ const extensions = process.atomBinding('extension') const {app, BrowserWindow, ipcMain, webContents} = require('electron') const path = require('path') +const browserActions = require('./browser-actions') // List of currently active background pages by extensionId var backgroundPages = {} @@ -38,9 +39,19 @@ process.on('load-extension', function (base_dir, options, cb) { manifest = options.manifest || {} manifest_location = options.manifest_location || 'unpacked' flags = options.flags || 0 - - var install_info = extensions.load(base_dir, manifest, manifest_location, flags) - cb && cb(install_info) + var installInfo = extensions.load(base_dir, manifest, manifest_location, flags) + cb && cb(installInfo) + let browserAction = installInfo.manifest.browser_action + if (browserAction) { + let details = { + title: browserAction.default_title, + path: browserAction.default_icon, + popup: browserAction.default_popup + } + browserActions.setDefaultBrowserAction(installInfo.id, details) + addBackgroundPageEvent(installInfo.id, 'chrome-browser-action-clicked') + process.emit('chrome-browser-action-registered', installInfo.id, details) + } }) var urlBlacklist = []; @@ -362,7 +373,7 @@ var initializeTab = function (tabId, webContents) { tabs[tabId].tabInfo = extensions.tabValue(webContents) let pending = pending_tabs[tabId] - if (pending) { + if (pending && !pending.sender.isDestroyed()) { // sender may be gone when we try to call this try { pending.sender.send('chrome-tabs-create-response-' + pending.responseId, tabs[tabId].tabInfo) @@ -411,6 +422,7 @@ app.on('web-contents-created', function (event, webContents) { }) webContents.on('destroyed', function () { chromeTabsRemoved(tabId) + browserActions.onDestroyed(tabId) }) webContents.on('crashed', function () { chromeTabsRemoved(tabId) @@ -512,17 +524,61 @@ ipcMain.on('chrome-windows-update', function (evt, responseId, windowId, updateI }) // chrome.browserAction -var browserActionPopups = {} -ipcMain.on('register-chrome-browser-action', function (evt, extensionId, actionTitle) { - addBackgroundPageEvent(extensionId, 'chrome-browser-action-clicked') - process.emit('chrome-browser-action-registered', extensionId, actionTitle) +ipcMain.on('chrome-browser-action-set-badge-background-color', function (evt, extensionId, details) { + process.emit('chrome-browser-action-set-badge-background-color', extensionId, details) + browserActions.setBadgeBackgroundColor(extensionId, details) +}) + +ipcMain.on('chrome-browser-action-get-background-color-', function (evt, responseId, details) { + let result = browserActions.getBackgroundColor(extensionId) + evt.sender.send('chrome-browser-action-get-background-color-response-' + responseId, result) +}) + +ipcMain.on('chrome-browser-action-set-icon', function (evt, responseId, extensionId, details) { + process.emit('chrome-browser-action-set-icon', extensionId, details) + evt.sender.send('chrome-browser-action-set-icon-response-' + responseId) +}) + +ipcMain.on('chrome-browser-action-get-icon-', function (evt, responseId, details) { + let result = browserActions.getIcon(extensionId) + evt.sender.send('chrome-browser-action-get-icon-response-' + responseId, result) +}) + +ipcMain.on('chrome-browser-action-set-badge-text', function (evt, extensionId, details) { + process.emit('chrome-browser-action-set-badge-text', extensionId, details, details.tabId) + browserActions.setBadgeText(extensionId, details) +}) + +ipcMain.on('chrome-browser-action-get-badge-text-', function (evt, responseId, details) { + let result = browserActions.getBadgeText(extensionId) + evt.sender.send('chrome-browser-action-get-badge-text-response-' + responseId, result) +}) + +ipcMain.on('chrome-browser-action-set-title', function (evt, extensionId, details) { + process.emit('chrome-browser-action-set-title', extensionId, details) + browserActions.setTitle(extensionId, details) +}) + +ipcMain.on('chrome-browser-action-get-title', function (evt, responseId, details) { + let result = browserActions.getTitle(extensionId) + evt.sender.send('chrome-browser-action-get-title-response-' + responseId, result) +}) + +ipcMain.on('chrome-browser-action-set-popup', function (evt, extensionId, details) { + process.emit('chrome-browser-action-set-popup', extensionId, details) + browserActions.setPopup(extensionId, details) +}) + +ipcMain.on('chrome-browser-action-get-popup', function (evt, responseId, details) { + let result = browserActions.getPopup(extensionId, details) + evt.sender.send('chrome-browser-action-get-popup-response-' + responseId, result) }) ipcMain.on('chrome-browser-action-clicked', function (evt, extensionId, tabId, name, props) { - let popup = browserActionPopups[extensionId] + let popup = browserActions.getPopup(extensionId, {tabId}) if (popup) { - process.emit('chrome-browser-action-popup', extensionId, tabId, name, props, getResourceURL(extensionId, popup)) + process.emit('chrome-browser-action-popup', extensionId, tabId, name, getResourceURL(extensionId, popup), props) } else { let response = getTabValue(tabId) if (response) { @@ -531,12 +587,6 @@ ipcMain.on('chrome-browser-action-clicked', function (evt, extensionId, tabId, n } }) -ipcMain.on('chrome-browser-action-set-popup', function (evt, extensionId, details) { - if (details.popup) { - browserActionPopups[extensionId] = details.popup - } -}) - // TODO(bridiver) - refactor this in browser-laptop and remove // https://github.com/brave/browser-laptop/pull/3241/files#r75715202 ipcMain.on('autofill-selection-clicked', function (evt, tabId, value, frontend_id, index) { diff --git a/lib/browser/guest-view-manager.js b/lib/browser/guest-view-manager.js index 3a35d34588..9e456216da 100644 --- a/lib/browser/guest-view-manager.js +++ b/lib/browser/guest-view-manager.js @@ -22,7 +22,10 @@ let supportedWebViewEvents = [ 'did-stop-loading', 'did-get-response-details', 'did-get-redirect-request', + 'document-available', + 'document-onload', 'dom-ready', + 'preferred-size-changed', 'console-message', 'devtools-opened', 'devtools-closed', diff --git a/lib/renderer/web-view/guest-view-internal.js b/lib/renderer/web-view/guest-view-internal.js index ec606d85f5..5f938b7864 100644 --- a/lib/renderer/web-view/guest-view-internal.js +++ b/lib/renderer/web-view/guest-view-internal.js @@ -19,7 +19,10 @@ var WEB_VIEW_EVENTS = { 'did-stop-loading': [], 'did-get-response-details': ['status', 'newURL', 'originalURL', 'httpResponseCode', 'requestMethod', 'referrer', 'headers', 'resourceType'], 'did-get-redirect-request': ['oldURL', 'newURL', 'isMainFrame'], + 'document-available': [], + 'document-onload': [], 'dom-ready': [], + 'preferred-size-changed': ['size'], 'console-message': ['level', 'message', 'line', 'sourceId'], 'devtools-opened': [], 'devtools-closed': [], diff --git a/lib/renderer/web-view/web-view.js b/lib/renderer/web-view/web-view.js index 80863eb156..fdde59448f 100644 --- a/lib/renderer/web-view/web-view.js +++ b/lib/renderer/web-view/web-view.js @@ -445,7 +445,8 @@ var registerWebViewElement = function () { 'zoomIn', 'zoomOut', 'zoomReset', - 'getZoomPercent' + 'getZoomPercent', + 'getPreferredSize' ] nonblockMethods = [ 'insertCSS',