// Copyright (c) 2017 GitHub, Inc. // Use of this source code is governed by the MIT license that can be // found in the LICENSE file. #include "atom/browser/api/atom_api_browser_view.h" #include "atom/browser/api/atom_api_web_contents.h" #include "atom/browser/browser.h" #include "atom/browser/native_browser_view.h" #include "atom/common/color_util.h" #include "atom/common/native_mate_converters/gfx_converter.h" #include "atom/common/native_mate_converters/value_converter.h" #include "atom/common/node_includes.h" #include "atom/common/options_switches.h" #include "native_mate/constructor.h" #include "native_mate/dictionary.h" #include "ui/gfx/geometry/rect.h" namespace mate { template <> struct Converter { static bool FromV8(v8::Isolate* isolate, v8::Local val, atom::AutoResizeFlags* auto_resize_flags) { mate::Dictionary params; if (!ConvertFromV8(isolate, val, ¶ms)) { return false; } uint8_t flags = 0; bool width = false; if (params.Get("width", &width) && width) { flags |= atom::kAutoResizeWidth; } bool height = false; if (params.Get("height", &height) && height) { flags |= atom::kAutoResizeHeight; } bool horizontal = false; if (params.Get("horizontal", &horizontal) && horizontal) { flags |= atom::kAutoResizeHorizontal; } bool vertical = false; if (params.Get("vertical", &vertical) && vertical) { flags |= atom::kAutoResizeVertical; } *auto_resize_flags = static_cast(flags); return true; } }; } // namespace mate namespace atom { namespace api { BrowserView::BrowserView(v8::Isolate* isolate, v8::Local wrapper, const mate::Dictionary& options) { Init(isolate, wrapper, options); } void BrowserView::Init(v8::Isolate* isolate, v8::Local wrapper, const mate::Dictionary& options) { mate::Dictionary web_preferences = mate::Dictionary::CreateEmpty(isolate); options.Get(options::kWebPreferences, &web_preferences); web_preferences.Set("isBrowserView", true); mate::Handle web_contents = WebContents::Create(isolate, web_preferences); web_contents_.Reset(isolate, web_contents.ToV8()); api_web_contents_ = web_contents.get(); Observe(web_contents->web_contents()); view_.reset( NativeBrowserView::Create(api_web_contents_->managed_web_contents())); InitWith(isolate, wrapper); } BrowserView::~BrowserView() { if (api_web_contents_) { // destroy() is called // Destroy WebContents asynchronously unless app is shutting down, // because destroy() might be called inside WebContents's event handler. api_web_contents_->DestroyWebContents(!Browser::Get()->is_shutting_down()); } } void BrowserView::WebContentsDestroyed() { api_web_contents_ = nullptr; web_contents_.Reset(); } // static mate::WrappableBase* BrowserView::New(mate::Arguments* args) { if (!Browser::Get()->is_ready()) { args->ThrowError("Cannot create BrowserView before app is ready"); return nullptr; } if (args->Length() > 1) { args->ThrowError("Too many arguments"); return nullptr; } mate::Dictionary options; if (!(args->Length() == 1 && args->GetNext(&options))) { options = mate::Dictionary::CreateEmpty(args->isolate()); } return new BrowserView(args->isolate(), args->GetThis(), options); } int32_t BrowserView::ID() const { return weak_map_id(); } void BrowserView::SetAutoResize(AutoResizeFlags flags) { view_->SetAutoResizeFlags(flags); } void BrowserView::SetBounds(const gfx::Rect& bounds) { view_->SetBounds(bounds); } void BrowserView::SetBackgroundColor(const std::string& color_name) { view_->SetBackgroundColor(ParseHexColor(color_name)); } v8::Local BrowserView::GetWebContents() { if (web_contents_.IsEmpty()) { return v8::Null(isolate()); } return v8::Local::New(isolate(), web_contents_); } // static void BrowserView::BuildPrototype(v8::Isolate* isolate, v8::Local prototype) { prototype->SetClassName(mate::StringToV8(isolate, "BrowserView")); mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate()) .MakeDestroyable() .SetMethod("setAutoResize", &BrowserView::SetAutoResize) .SetMethod("setBounds", &BrowserView::SetBounds) .SetMethod("setBackgroundColor", &BrowserView::SetBackgroundColor) .SetProperty("webContents", &BrowserView::GetWebContents) .SetProperty("id", &BrowserView::ID); } } // namespace api } // namespace atom namespace { using atom::api::BrowserView; void Initialize(v8::Local exports, v8::Local unused, v8::Local context, void* priv) { v8::Isolate* isolate = context->GetIsolate(); BrowserView::SetConstructor(isolate, base::BindRepeating(&BrowserView::New)); mate::Dictionary browser_view(isolate, BrowserView::GetConstructor(isolate) ->GetFunction(context) .ToLocalChecked()); browser_view.SetMethod("fromId", &mate::TrackableObject::FromWeakMapID); browser_view.SetMethod("getAllViews", &mate::TrackableObject::GetAll); mate::Dictionary dict(isolate, exports); dict.Set("BrowserView", browser_view); } } // namespace NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_browser_view, Initialize)