4
4
5
5
#include " shell/browser/api/electron_api_web_contents_view.h"
6
6
7
- #include " content/public/browser/web_contents_user_data .h"
7
+ #include " base/no_destructor .h"
8
8
#include " shell/browser/api/electron_api_web_contents.h"
9
9
#include " shell/browser/browser.h"
10
10
#include " shell/browser/ui/inspectable_web_contents_view.h"
11
+ #include " shell/browser/web_contents_preferences.h"
12
+ #include " shell/common/gin_converters/value_converter.h"
11
13
#include " shell/common/gin_helper/constructor.h"
12
14
#include " shell/common/gin_helper/dictionary.h"
15
+ #include " shell/common/gin_helper/object_template_builder.h"
13
16
#include " shell/common/node_includes.h"
14
17
15
18
#if defined(OS_MACOSX)
16
19
#include " shell/browser/ui/cocoa/delayed_native_view_host.h"
17
20
#endif
18
21
19
- namespace {
20
-
21
- // Used to indicate whether a WebContents already has a view.
22
- class WebContentsViewRelay
23
- : public content::WebContentsUserData<WebContentsViewRelay> {
24
- public:
25
- ~WebContentsViewRelay () override = default ;
26
-
27
- private:
28
- explicit WebContentsViewRelay (content::WebContents* contents) {}
29
- friend class content ::WebContentsUserData<WebContentsViewRelay>;
30
-
31
- electron::api::WebContentsView* view_ = nullptr ;
32
-
33
- WEB_CONTENTS_USER_DATA_KEY_DECL ();
34
-
35
- DISALLOW_COPY_AND_ASSIGN (WebContentsViewRelay);
36
- };
37
-
38
- WEB_CONTENTS_USER_DATA_KEY_IMPL (WebContentsViewRelay)
39
-
40
- } // namespace
41
-
42
22
namespace electron {
43
23
44
24
namespace api {
45
25
46
26
WebContentsView::WebContentsView (v8::Isolate* isolate,
47
- gin::Handle <WebContents> web_contents,
48
- InspectableWebContents* iwc)
27
+ gin::Handle <WebContents> web_contents)
49
28
#if defined(OS_MACOSX)
50
- : View(new DelayedNativeViewHost(iwc->GetView ()->GetNativeView())),
29
+ : View(new DelayedNativeViewHost(
30
+ web_contents->managed_web_contents ()->GetView()->GetNativeView())),
51
31
#else
52
- : View(iwc ->GetView ()->GetView()),
32
+ : View(web_contents-> managed_web_contents () ->GetView()->GetView()),
53
33
#endif
54
34
web_contents_ (isolate, web_contents->GetWrapper ()),
55
35
api_web_contents_(web_contents.get()) {
@@ -59,7 +39,6 @@ WebContentsView::WebContentsView(v8::Isolate* isolate,
59
39
// managed by InspectableWebContents.
60
40
set_delete_view (false );
61
41
#endif
62
- WebContentsViewRelay::CreateForWebContents (web_contents->web_contents ());
63
42
Observe (web_contents->web_contents ());
64
43
}
65
44
@@ -78,38 +57,78 @@ WebContentsView::~WebContentsView() {
78
57
}
79
58
}
80
59
60
+ gin::Handle <WebContents> WebContentsView::GetWebContents (v8::Isolate* isolate) {
61
+ return gin::CreateHandle (isolate, api_web_contents_);
62
+ }
63
+
81
64
void WebContentsView::WebContentsDestroyed () {
82
65
api_web_contents_ = nullptr ;
83
66
web_contents_.Reset ();
84
67
}
85
68
69
+ // static
70
+ gin::Handle <WebContentsView> WebContentsView::Create (
71
+ v8::Isolate* isolate,
72
+ const gin_helper::Dictionary& web_preferences) {
73
+ v8::Local<v8::Context> context = isolate->GetCurrentContext ();
74
+ v8::Local<v8::Value> arg = gin::ConvertToV8 (isolate, web_preferences);
75
+ v8::Local<v8::Object> obj;
76
+ if (GetConstructor (isolate)->NewInstance (context, 1 , &arg).ToLocal (&obj)) {
77
+ gin::Handle <WebContentsView> web_contents_view;
78
+ if (gin::ConvertFromV8 (isolate, obj, &web_contents_view))
79
+ return web_contents_view;
80
+ }
81
+ return gin::Handle <WebContentsView>();
82
+ }
83
+
84
+ // static
85
+ v8::Local<v8::Function> WebContentsView::GetConstructor (v8::Isolate* isolate) {
86
+ static base::NoDestructor<v8::Global<v8::Function>> constructor;
87
+ if (constructor.get ()->IsEmpty ()) {
88
+ constructor->Reset (
89
+ isolate, gin_helper::CreateConstructor<WebContentsView>(
90
+ isolate, base::BindRepeating (&WebContentsView::New)));
91
+ }
92
+ return v8::Local<v8::Function>::New (isolate, *constructor.get ());
93
+ }
94
+
86
95
// static
87
96
gin_helper::WrappableBase* WebContentsView::New (
88
97
gin_helper::Arguments* args,
89
- gin::Handle <WebContents> web_contents) {
90
- // Currently we only support InspectableWebContents, e.g. the WebContents
91
- // created by users directly. To support devToolsWebContents we need to create
92
- // a wrapper view.
93
- if (!web_contents->managed_web_contents ()) {
94
- args->ThrowError (" The WebContents must be created by user" );
95
- return nullptr ;
96
- }
97
- // Check if the WebContents has already been added to a view.
98
- if (WebContentsViewRelay::FromWebContents (web_contents->web_contents ())) {
99
- args->ThrowError (" The WebContents has already been added to a View" );
100
- return nullptr ;
98
+ const gin_helper::Dictionary& web_preferences) {
99
+ // Check if BrowserWindow has passend |webContents| option to us.
100
+ gin::Handle <WebContents> web_contents;
101
+ if (web_preferences.GetHidden (" webContents" , &web_contents) &&
102
+ !web_contents.IsEmpty ()) {
103
+ // Set webPreferences from options if using an existing webContents.
104
+ // These preferences will be used when the webContent launches new
105
+ // render processes.
106
+ auto * existing_preferences =
107
+ WebContentsPreferences::From (web_contents->web_contents ());
108
+ base::DictionaryValue web_preferences_dict;
109
+ if (gin::ConvertFromV8 (args->isolate (), web_preferences.GetHandle (),
110
+ &web_preferences_dict)) {
111
+ existing_preferences->Clear ();
112
+ existing_preferences->Merge (web_preferences_dict);
113
+ }
114
+ } else {
115
+ // Create one if not.
116
+ web_contents = WebContents::Create (args->isolate (), web_preferences);
101
117
}
102
118
// Constructor call.
103
- auto * view = new WebContentsView (args->isolate (), web_contents,
104
- web_contents->managed_web_contents ());
119
+ auto * view = new WebContentsView (args->isolate (), web_contents);
105
120
view->InitWithArgs (args);
106
121
return view;
107
122
}
108
123
109
124
// static
110
125
void WebContentsView::BuildPrototype (
111
126
v8::Isolate* isolate,
112
- v8::Local<v8::FunctionTemplate> prototype) {}
127
+ v8::Local<v8::FunctionTemplate> prototype) {
128
+ prototype->SetClassName (gin::StringToV8 (isolate, " WebContentsView" ));
129
+ gin_helper::ObjectTemplateBuilder (isolate, prototype->PrototypeTemplate ())
130
+ .SetProperty (" webContents" , &WebContentsView::GetWebContents);
131
+ }
113
132
114
133
} // namespace api
115
134
@@ -125,9 +144,7 @@ void Initialize(v8::Local<v8::Object> exports,
125
144
void * priv) {
126
145
v8::Isolate* isolate = context->GetIsolate ();
127
146
gin_helper::Dictionary dict (isolate, exports);
128
- dict.Set (" WebContentsView" ,
129
- gin_helper::CreateConstructor<WebContentsView>(
130
- isolate, base::BindRepeating (&WebContentsView::New)));
147
+ dict.Set (" WebContentsView" , WebContentsView::GetConstructor (isolate));
131
148
}
132
149
133
150
} // namespace
0 commit comments