feat: add webContents.setWindowOpenHandler API (#24517)
Co-authored-by: Jeremy Rose <jeremya@chromium.org>
This commit is contained in:
parent
6b222a2d8a
commit
0b85fdf26c
56 changed files with 2087 additions and 885 deletions
|
@ -784,14 +784,13 @@ void Session::CreateInterruptedDownload(const gin_helper::Dictionary& options) {
|
|||
length, last_modified, etag, base::Time::FromDoubleT(start_time)));
|
||||
}
|
||||
|
||||
void Session::SetPreloads(
|
||||
const std::vector<base::FilePath::StringType>& preloads) {
|
||||
void Session::SetPreloads(const std::vector<base::FilePath>& preloads) {
|
||||
auto* prefs = SessionPreferences::FromBrowserContext(browser_context());
|
||||
DCHECK(prefs);
|
||||
prefs->set_preloads(preloads);
|
||||
}
|
||||
|
||||
std::vector<base::FilePath::StringType> Session::GetPreloads() const {
|
||||
std::vector<base::FilePath> Session::GetPreloads() const {
|
||||
auto* prefs = SessionPreferences::FromBrowserContext(browser_context());
|
||||
DCHECK(prefs);
|
||||
return prefs->preloads();
|
||||
|
|
|
@ -115,8 +115,8 @@ class Session : public gin::Wrappable<Session>,
|
|||
const std::string& uuid);
|
||||
void DownloadURL(const GURL& url);
|
||||
void CreateInterruptedDownload(const gin_helper::Dictionary& options);
|
||||
void SetPreloads(const std::vector<base::FilePath::StringType>& preloads);
|
||||
std::vector<base::FilePath::StringType> GetPreloads() const;
|
||||
void SetPreloads(const std::vector<base::FilePath>& preloads);
|
||||
std::vector<base::FilePath> GetPreloads() const;
|
||||
v8::Local<v8::Value> Cookies(v8::Isolate* isolate);
|
||||
v8::Local<v8::Value> Protocol(v8::Isolate* isolate);
|
||||
v8::Local<v8::Value> ServiceWorkerContext(v8::Isolate* isolate);
|
||||
|
|
|
@ -639,7 +639,11 @@ void WebContents::InitWithSessionAndOptions(
|
|||
prefs->caret_blink_interval = *interval;
|
||||
|
||||
// Save the preferences in C++.
|
||||
new WebContentsPreferences(web_contents(), options);
|
||||
// If there's already a WebContentsPreferences object, we created it as part
|
||||
// of the webContents.setWindowOpenHandler path, so don't overwrite it.
|
||||
if (!WebContentsPreferences::From(web_contents())) {
|
||||
new WebContentsPreferences(web_contents(), options);
|
||||
}
|
||||
// Trigger re-calculation of webkit prefs.
|
||||
web_contents()->NotifyPreferencesChanged();
|
||||
|
||||
|
@ -778,18 +782,44 @@ void WebContents::WebContentsCreatedWithFullParams(
|
|||
tracker->referrer = params.referrer.To<content::Referrer>();
|
||||
tracker->raw_features = params.raw_features;
|
||||
tracker->body = params.body;
|
||||
|
||||
v8::Isolate* isolate = JavascriptEnvironment::GetIsolate();
|
||||
v8::Locker locker(isolate);
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
|
||||
gin_helper::Dictionary dict;
|
||||
gin::ConvertFromV8(isolate, pending_child_web_preferences_.Get(isolate),
|
||||
&dict);
|
||||
pending_child_web_preferences_.Reset();
|
||||
|
||||
// Associate the preferences passed in via `setWindowOpenHandler` with the
|
||||
// content::WebContents that was just created for the child window. These
|
||||
// preferences will be picked up by the RenderWidgetHost via its call to the
|
||||
// delegate's OverrideWebkitPrefs.
|
||||
new WebContentsPreferences(new_contents, dict);
|
||||
}
|
||||
|
||||
bool WebContents::IsWebContentsCreationOverridden(
|
||||
content::SiteInstance* source_site_instance,
|
||||
content::mojom::WindowContainerType window_container_type,
|
||||
const GURL& opener_url,
|
||||
const std::string& frame_name,
|
||||
const GURL& target_url) {
|
||||
if (Emit("-will-add-new-contents", target_url, frame_name)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
const content::mojom::CreateNewWindowParams& params) {
|
||||
bool default_prevented = Emit("-will-add-new-contents", params.target_url,
|
||||
params.frame_name, params.raw_features);
|
||||
// If the app prevented the default, redirect to CreateCustomWebContents,
|
||||
// which always returns nullptr, which will result in the window open being
|
||||
// prevented (window.open() will return null in the renderer).
|
||||
return default_prevented;
|
||||
}
|
||||
|
||||
void WebContents::SetNextChildWebPreferences(
|
||||
const gin_helper::Dictionary preferences) {
|
||||
v8::Isolate* isolate = JavascriptEnvironment::GetIsolate();
|
||||
v8::Locker locker(isolate);
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
// Store these prefs for when Chrome calls WebContentsCreatedWithFullParams
|
||||
// with the new child contents.
|
||||
pending_child_web_preferences_.Reset(isolate, preferences.GetHandle());
|
||||
}
|
||||
|
||||
content::WebContents* WebContents::CreateCustomWebContents(
|
||||
|
@ -1076,7 +1106,7 @@ void WebContents::RenderViewDeleted(content::RenderViewHost* render_view_host) {
|
|||
if (web_contents()->GetRenderViewHost() == render_view_host) {
|
||||
// When the RVH that has been deleted is the current RVH it means that the
|
||||
// the web contents are being closed. This is communicated by this event.
|
||||
// Currently tracked by guest-window-manager.js to destroy the
|
||||
// Currently tracked by guest-window-manager.ts to destroy the
|
||||
// BrowserWindow.
|
||||
Emit("current-render-view-deleted",
|
||||
render_view_host->GetProcess()->GetID());
|
||||
|
@ -2738,11 +2768,11 @@ void WebContents::DoGetZoomLevel(DoGetZoomLevelCallback callback) {
|
|||
std::move(callback).Run(GetZoomLevel());
|
||||
}
|
||||
|
||||
std::vector<base::FilePath::StringType> WebContents::GetPreloadPaths() const {
|
||||
std::vector<base::FilePath> WebContents::GetPreloadPaths() const {
|
||||
auto result = SessionPreferences::GetValidPreloads(GetBrowserContext());
|
||||
|
||||
if (auto* web_preferences = WebContentsPreferences::From(web_contents())) {
|
||||
base::FilePath::StringType preload;
|
||||
base::FilePath preload;
|
||||
if (web_preferences->GetPreloadPath(&preload)) {
|
||||
result.emplace_back(preload);
|
||||
}
|
||||
|
@ -3017,6 +3047,8 @@ v8::Local<v8::ObjectTemplate> WebContents::FillObjectTemplate(
|
|||
.SetMethod("_getPrinters", &WebContents::GetPrinterList)
|
||||
.SetMethod("_printToPDF", &WebContents::PrintToPDF)
|
||||
#endif
|
||||
.SetMethod("_setNextChildWebPreferences",
|
||||
&WebContents::SetNextChildWebPreferences)
|
||||
.SetMethod("addWorkSpace", &WebContents::AddWorkSpace)
|
||||
.SetMethod("removeWorkSpace", &WebContents::RemoveWorkSpace)
|
||||
.SetMethod("showDefinitionForSelection",
|
||||
|
|
|
@ -252,6 +252,8 @@ class WebContents : public gin::Wrappable<WebContents>,
|
|||
v8::Local<v8::Promise> PrintToPDF(base::DictionaryValue settings);
|
||||
#endif
|
||||
|
||||
void SetNextChildWebPreferences(const gin_helper::Dictionary);
|
||||
|
||||
// DevTools workspace api.
|
||||
void AddWorkSpace(gin::Arguments* args, const base::FilePath& path);
|
||||
void RemoveWorkSpace(gin::Arguments* args, const base::FilePath& path);
|
||||
|
@ -354,7 +356,7 @@ class WebContents : public gin::Wrappable<WebContents>,
|
|||
const scoped_refptr<network::ResourceRequestBody>& body);
|
||||
|
||||
// Returns the preload script path of current WebContents.
|
||||
std::vector<base::FilePath::StringType> GetPreloadPaths() const;
|
||||
std::vector<base::FilePath> GetPreloadPaths() const;
|
||||
|
||||
// Returns the web preferences of current WebContents.
|
||||
v8::Local<v8::Value> GetWebPreferences(v8::Isolate* isolate) const;
|
||||
|
@ -456,8 +458,7 @@ class WebContents : public gin::Wrappable<WebContents>,
|
|||
content::SiteInstance* source_site_instance,
|
||||
content::mojom::WindowContainerType window_container_type,
|
||||
const GURL& opener_url,
|
||||
const std::string& frame_name,
|
||||
const GURL& target_url) override;
|
||||
const content::mojom::CreateNewWindowParams& params) override;
|
||||
content::WebContents* CreateCustomWebContents(
|
||||
content::RenderFrameHost* opener,
|
||||
content::SiteInstance* source_site_instance,
|
||||
|
@ -679,6 +680,8 @@ class WebContents : public gin::Wrappable<WebContents>,
|
|||
// Observers of this WebContents.
|
||||
base::ObserverList<ExtendedWebContentsObserver> observers_;
|
||||
|
||||
v8::Global<v8::Value> pending_child_web_preferences_;
|
||||
|
||||
bool initially_shown_ = true;
|
||||
|
||||
service_manager::BinderRegistryWithArgs<content::RenderFrameHost*> registry_;
|
||||
|
|
|
@ -225,12 +225,6 @@ void BindNetworkHintsHandler(
|
|||
NetworkHintsHandlerImpl::Create(frame_host, std::move(receiver));
|
||||
}
|
||||
|
||||
#if defined(OS_WIN)
|
||||
const base::FilePath::StringPieceType kPathDelimiter = FILE_PATH_LITERAL(";");
|
||||
#else
|
||||
const base::FilePath::StringPieceType kPathDelimiter = FILE_PATH_LITERAL(":");
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
// Used by the GetPrivilegeRequiredByUrl() and GetProcessPrivilege() functions
|
||||
// below. Extension, and isolated apps require different privileges to be
|
||||
|
@ -610,13 +604,21 @@ void ElectronBrowserClient::OverrideWebkitPrefs(
|
|||
? blink::mojom::PreferredColorScheme::kDark
|
||||
: blink::mojom::PreferredColorScheme::kLight;
|
||||
|
||||
auto* web_contents = content::WebContents::FromRenderViewHost(host);
|
||||
auto preloads =
|
||||
SessionPreferences::GetValidPreloads(web_contents->GetBrowserContext());
|
||||
if (!preloads.empty())
|
||||
prefs->preloads = preloads;
|
||||
if (CanUseCustomSiteInstance())
|
||||
prefs->disable_electron_site_instance_overrides = true;
|
||||
|
||||
SetFontDefaults(prefs);
|
||||
|
||||
// Custom preferences of guest page.
|
||||
auto* web_contents = content::WebContents::FromRenderViewHost(host);
|
||||
auto* web_preferences = WebContentsPreferences::From(web_contents);
|
||||
if (web_preferences)
|
||||
if (web_preferences) {
|
||||
web_preferences->OverrideWebkitPrefs(prefs);
|
||||
}
|
||||
}
|
||||
|
||||
void ElectronBrowserClient::SetCanUseCustomSiteInstance(bool should_disable) {
|
||||
|
@ -803,16 +805,6 @@ void ElectronBrowserClient::AppendExtraCommandLineSwitches(
|
|||
if (web_preferences)
|
||||
web_preferences->AppendCommandLineSwitches(
|
||||
command_line, IsRendererSubFrame(process_id));
|
||||
auto preloads = SessionPreferences::GetValidPreloads(
|
||||
web_contents->GetBrowserContext());
|
||||
if (!preloads.empty())
|
||||
command_line->AppendSwitchNative(
|
||||
switches::kPreloadScripts,
|
||||
base::JoinString(preloads, kPathDelimiter));
|
||||
if (CanUseCustomSiteInstance()) {
|
||||
command_line->AppendSwitch(
|
||||
switches::kDisableElectronSiteInstanceOverrides);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ template <typename T>
|
|||
class EventEmitterMixin {
|
||||
public:
|
||||
// this.emit(name, new Event(), args...);
|
||||
// Returns true if event.preventDefault() was called during processing.
|
||||
template <typename... Args>
|
||||
bool Emit(base::StringPiece name, Args&&... args) {
|
||||
v8::Isolate* isolate = electron::JavascriptEnvironment::GetIsolate();
|
||||
|
|
|
@ -25,13 +25,13 @@ SessionPreferences* SessionPreferences::FromBrowserContext(
|
|||
}
|
||||
|
||||
// static
|
||||
std::vector<base::FilePath::StringType> SessionPreferences::GetValidPreloads(
|
||||
std::vector<base::FilePath> SessionPreferences::GetValidPreloads(
|
||||
content::BrowserContext* context) {
|
||||
std::vector<base::FilePath::StringType> result;
|
||||
std::vector<base::FilePath> result;
|
||||
|
||||
if (auto* self = FromBrowserContext(context)) {
|
||||
for (const auto& preload : self->preloads()) {
|
||||
if (base::FilePath(preload).IsAbsolute()) {
|
||||
if (preload.IsAbsolute()) {
|
||||
result.emplace_back(preload);
|
||||
} else {
|
||||
LOG(ERROR) << "preload script must have absolute path: " << preload;
|
||||
|
|
|
@ -17,24 +17,22 @@ class SessionPreferences : public base::SupportsUserData::Data {
|
|||
public:
|
||||
static SessionPreferences* FromBrowserContext(
|
||||
content::BrowserContext* context);
|
||||
static std::vector<base::FilePath::StringType> GetValidPreloads(
|
||||
static std::vector<base::FilePath> GetValidPreloads(
|
||||
content::BrowserContext* context);
|
||||
|
||||
explicit SessionPreferences(content::BrowserContext* context);
|
||||
~SessionPreferences() override;
|
||||
|
||||
void set_preloads(const std::vector<base::FilePath::StringType>& preloads) {
|
||||
void set_preloads(const std::vector<base::FilePath>& preloads) {
|
||||
preloads_ = preloads;
|
||||
}
|
||||
const std::vector<base::FilePath::StringType>& preloads() const {
|
||||
return preloads_;
|
||||
}
|
||||
const std::vector<base::FilePath>& preloads() const { return preloads_; }
|
||||
|
||||
private:
|
||||
// The user data key.
|
||||
static int kLocatorKey;
|
||||
|
||||
std::vector<base::FilePath::StringType> preloads_;
|
||||
std::vector<base::FilePath> preloads_;
|
||||
};
|
||||
|
||||
} // namespace electron
|
||||
|
|
|
@ -241,22 +241,22 @@ bool WebContentsPreferences::GetPreference(base::StringPiece name,
|
|||
return GetAsString(&preference_, name, value);
|
||||
}
|
||||
|
||||
bool WebContentsPreferences::GetPreloadPath(
|
||||
base::FilePath::StringType* path) const {
|
||||
bool WebContentsPreferences::GetPreloadPath(base::FilePath* path) const {
|
||||
DCHECK(path);
|
||||
base::FilePath::StringType preload;
|
||||
if (GetAsString(&preference_, options::kPreloadScript, &preload)) {
|
||||
if (base::FilePath(preload).IsAbsolute()) {
|
||||
base::FilePath::StringType preload_path;
|
||||
if (GetAsString(&preference_, options::kPreloadScript, &preload_path)) {
|
||||
base::FilePath preload(preload_path);
|
||||
if (preload.IsAbsolute()) {
|
||||
*path = std::move(preload);
|
||||
return true;
|
||||
} else {
|
||||
LOG(ERROR) << "preload script must have absolute path.";
|
||||
}
|
||||
} else if (GetAsString(&preference_, options::kPreloadURL, &preload)) {
|
||||
} else if (GetAsString(&preference_, options::kPreloadURL, &preload_path)) {
|
||||
// Translate to file path if there is "preload-url" option.
|
||||
base::FilePath preload_path;
|
||||
if (net::FileURLToFilePath(GURL(preload), &preload_path)) {
|
||||
*path = std::move(preload_path.value());
|
||||
base::FilePath preload;
|
||||
if (net::FileURLToFilePath(GURL(preload_path), &preload)) {
|
||||
*path = std::move(preload);
|
||||
return true;
|
||||
} else {
|
||||
LOG(ERROR) << "preload url must be file:// protocol.";
|
||||
|
@ -287,36 +287,16 @@ WebContentsPreferences* WebContentsPreferences::From(
|
|||
void WebContentsPreferences::AppendCommandLineSwitches(
|
||||
base::CommandLine* command_line,
|
||||
bool is_subframe) {
|
||||
// Check if plugins are enabled.
|
||||
if (IsEnabled(options::kPlugins))
|
||||
command_line->AppendSwitch(switches::kEnablePlugins);
|
||||
|
||||
// Experimental flags.
|
||||
if (IsEnabled(options::kExperimentalFeatures))
|
||||
command_line->AppendSwitch(
|
||||
::switches::kEnableExperimentalWebPlatformFeatures);
|
||||
|
||||
// Check if we have node integration specified.
|
||||
if (IsEnabled(options::kNodeIntegration))
|
||||
command_line->AppendSwitch(switches::kNodeIntegration);
|
||||
|
||||
// Whether to enable node integration in Worker.
|
||||
if (IsEnabled(options::kNodeIntegrationInWorker))
|
||||
command_line->AppendSwitch(switches::kNodeIntegrationInWorker);
|
||||
|
||||
// Check if webview tag creation is enabled, default to nodeIntegration value.
|
||||
if (IsEnabled(options::kWebviewTag))
|
||||
command_line->AppendSwitch(switches::kWebviewTag);
|
||||
|
||||
// Sandbox can be enabled for renderer processes hosting cross-origin frames
|
||||
// unless nodeIntegrationInSubFrames is enabled
|
||||
bool can_sandbox_frame =
|
||||
is_subframe && !IsEnabled(options::kNodeIntegrationInSubFrames);
|
||||
|
||||
// If the `sandbox` option was passed to the BrowserWindow's webPreferences,
|
||||
// pass `--enable-sandbox` to the renderer so it won't have any node.js
|
||||
// integration. Otherwise disable Chromium sandbox, unless app.enableSandbox()
|
||||
// was called.
|
||||
if (IsEnabled(options::kSandbox) || can_sandbox_frame) {
|
||||
command_line->AppendSwitch(switches::kEnableSandbox);
|
||||
} else if (!command_line->HasSwitch(switches::kEnableSandbox)) {
|
||||
|
@ -324,15 +304,6 @@ void WebContentsPreferences::AppendCommandLineSwitches(
|
|||
command_line->AppendSwitch(::switches::kNoZygote);
|
||||
}
|
||||
|
||||
// Check if nativeWindowOpen is enabled.
|
||||
if (IsEnabled(options::kNativeWindowOpen))
|
||||
command_line->AppendSwitch(switches::kNativeWindowOpen);
|
||||
|
||||
// The preload script.
|
||||
base::FilePath::StringType preload;
|
||||
if (GetPreloadPath(&preload))
|
||||
command_line->AppendSwitchNative(switches::kPreloadScript, preload);
|
||||
|
||||
// Custom args for renderer process
|
||||
auto* customArgs =
|
||||
preference_.FindKeyOfType(options::kCustomArgs, base::Value::Type::LIST);
|
||||
|
@ -343,46 +314,13 @@ void WebContentsPreferences::AppendCommandLineSwitches(
|
|||
}
|
||||
}
|
||||
|
||||
#if BUILDFLAG(ENABLE_REMOTE_MODULE)
|
||||
// Whether to enable the remote module
|
||||
if (IsEnabled(options::kEnableRemoteModule, false))
|
||||
command_line->AppendSwitch(switches::kEnableRemoteModule);
|
||||
#endif
|
||||
|
||||
// Run Electron APIs and preload script in isolated world
|
||||
if (IsEnabled(options::kContextIsolation))
|
||||
command_line->AppendSwitch(switches::kContextIsolation);
|
||||
|
||||
if (IsEnabled(options::kWorldSafeExecuteJavaScript))
|
||||
command_line->AppendSwitch(switches::kWorldSafeExecuteJavaScript);
|
||||
|
||||
// --background-color.
|
||||
std::string s;
|
||||
if (GetAsString(&preference_, options::kBackgroundColor, &s)) {
|
||||
command_line->AppendSwitchASCII(switches::kBackgroundColor, s);
|
||||
} else if (!IsEnabled(options::kOffscreen)) {
|
||||
// For non-OSR WebContents, we expect to have white background, see
|
||||
// https://github.com/electron/electron/issues/13764 for more.
|
||||
command_line->AppendSwitchASCII(switches::kBackgroundColor, "#fff");
|
||||
}
|
||||
|
||||
// --offscreen
|
||||
// TODO(loc): Offscreen is duplicated in WebPreferences because it's needed
|
||||
// earlier than we can get WebPreferences at the moment.
|
||||
if (IsEnabled(options::kOffscreen)) {
|
||||
command_line->AppendSwitch(options::kOffscreen);
|
||||
}
|
||||
|
||||
// --guest-instance-id, which is used to identify guest WebContents.
|
||||
int guest_instance_id = 0;
|
||||
if (GetAsInteger(&preference_, options::kGuestInstanceID, &guest_instance_id))
|
||||
command_line->AppendSwitchASCII(switches::kGuestInstanceID,
|
||||
base::NumberToString(guest_instance_id));
|
||||
|
||||
// Pass the opener's window id.
|
||||
int opener_id;
|
||||
if (GetAsInteger(&preference_, options::kOpenerID, &opener_id))
|
||||
command_line->AppendSwitchASCII(switches::kOpenerID,
|
||||
base::NumberToString(opener_id));
|
||||
|
||||
#if defined(OS_MAC)
|
||||
// Enable scroll bounce.
|
||||
if (IsEnabled(options::kScrollBounce))
|
||||
|
@ -402,6 +340,7 @@ void WebContentsPreferences::AppendCommandLineSwitches(
|
|||
}
|
||||
}
|
||||
|
||||
std::string s;
|
||||
// Enable blink features.
|
||||
if (GetAsString(&preference_, options::kEnableBlinkFeatures, &s))
|
||||
command_line->AppendSwitchASCII(::switches::kEnableBlinkFeatures, s);
|
||||
|
@ -410,39 +349,8 @@ void WebContentsPreferences::AppendCommandLineSwitches(
|
|||
if (GetAsString(&preference_, options::kDisableBlinkFeatures, &s))
|
||||
command_line->AppendSwitchASCII(::switches::kDisableBlinkFeatures, s);
|
||||
|
||||
if (guest_instance_id) {
|
||||
// Webview `document.visibilityState` tracks window visibility so we need
|
||||
// to let it know if the window happens to be hidden right now.
|
||||
auto* manager = WebViewManager::GetWebViewManager(web_contents_);
|
||||
if (manager) {
|
||||
auto* embedder = manager->GetEmbedder(guest_instance_id);
|
||||
if (embedder) {
|
||||
auto* relay = NativeWindowRelay::FromWebContents(embedder);
|
||||
if (relay) {
|
||||
auto* window = relay->GetNativeWindow();
|
||||
if (window) {
|
||||
const bool visible = window->IsVisible() && !window->IsMinimized();
|
||||
if (!visible) {
|
||||
command_line->AppendSwitch(switches::kHiddenPage);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (IsEnabled(options::kNodeIntegrationInSubFrames))
|
||||
command_line->AppendSwitch(switches::kNodeIntegrationInSubFrames);
|
||||
|
||||
#if BUILDFLAG(ENABLE_BUILTIN_SPELLCHECKER)
|
||||
if (IsEnabled(options::kSpellcheck)) {
|
||||
command_line->AppendSwitch(switches::kEnableSpellcheck);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Whether to allow the WebSQL api
|
||||
if (IsEnabled(options::kEnableWebSQL))
|
||||
command_line->AppendSwitch(switches::kEnableWebSQL);
|
||||
if (IsEnabled(options::kNodeIntegrationInWorker))
|
||||
command_line->AppendSwitch(switches::kNodeIntegrationInWorker);
|
||||
|
||||
// We are appending args to a webContents so let's save the current state
|
||||
// of our preferences object so that during the lifetime of the WebContents
|
||||
|
@ -507,6 +415,87 @@ void WebContentsPreferences::OverrideWebkitPrefs(
|
|||
if (GetAsString(&preference_, "defaultEncoding", &encoding))
|
||||
prefs->default_encoding = encoding;
|
||||
|
||||
// --background-color.
|
||||
std::string color;
|
||||
if (GetAsString(&preference_, options::kBackgroundColor, &color)) {
|
||||
prefs->background_color = color;
|
||||
} else if (!IsEnabled(options::kOffscreen)) {
|
||||
prefs->background_color = "#fff";
|
||||
}
|
||||
|
||||
// Pass the opener's window id.
|
||||
int opener_id;
|
||||
if (GetAsInteger(&preference_, options::kOpenerID, &opener_id))
|
||||
prefs->opener_id = opener_id;
|
||||
|
||||
// Run Electron APIs and preload script in isolated world
|
||||
prefs->context_isolation = IsEnabled(options::kContextIsolation);
|
||||
|
||||
#if BUILDFLAG(ENABLE_REMOTE_MODULE)
|
||||
// Whether to enable the remote module
|
||||
prefs->enable_remote_module = IsEnabled(options::kEnableRemoteModule, false);
|
||||
#endif
|
||||
|
||||
prefs->world_safe_execute_javascript =
|
||||
IsEnabled(options::kWorldSafeExecuteJavaScript);
|
||||
|
||||
int guest_instance_id = 0;
|
||||
if (GetAsInteger(&preference_, options::kGuestInstanceID, &guest_instance_id))
|
||||
prefs->guest_instance_id = guest_instance_id;
|
||||
|
||||
prefs->hidden_page = false;
|
||||
if (guest_instance_id) {
|
||||
// Webview `document.visibilityState` tracks window visibility so we need
|
||||
// to let it know if the window happens to be hidden right now.
|
||||
auto* manager = WebViewManager::GetWebViewManager(web_contents_);
|
||||
if (manager) {
|
||||
auto* embedder = manager->GetEmbedder(guest_instance_id);
|
||||
if (embedder) {
|
||||
auto* relay = NativeWindowRelay::FromWebContents(embedder);
|
||||
if (relay) {
|
||||
auto* window = relay->GetNativeWindow();
|
||||
if (window) {
|
||||
const bool visible = window->IsVisible() && !window->IsMinimized();
|
||||
if (!visible) {
|
||||
prefs->hidden_page = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
prefs->offscreen = IsEnabled(options::kOffscreen);
|
||||
|
||||
// The preload script.
|
||||
GetPreloadPath(&prefs->preload);
|
||||
|
||||
// Check if nativeWindowOpen is enabled.
|
||||
prefs->native_window_open = IsEnabled(options::kNativeWindowOpen);
|
||||
|
||||
// Check if we have node integration specified.
|
||||
prefs->node_integration = IsEnabled(options::kNodeIntegration);
|
||||
|
||||
// Whether to enable node integration in Worker.
|
||||
prefs->node_integration_in_worker =
|
||||
IsEnabled(options::kNodeIntegrationInWorker);
|
||||
|
||||
prefs->node_integration_in_sub_frames =
|
||||
IsEnabled(options::kNodeIntegrationInSubFrames);
|
||||
|
||||
#if BUILDFLAG(ENABLE_BUILTIN_SPELLCHECKER)
|
||||
prefs->enable_spellcheck = IsEnabled(options::kSpellcheck);
|
||||
#endif
|
||||
|
||||
// Check if plugins are enabled.
|
||||
prefs->enable_plugins = IsEnabled(options::kPlugins);
|
||||
|
||||
// Check if webview tag creation is enabled, default to nodeIntegration value.
|
||||
prefs->webview_tag = IsEnabled(options::kWebviewTag);
|
||||
|
||||
// Whether to allow the WebSQL api
|
||||
prefs->enable_websql = IsEnabled(options::kEnableWebSQL);
|
||||
|
||||
std::string v8_cache_options;
|
||||
if (GetAsString(&preference_, "v8CacheOptions", &v8_cache_options)) {
|
||||
if (v8_cache_options == "none") {
|
||||
|
|
|
@ -59,7 +59,7 @@ class WebContentsPreferences
|
|||
bool GetPreference(base::StringPiece name, std::string* value) const;
|
||||
|
||||
// Returns the preload script path.
|
||||
bool GetPreloadPath(base::FilePath::StringType* path) const;
|
||||
bool GetPreloadPath(base::FilePath* path) const;
|
||||
|
||||
// Returns the web preferences.
|
||||
base::Value* preference() { return &preference_; }
|
||||
|
|
|
@ -40,6 +40,10 @@ void WebViewGuestDelegate::AttachToIframe(
|
|||
|
||||
content::WebContents* guest_web_contents = api_web_contents_->web_contents();
|
||||
|
||||
// Force a refresh of the webPreferences so that OverrideWebkitPrefs runs on
|
||||
// the new web contents before the renderer process initializes.
|
||||
// guest_web_contents->NotifyPreferencesChanged();
|
||||
|
||||
// Attach this inner WebContents |guest_web_contents| to the outer
|
||||
// WebContents |embedder_web_contents|. The outer WebContents's
|
||||
// frame |embedder_frame| hosts the inner WebContents.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue