| 
									
										
										
										
											2014-10-31 11:17:05 -07:00
										 |  |  | // Copyright (c) 2013 GitHub, Inc.
 | 
					
						
							| 
									
										
										
										
											2014-04-25 17:49:37 +08:00
										 |  |  | // Use of this source code is governed by the MIT license that can be
 | 
					
						
							| 
									
										
										
										
											2013-04-30 23:56:50 +08:00
										 |  |  | // found in the LICENSE file.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-04 12:19:40 -08:00
										 |  |  | #include "shell/browser/electron_javascript_dialog_manager.h"
 | 
					
						
							| 
									
										
										
										
											2013-04-30 23:56:50 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-16 09:13:06 +08:00
										 |  |  | #include <string>
 | 
					
						
							| 
									
										
										
										
											2018-09-12 19:25:56 -05:00
										 |  |  | #include <utility>
 | 
					
						
							| 
									
										
										
										
											2017-01-04 16:46:50 -08:00
										 |  |  | #include <vector>
 | 
					
						
							| 
									
										
										
										
											2014-03-16 09:13:06 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-04 16:46:50 -08:00
										 |  |  | #include "base/bind.h"
 | 
					
						
							| 
									
										
										
										
											2013-12-11 15:48:19 +08:00
										 |  |  | #include "base/strings/utf_string_conversions.h"
 | 
					
						
							| 
									
										
										
										
											2020-02-04 12:19:40 -08:00
										 |  |  | #include "shell/browser/api/electron_api_web_contents.h"
 | 
					
						
							| 
									
										
										
										
											2019-06-19 13:46:59 -07:00
										 |  |  | #include "shell/browser/native_window.h"
 | 
					
						
							|  |  |  | #include "shell/browser/ui/message_box.h"
 | 
					
						
							|  |  |  | #include "shell/browser/web_contents_preferences.h"
 | 
					
						
							|  |  |  | #include "shell/common/options_switches.h"
 | 
					
						
							| 
									
										
										
										
											2017-01-04 16:46:50 -08:00
										 |  |  | #include "ui/gfx/image/image_skia.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-04 13:50:44 +09:00
										 |  |  | using content::JavaScriptDialogType; | 
					
						
							| 
									
										
										
										
											2013-04-30 23:56:50 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-19 14:23:04 -07:00
										 |  |  | namespace electron { | 
					
						
							| 
									
										
										
										
											2018-03-06 11:31:56 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-15 13:07:49 +11:00
										 |  |  | namespace { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-06 11:31:56 +09:00
										 |  |  | constexpr int kUserWantsNoMoreDialogs = -1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | }  // namespace
 | 
					
						
							| 
									
										
										
										
											2013-04-30 23:56:50 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-16 16:16:05 -07:00
										 |  |  | ElectronJavaScriptDialogManager::ElectronJavaScriptDialogManager() {} | 
					
						
							| 
									
										
										
										
											2020-02-04 12:19:40 -08:00
										 |  |  | ElectronJavaScriptDialogManager::~ElectronJavaScriptDialogManager() = default; | 
					
						
							| 
									
										
										
										
											2017-04-27 19:28:48 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-04 12:19:40 -08:00
										 |  |  | void ElectronJavaScriptDialogManager::RunJavaScriptDialog( | 
					
						
							| 
									
										
										
										
											2014-03-01 19:53:50 +08:00
										 |  |  |     content::WebContents* web_contents, | 
					
						
							| 
									
										
										
										
											2018-04-12 13:18:34 +05:30
										 |  |  |     content::RenderFrameHost* rfh, | 
					
						
							| 
									
										
										
										
											2017-04-04 13:50:44 +09:00
										 |  |  |     JavaScriptDialogType dialog_type, | 
					
						
							| 
									
										
										
										
											2014-06-28 19:36:57 +08:00
										 |  |  |     const base::string16& message_text, | 
					
						
							|  |  |  |     const base::string16& default_prompt_text, | 
					
						
							| 
									
										
										
										
											2017-12-18 12:24:13 +11:00
										 |  |  |     DialogClosedCallback callback, | 
					
						
							| 
									
										
										
										
											2014-03-01 19:53:50 +08:00
										 |  |  |     bool* did_suppress_message) { | 
					
						
							| 
									
										
										
										
											2018-04-12 13:18:34 +05:30
										 |  |  |   auto origin_url = rfh->GetLastCommittedURL(); | 
					
						
							| 
									
										
										
										
											2019-03-27 11:21:10 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   std::string origin; | 
					
						
							|  |  |  |   // For file:// URLs we do the alert filtering by the
 | 
					
						
							|  |  |  |   // file path currently loaded
 | 
					
						
							|  |  |  |   if (origin_url.SchemeIsFile()) { | 
					
						
							|  |  |  |     origin = origin_url.path(); | 
					
						
							|  |  |  |   } else { | 
					
						
							|  |  |  |     origin = origin_url.GetOrigin().spec(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-06 11:31:56 +09:00
										 |  |  |   if (origin_counts_[origin] == kUserWantsNoMoreDialogs) { | 
					
						
							| 
									
										
										
										
											2018-03-12 17:27:43 +09:00
										 |  |  |     return std::move(callback).Run(false, base::string16()); | 
					
						
							| 
									
										
										
										
											2018-01-24 20:50:00 -06:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2018-01-10 17:07:56 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-04 13:50:44 +09:00
										 |  |  |   if (dialog_type != JavaScriptDialogType::JAVASCRIPT_DIALOG_TYPE_ALERT && | 
					
						
							|  |  |  |       dialog_type != JavaScriptDialogType::JAVASCRIPT_DIALOG_TYPE_CONFIRM) { | 
					
						
							| 
									
										
										
										
											2017-12-18 12:31:00 +11:00
										 |  |  |     std::move(callback).Run(false, base::string16()); | 
					
						
							| 
									
										
										
										
											2017-01-04 16:46:50 -08:00
										 |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-02 23:50:44 +03:00
										 |  |  |   auto* web_preferences = WebContentsPreferences::From(web_contents); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (web_preferences && web_preferences->IsEnabled("disableDialogs")) { | 
					
						
							|  |  |  |     return std::move(callback).Run(false, base::string16()); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-27 11:15:58 -07:00
										 |  |  |   // No default button
 | 
					
						
							|  |  |  |   int default_id = -1; | 
					
						
							|  |  |  |   int cancel_id = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-06 08:53:06 -08:00
										 |  |  |   std::vector<std::string> buttons = {"OK"}; | 
					
						
							| 
									
										
										
										
											2017-04-04 13:50:44 +09:00
										 |  |  |   if (dialog_type == JavaScriptDialogType::JAVASCRIPT_DIALOG_TYPE_CONFIRM) { | 
					
						
							| 
									
										
										
										
											2019-09-13 10:26:59 -04:00
										 |  |  |     buttons.emplace_back("Cancel"); | 
					
						
							| 
									
										
										
										
											2019-03-27 11:15:58 -07:00
										 |  |  |     // First button is default, second button is cancel
 | 
					
						
							|  |  |  |     default_id = 0; | 
					
						
							|  |  |  |     cancel_id = 1; | 
					
						
							| 
									
										
										
										
											2017-01-04 16:46:50 -08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-10 17:07:56 +11:00
										 |  |  |   origin_counts_[origin]++; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-08 16:36:21 +09:00
										 |  |  |   std::string checkbox; | 
					
						
							| 
									
										
										
										
											2018-04-17 21:55:30 -04:00
										 |  |  |   if (origin_counts_[origin] > 1 && web_preferences && | 
					
						
							| 
									
										
										
										
											2018-04-03 12:19:35 +09:00
										 |  |  |       web_preferences->IsEnabled("safeDialogs") && | 
					
						
							| 
									
										
										
										
											2018-08-03 14:23:07 -07:00
										 |  |  |       !web_preferences->GetPreference("safeDialogsMessage", &checkbox)) { | 
					
						
							| 
									
										
										
										
											2018-04-03 12:19:35 +09:00
										 |  |  |     checkbox = "Prevent this app from creating additional dialogs"; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Don't set parent for offscreen window.
 | 
					
						
							|  |  |  |   NativeWindow* window = nullptr; | 
					
						
							| 
									
										
										
										
											2018-05-29 10:09:51 +02:00
										 |  |  |   if (web_preferences && !web_preferences->IsEnabled(options::kOffscreen)) { | 
					
						
							| 
									
										
										
										
											2018-04-03 12:19:35 +09:00
										 |  |  |     auto* relay = NativeWindowRelay::FromWebContents(web_contents); | 
					
						
							|  |  |  |     if (relay) | 
					
						
							| 
									
										
										
										
											2018-10-02 15:14:43 -07:00
										 |  |  |       window = relay->GetNativeWindow(); | 
					
						
							| 
									
										
										
										
											2018-01-10 17:07:56 +11:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2018-03-06 15:18:45 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-19 14:23:04 -07:00
										 |  |  |   electron::MessageBoxSettings settings; | 
					
						
							| 
									
										
										
										
											2019-06-14 08:26:25 -07:00
										 |  |  |   settings.parent_window = window; | 
					
						
							| 
									
										
										
										
											2020-02-25 16:47:59 +00:00
										 |  |  |   settings.checkbox_label = checkbox; | 
					
						
							| 
									
										
										
										
											2019-06-14 08:26:25 -07:00
										 |  |  |   settings.buttons = buttons; | 
					
						
							|  |  |  |   settings.default_id = default_id; | 
					
						
							|  |  |  |   settings.cancel_id = cancel_id; | 
					
						
							|  |  |  |   settings.message = base::UTF16ToUTF8(message_text); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-19 14:23:04 -07:00
										 |  |  |   electron::ShowMessageBox( | 
					
						
							| 
									
										
										
										
											2019-06-14 08:26:25 -07:00
										 |  |  |       settings, | 
					
						
							| 
									
										
										
										
											2020-02-04 12:19:40 -08:00
										 |  |  |       base::BindOnce(&ElectronJavaScriptDialogManager::OnMessageBoxCallback, | 
					
						
							| 
									
										
										
										
											2020-04-13 13:52:07 -07:00
										 |  |  |                      base::Unretained(this), std::move(callback), origin)); | 
					
						
							| 
									
										
										
										
											2014-03-01 19:53:50 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-04 12:19:40 -08:00
										 |  |  | void ElectronJavaScriptDialogManager::RunBeforeUnloadDialog( | 
					
						
							| 
									
										
										
										
											2013-04-30 23:56:50 +08:00
										 |  |  |     content::WebContents* web_contents, | 
					
						
							| 
									
										
										
										
											2018-04-12 13:18:34 +05:30
										 |  |  |     content::RenderFrameHost* rfh, | 
					
						
							| 
									
										
										
										
											2013-04-30 23:56:50 +08:00
										 |  |  |     bool is_reload, | 
					
						
							| 
									
										
										
										
											2017-12-18 12:24:13 +11:00
										 |  |  |     DialogClosedCallback callback) { | 
					
						
							| 
									
										
										
										
											2020-07-16 16:16:05 -07:00
										 |  |  |   auto* api_web_contents = api::WebContents::From(web_contents); | 
					
						
							|  |  |  |   if (api_web_contents) { | 
					
						
							|  |  |  |     bool default_prevented = api_web_contents->Emit("will-prevent-unload"); | 
					
						
							|  |  |  |     std::move(callback).Run(default_prevented, base::string16()); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2013-04-30 23:56:50 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-04 12:19:40 -08:00
										 |  |  | void ElectronJavaScriptDialogManager::CancelDialogs( | 
					
						
							| 
									
										
										
										
											2017-01-24 12:18:56 +09:00
										 |  |  |     content::WebContents* web_contents, | 
					
						
							| 
									
										
										
										
											2018-04-17 21:55:30 -04:00
										 |  |  |     bool reset_state) {} | 
					
						
							| 
									
										
										
										
											2017-01-24 12:18:56 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-04 12:19:40 -08:00
										 |  |  | void ElectronJavaScriptDialogManager::OnMessageBoxCallback( | 
					
						
							| 
									
										
										
										
											2018-03-12 17:27:43 +09:00
										 |  |  |     DialogClosedCallback callback, | 
					
						
							| 
									
										
										
										
											2018-01-10 17:07:56 +11:00
										 |  |  |     const std::string& origin, | 
					
						
							| 
									
										
										
										
											2017-02-06 15:35:36 +00:00
										 |  |  |     int code, | 
					
						
							|  |  |  |     bool checkbox_checked) { | 
					
						
							| 
									
										
										
										
											2018-03-06 11:35:53 +09:00
										 |  |  |   if (checkbox_checked) | 
					
						
							|  |  |  |     origin_counts_[origin] = kUserWantsNoMoreDialogs; | 
					
						
							| 
									
										
										
										
											2018-03-12 17:27:43 +09:00
										 |  |  |   std::move(callback).Run(code == 0, base::string16()); | 
					
						
							| 
									
										
										
										
											2017-01-04 16:46:50 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-19 14:23:04 -07:00
										 |  |  | }  // namespace electron
 |