mirror of
https://github.com/electron/electron.git
synced 2026-02-19 03:14:51 -05:00
Compare commits
94 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b763d81d79 | ||
|
|
7521454161 | ||
|
|
36f0583077 | ||
|
|
96391dbb3b | ||
|
|
d5cf2e1244 | ||
|
|
9a665eb5fb | ||
|
|
6b16695ba3 | ||
|
|
ac714a1d02 | ||
|
|
e5e94fce02 | ||
|
|
f65a7983c6 | ||
|
|
d1f5d20098 | ||
|
|
2f67cd5b35 | ||
|
|
3fd0ac6d44 | ||
|
|
4a6cad7ba5 | ||
|
|
eccede0c0d | ||
|
|
9ed83e7512 | ||
|
|
b3ed83055c | ||
|
|
2360f3eb11 | ||
|
|
4175e947bb | ||
|
|
1cbcd05ab7 | ||
|
|
40c7e767ef | ||
|
|
66c5a8362a | ||
|
|
d6ba1421fa | ||
|
|
ccad8ec125 | ||
|
|
d2bff97199 | ||
|
|
46a1ce8117 | ||
|
|
042f24c5b6 | ||
|
|
c3624116ae | ||
|
|
492397b815 | ||
|
|
3a0b72e5dc | ||
|
|
914939c793 | ||
|
|
b8874913f2 | ||
|
|
dc959414a3 | ||
|
|
bcdc4435b4 | ||
|
|
303da32dd3 | ||
|
|
8fd91cc35b | ||
|
|
3001c76483 | ||
|
|
28a9963ca7 | ||
|
|
b5f290d8d2 | ||
|
|
4574a21ed3 | ||
|
|
7aaaa24da7 | ||
|
|
ded4a94a92 | ||
|
|
c6fd15e641 | ||
|
|
36965a6b4e | ||
|
|
53c3e01af6 | ||
|
|
d2571f3a9e | ||
|
|
e1a8050eab | ||
|
|
7b1f5a9cea | ||
|
|
5b9393c173 | ||
|
|
98180568f2 | ||
|
|
f005ac8d8b | ||
|
|
a0d824ccf5 | ||
|
|
ee1529587c | ||
|
|
5e665c1d38 | ||
|
|
61d1df2b43 | ||
|
|
6c4ee66165 | ||
|
|
84b014577f | ||
|
|
84ec42463b | ||
|
|
01c8f698ee | ||
|
|
f53a9c1268 | ||
|
|
56c545f679 | ||
|
|
34c1a53441 | ||
|
|
8d330f7dde | ||
|
|
3c0d90eca8 | ||
|
|
9d30245fb4 | ||
|
|
0efccf45bc | ||
|
|
4e0d4c4785 | ||
|
|
6d313b48f2 | ||
|
|
330e8abd16 | ||
|
|
ffd8c36f4f | ||
|
|
efa12608e0 | ||
|
|
969ac4ced1 | ||
|
|
a2d77352e5 | ||
|
|
55c48efb90 | ||
|
|
7a285cd0ea | ||
|
|
415fbfaf41 | ||
|
|
1a41e196e8 | ||
|
|
4f63509ebd | ||
|
|
45a554f305 | ||
|
|
29a0bc23c4 | ||
|
|
f7508f17c5 | ||
|
|
d2538cd3b1 | ||
|
|
fae52d8e4a | ||
|
|
064f198162 | ||
|
|
fd2a9cb056 | ||
|
|
b4c27eeaa1 | ||
|
|
93b4d20c59 | ||
|
|
c647bf5d27 | ||
|
|
cbca75d184 | ||
|
|
8054fc83ac | ||
|
|
0b7680aa14 | ||
|
|
668e85dd7c | ||
|
|
e253c9bfe6 | ||
|
|
c00d3536d1 |
File diff suppressed because it is too large
Load Diff
2
DEPS
2
DEPS
@@ -10,7 +10,7 @@ gclient_gn_args = [
|
||||
|
||||
vars = {
|
||||
'chromium_version':
|
||||
'69.0.3497.106',
|
||||
'69.0.3497.128',
|
||||
'node_version':
|
||||
'8bc5d171a0873c0ba49f9433798bc8b67399788c',
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "atom/browser/browser.h"
|
||||
#include "atom/common/atom_version.h"
|
||||
#include "atom/common/chrome_version.h"
|
||||
#include "atom/common/options_switches.h"
|
||||
@@ -14,8 +15,10 @@
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/strings/string_split.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/strings/stringprintf.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "content/public/common/content_constants.h"
|
||||
#include "content/public/common/content_switches.h"
|
||||
#include "content/public/common/pepper_plugin_info.h"
|
||||
#include "content/public/common/user_agent.h"
|
||||
#include "electron/buildflags/buildflags.h"
|
||||
@@ -173,6 +176,27 @@ void ConvertStringWithSeparatorToVector(std::vector<std::string>* vec,
|
||||
base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
|
||||
}
|
||||
|
||||
std::string RemoveWhitespace(const std::string& str) {
|
||||
std::string trimmed;
|
||||
if (base::RemoveChars(str, " ", &trimmed))
|
||||
return trimmed;
|
||||
else
|
||||
return str;
|
||||
}
|
||||
|
||||
bool IsBrowserProcess() {
|
||||
const base::CommandLine* command_line =
|
||||
base::CommandLine::ForCurrentProcess();
|
||||
std::string process_type =
|
||||
command_line->GetSwitchValueASCII(::switches::kProcessType);
|
||||
return process_type.empty();
|
||||
}
|
||||
|
||||
std::string BuildDefaultUserAgent() {
|
||||
return "Chrome/" CHROME_VERSION_STRING " " ATOM_PRODUCT_NAME
|
||||
"/" ATOM_VERSION_STRING;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
AtomContentClient::AtomContentClient() {}
|
||||
@@ -184,9 +208,35 @@ std::string AtomContentClient::GetProduct() const {
|
||||
}
|
||||
|
||||
std::string AtomContentClient::GetUserAgent() const {
|
||||
return content::BuildUserAgentFromProduct("Chrome/" CHROME_VERSION_STRING
|
||||
" " ATOM_PRODUCT_NAME
|
||||
"/" ATOM_VERSION_STRING);
|
||||
if (IsBrowserProcess()) {
|
||||
if (user_agent_override_.empty()) {
|
||||
auto* browser = Browser::Get();
|
||||
std::string name = RemoveWhitespace(browser->GetName());
|
||||
std::string user_agent;
|
||||
if (name == ATOM_PRODUCT_NAME) {
|
||||
user_agent = BuildDefaultUserAgent();
|
||||
} else {
|
||||
user_agent = base::StringPrintf(
|
||||
"%s/%s Chrome/%s " ATOM_PRODUCT_NAME "/" ATOM_VERSION_STRING,
|
||||
name.c_str(), browser->GetVersion().c_str(), CHROME_VERSION_STRING);
|
||||
}
|
||||
return content::BuildUserAgentFromProduct(user_agent);
|
||||
}
|
||||
return user_agent_override_;
|
||||
}
|
||||
// In a renderer process the user agent should be provided on the CLI
|
||||
// If it's not we just fallback to the default one, this should never happen
|
||||
// but we want to handle it gracefully
|
||||
const base::CommandLine* command_line =
|
||||
base::CommandLine::ForCurrentProcess();
|
||||
std::string cli_user_agent = command_line->GetSwitchValueASCII("user-agent");
|
||||
if (cli_user_agent.empty())
|
||||
return BuildDefaultUserAgent();
|
||||
return cli_user_agent;
|
||||
}
|
||||
|
||||
void AtomContentClient::SetUserAgent(const std::string& user_agent) {
|
||||
user_agent_override_ = user_agent;
|
||||
}
|
||||
|
||||
base::string16 AtomContentClient::GetLocalizedString(int message_id) const {
|
||||
|
||||
@@ -18,10 +18,12 @@ class AtomContentClient : public brightray::ContentClient {
|
||||
AtomContentClient();
|
||||
~AtomContentClient() override;
|
||||
|
||||
std::string GetUserAgent() const override;
|
||||
void SetUserAgent(const std::string& user_agent);
|
||||
|
||||
protected:
|
||||
// content::ContentClient:
|
||||
std::string GetProduct() const override;
|
||||
std::string GetUserAgent() const override;
|
||||
base::string16 GetLocalizedString(int message_id) const override;
|
||||
void AddAdditionalSchemes(Schemes* schemes) override;
|
||||
void AddPepperPlugins(
|
||||
@@ -31,6 +33,8 @@ class AtomContentClient : public brightray::ContentClient {
|
||||
std::vector<media::CdmHostFilePath>* cdm_host_file_paths) override;
|
||||
|
||||
private:
|
||||
std::string user_agent_override_ = "";
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomContentClient);
|
||||
};
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "atom/app/atom_content_client.h"
|
||||
#include "atom/browser/api/atom_api_menu.h"
|
||||
#include "atom/browser/api/atom_api_session.h"
|
||||
#include "atom/browser/api/atom_api_web_contents.h"
|
||||
@@ -43,6 +44,7 @@
|
||||
#include "content/public/browser/client_certificate_delegate.h"
|
||||
#include "content/public/browser/gpu_data_manager.h"
|
||||
#include "content/public/browser/render_frame_host.h"
|
||||
#include "content/public/common/content_client.h"
|
||||
#include "content/public/common/content_switches.h"
|
||||
#include "media/audio/audio_manager.h"
|
||||
#include "native_mate/object_template_builder.h"
|
||||
@@ -1236,6 +1238,18 @@ void App::EnableMixedSandbox(mate::Arguments* args) {
|
||||
command_line->AppendSwitch(switches::kEnableMixedSandbox);
|
||||
}
|
||||
|
||||
void App::SetUserAgentFallback(const std::string& user_agent) {
|
||||
AtomContentClient* client =
|
||||
static_cast<AtomContentClient*>(content::GetContentClient());
|
||||
client->SetUserAgent(user_agent);
|
||||
}
|
||||
|
||||
std::string App::GetUserAgentFallback() {
|
||||
AtomContentClient* client =
|
||||
static_cast<AtomContentClient*>(content::GetContentClient());
|
||||
return client->GetUserAgent();
|
||||
}
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
bool App::MoveToApplicationsFolder(mate::Arguments* args) {
|
||||
return ui::cocoa::AtomBundleMover::Move(args);
|
||||
@@ -1342,6 +1356,8 @@ void App::BuildPrototype(v8::Isolate* isolate,
|
||||
.SetMethod("startAccessingSecurityScopedResource",
|
||||
&App::StartAccessingSecurityScopedResource)
|
||||
#endif
|
||||
.SetProperty("userAgentFallback", &App::GetUserAgentFallback,
|
||||
&App::SetUserAgentFallback)
|
||||
.SetMethod("enableSandbox", &App::EnableSandbox)
|
||||
.SetMethod("enableMixedSandbox", &App::EnableMixedSandbox);
|
||||
}
|
||||
|
||||
@@ -205,6 +205,8 @@ class App : public AtomBrowserClient::Delegate,
|
||||
const std::string& info_type);
|
||||
void EnableSandbox(mate::Arguments* args);
|
||||
void EnableMixedSandbox(mate::Arguments* args);
|
||||
void SetUserAgentFallback(const std::string& user_agent);
|
||||
std::string GetUserAgentFallback();
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
bool MoveToApplicationsFolder(mate::Arguments* args);
|
||||
|
||||
@@ -1184,6 +1184,9 @@ void WebContents::LoadURL(const GURL& url, const mate::Dictionary& options) {
|
||||
params.transition_type = ui::PAGE_TRANSITION_TYPED;
|
||||
params.should_clear_history_list = true;
|
||||
params.override_user_agent = content::NavigationController::UA_OVERRIDE_TRUE;
|
||||
// Discord non-committed entries to ensure that we don't re-use a pending
|
||||
// entry
|
||||
web_contents()->GetController().DiscardNonCommittedEntries();
|
||||
web_contents()->GetController().LoadURLWithParams(params);
|
||||
|
||||
// Set the background color of RenderWidgetHostView.
|
||||
@@ -1455,7 +1458,7 @@ bool WebContents::IsDOMReady() const {
|
||||
|
||||
#if BUILDFLAG(ENABLE_PRINTING)
|
||||
void WebContents::Print(mate::Arguments* args) {
|
||||
bool silent, print_background = false;
|
||||
bool silent = false, print_background = false;
|
||||
base::string16 device_name;
|
||||
mate::Dictionary options = mate::Dictionary::CreateEmpty(args->isolate());
|
||||
base::DictionaryValue settings;
|
||||
|
||||
@@ -17,12 +17,15 @@ namespace mate {
|
||||
StreamSubscriber::StreamSubscriber(
|
||||
v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> emitter,
|
||||
base::WeakPtr<atom::URLRequestStreamJob> url_job)
|
||||
: isolate_(isolate),
|
||||
base::WeakPtr<atom::URLRequestStreamJob> url_job,
|
||||
scoped_refptr<base::SequencedTaskRunner> ui_task_runner)
|
||||
: base::RefCountedDeleteOnSequence<StreamSubscriber>(ui_task_runner),
|
||||
isolate_(isolate),
|
||||
emitter_(isolate, emitter),
|
||||
url_job_(url_job),
|
||||
weak_factory_(this) {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||
DCHECK(ui_task_runner->RunsTasksInCurrentSequence());
|
||||
|
||||
auto weak_self = weak_factory_.GetWeakPtr();
|
||||
On("data", base::Bind(&StreamSubscriber::OnData, weak_self));
|
||||
On("end", base::Bind(&StreamSubscriber::OnEnd, weak_self));
|
||||
@@ -30,13 +33,12 @@ StreamSubscriber::StreamSubscriber(
|
||||
}
|
||||
|
||||
StreamSubscriber::~StreamSubscriber() {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||
RemoveAllListeners();
|
||||
}
|
||||
|
||||
void StreamSubscriber::On(const std::string& event,
|
||||
EventCallback&& callback) { // NOLINT
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||
DCHECK(owning_task_runner()->RunsTasksInCurrentSequence());
|
||||
DCHECK(js_handlers_.find(event) == js_handlers_.end());
|
||||
|
||||
v8::Locker locker(isolate_);
|
||||
@@ -50,7 +52,7 @@ void StreamSubscriber::On(const std::string& event,
|
||||
}
|
||||
|
||||
void StreamSubscriber::Off(const std::string& event) {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||
DCHECK(owning_task_runner()->RunsTasksInCurrentSequence());
|
||||
DCHECK(js_handlers_.find(event) != js_handlers_.end());
|
||||
|
||||
v8::Locker locker(isolate_);
|
||||
@@ -96,6 +98,7 @@ void StreamSubscriber::OnError(mate::Arguments* args) {
|
||||
}
|
||||
|
||||
void StreamSubscriber::RemoveAllListeners() {
|
||||
DCHECK(owning_task_runner()->RunsTasksInCurrentSequence());
|
||||
v8::Locker locker(isolate_);
|
||||
v8::Isolate::Scope isolate_scope(isolate_);
|
||||
v8::HandleScope handle_scope(isolate_);
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
#include <vector>
|
||||
|
||||
#include "base/callback.h"
|
||||
#include "base/memory/ref_counted.h"
|
||||
#include "base/memory/ref_counted_delete_on_sequence.h"
|
||||
#include "base/memory/weak_ptr.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "v8/include/v8.h"
|
||||
@@ -23,17 +25,25 @@ namespace mate {
|
||||
|
||||
class Arguments;
|
||||
|
||||
class StreamSubscriber {
|
||||
class StreamSubscriber
|
||||
: public base::RefCountedDeleteOnSequence<StreamSubscriber> {
|
||||
public:
|
||||
REQUIRE_ADOPTION_FOR_REFCOUNTED_TYPE();
|
||||
|
||||
StreamSubscriber(v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> emitter,
|
||||
base::WeakPtr<atom::URLRequestStreamJob> url_job);
|
||||
~StreamSubscriber();
|
||||
base::WeakPtr<atom::URLRequestStreamJob> url_job,
|
||||
scoped_refptr<base::SequencedTaskRunner> ui_task_runner);
|
||||
|
||||
private:
|
||||
friend class base::DeleteHelper<StreamSubscriber>;
|
||||
friend class base::RefCountedDeleteOnSequence<StreamSubscriber>;
|
||||
|
||||
using JSHandlersMap = std::map<std::string, v8::Global<v8::Value>>;
|
||||
using EventCallback = base::Callback<void(mate::Arguments* args)>;
|
||||
|
||||
~StreamSubscriber();
|
||||
|
||||
void On(const std::string& event, EventCallback&& callback); // NOLINT
|
||||
void Off(const std::string& event);
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "atom/app/atom_content_client.h"
|
||||
#include "atom/browser/atom_blob_reader.h"
|
||||
#include "atom/browser/atom_browser_main_parts.h"
|
||||
#include "atom/browser/atom_download_manager_delegate.h"
|
||||
@@ -42,6 +43,7 @@
|
||||
#include "components/proxy_config/proxy_config_pref_names.h"
|
||||
#include "content/browser/blob_storage/chrome_blob_storage_context.h"
|
||||
#include "content/public/browser/storage_partition.h"
|
||||
#include "content/public/common/content_client.h"
|
||||
#include "content/public/common/user_agent.h"
|
||||
#include "net/base/escape.h"
|
||||
|
||||
@@ -51,14 +53,6 @@ namespace atom {
|
||||
|
||||
namespace {
|
||||
|
||||
std::string RemoveWhitespace(const std::string& str) {
|
||||
std::string trimmed;
|
||||
if (base::RemoveChars(str, " ", &trimmed))
|
||||
return trimmed;
|
||||
else
|
||||
return str;
|
||||
}
|
||||
|
||||
// Convert string to lower case and escape it.
|
||||
std::string MakePartitionName(const std::string& input) {
|
||||
return net::EscapePath(base::ToLowerASCII(input));
|
||||
@@ -78,19 +72,9 @@ AtomBrowserContext::AtomBrowserContext(const std::string& partition,
|
||||
storage_policy_(new SpecialStoragePolicy),
|
||||
in_memory_(in_memory),
|
||||
weak_factory_(this) {
|
||||
// Construct user agent string.
|
||||
Browser* browser = Browser::Get();
|
||||
std::string name = RemoveWhitespace(browser->GetName());
|
||||
std::string user_agent;
|
||||
if (name == ATOM_PRODUCT_NAME) {
|
||||
user_agent = "Chrome/" CHROME_VERSION_STRING " " ATOM_PRODUCT_NAME
|
||||
"/" ATOM_VERSION_STRING;
|
||||
} else {
|
||||
user_agent = base::StringPrintf(
|
||||
"%s/%s Chrome/%s " ATOM_PRODUCT_NAME "/" ATOM_VERSION_STRING,
|
||||
name.c_str(), browser->GetVersion().c_str(), CHROME_VERSION_STRING);
|
||||
}
|
||||
user_agent_ = content::BuildUserAgentFromProduct(user_agent);
|
||||
AtomContentClient* client =
|
||||
static_cast<AtomContentClient*>(content::GetContentClient());
|
||||
user_agent_ = client->GetUserAgent();
|
||||
|
||||
// Read options.
|
||||
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
|
||||
|
||||
@@ -88,19 +88,53 @@ void AtomDownloadManagerDelegate::OnDownloadPathGenerated(
|
||||
if (relay)
|
||||
window = relay->GetNativeWindow();
|
||||
|
||||
auto* web_preferences = WebContentsPreferences::From(web_contents);
|
||||
bool offscreen =
|
||||
!web_preferences || web_preferences->IsEnabled(options::kOffscreen);
|
||||
|
||||
// Show save dialog if save path was not set already on item
|
||||
base::FilePath path;
|
||||
GetItemSavePath(item, &path);
|
||||
// Show save dialog if save path was not set already on item
|
||||
file_dialog::DialogSettings settings;
|
||||
settings.parent_window = window;
|
||||
settings.force_detached = offscreen;
|
||||
settings.title = item->GetURL().spec();
|
||||
settings.default_path = default_path;
|
||||
if (path.empty() && file_dialog::ShowSaveDialog(settings, &path)) {
|
||||
if (path.empty()) {
|
||||
file_dialog::DialogSettings settings;
|
||||
settings.parent_window = window;
|
||||
settings.title = item->GetURL().spec();
|
||||
settings.default_path = default_path;
|
||||
|
||||
auto* web_preferences = WebContentsPreferences::From(web_contents);
|
||||
const bool offscreen =
|
||||
!web_preferences || web_preferences->IsEnabled(options::kOffscreen);
|
||||
settings.force_detached = offscreen;
|
||||
|
||||
auto dialog_callback =
|
||||
base::Bind(&AtomDownloadManagerDelegate::OnDownloadSaveDialogDone,
|
||||
base::Unretained(this), download_id, callback);
|
||||
file_dialog::ShowSaveDialog(settings, dialog_callback);
|
||||
} else {
|
||||
callback.Run(path, download::DownloadItem::TARGET_DISPOSITION_PROMPT,
|
||||
download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, path,
|
||||
download::DOWNLOAD_INTERRUPT_REASON_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(MAS_BUILD)
|
||||
void AtomDownloadManagerDelegate::OnDownloadSaveDialogDone(
|
||||
uint32_t download_id,
|
||||
const content::DownloadTargetCallback& download_callback,
|
||||
bool result,
|
||||
const base::FilePath& path,
|
||||
const std::string& bookmark)
|
||||
#else
|
||||
void AtomDownloadManagerDelegate::OnDownloadSaveDialogDone(
|
||||
uint32_t download_id,
|
||||
const content::DownloadTargetCallback& download_callback,
|
||||
bool result,
|
||||
const base::FilePath& path)
|
||||
#endif
|
||||
{
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||
|
||||
auto* item = download_manager_->GetDownload(download_id);
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
if (result) {
|
||||
// Remember the last selected download directory.
|
||||
AtomBrowserContext* browser_context = static_cast<AtomBrowserContext*>(
|
||||
download_manager_->GetBrowserContext());
|
||||
@@ -117,12 +151,16 @@ void AtomDownloadManagerDelegate::OnDownloadPathGenerated(
|
||||
}
|
||||
|
||||
// Running the DownloadTargetCallback with an empty FilePath signals that the
|
||||
// download should be cancelled.
|
||||
// If user cancels the file save dialog, run the callback with empty FilePath.
|
||||
callback.Run(path, download::DownloadItem::TARGET_DISPOSITION_PROMPT,
|
||||
download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, path,
|
||||
path.empty() ? download::DOWNLOAD_INTERRUPT_REASON_USER_CANCELED
|
||||
: download::DOWNLOAD_INTERRUPT_REASON_NONE);
|
||||
// download should be cancelled. If user cancels the file save dialog, run
|
||||
// the callback with empty FilePath.
|
||||
const base::FilePath download_path = result ? path : base::FilePath();
|
||||
const auto interrupt_reason =
|
||||
download_path.empty() ? download::DOWNLOAD_INTERRUPT_REASON_USER_CANCELED
|
||||
: download::DOWNLOAD_INTERRUPT_REASON_NONE;
|
||||
download_callback.Run(download_path,
|
||||
download::DownloadItem::TARGET_DISPOSITION_PROMPT,
|
||||
download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
|
||||
download_path, interrupt_reason);
|
||||
}
|
||||
|
||||
void AtomDownloadManagerDelegate::Shutdown() {
|
||||
|
||||
@@ -24,10 +24,6 @@ class AtomDownloadManagerDelegate : public content::DownloadManagerDelegate {
|
||||
explicit AtomDownloadManagerDelegate(content::DownloadManager* manager);
|
||||
~AtomDownloadManagerDelegate() override;
|
||||
|
||||
void OnDownloadPathGenerated(uint32_t download_id,
|
||||
const content::DownloadTargetCallback& callback,
|
||||
const base::FilePath& default_path);
|
||||
|
||||
// content::DownloadManagerDelegate:
|
||||
void Shutdown() override;
|
||||
bool DetermineDownloadTarget(
|
||||
@@ -42,6 +38,25 @@ class AtomDownloadManagerDelegate : public content::DownloadManagerDelegate {
|
||||
// Get the save path set on the associated api::DownloadItem object
|
||||
void GetItemSavePath(download::DownloadItem* item, base::FilePath* path);
|
||||
|
||||
void OnDownloadPathGenerated(uint32_t download_id,
|
||||
const content::DownloadTargetCallback& callback,
|
||||
const base::FilePath& default_path);
|
||||
|
||||
#if defined(MAS_BUILD)
|
||||
void OnDownloadSaveDialogDone(
|
||||
uint32_t download_id,
|
||||
const content::DownloadTargetCallback& download_callback,
|
||||
bool result,
|
||||
const base::FilePath& path,
|
||||
const std::string& bookmark);
|
||||
#else
|
||||
void OnDownloadSaveDialogDone(
|
||||
uint32_t download_id,
|
||||
const content::DownloadTargetCallback& download_callback,
|
||||
bool result,
|
||||
const base::FilePath& path);
|
||||
#endif
|
||||
|
||||
content::DownloadManager* download_manager_;
|
||||
base::WeakPtrFactory<AtomDownloadManagerDelegate> weak_ptr_factory_;
|
||||
|
||||
|
||||
@@ -48,6 +48,8 @@ network::mojom::HttpAuthDynamicParamsPtr CreateHttpAuthDynamicParams(
|
||||
command_line.GetSwitchValueASCII(switches::kAuthServerWhitelist);
|
||||
auth_dynamic_params->delegate_whitelist = command_line.GetSwitchValueASCII(
|
||||
switches::kAuthNegotiateDelegateWhitelist);
|
||||
auth_dynamic_params->enable_negotiate_port =
|
||||
command_line.HasSwitch(atom::switches::kEnableAuthNegotiatePort);
|
||||
|
||||
return auth_dynamic_params;
|
||||
}
|
||||
|
||||
@@ -585,7 +585,12 @@ void NativeWindowMac::Hide() {
|
||||
}
|
||||
|
||||
bool NativeWindowMac::IsVisible() {
|
||||
return [window_ isVisible];
|
||||
bool occluded = [window_ occlusionState] == NSWindowOcclusionStateVisible;
|
||||
|
||||
// For a window to be visible, it must be visible to the user in the
|
||||
// foreground of the app, which means that it should not be minimized or
|
||||
// occluded
|
||||
return [window_ isVisible] && !occluded && !IsMinimized();
|
||||
}
|
||||
|
||||
bool NativeWindowMac::IsEnabled() {
|
||||
@@ -1118,17 +1123,23 @@ void NativeWindowMac::SetProgressBar(double progress,
|
||||
const NativeWindow::ProgressState state) {
|
||||
NSDockTile* dock_tile = [NSApp dockTile];
|
||||
|
||||
// Sometimes macOS would install a default contentView for dock, we must
|
||||
// verify whether NSProgressIndicator has been installed.
|
||||
bool first_time = !dock_tile.contentView ||
|
||||
[[dock_tile.contentView subviews] count] == 0 ||
|
||||
![[[dock_tile.contentView subviews] lastObject]
|
||||
isKindOfClass:[NSProgressIndicator class]];
|
||||
|
||||
// For the first time API invoked, we need to create a ContentView in
|
||||
// DockTile.
|
||||
if (dock_tile.contentView == nullptr) {
|
||||
NSImageView* image_view = [[NSImageView alloc] init];
|
||||
if (first_time) {
|
||||
NSImageView* image_view = [[[NSImageView alloc] init] autorelease];
|
||||
[image_view setImage:[NSApp applicationIconImage]];
|
||||
[dock_tile setContentView:image_view];
|
||||
}
|
||||
|
||||
if ([[dock_tile.contentView subviews] count] == 0) {
|
||||
NSProgressIndicator* progress_indicator = [[AtomProgressBar alloc]
|
||||
initWithFrame:NSMakeRect(0.0f, 0.0f, dock_tile.size.width, 15.0)];
|
||||
NSRect frame = NSMakeRect(0.0f, 0.0f, dock_tile.size.width, 15.0);
|
||||
NSProgressIndicator* progress_indicator =
|
||||
[[[AtomProgressBar alloc] initWithFrame:frame] autorelease];
|
||||
[progress_indicator setStyle:NSProgressIndicatorBarStyle];
|
||||
[progress_indicator setIndeterminate:NO];
|
||||
[progress_indicator setBezeled:YES];
|
||||
@@ -1139,7 +1150,7 @@ void NativeWindowMac::SetProgressBar(double progress,
|
||||
}
|
||||
|
||||
NSProgressIndicator* progress_indicator = static_cast<NSProgressIndicator*>(
|
||||
[[[dock_tile contentView] subviews] objectAtIndex:0]);
|
||||
[[[dock_tile contentView] subviews] lastObject]);
|
||||
if (progress < 0) {
|
||||
[progress_indicator setHidden:YES];
|
||||
} else if (progress > 1) {
|
||||
|
||||
@@ -349,6 +349,9 @@ void NativeWindowViews::Show() {
|
||||
|
||||
widget()->native_widget_private()->ShowWithWindowState(GetRestoredState());
|
||||
|
||||
// explicitly focus the window
|
||||
widget()->Activate();
|
||||
|
||||
NotifyWindowShow();
|
||||
|
||||
#if defined(USE_X11)
|
||||
|
||||
@@ -13,14 +13,16 @@
|
||||
#include "atom/common/api/event_emitter_caller.h"
|
||||
#include "atom/common/atom_constants.h"
|
||||
#include "atom/common/native_mate_converters/net_converter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "base/strings/string_number_conversions.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/threading/thread_task_runner_handle.h"
|
||||
#include "base/time/time.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "net/base/net_errors.h"
|
||||
#include "net/filter/gzip_source_stream.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace {
|
||||
@@ -82,14 +84,14 @@ void BeforeStartInUI(base::WeakPtr<URLRequestStreamJob> job,
|
||||
return;
|
||||
}
|
||||
|
||||
auto subscriber = std::make_unique<mate::StreamSubscriber>(
|
||||
args->isolate(), data.GetHandle(), job);
|
||||
auto subscriber = base::MakeRefCounted<mate::StreamSubscriber>(
|
||||
args->isolate(), data.GetHandle(), job,
|
||||
base::ThreadTaskRunnerHandle::Get());
|
||||
|
||||
content::BrowserThread::PostTask(
|
||||
content::BrowserThread::IO, FROM_HERE,
|
||||
base::BindOnce(&URLRequestStreamJob::StartAsync, job,
|
||||
std::move(subscriber), base::RetainedRef(response_headers),
|
||||
ended, error));
|
||||
base::BindOnce(&URLRequestStreamJob::StartAsync, job, subscriber,
|
||||
base::RetainedRef(response_headers), ended, error));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
@@ -104,10 +106,7 @@ URLRequestStreamJob::URLRequestStreamJob(net::URLRequest* request,
|
||||
weak_factory_(this) {}
|
||||
|
||||
URLRequestStreamJob::~URLRequestStreamJob() {
|
||||
if (subscriber_) {
|
||||
content::BrowserThread::DeleteSoon(content::BrowserThread::UI, FROM_HERE,
|
||||
std::move(subscriber_));
|
||||
}
|
||||
DCHECK(!subscriber_ || subscriber_->HasOneRef());
|
||||
}
|
||||
|
||||
void URLRequestStreamJob::Start() {
|
||||
@@ -121,7 +120,7 @@ void URLRequestStreamJob::Start() {
|
||||
}
|
||||
|
||||
void URLRequestStreamJob::StartAsync(
|
||||
std::unique_ptr<mate::StreamSubscriber> subscriber,
|
||||
scoped_refptr<mate::StreamSubscriber> subscriber,
|
||||
scoped_refptr<net::HttpResponseHeaders> response_headers,
|
||||
bool ended,
|
||||
int error) {
|
||||
@@ -133,7 +132,7 @@ void URLRequestStreamJob::StartAsync(
|
||||
|
||||
ended_ = ended;
|
||||
response_headers_ = response_headers;
|
||||
subscriber_ = std::move(subscriber);
|
||||
subscriber_ = subscriber;
|
||||
request_start_time_ = base::TimeTicks::Now();
|
||||
NotifyHeadersComplete();
|
||||
}
|
||||
@@ -192,12 +191,13 @@ int URLRequestStreamJob::ReadRawData(net::IOBuffer* dest, int dest_size) {
|
||||
}
|
||||
|
||||
void URLRequestStreamJob::DoneReading() {
|
||||
content::BrowserThread::DeleteSoon(content::BrowserThread::UI, FROM_HERE,
|
||||
std::move(subscriber_));
|
||||
write_buffer_.clear();
|
||||
}
|
||||
|
||||
void URLRequestStreamJob::DoneReadingRedirectResponse() {
|
||||
if (subscriber_) {
|
||||
subscriber_ = nullptr;
|
||||
}
|
||||
DoneReading();
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ class URLRequestStreamJob : public JsAsker, public net::URLRequestJob {
|
||||
net::NetworkDelegate* network_delegate);
|
||||
~URLRequestStreamJob() override;
|
||||
|
||||
void StartAsync(std::unique_ptr<mate::StreamSubscriber> subscriber,
|
||||
void StartAsync(scoped_refptr<mate::StreamSubscriber> subscriber,
|
||||
scoped_refptr<net::HttpResponseHeaders> response_headers,
|
||||
bool ended,
|
||||
int error);
|
||||
@@ -62,7 +62,7 @@ class URLRequestStreamJob : public JsAsker, public net::URLRequestJob {
|
||||
base::TimeTicks request_start_time_;
|
||||
base::TimeTicks response_start_time_;
|
||||
scoped_refptr<net::HttpResponseHeaders> response_headers_;
|
||||
std::unique_ptr<mate::StreamSubscriber> subscriber_;
|
||||
scoped_refptr<mate::StreamSubscriber> subscriber_;
|
||||
|
||||
base::WeakPtrFactory<URLRequestStreamJob> weak_factory_;
|
||||
|
||||
|
||||
@@ -17,9 +17,9 @@
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>electron.icns</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>4.0.4</string>
|
||||
<string>4.2.2</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>4.0.4</string>
|
||||
<string>4.2.2</string>
|
||||
<key>LSApplicationCategoryType</key>
|
||||
<string>public.app-category.developer-tools</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
|
||||
@@ -50,8 +50,8 @@ END
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 4,0,4,0
|
||||
PRODUCTVERSION 4,0,4,0
|
||||
FILEVERSION 4,2,2,0
|
||||
PRODUCTVERSION 4,2,2,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@@ -68,12 +68,12 @@ BEGIN
|
||||
BEGIN
|
||||
VALUE "CompanyName", "GitHub, Inc."
|
||||
VALUE "FileDescription", "Electron"
|
||||
VALUE "FileVersion", "4.0.4"
|
||||
VALUE "FileVersion", "4.2.2"
|
||||
VALUE "InternalName", "electron.exe"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved."
|
||||
VALUE "OriginalFilename", "electron.exe"
|
||||
VALUE "ProductName", "Electron"
|
||||
VALUE "ProductVersion", "4.0.4"
|
||||
VALUE "ProductVersion", "4.2.2"
|
||||
VALUE "SquirrelAwareVersion", "1"
|
||||
END
|
||||
END
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "ui/base/l10n/l10n_util_mac.h"
|
||||
#include "ui/events/cocoa/cocoa_event_utils.h"
|
||||
#include "ui/gfx/image/image.h"
|
||||
#include "ui/strings/grit/ui_strings.h"
|
||||
|
||||
using content::BrowserThread;
|
||||
|
||||
@@ -56,6 +57,29 @@ Role kRolesMap[] = {
|
||||
{@selector(clearRecentDocuments:), "clearrecentdocuments"},
|
||||
};
|
||||
|
||||
// Called when adding a submenu to the menu and checks if the submenu, via its
|
||||
// |model|, has visible child items.
|
||||
bool MenuHasVisibleItems(const atom::AtomMenuModel* model) {
|
||||
int count = model->GetItemCount();
|
||||
for (int index = 0; index < count; index++) {
|
||||
if (model->IsVisibleAt(index))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Called when an empty submenu is created. This inserts a menu item labeled
|
||||
// "(empty)" into the submenu. Matches Windows behavior.
|
||||
NSMenu* MakeEmptySubmenu() {
|
||||
base::scoped_nsobject<NSMenu> submenu([[NSMenu alloc] initWithTitle:@""]);
|
||||
NSString* empty_menu_title =
|
||||
l10n_util::GetNSString(IDS_APP_MENU_EMPTY_SUBMENU);
|
||||
|
||||
[submenu addItemWithTitle:empty_menu_title action:NULL keyEquivalent:@""];
|
||||
[[submenu itemAtIndex:0] setEnabled:NO];
|
||||
return submenu.autorelease();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// Menu item is located for ease of removing it from the parent owner
|
||||
@@ -218,13 +242,21 @@ static base::scoped_nsobject<NSMenu> recentDocumentsMenuSwap_;
|
||||
NSMenu* submenu = [[NSMenu alloc] initWithTitle:label];
|
||||
[item setSubmenu:submenu];
|
||||
[NSApp setServicesMenu:submenu];
|
||||
} else if (type == atom::AtomMenuModel::TYPE_SUBMENU) {
|
||||
} else if (type == atom::AtomMenuModel::TYPE_SUBMENU &&
|
||||
model->IsVisibleAt(index)) {
|
||||
// We need to specifically check that the submenu top-level item has been
|
||||
// enabled as it's not validated by validateUserInterfaceItem
|
||||
if (!model->IsEnabledAt(index))
|
||||
[item setEnabled:NO];
|
||||
|
||||
// Recursively build a submenu from the sub-model at this index.
|
||||
[item setTarget:nil];
|
||||
[item setAction:nil];
|
||||
atom::AtomMenuModel* submenuModel =
|
||||
static_cast<atom::AtomMenuModel*>(model->GetSubmenuModelAt(index));
|
||||
NSMenu* submenu = [self menuFromModel:submenuModel];
|
||||
NSMenu* submenu = MenuHasVisibleItems(submenuModel)
|
||||
? [self menuFromModel:submenuModel]
|
||||
: MakeEmptySubmenu();
|
||||
[submenu setTitle:[item title]];
|
||||
[item setSubmenu:submenu];
|
||||
|
||||
|
||||
@@ -623,9 +623,14 @@ static NSString* const ImageScrubberItemIdentifier = @"scrubber.image.item";
|
||||
segments[i].Get("enabled", &enabled);
|
||||
if (segments[i].Get("label", &label)) {
|
||||
[control setLabel:base::SysUTF8ToNSString(label) forSegment:i];
|
||||
} else if (segments[i].Get("icon", &image)) {
|
||||
} else {
|
||||
[control setLabel:@"" forSegment:i];
|
||||
}
|
||||
if (segments[i].Get("icon", &image)) {
|
||||
[control setImage:image.AsNSImage() forSegment:i];
|
||||
[control setImageScaling:NSImageScaleProportionallyUpOrDown forSegment:i];
|
||||
} else {
|
||||
[control setImage:nil forSegment:i];
|
||||
}
|
||||
[control setEnabled:enabled forSegment:i];
|
||||
}
|
||||
|
||||
@@ -284,7 +284,7 @@ bool ShowOpenDialog(const DialogSettings& settings,
|
||||
|
||||
void OpenDialogCompletion(int chosen,
|
||||
NSOpenPanel* dialog,
|
||||
const DialogSettings& settings,
|
||||
bool security_scoped_bookmarks,
|
||||
const OpenDialogCallback& callback) {
|
||||
if (chosen == NSFileHandlingPanelCancelButton) {
|
||||
#if defined(MAS_BUILD)
|
||||
@@ -297,7 +297,7 @@ void OpenDialogCompletion(int chosen,
|
||||
std::vector<base::FilePath> paths;
|
||||
#if defined(MAS_BUILD)
|
||||
std::vector<std::string> bookmarks;
|
||||
if (settings.security_scoped_bookmarks) {
|
||||
if (security_scoped_bookmarks) {
|
||||
ReadDialogPathsWithBookmarks(dialog, &paths, &bookmarks);
|
||||
} else {
|
||||
ReadDialogPaths(dialog, &paths);
|
||||
@@ -320,17 +320,21 @@ void ShowOpenDialog(const DialogSettings& settings,
|
||||
// Duplicate the callback object here since c is a reference and gcd would
|
||||
// only store the pointer, by duplication we can force gcd to store a copy.
|
||||
__block OpenDialogCallback callback = c;
|
||||
// Capture the value of the security_scoped_bookmarks settings flag
|
||||
// and pass it to the completion handler.
|
||||
bool security_scoped_bookmarks = settings.security_scoped_bookmarks;
|
||||
|
||||
if (!settings.parent_window || !settings.parent_window->GetNativeWindow() ||
|
||||
settings.force_detached) {
|
||||
[dialog beginWithCompletionHandler:^(NSInteger chosen) {
|
||||
OpenDialogCompletion(chosen, dialog, settings, callback);
|
||||
OpenDialogCompletion(chosen, dialog, security_scoped_bookmarks, callback);
|
||||
}];
|
||||
} else {
|
||||
NSWindow* window = settings.parent_window->GetNativeWindow();
|
||||
[dialog beginSheetModalForWindow:window
|
||||
completionHandler:^(NSInteger chosen) {
|
||||
OpenDialogCompletion(chosen, dialog, settings, callback);
|
||||
OpenDialogCompletion(chosen, dialog,
|
||||
security_scoped_bookmarks, callback);
|
||||
}];
|
||||
}
|
||||
}
|
||||
@@ -351,7 +355,7 @@ bool ShowSaveDialog(const DialogSettings& settings, base::FilePath* path) {
|
||||
|
||||
void SaveDialogCompletion(int chosen,
|
||||
NSSavePanel* dialog,
|
||||
const DialogSettings& settings,
|
||||
bool security_scoped_bookmarks,
|
||||
const SaveDialogCallback& callback) {
|
||||
if (chosen == NSFileHandlingPanelCancelButton) {
|
||||
#if defined(MAS_BUILD)
|
||||
@@ -363,7 +367,7 @@ void SaveDialogCompletion(int chosen,
|
||||
std::string path = base::SysNSStringToUTF8([[dialog URL] path]);
|
||||
#if defined(MAS_BUILD)
|
||||
std::string bookmark;
|
||||
if (settings.security_scoped_bookmarks) {
|
||||
if (security_scoped_bookmarks) {
|
||||
bookmark = GetBookmarkDataFromNSURL([dialog URL]);
|
||||
}
|
||||
callback.Run(true, base::FilePath(path), bookmark);
|
||||
@@ -381,17 +385,19 @@ void ShowSaveDialog(const DialogSettings& settings,
|
||||
[dialog setCanSelectHiddenExtension:YES];
|
||||
|
||||
__block SaveDialogCallback callback = c;
|
||||
bool security_scoped_bookmarks = settings.security_scoped_bookmarks;
|
||||
|
||||
if (!settings.parent_window || !settings.parent_window->GetNativeWindow() ||
|
||||
settings.force_detached) {
|
||||
[dialog beginWithCompletionHandler:^(NSInteger chosen) {
|
||||
SaveDialogCompletion(chosen, dialog, settings, callback);
|
||||
SaveDialogCompletion(chosen, dialog, security_scoped_bookmarks, callback);
|
||||
}];
|
||||
} else {
|
||||
NSWindow* window = settings.parent_window->GetNativeWindow();
|
||||
[dialog beginSheetModalForWindow:window
|
||||
completionHandler:^(NSInteger chosen) {
|
||||
SaveDialogCompletion(chosen, dialog, settings, callback);
|
||||
SaveDialogCompletion(chosen, dialog,
|
||||
security_scoped_bookmarks, callback);
|
||||
}];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "cc/base/switches.h"
|
||||
#include "content/public/browser/render_frame_host.h"
|
||||
#include "content/public/browser/render_process_host.h"
|
||||
#include "content/public/common/content_client.h"
|
||||
#include "content/public/common/content_switches.h"
|
||||
#include "content/public/common/web_preferences.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
@@ -229,6 +230,9 @@ WebContentsPreferences* WebContentsPreferences::From(
|
||||
|
||||
void WebContentsPreferences::AppendCommandLineSwitches(
|
||||
base::CommandLine* command_line) {
|
||||
// Append UA Override
|
||||
command_line->AppendSwitchASCII("user-agent",
|
||||
content::GetContentClient()->GetUserAgent());
|
||||
// Check if plugins are enabled.
|
||||
if (IsEnabled(options::kPlugins))
|
||||
command_line->AppendSwitch(switches::kEnablePlugins);
|
||||
|
||||
@@ -81,49 +81,71 @@ float GetScaleFactorFromOptions(mate::Arguments* args) {
|
||||
return scale_factor;
|
||||
}
|
||||
|
||||
bool AddImageSkiaRep(gfx::ImageSkia* image,
|
||||
const unsigned char* data,
|
||||
size_t size,
|
||||
int width,
|
||||
int height,
|
||||
double scale_factor) {
|
||||
auto decoded = std::make_unique<SkBitmap>();
|
||||
bool AddImageSkiaRepFromPNG(gfx::ImageSkia* image,
|
||||
const unsigned char* data,
|
||||
size_t size,
|
||||
double scale_factor) {
|
||||
SkBitmap bitmap;
|
||||
if (!gfx::PNGCodec::Decode(data, size, &bitmap))
|
||||
return false;
|
||||
|
||||
// Try PNG first.
|
||||
if (!gfx::PNGCodec::Decode(data, size, decoded.get())) {
|
||||
// Try JPEG.
|
||||
decoded = gfx::JPEGCodec::Decode(data, size);
|
||||
if (decoded) {
|
||||
// `JPEGCodec::Decode()` doesn't tell `SkBitmap` instance it creates
|
||||
// that all of its pixels are opaque, that's why the bitmap gets
|
||||
// an alpha type `kPremul_SkAlphaType` instead of `kOpaque_SkAlphaType`.
|
||||
// Let's fix it here.
|
||||
// TODO(alexeykuzmin): This workaround should be removed
|
||||
// when the `JPEGCodec::Decode()` code is fixed.
|
||||
// See https://github.com/electron/electron/issues/11294.
|
||||
decoded->setAlphaType(SkAlphaType::kOpaque_SkAlphaType);
|
||||
}
|
||||
}
|
||||
|
||||
if (!decoded) {
|
||||
// Try Bitmap
|
||||
if (width > 0 && height > 0) {
|
||||
decoded.reset(new SkBitmap);
|
||||
decoded->allocN32Pixels(width, height, false);
|
||||
decoded->setPixels(
|
||||
const_cast<void*>(reinterpret_cast<const void*>(data)));
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
image->AddRepresentation(gfx::ImageSkiaRep(*decoded, scale_factor));
|
||||
image->AddRepresentation(gfx::ImageSkiaRep(bitmap, scale_factor));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AddImageSkiaRep(gfx::ImageSkia* image,
|
||||
const base::FilePath& path,
|
||||
double scale_factor) {
|
||||
bool AddImageSkiaRepFromJPEG(gfx::ImageSkia* image,
|
||||
const unsigned char* data,
|
||||
size_t size,
|
||||
double scale_factor) {
|
||||
auto bitmap = gfx::JPEGCodec::Decode(data, size);
|
||||
if (!bitmap)
|
||||
return false;
|
||||
|
||||
// `JPEGCodec::Decode()` doesn't tell `SkBitmap` instance it creates
|
||||
// that all of its pixels are opaque, that's why the bitmap gets
|
||||
// an alpha type `kPremul_SkAlphaType` instead of `kOpaque_SkAlphaType`.
|
||||
// Let's fix it here.
|
||||
// TODO(alexeykuzmin): This workaround should be removed
|
||||
// when the `JPEGCodec::Decode()` code is fixed.
|
||||
// See https://github.com/electron/electron/issues/11294.
|
||||
bitmap->setAlphaType(SkAlphaType::kOpaque_SkAlphaType);
|
||||
|
||||
image->AddRepresentation(gfx::ImageSkiaRep(*bitmap, scale_factor));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AddImageSkiaRepFromBuffer(gfx::ImageSkia* image,
|
||||
const unsigned char* data,
|
||||
size_t size,
|
||||
int width,
|
||||
int height,
|
||||
double scale_factor) {
|
||||
// Try PNG first.
|
||||
if (AddImageSkiaRepFromPNG(image, data, size, scale_factor))
|
||||
return true;
|
||||
|
||||
// Try JPEG second.
|
||||
if (AddImageSkiaRepFromJPEG(image, data, size, scale_factor))
|
||||
return true;
|
||||
|
||||
if (width == 0 || height == 0)
|
||||
return false;
|
||||
|
||||
auto info = SkImageInfo::MakeN32(width, height, kPremul_SkAlphaType);
|
||||
if (size < info.computeMinByteSize())
|
||||
return false;
|
||||
|
||||
SkBitmap bitmap;
|
||||
bitmap.allocN32Pixels(width, height, false);
|
||||
bitmap.writePixels({info, data, bitmap.rowBytes()});
|
||||
|
||||
image->AddRepresentation(gfx::ImageSkiaRep(bitmap, scale_factor));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AddImageSkiaRepFromPath(gfx::ImageSkia* image,
|
||||
const base::FilePath& path,
|
||||
double scale_factor) {
|
||||
std::string file_contents;
|
||||
{
|
||||
base::ThreadRestrictions::ScopedAllowIO allow_io;
|
||||
@@ -134,7 +156,8 @@ bool AddImageSkiaRep(gfx::ImageSkia* image,
|
||||
const unsigned char* data =
|
||||
reinterpret_cast<const unsigned char*>(file_contents.data());
|
||||
size_t size = file_contents.size();
|
||||
return AddImageSkiaRep(image, data, size, 0, 0, scale_factor);
|
||||
|
||||
return AddImageSkiaRepFromBuffer(image, data, size, 0, 0, scale_factor);
|
||||
}
|
||||
|
||||
bool PopulateImageSkiaRepsFromPath(gfx::ImageSkia* image,
|
||||
@@ -143,12 +166,12 @@ bool PopulateImageSkiaRepsFromPath(gfx::ImageSkia* image,
|
||||
std::string filename(path.BaseName().RemoveExtension().AsUTF8Unsafe());
|
||||
if (base::MatchPattern(filename, "*@*x"))
|
||||
// Don't search for other representations if the DPI has been specified.
|
||||
return AddImageSkiaRep(image, path, GetScaleFactorFromPath(path));
|
||||
return AddImageSkiaRepFromPath(image, path, GetScaleFactorFromPath(path));
|
||||
else
|
||||
succeed |= AddImageSkiaRep(image, path, 1.0f);
|
||||
succeed |= AddImageSkiaRepFromPath(image, path, 1.0f);
|
||||
|
||||
for (const ScaleFactorPair& pair : kScaleFactorPairs)
|
||||
succeed |= AddImageSkiaRep(
|
||||
succeed |= AddImageSkiaRepFromPath(
|
||||
image, path.InsertBeforeExtensionASCII(pair.name), pair.scale);
|
||||
return succeed;
|
||||
}
|
||||
@@ -423,19 +446,20 @@ void NativeImage::AddRepresentation(const mate::Dictionary& options) {
|
||||
v8::Local<v8::Value> buffer;
|
||||
GURL url;
|
||||
if (options.Get("buffer", &buffer) && node::Buffer::HasInstance(buffer)) {
|
||||
AddImageSkiaRep(
|
||||
&image_skia,
|
||||
reinterpret_cast<unsigned char*>(node::Buffer::Data(buffer)),
|
||||
node::Buffer::Length(buffer), width, height, scale_factor);
|
||||
skia_rep_added = true;
|
||||
auto* data = reinterpret_cast<unsigned char*>(node::Buffer::Data(buffer));
|
||||
auto size = node::Buffer::Length(buffer);
|
||||
skia_rep_added = AddImageSkiaRepFromBuffer(&image_skia, data, size, width,
|
||||
height, scale_factor);
|
||||
} else if (options.Get("dataURL", &url)) {
|
||||
std::string mime_type, charset, data;
|
||||
if (net::DataURL::Parse(url, &mime_type, &charset, &data)) {
|
||||
if (mime_type == "image/png" || mime_type == "image/jpeg") {
|
||||
AddImageSkiaRep(&image_skia,
|
||||
reinterpret_cast<const unsigned char*>(data.c_str()),
|
||||
data.size(), width, height, scale_factor);
|
||||
skia_rep_added = true;
|
||||
auto* data_ptr = reinterpret_cast<const unsigned char*>(data.c_str());
|
||||
if (mime_type == "image/png") {
|
||||
skia_rep_added = AddImageSkiaRepFromPNG(&image_skia, data_ptr,
|
||||
data.size(), scale_factor);
|
||||
} else if (mime_type == "image/jpeg") {
|
||||
skia_rep_added = AddImageSkiaRepFromJPEG(&image_skia, data_ptr,
|
||||
data.size(), scale_factor);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -509,6 +533,11 @@ mate::Handle<NativeImage> NativeImage::CreateFromPath(
|
||||
mate::Handle<NativeImage> NativeImage::CreateFromBuffer(
|
||||
mate::Arguments* args,
|
||||
v8::Local<v8::Value> buffer) {
|
||||
if (!node::Buffer::HasInstance(buffer)) {
|
||||
args->ThrowError("buffer must be a node Buffer");
|
||||
return mate::Handle<NativeImage>();
|
||||
}
|
||||
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
double scale_factor = 1.;
|
||||
@@ -521,9 +550,9 @@ mate::Handle<NativeImage> NativeImage::CreateFromBuffer(
|
||||
}
|
||||
|
||||
gfx::ImageSkia image_skia;
|
||||
AddImageSkiaRep(&image_skia,
|
||||
reinterpret_cast<unsigned char*>(node::Buffer::Data(buffer)),
|
||||
node::Buffer::Length(buffer), width, height, scale_factor);
|
||||
AddImageSkiaRepFromBuffer(
|
||||
&image_skia, reinterpret_cast<unsigned char*>(node::Buffer::Data(buffer)),
|
||||
node::Buffer::Length(buffer), width, height, scale_factor);
|
||||
return Create(args->isolate(), gfx::Image(image_skia));
|
||||
}
|
||||
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
#define ATOM_COMMON_ATOM_VERSION_H_
|
||||
|
||||
#define ATOM_MAJOR_VERSION 4
|
||||
#define ATOM_MINOR_VERSION 0
|
||||
#define ATOM_PATCH_VERSION 4
|
||||
#define ATOM_MINOR_VERSION 2
|
||||
#define ATOM_PATCH_VERSION 2
|
||||
// clang-format off
|
||||
// #define ATOM_PRE_RELEASE_VERSION
|
||||
// clang-format on
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#ifndef ATOM_COMMON_CHROME_VERSION_H_
|
||||
#define ATOM_COMMON_CHROME_VERSION_H_
|
||||
|
||||
#define CHROME_VERSION_STRING "69.0.3497.106"
|
||||
#define CHROME_VERSION_STRING "69.0.3497.128"
|
||||
#define CHROME_VERSION "v" CHROME_VERSION_STRING
|
||||
|
||||
#endif // ATOM_COMMON_CHROME_VERSION_H_
|
||||
|
||||
@@ -93,8 +93,13 @@ bool RegisterNonABICompliantCodeRange(void* start, size_t size_in_bytes) {
|
||||
|
||||
// All addresses are 32bit relative offsets to start.
|
||||
record->runtime_function.BeginAddress = 0;
|
||||
#if defined(_M_ARM64)
|
||||
record->runtime_function.FunctionLength =
|
||||
base::checked_cast<DWORD>(size_in_bytes);
|
||||
#else
|
||||
record->runtime_function.EndAddress =
|
||||
base::checked_cast<DWORD>(size_in_bytes);
|
||||
#endif
|
||||
record->runtime_function.UnwindData =
|
||||
offsetof(ExceptionHandlerRecord, unwind_info);
|
||||
|
||||
|
||||
@@ -181,24 +181,45 @@ bool Converter<net::HttpResponseHeaders*>::FromV8(
|
||||
if (!val->IsObject()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto addHeaderFromValue = [&isolate, &out](
|
||||
const std::string& key,
|
||||
const v8::Local<v8::Value>& localVal) {
|
||||
auto context = isolate->GetCurrentContext();
|
||||
v8::Local<v8::String> localStrVal;
|
||||
if (!localVal->ToString(context).ToLocal(&localStrVal)) {
|
||||
return false;
|
||||
}
|
||||
std::string value;
|
||||
mate::ConvertFromV8(isolate, localStrVal, &value);
|
||||
out->AddHeader(key + ": " + value);
|
||||
return true;
|
||||
};
|
||||
|
||||
auto context = isolate->GetCurrentContext();
|
||||
auto headers = v8::Local<v8::Object>::Cast(val);
|
||||
auto keys = headers->GetOwnPropertyNames();
|
||||
for (uint32_t i = 0; i < keys->Length(); i++) {
|
||||
v8::Local<v8::String> key, value;
|
||||
if (!keys->Get(i)->ToString(context).ToLocal(&key)) {
|
||||
v8::Local<v8::String> keyVal;
|
||||
if (!keys->Get(i)->ToString(context).ToLocal(&keyVal)) {
|
||||
return false;
|
||||
}
|
||||
if (!headers->Get(key)->ToString(context).ToLocal(&value)) {
|
||||
return false;
|
||||
std::string key;
|
||||
mate::ConvertFromV8(isolate, keyVal, &key);
|
||||
|
||||
auto localVal = headers->Get(keyVal);
|
||||
if (localVal->IsArray()) {
|
||||
auto values = v8::Local<v8::Array>::Cast(localVal);
|
||||
for (uint32_t j = 0; j < values->Length(); j++) {
|
||||
if (!addHeaderFromValue(key, values->Get(j))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!addHeaderFromValue(key, localVal)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
v8::String::Utf8Value key_utf8(key);
|
||||
v8::String::Utf8Value value_utf8(value);
|
||||
std::string k(*key_utf8, key_utf8.length());
|
||||
std::string v(*value_utf8, value_utf8.length());
|
||||
std::ostringstream tmp;
|
||||
tmp << k << ": " << v;
|
||||
out->AddHeader(tmp.str());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -247,6 +247,9 @@ const char kAuthServerWhitelist[] = "auth-server-whitelist";
|
||||
const char kAuthNegotiateDelegateWhitelist[] =
|
||||
"auth-negotiate-delegate-whitelist";
|
||||
|
||||
// If set, include the port in generated Kerberos SPNs.
|
||||
const char kEnableAuthNegotiatePort[] = "enable-auth-negotiate-port";
|
||||
|
||||
} // namespace switches
|
||||
|
||||
} // namespace atom
|
||||
|
||||
@@ -118,6 +118,7 @@ extern const char kDiskCacheSize[];
|
||||
extern const char kIgnoreConnectionsLimit[];
|
||||
extern const char kAuthServerWhitelist[];
|
||||
extern const char kAuthNegotiateDelegateWhitelist[];
|
||||
extern const char kEnableAuthNegotiatePort[];
|
||||
|
||||
} // namespace switches
|
||||
|
||||
|
||||
@@ -2,9 +2,10 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/renderer/api/atom_api_web_frame.h"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "atom/common/api/api_messages.h"
|
||||
#include "atom/common/api/event_emitter_caller.h"
|
||||
@@ -111,15 +112,15 @@ class ScriptExecutionCallback : public blink::WebScriptExecutionCallback {
|
||||
DISALLOW_COPY_AND_ASSIGN(ScriptExecutionCallback);
|
||||
};
|
||||
|
||||
class FrameSpellChecker : public content::RenderFrameVisitor {
|
||||
class FrameSetSpellChecker : public content::RenderFrameVisitor {
|
||||
public:
|
||||
explicit FrameSpellChecker(SpellCheckClient* spell_check_client,
|
||||
content::RenderFrame* main_frame)
|
||||
: spell_check_client_(spell_check_client), main_frame_(main_frame) {}
|
||||
~FrameSpellChecker() override {
|
||||
spell_check_client_ = nullptr;
|
||||
main_frame_ = nullptr;
|
||||
FrameSetSpellChecker(SpellCheckClient* spell_check_client,
|
||||
content::RenderFrame* main_frame)
|
||||
: spell_check_client_(spell_check_client), main_frame_(main_frame) {
|
||||
content::RenderFrame::ForEach(this);
|
||||
main_frame->GetWebFrame()->SetSpellCheckPanelHostClient(spell_check_client);
|
||||
}
|
||||
|
||||
bool Visit(content::RenderFrame* render_frame) override {
|
||||
auto* view = render_frame->GetRenderView();
|
||||
if (view->GetMainRenderFrame() == main_frame_ ||
|
||||
@@ -132,93 +133,130 @@ class FrameSpellChecker : public content::RenderFrameVisitor {
|
||||
private:
|
||||
SpellCheckClient* spell_check_client_;
|
||||
content::RenderFrame* main_frame_;
|
||||
DISALLOW_COPY_AND_ASSIGN(FrameSpellChecker);
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(FrameSetSpellChecker);
|
||||
};
|
||||
|
||||
class SpellCheckerHolder : public content::RenderFrameObserver {
|
||||
public:
|
||||
// Find existing holder for the |render_frame|.
|
||||
static SpellCheckerHolder* FromRenderFrame(
|
||||
content::RenderFrame* render_frame) {
|
||||
for (auto* holder : instances_) {
|
||||
if (holder->render_frame() == render_frame)
|
||||
return holder;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
SpellCheckerHolder(content::RenderFrame* render_frame,
|
||||
std::unique_ptr<SpellCheckClient> spell_check_client)
|
||||
: content::RenderFrameObserver(render_frame),
|
||||
spell_check_client_(std::move(spell_check_client)) {
|
||||
DCHECK(!FromRenderFrame(render_frame));
|
||||
instances_.insert(this);
|
||||
}
|
||||
|
||||
~SpellCheckerHolder() final { instances_.erase(this); }
|
||||
|
||||
void UnsetAndDestroy() {
|
||||
FrameSetSpellChecker set_spell_checker(nullptr, render_frame());
|
||||
delete this;
|
||||
}
|
||||
|
||||
// RenderFrameObserver implementation.
|
||||
void OnDestruct() final {
|
||||
// Since we delete this in WillReleaseScriptContext, this method is unlikely
|
||||
// to be called, but override anyway since I'm not sure if there are some
|
||||
// corner cases.
|
||||
//
|
||||
// Note that while there are two "delete this", it is totally fine as the
|
||||
// observer unsubscribes automatically in destructor and the other one won't
|
||||
// be called.
|
||||
//
|
||||
// Also note that we should not call UnsetAndDestroy here, as the render
|
||||
// frame is going to be destroyed.
|
||||
delete this;
|
||||
}
|
||||
|
||||
void WillReleaseScriptContext(v8::Local<v8::Context> context,
|
||||
int world_id) final {
|
||||
// Unset spell checker when the script context is going to be released, as
|
||||
// the spell check implementation lives there.
|
||||
UnsetAndDestroy();
|
||||
}
|
||||
|
||||
private:
|
||||
static std::set<SpellCheckerHolder*> instances_;
|
||||
|
||||
std::unique_ptr<SpellCheckClient> spell_check_client_;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
class AtomWebFrameObserver : public content::RenderFrameObserver {
|
||||
public:
|
||||
explicit AtomWebFrameObserver(
|
||||
content::RenderFrame* render_frame,
|
||||
std::unique_ptr<SpellCheckClient> spell_check_client)
|
||||
: content::RenderFrameObserver(render_frame),
|
||||
spell_check_client_(std::move(spell_check_client)) {}
|
||||
~AtomWebFrameObserver() final {}
|
||||
// static
|
||||
std::set<SpellCheckerHolder*> SpellCheckerHolder::instances_;
|
||||
|
||||
// RenderFrameObserver implementation.
|
||||
void OnDestruct() final {
|
||||
spell_check_client_.reset();
|
||||
// Frame observers should delete themselves
|
||||
delete this;
|
||||
}
|
||||
|
||||
private:
|
||||
std::unique_ptr<SpellCheckClient> spell_check_client_;
|
||||
};
|
||||
|
||||
WebFrame::WebFrame(v8::Isolate* isolate)
|
||||
: web_frame_(blink::WebLocalFrame::FrameForCurrentContext()) {
|
||||
Init(isolate);
|
||||
void SetName(v8::Local<v8::Value> window, const std::string& name) {
|
||||
GetRenderFrame(window)->GetWebFrame()->SetName(
|
||||
blink::WebString::FromUTF8(name));
|
||||
}
|
||||
|
||||
WebFrame::WebFrame(v8::Isolate* isolate, blink::WebLocalFrame* blink_frame)
|
||||
: web_frame_(blink_frame) {
|
||||
Init(isolate);
|
||||
}
|
||||
|
||||
WebFrame::~WebFrame() {}
|
||||
|
||||
void WebFrame::SetName(const std::string& name) {
|
||||
web_frame_->SetName(blink::WebString::FromUTF8(name));
|
||||
}
|
||||
|
||||
double WebFrame::SetZoomLevel(double level) {
|
||||
double SetZoomLevel(v8::Local<v8::Value> window, double level) {
|
||||
double result = 0.0;
|
||||
content::RenderFrame* render_frame =
|
||||
content::RenderFrame::FromWebFrame(web_frame_);
|
||||
content::RenderFrame* render_frame = GetRenderFrame(window);
|
||||
render_frame->Send(new AtomFrameHostMsg_SetTemporaryZoomLevel(
|
||||
render_frame->GetRoutingID(), level, &result));
|
||||
return result;
|
||||
}
|
||||
|
||||
double WebFrame::GetZoomLevel() const {
|
||||
double GetZoomLevel(v8::Local<v8::Value> window) {
|
||||
double result = 0.0;
|
||||
content::RenderFrame* render_frame =
|
||||
content::RenderFrame::FromWebFrame(web_frame_);
|
||||
content::RenderFrame* render_frame = GetRenderFrame(window);
|
||||
render_frame->Send(
|
||||
new AtomFrameHostMsg_GetZoomLevel(render_frame->GetRoutingID(), &result));
|
||||
return result;
|
||||
}
|
||||
|
||||
double WebFrame::SetZoomFactor(double factor) {
|
||||
double SetZoomFactor(v8::Local<v8::Value> window, double factor) {
|
||||
return blink::WebView::ZoomLevelToZoomFactor(
|
||||
SetZoomLevel(blink::WebView::ZoomFactorToZoomLevel(factor)));
|
||||
SetZoomLevel(window, blink::WebView::ZoomFactorToZoomLevel(factor)));
|
||||
}
|
||||
|
||||
double WebFrame::GetZoomFactor() const {
|
||||
return blink::WebView::ZoomLevelToZoomFactor(GetZoomLevel());
|
||||
double GetZoomFactor(v8::Local<v8::Value> window) {
|
||||
return blink::WebView::ZoomLevelToZoomFactor(GetZoomLevel(window));
|
||||
}
|
||||
|
||||
void WebFrame::SetVisualZoomLevelLimits(double min_level, double max_level) {
|
||||
web_frame_->View()->SetDefaultPageScaleLimits(min_level, max_level);
|
||||
web_frame_->View()->SetIgnoreViewportTagScaleLimits(true);
|
||||
void SetVisualZoomLevelLimits(v8::Local<v8::Value> window,
|
||||
double min_level,
|
||||
double max_level) {
|
||||
blink::WebFrame* web_frame = GetRenderFrame(window)->GetWebFrame();
|
||||
web_frame->View()->SetDefaultPageScaleLimits(min_level, max_level);
|
||||
web_frame->View()->SetIgnoreViewportTagScaleLimits(true);
|
||||
}
|
||||
|
||||
void WebFrame::SetLayoutZoomLevelLimits(double min_level, double max_level) {
|
||||
web_frame_->View()->ZoomLimitsChanged(min_level, max_level);
|
||||
void SetLayoutZoomLevelLimits(v8::Local<v8::Value> window,
|
||||
double min_level,
|
||||
double max_level) {
|
||||
blink::WebFrame* web_frame = GetRenderFrame(window)->GetWebFrame();
|
||||
web_frame->View()->ZoomLimitsChanged(min_level, max_level);
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> WebFrame::RegisterEmbedderCustomElement(
|
||||
v8::Local<v8::Value> RegisterEmbedderCustomElement(
|
||||
v8::Local<v8::Value> window,
|
||||
v8::Local<v8::Object> context,
|
||||
const base::string16& name,
|
||||
v8::Local<v8::Object> options) {
|
||||
v8::Context::Scope context_scope(context->CreationContext());
|
||||
return web_frame_->GetDocument().RegisterEmbedderCustomElement(
|
||||
blink::WebString::FromUTF16(name), options);
|
||||
return GetRenderFrame(context)
|
||||
->GetWebFrame()
|
||||
->GetDocument()
|
||||
.RegisterEmbedderCustomElement(blink::WebString::FromUTF16(name),
|
||||
options);
|
||||
}
|
||||
|
||||
int WebFrame::GetWebFrameId(v8::Local<v8::Value> content_window) {
|
||||
int GetWebFrameId(v8::Local<v8::Value> window,
|
||||
v8::Local<v8::Value> content_window) {
|
||||
// Get the WebLocalFrame before (possibly) executing any user-space JS while
|
||||
// getting the |params|. We track the status of the RenderFrame via an
|
||||
// observer in case it is deleted during user code execution.
|
||||
@@ -237,34 +275,42 @@ int WebFrame::GetWebFrameId(v8::Local<v8::Value> content_window) {
|
||||
return render_frame->GetRoutingID();
|
||||
}
|
||||
|
||||
void WebFrame::SetSpellCheckProvider(mate::Arguments* args,
|
||||
const std::string& language,
|
||||
bool auto_spell_correct_turned_on,
|
||||
v8::Local<v8::Object> provider) {
|
||||
void SetSpellCheckProvider(mate::Arguments* args,
|
||||
v8::Local<v8::Value> window,
|
||||
const std::string& language,
|
||||
bool auto_spell_correct_turned_on,
|
||||
v8::Local<v8::Object> provider) {
|
||||
if (!provider->Has(mate::StringToV8(args->isolate(), "spellCheck"))) {
|
||||
args->ThrowError("\"spellCheck\" has to be defined");
|
||||
return;
|
||||
}
|
||||
|
||||
auto spell_check_client = std::make_unique<SpellCheckClient>(
|
||||
language, auto_spell_correct_turned_on, args->isolate(), provider);
|
||||
// Remove the old client.
|
||||
content::RenderFrame* render_frame = GetRenderFrame(window);
|
||||
auto* existing = SpellCheckerHolder::FromRenderFrame(render_frame);
|
||||
if (existing)
|
||||
existing->UnsetAndDestroy();
|
||||
|
||||
// Set spellchecker for all live frames in the same process or
|
||||
// in the sandbox mode for all live sub frames to this WebFrame.
|
||||
auto* render_frame = content::RenderFrame::FromWebFrame(web_frame_);
|
||||
FrameSpellChecker spell_checker(spell_check_client.get(), render_frame);
|
||||
content::RenderFrame::ForEach(&spell_checker);
|
||||
web_frame_->SetSpellCheckPanelHostClient(spell_check_client.get());
|
||||
new AtomWebFrameObserver(render_frame, std::move(spell_check_client));
|
||||
auto spell_check_client = std::make_unique<SpellCheckClient>(
|
||||
language, auto_spell_correct_turned_on, args->isolate(), provider);
|
||||
FrameSetSpellChecker spell_checker(spell_check_client.get(), render_frame);
|
||||
|
||||
// Attach the spell checker to RenderFrame.
|
||||
new SpellCheckerHolder(render_frame, std::move(spell_check_client));
|
||||
}
|
||||
|
||||
void WebFrame::RegisterURLSchemeAsBypassingCSP(const std::string& scheme) {
|
||||
void RegisterURLSchemeAsBypassingCSP(v8::Local<v8::Value> window,
|
||||
const std::string& scheme) {
|
||||
// Register scheme to bypass pages's Content Security Policy.
|
||||
blink::SchemeRegistry::RegisterURLSchemeAsBypassingContentSecurityPolicy(
|
||||
WTF::String::FromUTF8(scheme.data(), scheme.length()));
|
||||
}
|
||||
|
||||
void WebFrame::RegisterURLSchemeAsPrivileged(const std::string& scheme,
|
||||
mate::Arguments* args) {
|
||||
void RegisterURLSchemeAsPrivileged(v8::Local<v8::Value> window,
|
||||
const std::string& scheme,
|
||||
mate::Arguments* args) {
|
||||
// TODO(deepak1556): blink::SchemeRegistry methods should be called
|
||||
// before any renderer threads are created. Fixing this would break
|
||||
// current api. Change it with 2.0.
|
||||
@@ -275,7 +321,7 @@ void WebFrame::RegisterURLSchemeAsPrivileged(const std::string& scheme,
|
||||
bool allowServiceWorkers = true;
|
||||
bool supportFetchAPI = true;
|
||||
bool corsEnabled = true;
|
||||
if (args->Length() == 2) {
|
||||
if (args->Length() == 3) {
|
||||
mate::Dictionary options;
|
||||
if (args->GetNext(&options)) {
|
||||
options.Get("secure", &secure);
|
||||
@@ -305,30 +351,42 @@ void WebFrame::RegisterURLSchemeAsPrivileged(const std::string& scheme,
|
||||
}
|
||||
}
|
||||
|
||||
void WebFrame::InsertText(const std::string& text) {
|
||||
web_frame_->FrameWidget()->GetActiveWebInputMethodController()->CommitText(
|
||||
blink::WebString::FromUTF8(text),
|
||||
blink::WebVector<blink::WebImeTextSpan>(), blink::WebRange(), 0);
|
||||
void InsertText(v8::Local<v8::Value> window, const std::string& text) {
|
||||
blink::WebFrame* web_frame = GetRenderFrame(window)->GetWebFrame();
|
||||
if (web_frame->IsWebLocalFrame()) {
|
||||
web_frame->ToWebLocalFrame()
|
||||
->FrameWidget()
|
||||
->GetActiveWebInputMethodController()
|
||||
->CommitText(blink::WebString::FromUTF8(text),
|
||||
blink::WebVector<blink::WebImeTextSpan>(),
|
||||
blink::WebRange(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
void WebFrame::InsertCSS(const std::string& css) {
|
||||
web_frame_->GetDocument().InsertStyleSheet(blink::WebString::FromUTF8(css));
|
||||
void InsertCSS(v8::Local<v8::Value> window, const std::string& css) {
|
||||
blink::WebFrame* web_frame = GetRenderFrame(window)->GetWebFrame();
|
||||
if (web_frame->IsWebLocalFrame()) {
|
||||
web_frame->ToWebLocalFrame()->GetDocument().InsertStyleSheet(
|
||||
blink::WebString::FromUTF8(css));
|
||||
}
|
||||
}
|
||||
|
||||
void WebFrame::ExecuteJavaScript(const base::string16& code,
|
||||
mate::Arguments* args) {
|
||||
void ExecuteJavaScript(v8::Local<v8::Value> window,
|
||||
const base::string16& code,
|
||||
mate::Arguments* args) {
|
||||
bool has_user_gesture = false;
|
||||
args->GetNext(&has_user_gesture);
|
||||
ScriptExecutionCallback::CompletionCallback completion_callback;
|
||||
args->GetNext(&completion_callback);
|
||||
std::unique_ptr<blink::WebScriptExecutionCallback> callback(
|
||||
new ScriptExecutionCallback(completion_callback));
|
||||
web_frame_->RequestExecuteScriptAndReturnValue(
|
||||
GetRenderFrame(window)->GetWebFrame()->RequestExecuteScriptAndReturnValue(
|
||||
blink::WebScriptSource(blink::WebString::FromUTF16(code)),
|
||||
has_user_gesture, callback.release());
|
||||
}
|
||||
|
||||
void WebFrame::ExecuteJavaScriptInIsolatedWorld(
|
||||
void ExecuteJavaScriptInIsolatedWorld(
|
||||
v8::Local<v8::Value> window,
|
||||
int world_id,
|
||||
const std::vector<mate::Dictionary>& scripts,
|
||||
mate::Arguments* args) {
|
||||
@@ -363,186 +421,132 @@ void WebFrame::ExecuteJavaScriptInIsolatedWorld(
|
||||
std::unique_ptr<blink::WebScriptExecutionCallback> callback(
|
||||
new ScriptExecutionCallback(completion_callback));
|
||||
|
||||
web_frame_->RequestExecuteScriptInIsolatedWorld(
|
||||
GetRenderFrame(window)->GetWebFrame()->RequestExecuteScriptInIsolatedWorld(
|
||||
world_id, &sources.front(), sources.size(), has_user_gesture,
|
||||
scriptExecutionType, callback.release());
|
||||
}
|
||||
|
||||
void WebFrame::SetIsolatedWorldSecurityOrigin(int world_id,
|
||||
const std::string& origin_url) {
|
||||
web_frame_->SetIsolatedWorldSecurityOrigin(
|
||||
void SetIsolatedWorldSecurityOrigin(v8::Local<v8::Value> window,
|
||||
int world_id,
|
||||
const std::string& origin_url) {
|
||||
GetRenderFrame(window)->GetWebFrame()->SetIsolatedWorldSecurityOrigin(
|
||||
world_id, blink::WebSecurityOrigin::CreateFromString(
|
||||
blink::WebString::FromUTF8(origin_url)));
|
||||
}
|
||||
|
||||
void WebFrame::SetIsolatedWorldContentSecurityPolicy(
|
||||
int world_id,
|
||||
const std::string& security_policy) {
|
||||
web_frame_->SetIsolatedWorldContentSecurityPolicy(
|
||||
void SetIsolatedWorldContentSecurityPolicy(v8::Local<v8::Value> window,
|
||||
int world_id,
|
||||
const std::string& security_policy) {
|
||||
GetRenderFrame(window)->GetWebFrame()->SetIsolatedWorldContentSecurityPolicy(
|
||||
world_id, blink::WebString::FromUTF8(security_policy));
|
||||
}
|
||||
|
||||
void WebFrame::SetIsolatedWorldHumanReadableName(int world_id,
|
||||
const std::string& name) {
|
||||
web_frame_->SetIsolatedWorldHumanReadableName(
|
||||
void SetIsolatedWorldHumanReadableName(v8::Local<v8::Value> window,
|
||||
int world_id,
|
||||
const std::string& name) {
|
||||
GetRenderFrame(window)->GetWebFrame()->SetIsolatedWorldHumanReadableName(
|
||||
world_id, blink::WebString::FromUTF8(name));
|
||||
}
|
||||
|
||||
// static
|
||||
mate::Handle<WebFrame> WebFrame::Create(v8::Isolate* isolate) {
|
||||
return mate::CreateHandle(isolate, new WebFrame(isolate));
|
||||
}
|
||||
|
||||
blink::WebCache::ResourceTypeStats WebFrame::GetResourceUsage(
|
||||
v8::Isolate* isolate) {
|
||||
blink::WebCache::ResourceTypeStats GetResourceUsage(v8::Isolate* isolate) {
|
||||
blink::WebCache::ResourceTypeStats stats;
|
||||
blink::WebCache::GetResourceTypeStats(&stats);
|
||||
return stats;
|
||||
}
|
||||
|
||||
void WebFrame::ClearCache(v8::Isolate* isolate) {
|
||||
void ClearCache(v8::Isolate* isolate) {
|
||||
isolate->IdleNotificationDeadline(0.5);
|
||||
blink::WebCache::Clear();
|
||||
base::MemoryPressureListener::NotifyMemoryPressure(
|
||||
base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> WebFrame::Opener() const {
|
||||
blink::WebFrame* frame = web_frame_->Opener();
|
||||
if (frame && frame->IsWebLocalFrame())
|
||||
return mate::CreateHandle(isolate(),
|
||||
new WebFrame(isolate(), frame->ToWebLocalFrame()))
|
||||
.ToV8();
|
||||
else
|
||||
return v8::Null(isolate());
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> WebFrame::Parent() const {
|
||||
blink::WebFrame* frame = web_frame_->Parent();
|
||||
if (frame && frame->IsWebLocalFrame())
|
||||
return mate::CreateHandle(isolate(),
|
||||
new WebFrame(isolate(), frame->ToWebLocalFrame()))
|
||||
.ToV8();
|
||||
else
|
||||
return v8::Null(isolate());
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> WebFrame::Top() const {
|
||||
blink::WebFrame* frame = web_frame_->Top();
|
||||
if (frame && frame->IsWebLocalFrame())
|
||||
return mate::CreateHandle(isolate(),
|
||||
new WebFrame(isolate(), frame->ToWebLocalFrame()))
|
||||
.ToV8();
|
||||
else
|
||||
return v8::Null(isolate());
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> WebFrame::FirstChild() const {
|
||||
blink::WebFrame* frame = web_frame_->FirstChild();
|
||||
if (frame && frame->IsWebLocalFrame())
|
||||
return mate::CreateHandle(isolate(),
|
||||
new WebFrame(isolate(), frame->ToWebLocalFrame()))
|
||||
.ToV8();
|
||||
else
|
||||
return v8::Null(isolate());
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> WebFrame::NextSibling() const {
|
||||
blink::WebFrame* frame = web_frame_->NextSibling();
|
||||
if (frame && frame->IsWebLocalFrame())
|
||||
return mate::CreateHandle(isolate(),
|
||||
new WebFrame(isolate(), frame->ToWebLocalFrame()))
|
||||
.ToV8();
|
||||
else
|
||||
return v8::Null(isolate());
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> WebFrame::GetFrameForSelector(
|
||||
const std::string& selector) const {
|
||||
blink::WebElement element = web_frame_->GetDocument().QuerySelector(
|
||||
blink::WebString::FromUTF8(selector));
|
||||
blink::WebLocalFrame* element_frame =
|
||||
blink::WebLocalFrame::FromFrameOwnerElement(element);
|
||||
if (element_frame)
|
||||
return mate::CreateHandle(isolate(), new WebFrame(isolate(), element_frame))
|
||||
.ToV8();
|
||||
else
|
||||
return v8::Null(isolate());
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> WebFrame::FindFrameByName(const std::string& name) const {
|
||||
blink::WebLocalFrame* local_frame =
|
||||
web_frame_->FindFrameByName(blink::WebString::FromUTF8(name))
|
||||
->ToWebLocalFrame();
|
||||
if (local_frame)
|
||||
return mate::CreateHandle(isolate(), new WebFrame(isolate(), local_frame))
|
||||
.ToV8();
|
||||
else
|
||||
return v8::Null(isolate());
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> WebFrame::FindFrameByRoutingId(int routing_id) const {
|
||||
v8::Local<v8::Value> FindFrameByRoutingId(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> window,
|
||||
int routing_id) {
|
||||
content::RenderFrame* render_frame =
|
||||
content::RenderFrame::FromRoutingID(routing_id);
|
||||
blink::WebLocalFrame* local_frame = nullptr;
|
||||
if (render_frame)
|
||||
local_frame = render_frame->GetWebFrame();
|
||||
if (local_frame)
|
||||
return mate::CreateHandle(isolate(), new WebFrame(isolate(), local_frame))
|
||||
.ToV8();
|
||||
return render_frame->GetWebFrame()->MainWorldScriptContext()->Global();
|
||||
else
|
||||
return v8::Null(isolate());
|
||||
return v8::Null(isolate);
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> WebFrame::RoutingId() const {
|
||||
int routing_id = content::RenderFrame::GetRoutingIdForWebFrame(web_frame_);
|
||||
return v8::Number::New(isolate(), routing_id);
|
||||
v8::Local<v8::Value> GetOpener(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> window) {
|
||||
blink::WebFrame* frame = GetRenderFrame(window)->GetWebFrame()->Opener();
|
||||
if (frame && frame->IsWebLocalFrame())
|
||||
return frame->ToWebLocalFrame()->MainWorldScriptContext()->Global();
|
||||
else
|
||||
return v8::Null(isolate);
|
||||
}
|
||||
|
||||
// static
|
||||
void WebFrame::BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype) {
|
||||
prototype->SetClassName(mate::StringToV8(isolate, "WebFrame"));
|
||||
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||
.SetMethod("setName", &WebFrame::SetName)
|
||||
.SetMethod("setZoomLevel", &WebFrame::SetZoomLevel)
|
||||
.SetMethod("getZoomLevel", &WebFrame::GetZoomLevel)
|
||||
.SetMethod("setZoomFactor", &WebFrame::SetZoomFactor)
|
||||
.SetMethod("getZoomFactor", &WebFrame::GetZoomFactor)
|
||||
.SetMethod("setVisualZoomLevelLimits",
|
||||
&WebFrame::SetVisualZoomLevelLimits)
|
||||
.SetMethod("setLayoutZoomLevelLimits",
|
||||
&WebFrame::SetLayoutZoomLevelLimits)
|
||||
.SetMethod("registerEmbedderCustomElement",
|
||||
&WebFrame::RegisterEmbedderCustomElement)
|
||||
.SetMethod("getWebFrameId", &WebFrame::GetWebFrameId)
|
||||
.SetMethod("setSpellCheckProvider", &WebFrame::SetSpellCheckProvider)
|
||||
.SetMethod("registerURLSchemeAsBypassingCSP",
|
||||
&WebFrame::RegisterURLSchemeAsBypassingCSP)
|
||||
.SetMethod("registerURLSchemeAsPrivileged",
|
||||
&WebFrame::RegisterURLSchemeAsPrivileged)
|
||||
.SetMethod("insertText", &WebFrame::InsertText)
|
||||
.SetMethod("insertCSS", &WebFrame::InsertCSS)
|
||||
.SetMethod("executeJavaScript", &WebFrame::ExecuteJavaScript)
|
||||
.SetMethod("executeJavaScriptInIsolatedWorld",
|
||||
&WebFrame::ExecuteJavaScriptInIsolatedWorld)
|
||||
.SetMethod("setIsolatedWorldSecurityOrigin",
|
||||
&WebFrame::SetIsolatedWorldSecurityOrigin)
|
||||
.SetMethod("setIsolatedWorldContentSecurityPolicy",
|
||||
&WebFrame::SetIsolatedWorldContentSecurityPolicy)
|
||||
.SetMethod("setIsolatedWorldHumanReadableName",
|
||||
&WebFrame::SetIsolatedWorldHumanReadableName)
|
||||
.SetMethod("getResourceUsage", &WebFrame::GetResourceUsage)
|
||||
.SetMethod("clearCache", &WebFrame::ClearCache)
|
||||
.SetMethod("getFrameForSelector", &WebFrame::GetFrameForSelector)
|
||||
.SetMethod("findFrameByName", &WebFrame::FindFrameByName)
|
||||
.SetProperty("opener", &WebFrame::Opener)
|
||||
.SetProperty("parent", &WebFrame::Parent)
|
||||
.SetProperty("top", &WebFrame::Top)
|
||||
.SetProperty("firstChild", &WebFrame::FirstChild)
|
||||
.SetProperty("nextSibling", &WebFrame::NextSibling)
|
||||
.SetProperty("routingId", &WebFrame::RoutingId)
|
||||
.SetMethod("findFrameByRoutingId", &WebFrame::FindFrameByRoutingId);
|
||||
// Don't name it as GetParent, Windows has API with same name.
|
||||
v8::Local<v8::Value> GetFrameParent(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> window) {
|
||||
blink::WebFrame* frame = GetRenderFrame(window)->GetWebFrame()->Parent();
|
||||
if (frame && frame->IsWebLocalFrame())
|
||||
return frame->ToWebLocalFrame()->MainWorldScriptContext()->Global();
|
||||
else
|
||||
return v8::Null(isolate);
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> GetTop(v8::Isolate* isolate, v8::Local<v8::Value> window) {
|
||||
blink::WebFrame* frame = GetRenderFrame(window)->GetWebFrame()->Top();
|
||||
if (frame && frame->IsWebLocalFrame())
|
||||
return frame->ToWebLocalFrame()->MainWorldScriptContext()->Global();
|
||||
else
|
||||
return v8::Null(isolate);
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> GetFirstChild(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> window) {
|
||||
blink::WebFrame* frame = GetRenderFrame(window)->GetWebFrame()->FirstChild();
|
||||
if (frame && frame->IsWebLocalFrame())
|
||||
return frame->ToWebLocalFrame()->MainWorldScriptContext()->Global();
|
||||
else
|
||||
return v8::Null(isolate);
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> GetNextSibling(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> window) {
|
||||
blink::WebFrame* frame = GetRenderFrame(window)->GetWebFrame()->NextSibling();
|
||||
if (frame && frame->IsWebLocalFrame())
|
||||
return frame->ToWebLocalFrame()->MainWorldScriptContext()->Global();
|
||||
else
|
||||
return v8::Null(isolate);
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> GetFrameForSelector(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> window,
|
||||
const std::string& selector) {
|
||||
blink::WebElement element =
|
||||
GetRenderFrame(window)->GetWebFrame()->GetDocument().QuerySelector(
|
||||
blink::WebString::FromUTF8(selector));
|
||||
if (element.IsNull()) // not found
|
||||
return v8::Null(isolate);
|
||||
|
||||
blink::WebFrame* frame = blink::WebFrame::FromFrameOwnerElement(element);
|
||||
if (frame && frame->IsWebLocalFrame())
|
||||
return frame->ToWebLocalFrame()->MainWorldScriptContext()->Global();
|
||||
else
|
||||
return v8::Null(isolate);
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> FindFrameByName(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> window,
|
||||
const std::string& name) {
|
||||
blink::WebFrame* frame =
|
||||
GetRenderFrame(window)->GetWebFrame()->FindFrameByName(
|
||||
blink::WebString::FromUTF8(name));
|
||||
if (frame && frame->IsWebLocalFrame())
|
||||
return frame->ToWebLocalFrame()->MainWorldScriptContext()->Global();
|
||||
else
|
||||
return v8::Null(isolate);
|
||||
}
|
||||
|
||||
int GetRoutingId(v8::Local<v8::Value> window) {
|
||||
return GetRenderFrame(window)->GetRoutingID();
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
@@ -551,16 +555,51 @@ void WebFrame::BuildPrototype(v8::Isolate* isolate,
|
||||
|
||||
namespace {
|
||||
|
||||
using atom::api::WebFrame;
|
||||
|
||||
void Initialize(v8::Local<v8::Object> exports,
|
||||
v8::Local<v8::Value> unused,
|
||||
v8::Local<v8::Context> context,
|
||||
void* priv) {
|
||||
using namespace atom::api; // NOLINT(build/namespaces)
|
||||
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
mate::Dictionary dict(isolate, exports);
|
||||
dict.Set("webFrame", WebFrame::Create(isolate));
|
||||
dict.Set("WebFrame", WebFrame::GetConstructor(isolate)->GetFunction());
|
||||
dict.SetMethod("setName", &SetName);
|
||||
dict.SetMethod("setZoomLevel", &SetZoomLevel);
|
||||
dict.SetMethod("getZoomLevel", &GetZoomLevel);
|
||||
dict.SetMethod("setZoomFactor", &SetZoomFactor);
|
||||
dict.SetMethod("getZoomFactor", &GetZoomFactor);
|
||||
dict.SetMethod("setVisualZoomLevelLimits", &SetVisualZoomLevelLimits);
|
||||
dict.SetMethod("setLayoutZoomLevelLimits", &SetLayoutZoomLevelLimits);
|
||||
dict.SetMethod("registerEmbedderCustomElement",
|
||||
&RegisterEmbedderCustomElement);
|
||||
dict.SetMethod("getWebFrameId", &GetWebFrameId);
|
||||
dict.SetMethod("setSpellCheckProvider", &SetSpellCheckProvider);
|
||||
dict.SetMethod("registerURLSchemeAsBypassingCSP",
|
||||
&RegisterURLSchemeAsBypassingCSP);
|
||||
dict.SetMethod("registerURLSchemeAsPrivileged",
|
||||
&RegisterURLSchemeAsPrivileged);
|
||||
dict.SetMethod("insertText", &InsertText);
|
||||
dict.SetMethod("insertCSS", &InsertCSS);
|
||||
dict.SetMethod("executeJavaScript", &ExecuteJavaScript);
|
||||
dict.SetMethod("executeJavaScriptInIsolatedWorld",
|
||||
&ExecuteJavaScriptInIsolatedWorld);
|
||||
dict.SetMethod("setIsolatedWorldSecurityOrigin",
|
||||
&SetIsolatedWorldSecurityOrigin);
|
||||
dict.SetMethod("setIsolatedWorldContentSecurityPolicy",
|
||||
&SetIsolatedWorldContentSecurityPolicy);
|
||||
dict.SetMethod("setIsolatedWorldHumanReadableName",
|
||||
&SetIsolatedWorldHumanReadableName);
|
||||
dict.SetMethod("getResourceUsage", &GetResourceUsage);
|
||||
dict.SetMethod("clearCache", &ClearCache);
|
||||
dict.SetMethod("_findFrameByRoutingId", &FindFrameByRoutingId);
|
||||
dict.SetMethod("_getFrameForSelector", &GetFrameForSelector);
|
||||
dict.SetMethod("_findFrameByName", &FindFrameByName);
|
||||
dict.SetMethod("_getOpener", &GetOpener);
|
||||
dict.SetMethod("_getParent", &GetFrameParent);
|
||||
dict.SetMethod("_getTop", &GetTop);
|
||||
dict.SetMethod("_getFirstChild", &GetFirstChild);
|
||||
dict.SetMethod("_getNextSibling", &GetNextSibling);
|
||||
dict.SetMethod("_getRoutingId", &GetRoutingId);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -1,110 +0,0 @@
|
||||
// Copyright (c) 2014 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_RENDERER_API_ATOM_API_WEB_FRAME_H_
|
||||
#define ATOM_RENDERER_API_ATOM_API_WEB_FRAME_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "native_mate/handle.h"
|
||||
#include "native_mate/wrappable.h"
|
||||
#include "third_party/blink/public/platform/web_cache.h"
|
||||
|
||||
namespace blink {
|
||||
class WebLocalFrame;
|
||||
}
|
||||
|
||||
namespace mate {
|
||||
class Dictionary;
|
||||
class Arguments;
|
||||
} // namespace mate
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
class WebFrame : public mate::Wrappable<WebFrame> {
|
||||
public:
|
||||
static mate::Handle<WebFrame> Create(v8::Isolate* isolate);
|
||||
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype);
|
||||
|
||||
private:
|
||||
explicit WebFrame(v8::Isolate* isolate);
|
||||
explicit WebFrame(v8::Isolate* isolate, blink::WebLocalFrame* blink_frame);
|
||||
~WebFrame() override;
|
||||
|
||||
void SetName(const std::string& name);
|
||||
|
||||
double SetZoomLevel(double level);
|
||||
double GetZoomLevel() const;
|
||||
double SetZoomFactor(double factor);
|
||||
double GetZoomFactor() const;
|
||||
|
||||
void SetVisualZoomLevelLimits(double min_level, double max_level);
|
||||
void SetLayoutZoomLevelLimits(double min_level, double max_level);
|
||||
|
||||
v8::Local<v8::Value> RegisterEmbedderCustomElement(
|
||||
v8::Local<v8::Object> context,
|
||||
const base::string16& name,
|
||||
v8::Local<v8::Object> options);
|
||||
int GetWebFrameId(v8::Local<v8::Value> content_window);
|
||||
|
||||
// Set the provider that will be used by SpellCheckClient for spell check.
|
||||
void SetSpellCheckProvider(mate::Arguments* args,
|
||||
const std::string& language,
|
||||
bool auto_spell_correct_turned_on,
|
||||
v8::Local<v8::Object> provider);
|
||||
|
||||
void RegisterURLSchemeAsBypassingCSP(const std::string& scheme);
|
||||
void RegisterURLSchemeAsPrivileged(const std::string& scheme,
|
||||
mate::Arguments* args);
|
||||
|
||||
// Editing.
|
||||
void InsertText(const std::string& text);
|
||||
void InsertCSS(const std::string& css);
|
||||
|
||||
// Executing scripts.
|
||||
void ExecuteJavaScript(const base::string16& code, mate::Arguments* args);
|
||||
void ExecuteJavaScriptInIsolatedWorld(
|
||||
int world_id,
|
||||
const std::vector<mate::Dictionary>& scripts,
|
||||
mate::Arguments* args);
|
||||
|
||||
// Isolated world related methods
|
||||
void SetIsolatedWorldSecurityOrigin(int world_id,
|
||||
const std::string& origin_url);
|
||||
void SetIsolatedWorldContentSecurityPolicy(
|
||||
int world_id,
|
||||
const std::string& security_policy);
|
||||
void SetIsolatedWorldHumanReadableName(int world_id, const std::string& name);
|
||||
|
||||
// Resource related methods
|
||||
blink::WebCache::ResourceTypeStats GetResourceUsage(v8::Isolate* isolate);
|
||||
void ClearCache(v8::Isolate* isolate);
|
||||
|
||||
// Frame navigation
|
||||
v8::Local<v8::Value> Opener() const;
|
||||
v8::Local<v8::Value> Parent() const;
|
||||
v8::Local<v8::Value> Top() const;
|
||||
v8::Local<v8::Value> FirstChild() const;
|
||||
v8::Local<v8::Value> NextSibling() const;
|
||||
v8::Local<v8::Value> GetFrameForSelector(const std::string& selector) const;
|
||||
v8::Local<v8::Value> FindFrameByName(const std::string& name) const;
|
||||
v8::Local<v8::Value> FindFrameByRoutingId(int routing_id) const;
|
||||
v8::Local<v8::Value> RoutingId() const;
|
||||
|
||||
blink::WebLocalFrame* web_frame_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(WebFrame);
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_RENDERER_API_ATOM_API_WEB_FRAME_H_
|
||||
@@ -158,6 +158,8 @@ void AtomSandboxedRendererClient::InitializeBindings(
|
||||
process.SetMethod("hang", AtomBindings::Hang);
|
||||
process.SetMethod("getHeapStatistics", &AtomBindings::GetHeapStatistics);
|
||||
process.SetMethod("getSystemMemoryInfo", &AtomBindings::GetSystemMemoryInfo);
|
||||
process.SetMethod("getProcessMemoryInfo",
|
||||
&AtomBindings::GetProcessMemoryInfo);
|
||||
process.SetMethod(
|
||||
"getCPUUsage",
|
||||
base::Bind(&AtomBindings::GetCPUUsage, base::Unretained(metrics_.get())));
|
||||
@@ -230,6 +232,8 @@ void AtomSandboxedRendererClient::DidCreateScriptContext(
|
||||
// Execute the function with proper arguments
|
||||
ignore_result(
|
||||
func->Call(context, v8::Null(isolate), node::arraysize(args), args));
|
||||
|
||||
InvokeIpcCallback(context, "onLoaded", std::vector<v8::Local<v8::Value>>());
|
||||
}
|
||||
|
||||
void AtomSandboxedRendererClient::WillReleaseScriptContext(
|
||||
|
||||
@@ -13,8 +13,6 @@
|
||||
|
||||
namespace brightray {
|
||||
|
||||
int g_identifier_ = 1;
|
||||
|
||||
CocoaNotification::CocoaNotification(NotificationDelegate* delegate,
|
||||
NotificationPresenter* presenter)
|
||||
: Notification(delegate, presenter) {}
|
||||
@@ -29,7 +27,9 @@ void CocoaNotification::Show(const NotificationOptions& options) {
|
||||
notification_.reset([[NSUserNotification alloc] init]);
|
||||
|
||||
NSString* identifier =
|
||||
[NSString stringWithFormat:@"ElectronNotification%d", g_identifier_++];
|
||||
[NSString stringWithFormat:@"%@:notification:%@",
|
||||
[[NSBundle mainBundle] bundleIdentifier],
|
||||
[[[NSUUID alloc] init] UUIDString]];
|
||||
|
||||
[notification_ setTitle:base::SysUTF16ToNSString(options.title)];
|
||||
[notification_ setSubtitle:base::SysUTF16ToNSString(options.subtitle)];
|
||||
@@ -115,6 +115,8 @@ void CocoaNotification::Dismiss() {
|
||||
NotificationDismissed();
|
||||
|
||||
this->LogAction("dismissed");
|
||||
|
||||
notification_.reset(nil);
|
||||
}
|
||||
|
||||
void CocoaNotification::NotificationDisplayed() {
|
||||
|
||||
@@ -20,10 +20,6 @@ std::string GetProductInternal() {
|
||||
GetApplicationVersion().c_str());
|
||||
}
|
||||
|
||||
std::string GetBrightrayUserAgent() {
|
||||
return content::BuildUserAgentFromProduct(GetProductInternal());
|
||||
}
|
||||
|
||||
ContentClient::ContentClient() {}
|
||||
|
||||
ContentClient::~ContentClient() {}
|
||||
@@ -32,10 +28,6 @@ std::string ContentClient::GetProduct() const {
|
||||
return GetProductInternal();
|
||||
}
|
||||
|
||||
std::string ContentClient::GetUserAgent() const {
|
||||
return GetBrightrayUserAgent();
|
||||
}
|
||||
|
||||
base::string16 ContentClient::GetLocalizedString(int message_id) const {
|
||||
return l10n_util::GetStringUTF16(message_id);
|
||||
}
|
||||
|
||||
@@ -21,7 +21,6 @@ class ContentClient : public content::ContentClient {
|
||||
|
||||
private:
|
||||
std::string GetProduct() const override;
|
||||
std::string GetUserAgent() const override;
|
||||
base::string16 GetLocalizedString(int message_id) const override;
|
||||
base::StringPiece GetDataResource(int resource_id,
|
||||
ui::ScaleFactor) const override;
|
||||
|
||||
@@ -12,5 +12,6 @@ proprietary_codecs = true
|
||||
ffmpeg_branding = "Chrome"
|
||||
|
||||
enable_basic_printing = true
|
||||
angle_enable_vulkan_validation_layers = false
|
||||
|
||||
is_cfi = false
|
||||
|
||||
@@ -422,6 +422,52 @@ Emitted when `remote.getGlobal()` is called in the renderer process of `webConte
|
||||
Calling `event.preventDefault()` will prevent the global from being returned.
|
||||
Custom value can be returned by setting `event.returnValue`.
|
||||
|
||||
### Event: 'remote-get-builtin'
|
||||
|
||||
Returns:
|
||||
|
||||
* `event` Event
|
||||
* `webContents` [WebContents](web-contents.md)
|
||||
* `moduleName` String
|
||||
|
||||
Emitted when `remote.getBuiltin()` is called in the renderer process of `webContents`.
|
||||
Calling `event.preventDefault()` will prevent the module from being returned.
|
||||
Custom value can be returned by setting `event.returnValue`.
|
||||
|
||||
### Event: 'remote-get-current-window'
|
||||
|
||||
Returns:
|
||||
|
||||
* `event` Event
|
||||
* `webContents` [WebContents](web-contents.md)
|
||||
|
||||
Emitted when `remote.getCurrentWindow()` is called in the renderer process of `webContents`.
|
||||
Calling `event.preventDefault()` will prevent the object from being returned.
|
||||
Custom value can be returned by setting `event.returnValue`.
|
||||
|
||||
### Event: 'remote-get-current-web-contents'
|
||||
|
||||
Returns:
|
||||
|
||||
* `event` Event
|
||||
* `webContents` [WebContents](web-contents.md)
|
||||
|
||||
Emitted when `remote.getCurrentWebContents()` is called in the renderer process of `webContents`.
|
||||
Calling `event.preventDefault()` will prevent the object from being returned.
|
||||
Custom value can be returned by setting `event.returnValue`.
|
||||
|
||||
### Event: 'remote-get-guest-web-contents'
|
||||
|
||||
Returns:
|
||||
|
||||
* `event` Event
|
||||
* `webContents` [WebContents](web-contents.md)
|
||||
* `guestWebContents` [WebContents](web-contents.md)
|
||||
|
||||
Emitted when `<webview>.getWebContents()` is called in the renderer process of `webContents`.
|
||||
Calling `event.preventDefault()` will prevent the object from being returned.
|
||||
Custom value can be returned by setting `event.returnValue`.
|
||||
|
||||
## Methods
|
||||
|
||||
The `app` object has the following methods:
|
||||
@@ -1215,6 +1261,15 @@ Sets the `image` associated with this dock icon.
|
||||
|
||||
## Properties
|
||||
|
||||
### `app.userAgentFallback`
|
||||
|
||||
A `String` which is the user agent string Electron will use as a global fallback.
|
||||
|
||||
This is the user agent that will be used when no user agent is set at the
|
||||
`webContents` or `session` level. Useful for ensuring your entire
|
||||
app has the same user agent. Set to a custom value as early as possible
|
||||
in your apps initialization to ensure that your overridden value is used.
|
||||
|
||||
### `app.isPackaged`
|
||||
|
||||
A `Boolean` property that returns `true` if the app is packaged, `false` otherwise. For many apps, this property can be used to distinguish development and production environments.
|
||||
|
||||
@@ -79,7 +79,7 @@ with `callback(error, cookies)` on complete.
|
||||
* `url` String - The url to associate the cookie with.
|
||||
* `name` String (optional) - The name of the cookie. Empty by default if omitted.
|
||||
* `value` String (optional) - The value of the cookie. Empty by default if omitted.
|
||||
* `domain` String (optional) - The domain of the cookie. Empty by default if omitted.
|
||||
* `domain` String (optional) - The domain of the cookie; this will be normalized with a preceding dot so that it's also valid for subdomains. Empty by default if omitted.
|
||||
* `path` String (optional) - The path of the cookie. Empty by default if omitted.
|
||||
* `secure` Boolean (optional) - Whether the cookie should be marked as Secure. Defaults to
|
||||
false.
|
||||
|
||||
@@ -95,8 +95,7 @@ them will get reported without `companyName`, `productName` or any of the `extra
|
||||
|
||||
Returns [`CrashReport`](structures/crash-report.md):
|
||||
|
||||
Returns the date and ID of the last crash report. If no crash reports have been
|
||||
sent or the crash reporter has not been started, `null` is returned.
|
||||
Returns the date and ID of the last crash report. Only crash reports that have been uploaded will be returned; even if a crash report is present on disk it will not be returned until it is uploaded. In the case that there are no uploaded reports, `null` is returned.
|
||||
|
||||
### `crashReporter.getUploadedReports()`
|
||||
|
||||
|
||||
@@ -92,3 +92,9 @@ objects, each `DesktopCapturerSource` represents a screen or an individual windo
|
||||
captured.
|
||||
|
||||
[`navigator.mediaDevices.getUserMedia`]: https://developer.mozilla.org/en/docs/Web/API/MediaDevices/getUserMedia
|
||||
|
||||
### Caveats
|
||||
|
||||
`navigator.mediaDevices.getUserMedia` does not work on macOS for audio capture due to a fundamental limitation whereby apps that want to access the system's audio require a [signed kernel extension](https://developer.apple.com/library/archive/documentation/Security/Conceptual/System_Integrity_Protection_Guide/KernelExtensions/KernelExtensions.html). Chromium, and by extension Electron, does not provide this.
|
||||
|
||||
It is possible to circumvent this limitation by capturing system audio with another macOS app like Soundflower and passing it through a virtual audio input device. This virtual device can then be queried with `navigator.mediaDevices.getUserMedia`.
|
||||
@@ -55,7 +55,7 @@ The `dialog` module has the following methods:
|
||||
* `filePaths` String[] - An array of file paths chosen by the user
|
||||
* `bookmarks` String[] _macOS_ _mas_ - An array matching the `filePaths` array of base64 encoded strings which contains security scoped bookmark data. `securityScopedBookmarks` must be enabled for this to be populated.
|
||||
|
||||
Returns `String[]`, an array of file paths chosen by the user,
|
||||
Returns `String[] | undefined`, an array of file paths chosen by the user,
|
||||
if the callback is provided it returns `undefined`.
|
||||
|
||||
The `browserWindow` argument allows the dialog to attach itself to a parent window, making it modal.
|
||||
@@ -106,8 +106,8 @@ shown.
|
||||
* `filename` String
|
||||
* `bookmark` String _macOS_ _mas_ - Base64 encoded string which contains the security scoped bookmark data for the saved file. `securityScopedBookmarks` must be enabled for this to be present.
|
||||
|
||||
Returns `String`, the path of the file chosen by the user,
|
||||
if a callback is provided it returns `undefined`.
|
||||
Returns `String | undefined`, the path of the file chosen by the user,
|
||||
if a callback is provided or the dialog is cancelled it returns `undefined`.
|
||||
|
||||
The `browserWindow` argument allows the dialog to attach itself to a parent window, making it modal.
|
||||
|
||||
|
||||
@@ -185,6 +185,12 @@ The `hslShift` is applied to the image with the following rules
|
||||
This means that `[-1, 0, 1]` will make the image completely white and
|
||||
`[-1, 1, 0]` will make the image completely black.
|
||||
|
||||
In some cases, the `NSImageName` doesn't match its string representation; one example of this is `NSFolderImageName`, whose string representation would actually be `NSFolder`. Therefore, you'll need to determine the correct string representation for your image before passing it in. This can be done with the following:
|
||||
|
||||
`echo -e '#import <Cocoa/Cocoa.h>\nint main() { NSLog(@"%@", SYSTEM_IMAGE_NAME); }' | clang -otest -x objective-c -framework Cocoa - && ./test`
|
||||
|
||||
where `SYSTEM_IMAGE_NAME` should be replaced with any value from [this list](https://developer.apple.com/documentation/appkit/nsimagename?language=objc).
|
||||
|
||||
## Class: NativeImage
|
||||
|
||||
> Natively wrap images such as tray, dock, and application icons.
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
* `name` String - The name of the cookie.
|
||||
* `value` String - The value of the cookie.
|
||||
* `domain` String (optional) - The domain of the cookie.
|
||||
* `hostOnly` Boolean (optional) - Whether the cookie is a host-only cookie.
|
||||
* `domain` String (optional) - The domain of the cookie; this will be normalized with a preceding dot so that it's also valid for subdomains.
|
||||
* `hostOnly` Boolean (optional) - Whether the cookie is a host-only cookie; this will only be `true` if no domain was passed.
|
||||
* `path` String (optional) - The path of the cookie.
|
||||
* `secure` Boolean (optional) - Whether the cookie is marked as secure.
|
||||
* `httpOnly` Boolean (optional) - Whether the cookie is marked as HTTP only.
|
||||
|
||||
@@ -138,11 +138,16 @@ new [`BrowserWindow`](browser-window.md). If you call `event.preventDefault()` a
|
||||
instance, failing to do so may result in unexpected behavior. For example:
|
||||
|
||||
```javascript
|
||||
myBrowserWindow.webContents.on('new-window', (event, url) => {
|
||||
myBrowserWindow.webContents.on('new-window', (event, url, frameName, disposition, options) => {
|
||||
event.preventDefault()
|
||||
const win = new BrowserWindow({ show: false })
|
||||
const win = new BrowserWindow({
|
||||
webContents: options.webContents, // use existing webContents if provided
|
||||
show: false
|
||||
})
|
||||
win.once('ready-to-show', () => win.show())
|
||||
win.loadURL(url)
|
||||
if (!options.webContents) {
|
||||
win.loadURL(url) // existing webContents will be navigated automatically
|
||||
}
|
||||
event.newGuest = win
|
||||
})
|
||||
```
|
||||
@@ -685,6 +690,48 @@ Emitted when `remote.getGlobal()` is called in the renderer process.
|
||||
Calling `event.preventDefault()` will prevent the global from being returned.
|
||||
Custom value can be returned by setting `event.returnValue`.
|
||||
|
||||
#### Event: 'remote-get-builtin'
|
||||
|
||||
Returns:
|
||||
|
||||
* `event` Event
|
||||
* `moduleName` String
|
||||
|
||||
Emitted when `remote.getBuiltin()` is called in the renderer process.
|
||||
Calling `event.preventDefault()` will prevent the module from being returned.
|
||||
Custom value can be returned by setting `event.returnValue`.
|
||||
|
||||
#### Event: 'remote-get-current-window'
|
||||
|
||||
Returns:
|
||||
|
||||
* `event` Event
|
||||
|
||||
Emitted when `remote.getCurrentWindow()` is called in the renderer process.
|
||||
Calling `event.preventDefault()` will prevent the object from being returned.
|
||||
Custom value can be returned by setting `event.returnValue`.
|
||||
|
||||
#### Event: 'remote-get-current-web-contents'
|
||||
|
||||
Returns:
|
||||
|
||||
* `event` Event
|
||||
|
||||
Emitted when `remote.getCurrentWebContents()` is called in the renderer process.
|
||||
Calling `event.preventDefault()` will prevent the object from being returned.
|
||||
Custom value can be returned by setting `event.returnValue`.
|
||||
|
||||
#### Event: 'remote-get-guest-web-contents'
|
||||
|
||||
Returns:
|
||||
|
||||
* `event` Event
|
||||
* `guestWebContents` [WebContents](web-contents.md)
|
||||
|
||||
Emitted when `<webview>.getWebContents()` is called in the renderer process.
|
||||
Calling `event.preventDefault()` will prevent the object from being returned.
|
||||
Custom value can be returned by setting `event.returnValue`.
|
||||
|
||||
### Instance Methods
|
||||
|
||||
#### `contents.loadURL(url[, options])`
|
||||
@@ -1540,6 +1587,10 @@ Takes a V8 heap snapshot and saves it to `filePath`.
|
||||
Controls whether or not this WebContents will throttle animations and timers
|
||||
when the page becomes backgrounded. This also affects the Page Visibility API.
|
||||
|
||||
#### `contents.getType()`
|
||||
|
||||
Returns `String` - the type of the webContent. Can be `backgroundPage`, `window`, `browserView`, `remote`, `webview` or `offscreen`.
|
||||
|
||||
### Instance Properties
|
||||
|
||||
#### `contents.id`
|
||||
|
||||
@@ -866,10 +866,6 @@ ipcRenderer.on('ping', () => {
|
||||
|
||||
Fired when the renderer process is crashed.
|
||||
|
||||
### Event: 'gpu-crashed'
|
||||
|
||||
Fired when the gpu process is crashed.
|
||||
|
||||
### Event: 'plugin-crashed'
|
||||
|
||||
Returns:
|
||||
|
||||
@@ -41,6 +41,7 @@ filenames = {
|
||||
"lib/browser/api/web-contents.js",
|
||||
"lib/browser/api/web-contents-view.js",
|
||||
"lib/browser/chrome-extension.js",
|
||||
"lib/browser/crash-reporter-init.js",
|
||||
"lib/browser/guest-view-manager.js",
|
||||
"lib/browser/guest-window-manager.js",
|
||||
"lib/browser/init.js",
|
||||
@@ -559,7 +560,6 @@ filenames = {
|
||||
"atom/renderer/api/atom_api_spell_check_client.cc",
|
||||
"atom/renderer/api/atom_api_spell_check_client.h",
|
||||
"atom/renderer/api/atom_api_web_frame.cc",
|
||||
"atom/renderer/api/atom_api_web_frame.h",
|
||||
"atom/renderer/atom_autofill_agent.cc",
|
||||
"atom/renderer/atom_autofill_agent.h",
|
||||
"atom/renderer/atom_render_frame_observer.cc",
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
'use strict'
|
||||
|
||||
const CrashReporter = require('@electron/internal/common/crash-reporter')
|
||||
const ipcMain = require('@electron/internal/browser/ipc-main-internal')
|
||||
const { crashReporterInit } = require('@electron/internal/browser/crash-reporter-init')
|
||||
|
||||
class CrashReporterMain extends CrashReporter {
|
||||
sendSync (channel, ...args) {
|
||||
const event = {}
|
||||
ipcMain.emit(channel, event, ...args)
|
||||
return event.returnValue
|
||||
init (options) {
|
||||
return crashReporterInit(options)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -263,7 +263,8 @@ module.exports = {
|
||||
|
||||
// Choose a default button to get selected when dialog is cancelled.
|
||||
if (cancelId == null) {
|
||||
cancelId = 0
|
||||
// If the defaultId is set to 0, ensure the cancel button is a different index (1)
|
||||
cancelId = (defaultId === 0 && buttons.length > 1) ? 1 : 0
|
||||
for (let i = 0; i < buttons.length; i++) {
|
||||
const text = buttons[i].toLowerCase()
|
||||
if (text === 'cancel' || text === 'no') {
|
||||
|
||||
@@ -109,6 +109,12 @@ Menu.prototype.insert = function (pos, item) {
|
||||
throw new TypeError('Invalid item')
|
||||
}
|
||||
|
||||
if (pos < 0) {
|
||||
throw new RangeError(`Position ${pos} cannot be less than 0`)
|
||||
} else if (pos > this.getItemCount()) {
|
||||
throw new RangeError(`Position ${pos} cannot be greater than the total MenuItem count`)
|
||||
}
|
||||
|
||||
// insert item depending on its type
|
||||
insertItemByType.call(this, item, pos)
|
||||
|
||||
|
||||
@@ -10,8 +10,12 @@ Object.setPrototypeOf(module.exports, new Proxy({}, {
|
||||
if (!app.isReady()) return
|
||||
|
||||
const netLog = session.defaultSession.netLog
|
||||
|
||||
if (!Object.getPrototypeOf(netLog).hasOwnProperty(property)) return
|
||||
|
||||
// check for properties on the prototype chain that aren't functions
|
||||
if (typeof netLog[property] !== 'function') return netLog[property]
|
||||
|
||||
// Returning a native function directly would throw error.
|
||||
return (...args) => netLog[property](...args)
|
||||
},
|
||||
|
||||
@@ -263,7 +263,7 @@ WebContents.prototype.printToPDF = function (options, callback) {
|
||||
|
||||
WebContents.prototype.print = function (...args) {
|
||||
if (features.isPrintingEnabled()) {
|
||||
this._print(args)
|
||||
this._print(...args)
|
||||
} else {
|
||||
console.error('Error: Printing feature is disabled.')
|
||||
}
|
||||
@@ -321,6 +321,17 @@ WebContents.prototype.findInPage = function (text, options = {}) {
|
||||
return this._findInPage(text, options)
|
||||
}
|
||||
|
||||
const safeProtocols = new Set([
|
||||
'chrome-devtools:',
|
||||
'chrome-extension:'
|
||||
])
|
||||
|
||||
const isWebContentsTrusted = function (contents) {
|
||||
const pageURL = contents._getURL()
|
||||
const { protocol } = url.parse(pageURL)
|
||||
return safeProtocols.has(protocol)
|
||||
}
|
||||
|
||||
// Add JavaScript wrappers for WebContents class.
|
||||
WebContents.prototype._init = function () {
|
||||
// The navigation controller.
|
||||
@@ -369,13 +380,22 @@ WebContents.prototype._init = function () {
|
||||
})
|
||||
})
|
||||
|
||||
this.on('remote-require', (event, ...args) => {
|
||||
app.emit('remote-require', event, this, ...args)
|
||||
})
|
||||
const forwardedEvents = [
|
||||
'remote-require',
|
||||
'remote-get-global',
|
||||
'remote-get-builtin',
|
||||
'remote-get-current-window',
|
||||
'remote-get-current-web-contents',
|
||||
'remote-get-guest-web-contents'
|
||||
]
|
||||
|
||||
this.on('remote-get-global', (event, ...args) => {
|
||||
app.emit('remote-get-global', event, this, ...args)
|
||||
})
|
||||
for (const eventName of forwardedEvents) {
|
||||
this.on(eventName, (event, ...args) => {
|
||||
if (!isWebContentsTrusted(event.sender)) {
|
||||
app.emit(eventName, event, this, ...args)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
deprecate.event(this, 'did-get-response-details', '-did-get-response-details')
|
||||
deprecate.event(this, 'did-get-redirect-request', '-did-get-redirect-request')
|
||||
|
||||
46
lib/browser/crash-reporter-init.js
Normal file
46
lib/browser/crash-reporter-init.js
Normal file
@@ -0,0 +1,46 @@
|
||||
'use strict'
|
||||
|
||||
const { app } = require('electron')
|
||||
const cp = require('child_process')
|
||||
const os = require('os')
|
||||
const path = require('path')
|
||||
|
||||
const getTempDirectory = function () {
|
||||
try {
|
||||
return app.getPath('temp')
|
||||
} catch (error) {
|
||||
return os.tmpdir()
|
||||
}
|
||||
}
|
||||
|
||||
exports.crashReporterInit = function (options) {
|
||||
const productName = options.productName || app.getName()
|
||||
const crashesDirectory = path.join(getTempDirectory(), `${productName} Crashes`)
|
||||
let crashServicePid
|
||||
|
||||
if (process.platform === 'win32') {
|
||||
const env = {
|
||||
ELECTRON_INTERNAL_CRASH_SERVICE: 1
|
||||
}
|
||||
const args = [
|
||||
'--reporter-url=' + options.submitURL,
|
||||
'--application-name=' + productName,
|
||||
'--crashes-directory=' + crashesDirectory,
|
||||
'--v=1'
|
||||
]
|
||||
|
||||
const crashServiceProcess = cp.spawn(process.helperExecPath, args, {
|
||||
env,
|
||||
detached: true
|
||||
})
|
||||
|
||||
crashServicePid = crashServiceProcess.pid
|
||||
}
|
||||
|
||||
return {
|
||||
productName,
|
||||
crashesDirectory,
|
||||
crashServicePid,
|
||||
appVersion: app.getVersion()
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,11 @@ const { webContents } = require('electron')
|
||||
const ipcMain = require('@electron/internal/browser/ipc-main-internal')
|
||||
const parseFeaturesString = require('@electron/internal/common/parse-features-string')
|
||||
const errorUtils = require('@electron/internal/common/error-utils')
|
||||
const { syncMethods, asyncMethods } = require('@electron/internal/common/web-view-methods')
|
||||
const {
|
||||
syncMethods,
|
||||
asyncCallbackMethods,
|
||||
asyncPromiseMethods
|
||||
} = require('@electron/internal/common/web-view-methods')
|
||||
|
||||
// Doesn't exist in early initialization.
|
||||
let webViewManager = null
|
||||
@@ -32,7 +36,6 @@ const supportedWebViewEvents = [
|
||||
'focus-change',
|
||||
'close',
|
||||
'crashed',
|
||||
'gpu-crashed',
|
||||
'plugin-crashed',
|
||||
'destroyed',
|
||||
'page-title-updated',
|
||||
@@ -391,7 +394,7 @@ ipcMain.on('ELECTRON_GUEST_VIEW_MANAGER_FOCUS_CHANGE', function (event, focus, g
|
||||
handleMessage('ELECTRON_GUEST_VIEW_MANAGER_ASYNC_CALL', function (event, requestId, guestInstanceId, method, args, hasCallback) {
|
||||
new Promise(resolve => {
|
||||
const guest = getGuestForWebContents(guestInstanceId, event.sender)
|
||||
if (!asyncMethods.has(method)) {
|
||||
if (!asyncCallbackMethods.has(method) && !asyncPromiseMethods.has(method)) {
|
||||
throw new Error(`Invalid method: ${method}`)
|
||||
}
|
||||
if (hasCallback) {
|
||||
|
||||
@@ -1,16 +1,14 @@
|
||||
'use strict'
|
||||
|
||||
const { spawn } = require('child_process')
|
||||
const electron = require('electron')
|
||||
const { EventEmitter } = require('events')
|
||||
const fs = require('fs')
|
||||
const os = require('os')
|
||||
const path = require('path')
|
||||
const v8Util = process.atomBinding('v8_util')
|
||||
const eventBinding = process.atomBinding('event')
|
||||
|
||||
const { isPromise } = electron
|
||||
|
||||
const { crashReporterInit } = require('@electron/internal/browser/crash-reporter-init')
|
||||
const ipcMain = require('@electron/internal/browser/ipc-main-internal')
|
||||
const objectsRegistry = require('@electron/internal/browser/objects-registry')
|
||||
const guestViewManager = require('@electron/internal/browser/guest-view-manager')
|
||||
@@ -296,42 +294,75 @@ handleRemoteCommand('ELECTRON_BROWSER_REQUIRE', function (event, contextId, modu
|
||||
const customEvent = eventBinding.createWithSender(event.sender)
|
||||
event.sender.emit('remote-require', customEvent, moduleName)
|
||||
|
||||
if (customEvent.defaultPrevented) {
|
||||
if (typeof customEvent.returnValue === 'undefined') {
|
||||
throw new Error(`Invalid module: ${moduleName}`)
|
||||
if (customEvent.returnValue === undefined) {
|
||||
if (customEvent.defaultPrevented) {
|
||||
throw new Error(`Blocked remote.require('${moduleName}')`)
|
||||
} else {
|
||||
customEvent.returnValue = process.mainModule.require(moduleName)
|
||||
}
|
||||
} else {
|
||||
customEvent.returnValue = process.mainModule.require(moduleName)
|
||||
}
|
||||
|
||||
return valueToMeta(event.sender, contextId, customEvent.returnValue)
|
||||
})
|
||||
|
||||
handleRemoteCommand('ELECTRON_BROWSER_GET_BUILTIN', function (event, contextId, module) {
|
||||
return valueToMeta(event.sender, contextId, electron[module])
|
||||
handleRemoteCommand('ELECTRON_BROWSER_GET_BUILTIN', function (event, contextId, moduleName) {
|
||||
const customEvent = eventBinding.createWithSender(event.sender)
|
||||
event.sender.emit('remote-get-builtin', customEvent, moduleName)
|
||||
|
||||
if (customEvent.returnValue === undefined) {
|
||||
if (customEvent.defaultPrevented) {
|
||||
throw new Error(`Blocked remote.getBuiltin('${moduleName}')`)
|
||||
} else {
|
||||
customEvent.returnValue = electron[moduleName]
|
||||
}
|
||||
}
|
||||
|
||||
return valueToMeta(event.sender, contextId, customEvent.returnValue)
|
||||
})
|
||||
|
||||
handleRemoteCommand('ELECTRON_BROWSER_GLOBAL', function (event, contextId, globalName) {
|
||||
const customEvent = eventBinding.createWithSender(event.sender)
|
||||
event.sender.emit('remote-get-global', customEvent, globalName)
|
||||
|
||||
if (customEvent.defaultPrevented) {
|
||||
if (typeof customEvent.returnValue === 'undefined') {
|
||||
throw new Error(`Invalid global: ${globalName}`)
|
||||
if (customEvent.returnValue === undefined) {
|
||||
if (customEvent.defaultPrevented) {
|
||||
throw new Error(`Blocked remote.getGlobal('${globalName}')`)
|
||||
} else {
|
||||
customEvent.returnValue = global[globalName]
|
||||
}
|
||||
} else {
|
||||
customEvent.returnValue = global[globalName]
|
||||
}
|
||||
|
||||
return valueToMeta(event.sender, contextId, customEvent.returnValue)
|
||||
})
|
||||
|
||||
handleRemoteCommand('ELECTRON_BROWSER_CURRENT_WINDOW', function (event, contextId) {
|
||||
return valueToMeta(event.sender, contextId, event.sender.getOwnerBrowserWindow())
|
||||
const customEvent = eventBinding.createWithSender(event.sender)
|
||||
event.sender.emit('remote-get-current-window', customEvent)
|
||||
|
||||
if (customEvent.returnValue === undefined) {
|
||||
if (customEvent.defaultPrevented) {
|
||||
throw new Error('Blocked remote.getCurrentWindow()')
|
||||
} else {
|
||||
customEvent.returnValue = event.sender.getOwnerBrowserWindow()
|
||||
}
|
||||
}
|
||||
|
||||
return valueToMeta(event.sender, contextId, customEvent.returnValue)
|
||||
})
|
||||
|
||||
handleRemoteCommand('ELECTRON_BROWSER_CURRENT_WEB_CONTENTS', function (event, contextId) {
|
||||
return valueToMeta(event.sender, contextId, event.sender)
|
||||
const customEvent = eventBinding.createWithSender(event.sender)
|
||||
event.sender.emit('remote-get-current-web-contents', customEvent)
|
||||
|
||||
if (customEvent.returnValue === undefined) {
|
||||
if (customEvent.defaultPrevented) {
|
||||
throw new Error('Blocked remote.getCurrentWebContents()')
|
||||
} else {
|
||||
customEvent.returnValue = event.sender
|
||||
}
|
||||
}
|
||||
|
||||
return valueToMeta(event.sender, contextId, customEvent.returnValue)
|
||||
})
|
||||
|
||||
handleRemoteCommand('ELECTRON_BROWSER_CONSTRUCTOR', function (event, contextId, id, args) {
|
||||
@@ -411,7 +442,19 @@ handleRemoteCommand('ELECTRON_BROWSER_CONTEXT_RELEASE', (event, contextId) => {
|
||||
|
||||
handleRemoteCommand('ELECTRON_BROWSER_GUEST_WEB_CONTENTS', function (event, contextId, guestInstanceId) {
|
||||
const guest = guestViewManager.getGuestForWebContents(guestInstanceId, event.sender)
|
||||
return valueToMeta(event.sender, contextId, guest)
|
||||
|
||||
const customEvent = eventBinding.createWithSender(event.sender)
|
||||
event.sender.emit('remote-get-guest-web-contents', customEvent, guest)
|
||||
|
||||
if (customEvent.returnValue === undefined) {
|
||||
if (customEvent.defaultPrevented) {
|
||||
throw new Error(`Blocked remote.getGuestForWebContents()`)
|
||||
} else {
|
||||
customEvent.returnValue = guest
|
||||
}
|
||||
}
|
||||
|
||||
return valueToMeta(event.sender, contextId, customEvent.returnValue)
|
||||
})
|
||||
|
||||
// Implements window.close()
|
||||
@@ -423,46 +466,6 @@ ipcMain.on('ELECTRON_BROWSER_WINDOW_CLOSE', function (event) {
|
||||
event.returnValue = null
|
||||
})
|
||||
|
||||
const getTempDirectory = function () {
|
||||
try {
|
||||
return electron.app.getPath('temp')
|
||||
} catch (error) {
|
||||
return os.tmpdir()
|
||||
}
|
||||
}
|
||||
|
||||
const crashReporterInit = function (options) {
|
||||
const productName = options.productName || electron.app.getName()
|
||||
const crashesDirectory = path.join(getTempDirectory(), `${productName} Crashes`)
|
||||
let crashServicePid
|
||||
|
||||
if (process.platform === 'win32') {
|
||||
const env = {
|
||||
ELECTRON_INTERNAL_CRASH_SERVICE: 1
|
||||
}
|
||||
const args = [
|
||||
'--reporter-url=' + options.submitURL,
|
||||
'--application-name=' + productName,
|
||||
'--crashes-directory=' + crashesDirectory,
|
||||
'--v=1'
|
||||
]
|
||||
|
||||
const crashServiceProcess = spawn(process.helperExecPath, args, {
|
||||
env,
|
||||
detached: true
|
||||
})
|
||||
|
||||
crashServicePid = crashServiceProcess.pid
|
||||
}
|
||||
|
||||
return {
|
||||
productName,
|
||||
crashesDirectory,
|
||||
crashServicePid,
|
||||
appVersion: electron.app.getVersion()
|
||||
}
|
||||
}
|
||||
|
||||
const setReturnValue = function (event, getValue) {
|
||||
try {
|
||||
event.returnValue = [null, getValue()]
|
||||
@@ -487,20 +490,27 @@ ipcMain.on('ELECTRON_BROWSER_CLIPBOARD_WRITE_FIND_TEXT', function (event, text)
|
||||
setReturnValue(event, () => electron.clipboard.writeFindText(text))
|
||||
})
|
||||
|
||||
ipcMain.on('ELECTRON_BROWSER_SANDBOX_LOAD', function (event) {
|
||||
const preloadPath = event.sender._getPreloadPath()
|
||||
const getPreloadScript = function (preloadPath) {
|
||||
let preloadSrc = null
|
||||
let preloadError = null
|
||||
if (preloadPath) {
|
||||
try {
|
||||
preloadSrc = fs.readFileSync(preloadPath).toString()
|
||||
} catch (err) {
|
||||
preloadError = { stack: err ? err.stack : (new Error(`Failed to load "${preloadPath}"`)).stack }
|
||||
preloadError = errorUtils.serialize(err)
|
||||
}
|
||||
}
|
||||
return { preloadPath, preloadSrc, preloadError }
|
||||
}
|
||||
|
||||
ipcMain.on('ELECTRON_BROWSER_SANDBOX_LOAD', function (event) {
|
||||
const preloadPaths = [
|
||||
...(event.sender.session ? event.sender.session.getPreloads() : []),
|
||||
event.sender._getPreloadPath()
|
||||
]
|
||||
|
||||
event.returnValue = {
|
||||
preloadSrc,
|
||||
preloadError,
|
||||
preloadScripts: preloadPaths.map(path => getPreloadScript(path)),
|
||||
isRemoteModuleEnabled: event.sender._isRemoteModuleEnabled(),
|
||||
process: {
|
||||
arch: process.arch,
|
||||
|
||||
@@ -2,28 +2,16 @@
|
||||
|
||||
const binding = process.atomBinding('crash_reporter')
|
||||
|
||||
const errorUtils = require('@electron/internal/common/error-utils')
|
||||
|
||||
class CrashReporter {
|
||||
contructor () {
|
||||
this.productName = null
|
||||
this.crashesDirectory = null
|
||||
}
|
||||
|
||||
sendSync (channel, ...args) {
|
||||
init (options) {
|
||||
throw new Error('Not implemented')
|
||||
}
|
||||
|
||||
invoke (command, ...args) {
|
||||
const [ error, result ] = this.sendSync(command, ...args)
|
||||
|
||||
if (error) {
|
||||
throw errorUtils.deserialize(error)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
start (options) {
|
||||
if (options == null) options = {}
|
||||
|
||||
@@ -51,7 +39,7 @@ class CrashReporter {
|
||||
throw new Error('submitURL is a required option to crashReporter.start')
|
||||
}
|
||||
|
||||
const ret = this.invoke('ELECTRON_CRASH_REPORTER_INIT', {
|
||||
const ret = this.init({
|
||||
submitURL,
|
||||
productName
|
||||
})
|
||||
|
||||
@@ -50,18 +50,20 @@ exports.syncMethods = new Set([
|
||||
'setZoomLevel'
|
||||
])
|
||||
|
||||
exports.asyncMethods = new Set([
|
||||
exports.asyncCallbackMethods = new Set([
|
||||
'insertCSS',
|
||||
'insertText',
|
||||
'send',
|
||||
'sendInputEvent',
|
||||
'setLayoutZoomLevelLimits',
|
||||
'setVisualZoomLevelLimits',
|
||||
// with callback
|
||||
'capturePage',
|
||||
'executeJavaScript',
|
||||
'getZoomFactor',
|
||||
'getZoomLevel',
|
||||
'print',
|
||||
'printToPDF'
|
||||
])
|
||||
|
||||
exports.asyncPromiseMethods = new Set([
|
||||
'capturePage',
|
||||
'executeJavaScript'
|
||||
])
|
||||
|
||||
@@ -2,10 +2,21 @@
|
||||
|
||||
const CrashReporter = require('@electron/internal/common/crash-reporter')
|
||||
const ipcRenderer = require('@electron/internal/renderer/ipc-renderer-internal')
|
||||
const errorUtils = require('@electron/internal/common/error-utils')
|
||||
|
||||
const invoke = function (command, ...args) {
|
||||
const [ error, result ] = ipcRenderer.sendSync(command, ...args)
|
||||
|
||||
if (error) {
|
||||
throw errorUtils.deserialize(error)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
class CrashReporterRenderer extends CrashReporter {
|
||||
sendSync (channel, ...args) {
|
||||
return ipcRenderer.sendSync(channel, ...args)
|
||||
init (options) {
|
||||
return invoke('ELECTRON_CRASH_REPORTER_INIT', options)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,13 +1,67 @@
|
||||
'use strict'
|
||||
|
||||
const { EventEmitter } = require('events')
|
||||
const { webFrame, WebFrame } = process.atomBinding('web_frame')
|
||||
const binding = process.atomBinding('web_frame')
|
||||
|
||||
// WebFrame is an EventEmitter.
|
||||
Object.setPrototypeOf(WebFrame.prototype, EventEmitter.prototype)
|
||||
EventEmitter.call(webFrame)
|
||||
class WebFrame extends EventEmitter {
|
||||
constructor (context) {
|
||||
super()
|
||||
|
||||
// Lots of webview would subscribe to webFrame's events.
|
||||
webFrame.setMaxListeners(0)
|
||||
this.context = context
|
||||
// Lots of webview would subscribe to webFrame's events.
|
||||
this.setMaxListeners(0)
|
||||
}
|
||||
|
||||
module.exports = webFrame
|
||||
findFrameByRoutingId (...args) {
|
||||
return getWebFrame(binding._findFrameByRoutingId(this.context, ...args))
|
||||
}
|
||||
|
||||
getFrameForSelector (...args) {
|
||||
return getWebFrame(binding._getFrameForSelector(this.context, ...args))
|
||||
}
|
||||
|
||||
findFrameByName (...args) {
|
||||
return getWebFrame(binding._findFrameByName(this.context, ...args))
|
||||
}
|
||||
|
||||
get opener () {
|
||||
return getWebFrame(binding._getOpener(this.context))
|
||||
}
|
||||
|
||||
get parent () {
|
||||
return getWebFrame(binding._getParent(this.context))
|
||||
}
|
||||
|
||||
get top () {
|
||||
return getWebFrame(binding._getTop(this.context))
|
||||
}
|
||||
|
||||
get firstChild () {
|
||||
return getWebFrame(binding._getFirstChild(this.context))
|
||||
}
|
||||
|
||||
get nextSibling () {
|
||||
return getWebFrame(binding._getNextSibling(this.context))
|
||||
}
|
||||
|
||||
get routingId () {
|
||||
return binding._getRoutingId(this.context)
|
||||
}
|
||||
}
|
||||
|
||||
// Populate the methods.
|
||||
for (const name in binding) {
|
||||
if (!name.startsWith('_')) { // some methods are manully populated above
|
||||
WebFrame.prototype[name] = function (...args) {
|
||||
return binding[name](this.context, ...args)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Helper to return WebFrame or null depending on context.
|
||||
// TODO(zcbenz): Consider returning same WebFrame for the same context.
|
||||
function getWebFrame (context) {
|
||||
return context ? new WebFrame(context) : null
|
||||
}
|
||||
|
||||
module.exports = new WebFrame(window)
|
||||
|
||||
@@ -4,8 +4,6 @@ const ipcRenderer = require('@electron/internal/renderer/ipc-renderer-internal')
|
||||
const Event = require('@electron/internal/renderer/extensions/event')
|
||||
const url = require('url')
|
||||
|
||||
let nextId = 0
|
||||
|
||||
class Tab {
|
||||
constructor (tabId) {
|
||||
this.id = tabId
|
||||
@@ -146,14 +144,12 @@ exports.injectTo = function (extensionId, isBackgroundPage, context) {
|
||||
}
|
||||
|
||||
chrome.tabs = {
|
||||
executeScript (tabId, details, callback) {
|
||||
const requestId = ++nextId
|
||||
ipcRenderer.once(`CHROME_TABS_EXECUTESCRIPT_RESULT_${requestId}`, (event, result) => {
|
||||
// Disabled due to false positive in StandardJS
|
||||
// eslint-disable-next-line standard/no-callback-literal
|
||||
callback([event.result])
|
||||
})
|
||||
ipcRenderer.send('CHROME_TABS_EXECUTESCRIPT', requestId, tabId, extensionId, details)
|
||||
executeScript (tabId, details, resultCallback) {
|
||||
if (resultCallback) {
|
||||
ipcRenderer.once(`CHROME_TABS_EXECUTESCRIPT_RESULT_${originResultID}`, (event, result) => resultCallback([result]))
|
||||
}
|
||||
ipcRenderer.send('CHROME_TABS_EXECUTESCRIPT', originResultID, tabId, extensionId, details)
|
||||
originResultID++
|
||||
},
|
||||
|
||||
sendMessage (tabId, message, options, responseCallback) {
|
||||
|
||||
@@ -28,7 +28,6 @@ const WEB_VIEW_EVENTS = {
|
||||
'focus-change': ['focus', 'guestInstanceId'],
|
||||
'close': [],
|
||||
'crashed': [],
|
||||
'gpu-crashed': [],
|
||||
'plugin-crashed': ['name', 'version'],
|
||||
'destroyed': [],
|
||||
'page-title-updated': ['title', 'explicitSet'],
|
||||
|
||||
@@ -7,7 +7,11 @@ const ipcRenderer = require('@electron/internal/renderer/ipc-renderer-internal')
|
||||
const guestViewInternal = require('@electron/internal/renderer/web-view/guest-view-internal')
|
||||
const webViewConstants = require('@electron/internal/renderer/web-view/web-view-constants')
|
||||
const errorUtils = require('@electron/internal/common/error-utils')
|
||||
const { syncMethods, asyncMethods } = require('@electron/internal/common/web-view-methods')
|
||||
const {
|
||||
syncMethods,
|
||||
asyncCallbackMethods,
|
||||
asyncPromiseMethods
|
||||
} = require('@electron/internal/common/web-view-methods')
|
||||
|
||||
// ID generator.
|
||||
let nextId = 0
|
||||
@@ -268,10 +272,36 @@ const registerWebViewElement = (window) => {
|
||||
ipcRenderer.send('ELECTRON_GUEST_VIEW_MANAGER_ASYNC_CALL', requestId, getGuestInstanceId(this), method, args, callback != null)
|
||||
}
|
||||
}
|
||||
for (const method of asyncMethods) {
|
||||
|
||||
for (const method of asyncCallbackMethods) {
|
||||
proto[method] = createNonBlockHandler(method)
|
||||
}
|
||||
|
||||
const createPromiseHandler = function (method) {
|
||||
return function (...args) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const callback = (typeof args[args.length - 1] === 'function') ? args.pop() : null
|
||||
const requestId = getNextId()
|
||||
|
||||
ipcRenderer.once(`ELECTRON_GUEST_VIEW_MANAGER_ASYNC_CALL_RESPONSE_${requestId}`, function (event, error, result) {
|
||||
if (error == null) {
|
||||
if (callback) {
|
||||
callback(result)
|
||||
}
|
||||
resolve(result)
|
||||
} else {
|
||||
reject(errorUtils.deserialize(error))
|
||||
}
|
||||
})
|
||||
ipcRenderer.send('ELECTRON_GUEST_VIEW_MANAGER_ASYNC_CALL', requestId, getGuestInstanceId(this), method, args, callback != null)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
for (const method of asyncPromiseMethods) {
|
||||
proto[method] = createPromiseHandler(method)
|
||||
}
|
||||
|
||||
// WebContents associated with this webview.
|
||||
proto.getWebContents = function () {
|
||||
const { getRemoteForUsage } = require('@electron/internal/renderer/remote')
|
||||
|
||||
@@ -58,12 +58,16 @@ ipcNative.onMessage = function (channel, args, senderId) {
|
||||
electron.ipcRenderer.emit(channel, { sender: electron.ipcRenderer, senderId }, ...args)
|
||||
}
|
||||
|
||||
ipcNative.onLoaded = function () {
|
||||
process.emit('loaded')
|
||||
}
|
||||
|
||||
ipcNative.onExit = function () {
|
||||
process.emit('exit')
|
||||
}
|
||||
|
||||
const {
|
||||
preloadSrc, preloadError, isRemoteModuleEnabled, process: processProps
|
||||
preloadScripts, isRemoteModuleEnabled, process: processProps
|
||||
} = ipcRenderer.sendSync('ELECTRON_BROWSER_SANDBOX_LOAD')
|
||||
|
||||
const makePropertyNonConfigurable = function (object, name) {
|
||||
@@ -90,6 +94,7 @@ Object.assign(preloadProcess, processProps)
|
||||
Object.assign(process, binding.process)
|
||||
Object.assign(process, processProps)
|
||||
|
||||
process.on('loaded', () => preloadProcess.emit('loaded'))
|
||||
process.on('exit', () => preloadProcess.emit('exit'))
|
||||
|
||||
// This is the `require` function that will be visible to the preload script
|
||||
@@ -100,7 +105,7 @@ function preloadRequire (module) {
|
||||
if (remoteModules.has(module)) {
|
||||
return require(module)
|
||||
}
|
||||
throw new Error('module not found')
|
||||
throw new Error(`module not found: ${module}`)
|
||||
}
|
||||
|
||||
switch (window.location.protocol) {
|
||||
@@ -126,6 +131,8 @@ if (!process.guestInstanceId && preloadProcess.argv.includes('--webview-tag=true
|
||||
require('@electron/internal/renderer/web-view/web-view').setupWebView(window)
|
||||
}
|
||||
|
||||
const errorUtils = require('@electron/internal/common/error-utils')
|
||||
|
||||
// Wrap the script into a function executed in global scope. It won't have
|
||||
// access to the current scope, so we'll expose a few objects as arguments:
|
||||
//
|
||||
@@ -145,7 +152,7 @@ if (!process.guestInstanceId && preloadProcess.argv.includes('--webview-tag=true
|
||||
// and any `require('electron')` calls in `preload.js` will work as expected
|
||||
// since browserify won't try to include `electron` in the bundle, falling back
|
||||
// to the `preloadRequire` function above.
|
||||
if (preloadSrc) {
|
||||
function runPreloadScript (preloadSrc) {
|
||||
const preloadWrapperSrc = `(function(require, process, Buffer, global, setImmediate, clearImmediate) {
|
||||
${preloadSrc}
|
||||
})`
|
||||
@@ -153,9 +160,21 @@ if (preloadSrc) {
|
||||
// eval in window scope
|
||||
const preloadFn = binding.createPreloadScript(preloadWrapperSrc)
|
||||
const { setImmediate, clearImmediate } = require('timers')
|
||||
|
||||
preloadFn(preloadRequire, preloadProcess, Buffer, global, setImmediate, clearImmediate)
|
||||
} else if (preloadError) {
|
||||
console.error(preloadError.stack)
|
||||
}
|
||||
|
||||
for (const { preloadPath, preloadSrc, preloadError } of preloadScripts) {
|
||||
try {
|
||||
if (preloadSrc) {
|
||||
runPreloadScript(preloadSrc)
|
||||
} else if (preloadError) {
|
||||
throw errorUtils.deserialize(preloadError)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`Unable to load preload script: ${preloadPath}`)
|
||||
console.error(`${error}`)
|
||||
}
|
||||
}
|
||||
|
||||
// Warn about security issues
|
||||
|
||||
2
package-lock.json
generated
2
package-lock.json
generated
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "electron",
|
||||
"version": "4.0.4",
|
||||
"version": "4.2.2",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "electron",
|
||||
"version": "4.0.4",
|
||||
"version": "4.2.2",
|
||||
"repository": "https://github.com/electron/electron",
|
||||
"description": "Build cross platform desktop apps with JavaScript, HTML, and CSS",
|
||||
"devDependencies": {
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
implement_ssl_get_tlsext_status_type.patch
|
||||
expose_ripemd160.patch
|
||||
expose_aes-cfb.patch
|
||||
sync_sorted_ciphers.patch
|
||||
handle_pub_key_null_in_ec_key_set_public_key.patch
|
||||
add_a_compatibility_evp_ciph_ocb_mode_value.patch
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: David Benjamin <davidben@google.com>
|
||||
Date: Sun, 14 Oct 2018 11:01:40 -0500
|
||||
Subject: Add a compatibility EVP_CIPH_OCB_MODE value.
|
||||
|
||||
Node references it these days. Also replace the no-op modes with negative
|
||||
numbers rather than zero. Stream ciphers like RC4 report a "mode" of zero, so
|
||||
code comparing the mode to a dummy value will get confused.
|
||||
|
||||
(I came across https://github.com/nodejs/node/pull/23635, though we'd have run
|
||||
into it sooner or later anyway. Better to just define the value and avoid ifdef
|
||||
proliferation.)
|
||||
|
||||
Change-Id: I223f25663e138480ad83f35aa16f5218f1425563
|
||||
Reviewed-on: https://boringssl-review.googlesource.com/c/32464
|
||||
Reviewed-by: Adam Langley <agl@google.com>
|
||||
Commit-Queue: Adam Langley <agl@google.com>
|
||||
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
|
||||
|
||||
diff --git a/include/openssl/cipher.h b/include/openssl/cipher.h
|
||||
index e2ab9449275a62ee8a93bd48284b39e8df88a14f..7d4d78b3730022fb61ae63c6d3a86a61cb0c91e2 100644
|
||||
--- a/include/openssl/cipher.h
|
||||
+++ b/include/openssl/cipher.h
|
||||
@@ -425,8 +425,9 @@ OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_256_cfb128(void);
|
||||
|
||||
// The following flags do nothing and are included only to make it easier to
|
||||
// compile code with BoringSSL.
|
||||
-#define EVP_CIPH_CCM_MODE 0
|
||||
-#define EVP_CIPH_WRAP_MODE 0
|
||||
+#define EVP_CIPH_CCM_MODE (-1)
|
||||
+#define EVP_CIPH_OCB_MODE (-2)
|
||||
+#define EVP_CIPH_WRAP_MODE (-3)
|
||||
#define EVP_CIPHER_CTX_FLAG_WRAP_ALLOW 0
|
||||
|
||||
// EVP_CIPHER_CTX_set_flags does nothing.
|
||||
@@ -71,7 +71,7 @@ index acc4719b7e9c4c4461fc6142f2ae9156b407915b..8b008a401ec2f2d0673f6876609dd578
|
||||
callback(EVP_aes_256_ecb(), "aes-256-ecb", NULL, arg);
|
||||
callback(EVP_aes_256_ofb(), "aes-256-ofb", NULL, arg);
|
||||
diff --git a/include/openssl/cipher.h b/include/openssl/cipher.h
|
||||
index 59634138cb60237f008eb99e7d8df54da7629c1a..b30b8434b301fb5b8630ae954698b6fee255df77 100644
|
||||
index 7d99d49ba7ae2d8a4eb80681cbd9b41eee86bac7..e2ab9449275a62ee8a93bd48284b39e8df88a14f 100644
|
||||
--- a/include/openssl/cipher.h
|
||||
+++ b/include/openssl/cipher.h
|
||||
@@ -421,6 +421,7 @@ OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_192_ofb(void);
|
||||
|
||||
@@ -80,7 +80,7 @@ index 38b8f9f78f76050174096740596ac59a0fe18757..acc4719b7e9c4c4461fc6142f2ae9156
|
||||
+ callback(EVP_ripemd160(), "ripemd160", NULL, arg);
|
||||
}
|
||||
diff --git a/include/openssl/digest.h b/include/openssl/digest.h
|
||||
index 1a1ca29732afae317c8e8740c629e8922fc83093..48ebdd1eb93b3febecddbc2545b7aae583f21525 100644
|
||||
index 4077d902a07c215659ed61b54a468231536d70ee..f15df35d16402256fa00263e2c2e71d55ce67d1a 100644
|
||||
--- a/include/openssl/digest.h
|
||||
+++ b/include/openssl/digest.h
|
||||
@@ -88,6 +88,9 @@ OPENSSL_EXPORT const EVP_MD *EVP_sha512(void);
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jeremy Apthorp <nornagon@nornagon.net>
|
||||
Date: Mon, 4 Mar 2019 10:59:35 -0800
|
||||
Subject: handle pub_key == null in EC_KEY_set_public_key
|
||||
|
||||
|
||||
diff --git a/crypto/fipsmodule/ec/ec_key.c b/crypto/fipsmodule/ec/ec_key.c
|
||||
index a6d469767adfad1c9095cc58c567b10c71e95cfa..d1f754afeba102208c668f3678f64abed666cd64 100644
|
||||
--- a/crypto/fipsmodule/ec/ec_key.c
|
||||
+++ b/crypto/fipsmodule/ec/ec_key.c
|
||||
@@ -267,7 +267,7 @@ int EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub_key) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
- if (EC_GROUP_cmp(key->group, pub_key->group, NULL) != 0) {
|
||||
+ if (pub_key != NULL && EC_GROUP_cmp(key->group, pub_key->group, NULL) != 0) {
|
||||
OPENSSL_PUT_ERROR(EC, EC_R_GROUP_MISMATCH);
|
||||
return 0;
|
||||
}
|
||||
@@ -14,10 +14,10 @@ Commit-Queue: David Benjamin <davidben@google.com>
|
||||
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
|
||||
|
||||
diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h
|
||||
index ae8b8385fc73701a4346202f213b5974af4e2aed..0f3d1747173ffb09eafd5c7d5d692ae3c35c9874 100644
|
||||
index f693030a8a7c4bf79dd791e1abd0e94f8e97a292..3fee95c0a89dc4a25da527e2ac9cc50bab9c35a6 100644
|
||||
--- a/include/openssl/ssl.h
|
||||
+++ b/include/openssl/ssl.h
|
||||
@@ -4268,6 +4268,14 @@ OPENSSL_EXPORT int OPENSSL_init_ssl(uint64_t opts,
|
||||
@@ -4293,6 +4293,14 @@ OPENSSL_EXPORT int OPENSSL_init_ssl(uint64_t opts,
|
||||
// Use |SSL_enable_ocsp_stapling| instead.
|
||||
OPENSSL_EXPORT int SSL_set_tlsext_status_type(SSL *ssl, int type);
|
||||
|
||||
@@ -33,10 +33,10 @@ index ae8b8385fc73701a4346202f213b5974af4e2aed..0f3d1747173ffb09eafd5c7d5d692ae3
|
||||
// success and zero on error. On success, |ssl| takes ownership of |resp|, which
|
||||
// must have been allocated by |OPENSSL_malloc|.
|
||||
diff --git a/ssl/ssl_lib.cc b/ssl/ssl_lib.cc
|
||||
index 9c16de4958ef29d638e05e0f90b9b15b11b15cac..1f648658b8cb6ae7b82132b276b927e8fb11a47a 100644
|
||||
index c68968a514b76717d4c42448ef4b9c440c330fb2..547be0229e2c60c8aefb4644bc84e96f5a17c7f3 100644
|
||||
--- a/ssl/ssl_lib.cc
|
||||
+++ b/ssl/ssl_lib.cc
|
||||
@@ -2751,6 +2751,19 @@ int SSL_set_tlsext_status_type(SSL *ssl, int type) {
|
||||
@@ -2896,6 +2896,19 @@ int SSL_set_tlsext_status_type(SSL *ssl, int type) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
85
patches/common/boringssl/sync_sorted_ciphers.patch
Normal file
85
patches/common/boringssl/sync_sorted_ciphers.patch
Normal file
@@ -0,0 +1,85 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shelley Vohr <shelley.vohr@gmail.com>
|
||||
Date: Thu, 7 Feb 2019 11:11:35 -0800
|
||||
Subject: sync EVP_get_cipherbyname with EVP_do_all_sorted
|
||||
|
||||
EVP_get_cipherbyname should work on everything that EVP_do_all_sorted
|
||||
lists, and conversely, there should be nothing that
|
||||
EVP_get_cipherbyname works on that EVP_do_all_sorted doesn't list.
|
||||
This thus does that.
|
||||
|
||||
diff --git a/crypto/cipher_extra/cipher_extra.c b/crypto/cipher_extra/cipher_extra.c
|
||||
index be7ef07b2c188a76890deb0f305cf92fcc57a64e..588a4773437c311877f275bf3679f9688cda3c46 100644
|
||||
--- a/crypto/cipher_extra/cipher_extra.c
|
||||
+++ b/crypto/cipher_extra/cipher_extra.c
|
||||
@@ -133,6 +133,14 @@ const EVP_CIPHER *EVP_get_cipherbyname(const char *name) {
|
||||
return EVP_aes_192_ofb();
|
||||
} else if (OPENSSL_strcasecmp(name, "aes-256-ofb") == 0) {
|
||||
return EVP_aes_256_ofb();
|
||||
+ } else if (OPENSSL_strcasecmp(name, "des-ecb") == 0) {
|
||||
+ return EVP_des_ecb();
|
||||
+ } else if (OPENSSL_strcasecmp(name, "des-ede") == 0) {
|
||||
+ return EVP_des_ede();
|
||||
+ } else if (OPENSSL_strcasecmp(name, "des-ede-cbc") == 0) {
|
||||
+ return EVP_des_ede_cbc();
|
||||
+ } else if (OPENSSL_strcasecmp(name, "rc2-cbc") == 0) {
|
||||
+ return EVP_rc2_cbc();
|
||||
}
|
||||
|
||||
return NULL;
|
||||
diff --git a/decrepit/evp/evp_do_all.c b/decrepit/evp/evp_do_all.c
|
||||
index 8b008a401ec2f2d0673f6876609dd5786cace4c2..3e88b29cb599730d2e8682070aaa4be38d06ed80 100644
|
||||
--- a/decrepit/evp/evp_do_all.c
|
||||
+++ b/decrepit/evp/evp_do_all.c
|
||||
@@ -21,15 +21,21 @@ void EVP_CIPHER_do_all_sorted(void (*callback)(const EVP_CIPHER *cipher,
|
||||
void *arg) {
|
||||
callback(EVP_aes_128_cbc(), "AES-128-CBC", NULL, arg);
|
||||
callback(EVP_aes_128_cfb128(), "AES-128-CFB", NULL, arg);
|
||||
- callback(EVP_aes_128_ctr(), "AES-128-CTR", NULL, arg);
|
||||
- callback(EVP_aes_128_ecb(), "AES-128-ECB", NULL, arg);
|
||||
- callback(EVP_aes_128_ofb(), "AES-128-OFB", NULL, arg);
|
||||
+ callback(EVP_aes_192_cbc(), "AES-192-CBC", NULL, arg);
|
||||
callback(EVP_aes_256_cbc(), "AES-256-CBC", NULL, arg);
|
||||
+ callback(EVP_aes_128_ctr(), "AES-128-CTR", NULL, arg);
|
||||
+ callback(EVP_aes_192_ctr(), "AES-192-CTR", NULL, arg);
|
||||
callback(EVP_aes_256_cfb128(), "AES-256-CFB", NULL, arg);
|
||||
callback(EVP_aes_256_ctr(), "AES-256-CTR", NULL, arg);
|
||||
+ callback(EVP_aes_128_ecb(), "AES-128-ECB", NULL, arg);
|
||||
+ callback(EVP_aes_192_ecb(), "AES-192-ECB", NULL, arg);
|
||||
callback(EVP_aes_256_ecb(), "AES-256-ECB", NULL, arg);
|
||||
+ callback(EVP_aes_128_ofb(), "AES-128-OFB", NULL, arg);
|
||||
+ callback(EVP_aes_192_ofb(), "AES-192-OFB", NULL, arg);
|
||||
callback(EVP_aes_256_ofb(), "AES-256-OFB", NULL, arg);
|
||||
- callback(EVP_aes_256_xts(), "AES-256-XTS", NULL, arg);
|
||||
+ callback(EVP_aes_128_gcm(), "AES-128-GCM", NULL, arg);
|
||||
+ callback(EVP_aes_192_gcm(), "AES-192-GCM", NULL, arg);
|
||||
+ callback(EVP_aes_256_gcm(), "AES-256-GCM", NULL, arg);
|
||||
callback(EVP_des_cbc(), "DES-CBC", NULL, arg);
|
||||
callback(EVP_des_ecb(), "DES-ECB", NULL, arg);
|
||||
callback(EVP_des_ede(), "DES-EDE", NULL, arg);
|
||||
@@ -41,15 +47,21 @@ void EVP_CIPHER_do_all_sorted(void (*callback)(const EVP_CIPHER *cipher,
|
||||
// OpenSSL returns everything twice, the second time in lower case.
|
||||
callback(EVP_aes_128_cbc(), "aes-128-cbc", NULL, arg);
|
||||
callback(EVP_aes_128_cfb128(), "aes-128-cfb", NULL, arg);
|
||||
- callback(EVP_aes_128_ctr(), "aes-128-ctr", NULL, arg);
|
||||
- callback(EVP_aes_128_ecb(), "aes-128-ecb", NULL, arg);
|
||||
- callback(EVP_aes_128_ofb(), "aes-128-ofb", NULL, arg);
|
||||
+ callback(EVP_aes_192_cbc(), "aes-192-cbc", NULL, arg);
|
||||
callback(EVP_aes_256_cbc(), "aes-256-cbc", NULL, arg);
|
||||
+ callback(EVP_aes_128_ctr(), "aes-128-ctr", NULL, arg);
|
||||
+ callback(EVP_aes_192_ctr(), "aes-192-ctr", NULL, arg);
|
||||
callback(EVP_aes_256_cfb128(), "aes-256-cfb", NULL, arg);
|
||||
callback(EVP_aes_256_ctr(), "aes-256-ctr", NULL, arg);
|
||||
+ callback(EVP_aes_128_ecb(), "aes-128-ecb", NULL, arg);
|
||||
+ callback(EVP_aes_192_ecb(), "aes-192-ecb", NULL, arg);
|
||||
callback(EVP_aes_256_ecb(), "aes-256-ecb", NULL, arg);
|
||||
+ callback(EVP_aes_128_ofb(), "aes-128-ofb", NULL, arg);
|
||||
+ callback(EVP_aes_192_ofb(), "aes-192-ofb", NULL, arg);
|
||||
callback(EVP_aes_256_ofb(), "aes-256-ofb", NULL, arg);
|
||||
- callback(EVP_aes_256_xts(), "aes-256-xts", NULL, arg);
|
||||
+ callback(EVP_aes_128_gcm(), "aes-128-gcm", NULL, arg);
|
||||
+ callback(EVP_aes_192_gcm(), "aes-192-gcm", NULL, arg);
|
||||
+ callback(EVP_aes_256_gcm(), "aes-256-gcm", NULL, arg);
|
||||
callback(EVP_des_cbc(), "des-cbc", NULL, arg);
|
||||
callback(EVP_des_ecb(), "des-ecb", NULL, arg);
|
||||
callback(EVP_des_ede(), "des-ede", NULL, arg);
|
||||
@@ -89,3 +89,15 @@ disable_color_correct_rendering.patch
|
||||
sqlite_upgrade_from_3_24_to_3_26.patch
|
||||
sqlite_update_api_3_26.patch
|
||||
tts.patch
|
||||
do_not_allow_impl_side_invalidations_until_frame_sink_is_fully_active.patch
|
||||
enable_inputpane_virtual_keyboard_functionality_by_default.patch
|
||||
merge_m72_filereader_make_a_copy_of_the_arraybuffer_when_returning.patch
|
||||
fix_system_tray_icons_being_cropped_under_kde.patch
|
||||
set_proper_permissions_for_package_s_framework_directory.patch
|
||||
intersection-observer.patch
|
||||
keyboard-lock-service-impl.patch
|
||||
make_--explicitly-allowed-ports_work_with_networkservice.patch
|
||||
fix_crashes_in_renderframeimpl_onselectpopupmenuitem_s.patch
|
||||
fix_re-entracy_problem_with_invalidateframesinkid.patch
|
||||
chore_expose_getcontentclient_to_embedders.patch
|
||||
tabbed_window_lagging.patch
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
From 3a68808c9e49e9a249ee9056015e30543747cd00 Mon Sep 17 00:00:00 2001
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Ales Pergl <alpergl@microsoft.com>
|
||||
Date: Thu, 20 Sep 2018 17:44:49 -0700
|
||||
Subject: allow_new_privs.patch
|
||||
|
||||
|
||||
diff --git a/base/process/launch.h b/base/process/launch.h
|
||||
index 7a2def2ef436..50afeaf5553a 100644
|
||||
index 7a2def2ef4365ee3dba0752fca46a6f7aa33ad81..50afeaf5553a1a4ae14ca30aa95ab65c258a0322 100644
|
||||
--- a/base/process/launch.h
|
||||
+++ b/base/process/launch.h
|
||||
@@ -180,7 +180,7 @@ struct BASE_EXPORT LaunchOptions {
|
||||
|
||||
@@ -6,10 +6,10 @@ Subject: boringssl BUILD.gn
|
||||
Build BoringSSL with some extra functions that nodejs needs.
|
||||
|
||||
diff --git a/third_party/boringssl/BUILD.gn b/third_party/boringssl/BUILD.gn
|
||||
index d31a9f29fa9c12e753708b2a1e75c33b70924300..fd45cfcb50fb659ff8d5a07b06aeecc8f0ecd3ee 100644
|
||||
index d31a9f29fa9c12e753708b2a1e75c33b70924300..12c0a84a39f4707f0120922aa64c813e5b2a7b0c 100644
|
||||
--- a/third_party/boringssl/BUILD.gn
|
||||
+++ b/third_party/boringssl/BUILD.gn
|
||||
@@ -45,6 +45,19 @@ config("no_asm_config") {
|
||||
@@ -46,6 +46,19 @@ config("no_asm_config") {
|
||||
|
||||
all_sources = crypto_sources + ssl_sources
|
||||
all_headers = crypto_headers + ssl_headers
|
||||
|
||||
@@ -29,7 +29,7 @@ diff --git a/content/browser/renderer_host/browser_compositor_view_mac.mm b/cont
|
||||
index 92afcc77910610e53378f55adc003cc1bdf3109a..42bd6fd7c169de36c775471c68b456f1386ff666 100644
|
||||
--- a/content/browser/renderer_host/browser_compositor_view_mac.mm
|
||||
+++ b/content/browser/renderer_host/browser_compositor_view_mac.mm
|
||||
@@ -81,6 +81,12 @@ BrowserCompositorMac::~BrowserCompositorMac() {
|
||||
@@ -81,6 +81,12 @@
|
||||
DCHECK_EQ(1u, num_erased);
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ index fcc00ee0e49f101cb1b10629747c4c4fa521776d..3232a0360e94e78621f7f672e3de4bdc
|
||||
|
||||
if (is_win) {
|
||||
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn
|
||||
index 959a59231746..48f1285c4657 100644
|
||||
index 959a592317462abb07eefbf03853e1610034c5f3..48f1285c465797bfba37cf2a86cfe21d78c533e6 100644
|
||||
--- a/build/config/compiler/BUILD.gn
|
||||
+++ b/build/config/compiler/BUILD.gn
|
||||
@@ -634,12 +634,12 @@ config("compiler") {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
From 88c91c7f60e6251c35fdb3549a5dd7fc66cfdf3b Mon Sep 17 00:00:00 2001
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Anonymous <anonymous@electronjs.org>
|
||||
Date: Wed, 19 Sep 2018 18:55:58 -0700
|
||||
Subject: build_toolchain_win_patch.patch
|
||||
@@ -18,7 +18,7 @@ For example, instead of generating `obj/ui/base/base_cc.pdb` the
|
||||
build will now generate `obj/ui/base/obj_ui_base_base_cc.pdb`.
|
||||
|
||||
diff --git a/build/toolchain/win/BUILD.gn b/build/toolchain/win/BUILD.gn
|
||||
index eb3e2b2b377d..fdffcdbdbbfe 100644
|
||||
index eb3e2b2b377dde31e062be46837bf509ecab0325..fdffcdbdbbfe1280f50c5b8401b117e24ea5267f 100644
|
||||
--- a/build/toolchain/win/BUILD.gn
|
||||
+++ b/build/toolchain/win/BUILD.gn
|
||||
@@ -173,6 +173,12 @@ template("msvc_toolchain") {
|
||||
@@ -48,7 +48,7 @@ index eb3e2b2b377d..fdffcdbdbbfe 100644
|
||||
|
||||
tool("rc") {
|
||||
diff --git a/build/toolchain/win/tool_wrapper.py b/build/toolchain/win/tool_wrapper.py
|
||||
index cb0393ecd507..ee21eb4b194b 100644
|
||||
index cb0393ecd507b865169e9d7c3037d7d5523ae30e..ee21eb4b194b35576883b31c94c9a1f56075e89b 100644
|
||||
--- a/build/toolchain/win/tool_wrapper.py
|
||||
+++ b/build/toolchain/win/tool_wrapper.py
|
||||
@@ -247,6 +247,25 @@ class WinTool(object):
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Samuel Attard <sattard@slack-corp.com>
|
||||
Date: Wed, 1 May 2019 18:04:41 -0700
|
||||
Subject: chore: expose GetContentClient to embedders
|
||||
|
||||
|
||||
diff --git a/content/public/common/content_client.h b/content/public/common/content_client.h
|
||||
index 528fd6abf6a623b8076803fddf5616d88f0978e8..e03bfeff5dabd55fe548ba828ae30065ba3f42d6 100644
|
||||
--- a/content/public/common/content_client.h
|
||||
+++ b/content/public/common/content_client.h
|
||||
@@ -58,10 +58,10 @@ struct PepperPluginInfo;
|
||||
// content code is called.
|
||||
CONTENT_EXPORT void SetContentClient(ContentClient* client);
|
||||
|
||||
-#if defined(CONTENT_IMPLEMENTATION)
|
||||
+//#if defined(CONTENT_IMPLEMENTATION)
|
||||
// Content's embedder API should only be used by content.
|
||||
-ContentClient* GetContentClient();
|
||||
-#endif
|
||||
+CONTENT_EXPORT ContentClient* GetContentClient();
|
||||
+//#endif
|
||||
|
||||
// Used for tests to override the relevant embedder interfaces. Each method
|
||||
// returns the old value.
|
||||
@@ -22,7 +22,7 @@ diff --git a/third_party/crashpad/crashpad/util/net/http_transport_mac.mm b/thir
|
||||
index 8d5f78cc6efc8b8e349958f51c78921a8c163c4e..a433bb357da5865144ade7d3663b1c9b36199f8e 100644
|
||||
--- a/third_party/crashpad/crashpad/util/net/http_transport_mac.mm
|
||||
+++ b/third_party/crashpad/crashpad/util/net/http_transport_mac.mm
|
||||
@@ -293,7 +293,7 @@ bool HTTPTransportMac::ExecuteSynchronously(std::string* response_body) {
|
||||
@@ -293,7 +293,7 @@ static void Unschedule(CFReadStreamRef stream,
|
||||
return false;
|
||||
}
|
||||
NSInteger http_status = [http_response statusCode];
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
From 0dbac64c4877f7783726d3bc04f332a1491285b7 Mon Sep 17 00:00:00 2001
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Anonymous <anonymous@electronjs.org>
|
||||
Date: Thu, 20 Sep 2018 17:45:44 -0700
|
||||
Subject: desktop_screen_win.patch
|
||||
|
||||
|
||||
diff --git a/ui/views/widget/desktop_aura/desktop_screen_win.cc b/ui/views/widget/desktop_aura/desktop_screen_win.cc
|
||||
index f772f64d656e..7d13f9f81b6c 100644
|
||||
index f772f64d656e88cd2631e388f92e00a845f84f16..7d13f9f81b6c4a9b2ac5ce7e54e6a0c58225517c 100644
|
||||
--- a/ui/views/widget/desktop_aura/desktop_screen_win.cc
|
||||
+++ b/ui/views/widget/desktop_aura/desktop_screen_win.cc
|
||||
@@ -32,6 +32,8 @@ display::Display DesktopScreenWin::GetDisplayMatching(
|
||||
|
||||
@@ -19,7 +19,7 @@ to deal with color spaces. That is being tracked at
|
||||
https://crbug.com/634542 and https://crbug.com/711107.
|
||||
|
||||
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc
|
||||
index f51e30c0d2a55f104ca0912e487484102e443c85..fbec9767bdefc3b90335ecc423ffd4ea31bf914d 100644
|
||||
index 507ece40522fc29a56908d9a6532947a7f67db35..1659c05bfeecbf8ef4264f946aa045d58beb2775 100644
|
||||
--- a/cc/trees/layer_tree_host_impl.cc
|
||||
+++ b/cc/trees/layer_tree_host_impl.cc
|
||||
@@ -1578,6 +1578,10 @@ void LayerTreeHostImpl::SetIsLikelyToRequireADraw(
|
||||
@@ -34,7 +34,7 @@ index f51e30c0d2a55f104ca0912e487484102e443c85..fbec9767bdefc3b90335ecc423ffd4ea
|
||||
// The pending tree will have the most recently updated color space, so
|
||||
// prefer that.
|
||||
diff --git a/cc/trees/layer_tree_settings.h b/cc/trees/layer_tree_settings.h
|
||||
index e124035096b02e82d526d7dfd0e70d4cf73819be..4f182c826a8d08a8674e3ca2f0bf833aa49a1309 100644
|
||||
index 736df815a2815484b561bdc4828dbb8592a43d3a..b9b624e475bc244154febb214d88c63aaba5bbab 100644
|
||||
--- a/cc/trees/layer_tree_settings.h
|
||||
+++ b/cc/trees/layer_tree_settings.h
|
||||
@@ -98,6 +98,8 @@ class CC_EXPORT LayerTreeSettings {
|
||||
@@ -47,7 +47,7 @@ index e124035096b02e82d526d7dfd0e70d4cf73819be..4f182c826a8d08a8674e3ca2f0bf833a
|
||||
// Image Decode Service and raster tiles without images until the decode is
|
||||
// ready.
|
||||
diff --git a/components/viz/common/display/renderer_settings.h b/components/viz/common/display/renderer_settings.h
|
||||
index 1327e8607c5192f2440341a33fc210aecd47ced5..543d6937a908560270c6bba431a255436b522608 100644
|
||||
index 740cb2ab71cfad11f51418f011ad8a68764c51f4..8c882d58a70a8f6c8f5d4ea861a38b24ffdd4573 100644
|
||||
--- a/components/viz/common/display/renderer_settings.h
|
||||
+++ b/components/viz/common/display/renderer_settings.h
|
||||
@@ -18,6 +18,7 @@ class VIZ_COMMON_EXPORT RendererSettings {
|
||||
@@ -80,7 +80,7 @@ index eca6020535249e51b428de9dd6454273e6c9dd71..e190d2fb2e2cc41135c119485c2d4475
|
||||
!command_line->HasSwitch(switches::kUIDisablePartialSwap);
|
||||
#if defined(OS_WIN)
|
||||
diff --git a/components/viz/service/display/gl_renderer.cc b/components/viz/service/display/gl_renderer.cc
|
||||
index a9ba5ca388b8d0979a1235a0d976b8cb3277f6d3..574deb6ad7d1b088eea43d87b8fe4637b980139b 100644
|
||||
index f37adb85d10e344ec9251334b0f46809428cd87a..4d26492492da3ddff0a2529a5e52e5506560a31c 100644
|
||||
--- a/components/viz/service/display/gl_renderer.cc
|
||||
+++ b/components/viz/service/display/gl_renderer.cc
|
||||
@@ -77,6 +77,9 @@
|
||||
@@ -237,10 +237,10 @@ index 0544d031b60d38279104a4ca9c6dc25126dea185..1acb3dfa55f39b8ecb9fccaa4627ac25
|
||||
base::Optional<skia::OpacityFilterCanvas> opacity_canvas;
|
||||
if (needs_transparency || disable_image_filtering) {
|
||||
diff --git a/components/viz/service/display/software_renderer.cc b/components/viz/service/display/software_renderer.cc
|
||||
index 5c41958ed259b1d3ae076312b97a802746897c98..4cb9801a859c12dae03e03073085ff82ea0e4a32 100644
|
||||
index b72323450524eb53e2ae1938da4e9410d456417f..bba0fd17ac0f95879e77c8112cb8f4da7b49e3ee 100644
|
||||
--- a/components/viz/service/display/software_renderer.cc
|
||||
+++ b/components/viz/service/display/software_renderer.cc
|
||||
@@ -334,9 +334,11 @@ void SoftwareRenderer::DrawPictureQuad(const PictureDrawQuad* quad) {
|
||||
@@ -333,9 +333,11 @@ void SoftwareRenderer::DrawPictureQuad(const PictureDrawQuad* quad) {
|
||||
|
||||
std::unique_ptr<SkCanvas> color_transform_canvas;
|
||||
// TODO(enne): color transform needs to be replicated in gles2_cmd_decoder
|
||||
@@ -256,10 +256,10 @@ index 5c41958ed259b1d3ae076312b97a802746897c98..4cb9801a859c12dae03e03073085ff82
|
||||
base::Optional<skia::OpacityFilterCanvas> opacity_canvas;
|
||||
if (needs_transparency || disable_image_filtering) {
|
||||
diff --git a/content/browser/gpu/gpu_process_host.cc b/content/browser/gpu/gpu_process_host.cc
|
||||
index 9511100e6077b6788abfead4b1962773a22ae40b..db2d8a4fc979b20810776cf2a31018d197cdba7d 100644
|
||||
index bdecceea7e66605869548efc15181d88cfb8a438..844790266cecd6f7dcfbd4f25e73fc16749f77dd 100644
|
||||
--- a/content/browser/gpu/gpu_process_host.cc
|
||||
+++ b/content/browser/gpu/gpu_process_host.cc
|
||||
@@ -193,6 +193,7 @@ GpuTerminationStatus ConvertToGpuTerminationStatus(
|
||||
@@ -192,6 +192,7 @@ GpuTerminationStatus ConvertToGpuTerminationStatus(
|
||||
|
||||
// Command-line switches to propagate to the GPU process.
|
||||
static const char* const kSwitchNames[] = {
|
||||
@@ -268,10 +268,10 @@ index 9511100e6077b6788abfead4b1962773a22ae40b..db2d8a4fc979b20810776cf2a31018d1
|
||||
service_manager::switches::kGpuSandboxAllowSysVShm,
|
||||
service_manager::switches::kGpuSandboxFailuresFatal,
|
||||
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc
|
||||
index 1f2897aabf94124f108a0f0449e4d687b084f1a4..4f88e4425ceada8af6b412b087ac134572222824 100644
|
||||
index 05e0ee79e5ada8eee03b2bff9c127b4f11610c17..35fdb9d351db5a6bdaa61742ec49dc75fe70cfa4 100644
|
||||
--- a/content/browser/renderer_host/render_process_host_impl.cc
|
||||
+++ b/content/browser/renderer_host/render_process_host_impl.cc
|
||||
@@ -218,6 +218,7 @@
|
||||
@@ -213,6 +213,7 @@
|
||||
#include "ui/base/ui_base_switches.h"
|
||||
#include "ui/base/ui_base_switches_util.h"
|
||||
#include "ui/display/display_switches.h"
|
||||
@@ -279,7 +279,7 @@ index 1f2897aabf94124f108a0f0449e4d687b084f1a4..4f88e4425ceada8af6b412b087ac1345
|
||||
#include "ui/gl/gl_switches.h"
|
||||
#include "ui/gl/gpu_switching_manager.h"
|
||||
#include "ui/native_theme/native_theme_features.h"
|
||||
@@ -2931,6 +2932,7 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer(
|
||||
@@ -2779,6 +2780,7 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer(
|
||||
// Propagate the following switches to the renderer command line (along
|
||||
// with any associated values) if present in the browser command line.
|
||||
static const char* const kSwitchNames[] = {
|
||||
@@ -288,10 +288,10 @@ index 1f2897aabf94124f108a0f0449e4d687b084f1a4..4f88e4425ceada8af6b412b087ac1345
|
||||
service_manager::switches::kDisableInProcessStackTraces,
|
||||
service_manager::switches::kDisableSeccompFilterSandbox,
|
||||
diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc
|
||||
index 6d0580d5b0b76109bbaf0d058ce4201dc970adf0..f0271310ec6112ca7276c5af13ee6677d393109e 100644
|
||||
index 560c7caaa74c295a203bfa53c1acc63f1eb4283f..c10f893e1734e59f3102c8d862ccdaca01a3d73f 100644
|
||||
--- a/content/renderer/render_widget.cc
|
||||
+++ b/content/renderer/render_widget.cc
|
||||
@@ -2565,6 +2565,9 @@ cc::LayerTreeSettings RenderWidget::GenerateLayerTreeSettings(
|
||||
@@ -2458,6 +2458,9 @@ cc::LayerTreeSettings RenderWidget::GenerateLayerTreeSettings(
|
||||
settings.main_frame_before_activation_enabled =
|
||||
cmd.HasSwitch(cc::switches::kEnableMainFrameBeforeActivation);
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
From 790e1e19af133252e95e3a4de8c8e7a3a011bf02 Mon Sep 17 00:00:00 2001
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: deepak1556 <hop2deep@gmail.com>
|
||||
Date: Thu, 20 Sep 2018 17:50:48 -0700
|
||||
Subject: disable_extensions_gn.patch
|
||||
@@ -6,7 +6,7 @@ Subject: disable_extensions_gn.patch
|
||||
Fix build files generation when chrome extensions are disabled.
|
||||
|
||||
diff --git a/chrome/browser/apps/app_shim/BUILD.gn b/chrome/browser/apps/app_shim/BUILD.gn
|
||||
index f8a6d1868788..350c3572ec54 100644
|
||||
index f8a6d1868788d0a984e70b23b6522cf9b74827da..350c3572ec54d85c2195555877d27486a1300273 100644
|
||||
--- a/chrome/browser/apps/app_shim/BUILD.gn
|
||||
+++ b/chrome/browser/apps/app_shim/BUILD.gn
|
||||
@@ -1,6 +1,7 @@
|
||||
@@ -46,7 +46,7 @@ index f8a6d1868788..350c3572ec54 100644
|
||||
+ }
|
||||
}
|
||||
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn
|
||||
index 1b14d628a63b..00401612c191 100644
|
||||
index 1b14d628a63b90532bf25251d0bec6c3f1c7a723..00401612c191836043eb0343d3ee3d42acbd5ea4 100644
|
||||
--- a/chrome/browser/ui/BUILD.gn
|
||||
+++ b/chrome/browser/ui/BUILD.gn
|
||||
@@ -2570,7 +2570,10 @@ split_static_library("ui") {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
From 56f1078f33969f1d3c097b398a10d251ea774add Mon Sep 17 00:00:00 2001
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Cheng Zhao <zcbenz@gmail.com>
|
||||
Date: Thu, 20 Sep 2018 17:48:27 -0700
|
||||
Subject: disable_scroll_begin_dcheck.patch
|
||||
@@ -8,7 +8,7 @@ these assertions. I grouped them together since they are all related to the
|
||||
ScrollBegin event.
|
||||
|
||||
diff --git a/content/browser/renderer_host/input/mouse_wheel_event_queue.cc b/content/browser/renderer_host/input/mouse_wheel_event_queue.cc
|
||||
index 702915772e4f..71fb66a7401c 100644
|
||||
index 702915772e4f150b473d3092d5d3a217d0a14602..71fb66a7401c3d46156dbfa7bc443d7e0b6192e1 100644
|
||||
--- a/content/browser/renderer_host/input/mouse_wheel_event_queue.cc
|
||||
+++ b/content/browser/renderer_host/input/mouse_wheel_event_queue.cc
|
||||
@@ -295,7 +295,7 @@ void MouseWheelEventQueue::SendScrollEnd(WebGestureEvent update_event,
|
||||
@@ -21,7 +21,7 @@ index 702915772e4f..71fb66a7401c 100644
|
||||
WebGestureEvent scroll_begin(gesture_update);
|
||||
scroll_begin.SetType(WebInputEvent::kGestureScrollBegin);
|
||||
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc
|
||||
index 28879dc5e9bb..222b5d7e91ec 100644
|
||||
index 28879dc5e9bb3f391513da6a7ad829244b39799d..222b5d7e91ec07c3a471299a0d33e2c901b582fd 100644
|
||||
--- a/content/browser/renderer_host/render_widget_host_impl.cc
|
||||
+++ b/content/browser/renderer_host/render_widget_host_impl.cc
|
||||
@@ -1321,8 +1321,8 @@ void RenderWidgetHostImpl::ForwardGestureEventWithLatencyInfo(
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Sunny Sachanandani <sunnyps@chromium.org>
|
||||
Date: Fri, 18 Jan 2019 03:51:46 +0000
|
||||
Subject: Do not allow impl side invalidations until frame sink is fully active
|
||||
|
||||
Impl side invalidations can fill up the pipeline blocking main thread
|
||||
commit, but draw is blocked for the first commit and activation after
|
||||
a new frame sink is created causing a hang in BeginMainFrame.
|
||||
|
||||
In the repro, |has_pending_tree_| and |active_tree_needs_first_draw_|
|
||||
are both true while |layer_tree_frame_sink_state_| is
|
||||
WAITING_FOR_COMMIT. This means the first invalidation activated and the
|
||||
second one created a pending tree, but draw is blocked because the frame
|
||||
sink hasn't produced first commit and activation. It's also possible
|
||||
that only one invalidation would trigger this bug because the main
|
||||
thread commit won't be able to activate and draw would be blocked again.
|
||||
|
||||
With this change, impl side invalidations are blocked until the first
|
||||
commit and activation for a frame sink have gone through.
|
||||
|
||||
Reproduced using an internal test page (b/122271331) and verified that
|
||||
it's fixed. Also verified that included test fails before this change.
|
||||
|
||||
Hopefully this fixes all instances of this long standing hang.
|
||||
|
||||
Bug: 622080
|
||||
Change-Id: I4b6835e0487f1e48244f41805e63897c9661e674
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/1419132
|
||||
Commit-Queue: Sunny Sachanandani <sunnyps@chromium.org>
|
||||
Commit-Queue: Khushal <khushalsagar@chromium.org>
|
||||
Reviewed-by: Khushal <khushalsagar@chromium.org>
|
||||
Auto-Submit: Sunny Sachanandani <sunnyps@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/master@{#623998}
|
||||
|
||||
diff --git a/cc/scheduler/scheduler_state_machine.cc b/cc/scheduler/scheduler_state_machine.cc
|
||||
index a81baa256eab487995faae4f7242266f4c922190..588aa6b6cac770656384cef86b56d5445644dd48 100644
|
||||
--- a/cc/scheduler/scheduler_state_machine.cc
|
||||
+++ b/cc/scheduler/scheduler_state_machine.cc
|
||||
@@ -712,8 +712,12 @@ bool SchedulerStateMachine::CouldCreatePendingTree() const {
|
||||
if (begin_frame_source_paused_)
|
||||
return false;
|
||||
|
||||
- // Don't create a pending tree till a frame sink is initialized.
|
||||
- if (!HasInitializedLayerTreeFrameSink())
|
||||
+ // Don't create a pending tree till a frame sink is fully initialized. Check
|
||||
+ // for the ACTIVE state explicitly instead of calling
|
||||
+ // HasInitializedLayerTreeFrameSink() because that only checks if frame sink
|
||||
+ // has been recreated, but doesn't check if we're waiting for first commit or
|
||||
+ // activation.
|
||||
+ if (layer_tree_frame_sink_state_ != LayerTreeFrameSinkState::ACTIVE)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
diff --git a/cc/scheduler/scheduler_state_machine_unittest.cc b/cc/scheduler/scheduler_state_machine_unittest.cc
|
||||
index aa742f8a8a2bf98a5d3a810d4164a44772719530..26d3adafda6236aebbfe8686c38bfa4181e9e470 100644
|
||||
--- a/cc/scheduler/scheduler_state_machine_unittest.cc
|
||||
+++ b/cc/scheduler/scheduler_state_machine_unittest.cc
|
||||
@@ -2310,24 +2310,63 @@ TEST(SchedulerStateMachineTest,
|
||||
SchedulerStateMachine::Action::PERFORM_IMPL_SIDE_INVALIDATION);
|
||||
}
|
||||
|
||||
-TEST(SchedulerStateMachineTest,
|
||||
- NoImplSideInvalidationWithoutLayerTreeFrameSink) {
|
||||
+TEST(SchedulerStateMachineTest, NoImplSideInvalidationUntilFrameSinkActive) {
|
||||
SchedulerSettings settings;
|
||||
StateMachine state(settings);
|
||||
- SET_UP_STATE(state);
|
||||
+ SET_UP_STATE(state)
|
||||
+
|
||||
+ // Prefer impl side invalidation over begin main frame.
|
||||
+ state.set_should_defer_invalidation_for_fast_main_frame(false);
|
||||
|
||||
- // Impl-side invalidations should not be triggered till the frame sink is
|
||||
- // initialized.
|
||||
state.DidLoseLayerTreeFrameSink();
|
||||
+
|
||||
+ // Create new frame sink but don't commit or activate yet.
|
||||
EXPECT_ACTION_UPDATE_STATE(
|
||||
SchedulerStateMachine::Action::BEGIN_LAYER_TREE_FRAME_SINK_CREATION);
|
||||
- EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::NONE);
|
||||
|
||||
- // No impl-side invalidations should be performed during frame sink creation.
|
||||
+ state.DidCreateAndInitializeLayerTreeFrameSink();
|
||||
+ state.SetNeedsBeginMainFrame();
|
||||
+
|
||||
bool needs_first_draw_on_activation = true;
|
||||
state.SetNeedsImplSideInvalidation(needs_first_draw_on_activation);
|
||||
+
|
||||
+ state.IssueNextBeginImplFrame();
|
||||
+ EXPECT_ACTION_UPDATE_STATE(
|
||||
+ SchedulerStateMachine::Action::SEND_BEGIN_MAIN_FRAME);
|
||||
+ // No impl side invalidation because we're still waiting for first commit.
|
||||
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::NONE);
|
||||
+
|
||||
+ state.NotifyBeginMainFrameStarted();
|
||||
+ state.NotifyReadyToCommit();
|
||||
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::COMMIT);
|
||||
+
|
||||
+ state.OnBeginImplFrameDeadline();
|
||||
+ state.OnBeginImplFrameIdle();
|
||||
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::NONE);
|
||||
+
|
||||
+ state.SetNeedsImplSideInvalidation(needs_first_draw_on_activation);
|
||||
+
|
||||
state.IssueNextBeginImplFrame();
|
||||
+ // No impl side invalidation because we're still waiting for first activation.
|
||||
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::NONE);
|
||||
+
|
||||
+ state.NotifyReadyToActivate();
|
||||
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::ACTIVATE_SYNC_TREE);
|
||||
+
|
||||
+ state.OnBeginImplFrameDeadline();
|
||||
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::Action::DRAW_IF_POSSIBLE);
|
||||
+ state.OnBeginImplFrameIdle();
|
||||
+
|
||||
+ state.SetNeedsBeginMainFrame();
|
||||
+ state.SetNeedsImplSideInvalidation(needs_first_draw_on_activation);
|
||||
+
|
||||
+ state.IssueNextBeginImplFrame();
|
||||
+ EXPECT_ACTION_UPDATE_STATE(
|
||||
+ SchedulerStateMachine::Action::SEND_BEGIN_MAIN_FRAME);
|
||||
+ // Impl side invalidation only after receiving first commit and activation for
|
||||
+ // new frame sink.
|
||||
+ EXPECT_ACTION_UPDATE_STATE(
|
||||
+ SchedulerStateMachine::Action::PERFORM_IMPL_SIDE_INVALIDATION);
|
||||
}
|
||||
|
||||
TEST(SchedulerStateMachineTest, ImplSideInvalidationWhenPendingTreeExists) {
|
||||
@@ -32,36 +32,36 @@ for a given `BrowserWindow` via a `webPreferences` option,
|
||||
similar to [`nodeIntegration`](https://electronjs.org/docs/tutorial/security#2-disable-nodejs-integration-for-remote-content).
|
||||
|
||||
diff --git a/content/common/dom_storage/dom_storage_map.cc b/content/common/dom_storage/dom_storage_map.cc
|
||||
index fd088fb170be..b90b6cf9132d 100644
|
||||
index fd088fb170bead6452ded14016f21f0c29659e03..b90b6cf9132d16bc3b2076c3fa313916e2b5ea7d 100644
|
||||
--- a/content/common/dom_storage/dom_storage_map.cc
|
||||
+++ b/content/common/dom_storage/dom_storage_map.cc
|
||||
@@ -185,10 +185,12 @@ bool DOMStorageMap::SetItemInternal(MapType* map_type,
|
||||
size_t new_item_size = size_in_storage(key, value);
|
||||
size_t new_storage_used = storage_used_ - old_item_size + new_item_size;
|
||||
|
||||
|
||||
+#if 0
|
||||
// Only check quota if the size is increasing, this allows
|
||||
// shrinking changes to pre-existing files that are over budget.
|
||||
if (new_item_size > old_item_size && new_storage_used > quota_)
|
||||
return false;
|
||||
+#endif
|
||||
|
||||
|
||||
(*map_type)[key] = value;
|
||||
ResetKeyIterator();
|
||||
diff --git a/content/common/dom_storage/dom_storage_types.h b/content/common/dom_storage/dom_storage_types.h
|
||||
index e87afe5b8ee0..61c9a0dfff60 100644
|
||||
index e87afe5b8ee07f7038a7cc9c40832b6cd27884da..61c9a0dfff60f79c7b36ff5c7d741c06dca03ada 100644
|
||||
--- a/content/common/dom_storage/dom_storage_types.h
|
||||
+++ b/content/common/dom_storage/dom_storage_types.h
|
||||
@@ -21,6 +21,7 @@ typedef std::map<base::string16, base::NullableString16> DOMStorageValuesMap;
|
||||
|
||||
|
||||
// The quota for each storage area.
|
||||
// This value is enforced in renderer processes and the browser process.
|
||||
+// However, Electron's dom_storage_limits.patch removes the code that checks this limit.
|
||||
const size_t kPerStorageAreaQuota = 10 * 1024 * 1024;
|
||||
|
||||
|
||||
// In the browser process we allow some overage to
|
||||
diff --git a/content/renderer/dom_storage/dom_storage_cached_area.cc b/content/renderer/dom_storage/dom_storage_cached_area.cc
|
||||
index 402c27727ff1..f5908a1c55f9 100644
|
||||
index 402c27727ff13f634e7e4d9a0fc714795f52b8c0..f5908a1c55f95f41ee532ccfdcbc2e2670a01d4b 100644
|
||||
--- a/content/renderer/dom_storage/dom_storage_cached_area.cc
|
||||
+++ b/content/renderer/dom_storage/dom_storage_cached_area.cc
|
||||
@@ -53,11 +53,13 @@ bool DOMStorageCachedArea::SetItem(int connection_id,
|
||||
@@ -75,11 +75,11 @@ index 402c27727ff1..f5908a1c55f9 100644
|
||||
kPerStorageAreaQuota)
|
||||
return false;
|
||||
+#endif
|
||||
|
||||
|
||||
PrimeIfNeeded(connection_id);
|
||||
base::NullableString16 old_value;
|
||||
diff --git a/content/renderer/dom_storage/local_storage_cached_area.cc b/content/renderer/dom_storage/local_storage_cached_area.cc
|
||||
index ffa21c9200d0..0edbd6152292 100644
|
||||
index ffa21c9200d0488db57eb598235e730d6aaa3687..0edbd615229238203fa1a3593802e712e3bfee4e 100644
|
||||
--- a/content/renderer/dom_storage/local_storage_cached_area.cc
|
||||
+++ b/content/renderer/dom_storage/local_storage_cached_area.cc
|
||||
@@ -141,11 +141,13 @@ bool LocalStorageCachedArea::SetItem(const base::string16& key,
|
||||
@@ -93,6 +93,6 @@ index ffa21c9200d0..0edbd6152292 100644
|
||||
kPerStorageAreaQuota)
|
||||
return false;
|
||||
+#endif
|
||||
|
||||
|
||||
EnsureLoaded();
|
||||
bool result = false;
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Dave Tapuska <dtapuska@chromium.org>
|
||||
Date: Mon, 11 Jun 2018 19:26:48 +0000
|
||||
Subject: Enable InputPane virtual keyboard functionality by default.
|
||||
|
||||
Flip feature flag on. New functionality is used for Windows 10 RS4 and
|
||||
later.
|
||||
|
||||
BUG=817501
|
||||
|
||||
Change-Id: I3c45ac35f925a3b72f2ff50d5f8fdad4895b3cfd
|
||||
Reviewed-on: https://chromium-review.googlesource.com/946928
|
||||
Commit-Queue: Dave Tapuska <dtapuska@chromium.org>
|
||||
Reviewed-by: Scott Violet <sky@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/master@{#566102}
|
||||
|
||||
diff --git a/ui/base/ui_base_features.cc b/ui/base/ui_base_features.cc
|
||||
index a2431e836940c4a1fc7fc95f128a2e2d5aab1b02..80add9507320a8e0dfb42f024095870faa7b3e3c 100644
|
||||
--- a/ui/base/ui_base_features.cc
|
||||
+++ b/ui/base/ui_base_features.cc
|
||||
@@ -97,7 +97,7 @@ const base::Feature kUiCompositorScrollWithLayers = {
|
||||
#if defined(OS_WIN)
|
||||
// Enables InputPane API for controlling on screen keyboard.
|
||||
const base::Feature kInputPaneOnScreenKeyboard = {
|
||||
- "InputPaneOnScreenKeyboard", base::FEATURE_DISABLED_BY_DEFAULT};
|
||||
+ "InputPaneOnScreenKeyboard", base::FEATURE_ENABLED_BY_DEFAULT};
|
||||
|
||||
// Enables using WM_POINTER instead of WM_TOUCH for touch events.
|
||||
const base::Feature kPointerEventsForTouch = {"PointerEventsForTouch",
|
||||
@@ -15,7 +15,7 @@ index 55df34044af7bafb55521738a6581410877494c0..56da4a1012a6bcf7a500c0e600a08776
|
||||
+++ b/chrome/browser/io_thread.cc
|
||||
@@ -360,6 +360,11 @@ void IOThread::Init() {
|
||||
#endif
|
||||
|
||||
|
||||
ConstructSystemRequestContext();
|
||||
+
|
||||
+ // Prevent DCHECK failures when a NetworkContext is created with an encrypted
|
||||
@@ -23,7 +23,7 @@ index 55df34044af7bafb55521738a6581410877494c0..56da4a1012a6bcf7a500c0e600a08776
|
||||
+ if (!base::FeatureList::IsEnabled(network::features::kNetworkService))
|
||||
+ content::GetNetworkServiceImpl()->set_os_crypt_is_configured();
|
||||
}
|
||||
|
||||
|
||||
void IOThread::CleanUp() {
|
||||
diff --git a/chrome/browser/profiles/off_the_record_profile_io_data.cc b/chrome/browser/profiles/off_the_record_profile_io_data.cc
|
||||
index ebb7e95151156209aae7234de0e17ef9241335a7..de61d90917a40d0d64bb7c15daad0fd2c1147247 100644
|
||||
@@ -32,7 +32,7 @@ index ebb7e95151156209aae7234de0e17ef9241335a7..de61d90917a40d0d64bb7c15daad0fd2
|
||||
@@ -215,14 +215,6 @@ void OffTheRecordProfileIOData::InitializeInternal(
|
||||
std::make_unique<net::ChannelIDService>(
|
||||
new net::DefaultChannelIDStore(nullptr)));
|
||||
|
||||
|
||||
- using content::CookieStoreConfig;
|
||||
- std::unique_ptr<net::CookieStore> cookie_store(CreateCookieStore(
|
||||
- CookieStoreConfig(base::FilePath(), false, false, nullptr)));
|
||||
@@ -51,7 +51,7 @@ index 6dd54b7d045f38195c3858699dbd4ac5ad877277..c4038dc1e9cd5c13e946919ef5747357
|
||||
@@ -450,49 +450,6 @@ void ProfileImplIOData::InitializeInternal(
|
||||
IOThread* const io_thread = profile_params->io_thread;
|
||||
IOThread::Globals* const io_thread_globals = io_thread->globals();
|
||||
|
||||
|
||||
- // This check is needed because with the network service the cookies are used
|
||||
- // in a different process. See the bottom of
|
||||
- // ProfileNetworkContextService::SetUpProfileIODataMainContext.
|
||||
@@ -96,7 +96,7 @@ index 6dd54b7d045f38195c3858699dbd4ac5ad877277..c4038dc1e9cd5c13e946919ef5747357
|
||||
- }
|
||||
-
|
||||
AddProtocolHandlersToBuilder(builder, protocol_handlers);
|
||||
|
||||
|
||||
// Install the Offline Page Interceptor.
|
||||
diff --git a/services/network/network_context.cc b/services/network/network_context.cc
|
||||
index 50b4f60a47c046796f2452a7454e2ed821113d3c..ec799409ac3597c2437d38a8686efcb8448255b8 100644
|
||||
@@ -120,12 +120,12 @@ index 50b4f60a47c046796f2452a7454e2ed821113d3c..ec799409ac3597c2437d38a8686efcb8
|
||||
- &session_cleanup_cookie_store, &session_cleanup_channel_id_store);
|
||||
+ url_request_context_owner_ = MakeURLRequestContext();
|
||||
url_request_context_ = url_request_context_owner_.url_request_context.get();
|
||||
|
||||
|
||||
network_service_->RegisterNetworkContext(this);
|
||||
@@ -323,10 +321,6 @@ NetworkContext::NetworkContext(
|
||||
binding_.set_connection_error_handler(base::BindOnce(
|
||||
&NetworkContext::OnConnectionError, base::Unretained(this)));
|
||||
|
||||
|
||||
- cookie_manager_ = std::make_unique<CookieManager>(
|
||||
- url_request_context_->cookie_store(), session_cleanup_cookie_store,
|
||||
- session_cleanup_channel_id_store,
|
||||
@@ -135,7 +135,7 @@ index 50b4f60a47c046796f2452a7454e2ed821113d3c..ec799409ac3597c2437d38a8686efcb8
|
||||
resource_scheduler_ =
|
||||
@@ -348,9 +342,6 @@ NetworkContext::NetworkContext(
|
||||
url_request_context_ = url_request_context_owner_.url_request_context.get();
|
||||
|
||||
|
||||
network_service_->RegisterNetworkContext(this);
|
||||
- cookie_manager_ = std::make_unique<CookieManager>(
|
||||
- url_request_context_->cookie_store(), nullptr, nullptr,
|
||||
@@ -146,7 +146,7 @@ index 50b4f60a47c046796f2452a7454e2ed821113d3c..ec799409ac3597c2437d38a8686efcb8
|
||||
@@ -819,6 +810,61 @@ URLRequestContextOwner NetworkContext::ApplyContextParamsToBuilder(
|
||||
network_service_->network_quality_estimator());
|
||||
}
|
||||
|
||||
|
||||
+ scoped_refptr<network::SessionCleanupCookieStore>
|
||||
+ session_cleanup_cookie_store;
|
||||
+ scoped_refptr<SessionCleanupChannelIDStore> session_cleanup_channel_id_store;
|
||||
@@ -208,7 +208,7 @@ index 50b4f60a47c046796f2452a7454e2ed821113d3c..ec799409ac3597c2437d38a8686efcb8
|
||||
@@ -1065,6 +1111,12 @@ URLRequestContextOwner NetworkContext::ApplyContextParamsToBuilder(
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
+ cookie_manager_ = std::make_unique<CookieManager>(
|
||||
+ result.url_request_context->cookie_store(),
|
||||
+ std::move(session_cleanup_cookie_store),
|
||||
@@ -217,11 +217,11 @@ index 50b4f60a47c046796f2452a7454e2ed821113d3c..ec799409ac3597c2437d38a8686efcb8
|
||||
+
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -1098,71 +1150,11 @@ void NetworkContext::OnConnectionError() {
|
||||
std::move(on_connection_close_callback_).Run(this);
|
||||
}
|
||||
|
||||
|
||||
-URLRequestContextOwner NetworkContext::MakeURLRequestContext(
|
||||
- SessionCleanupCookieStore** session_cleanup_cookie_store,
|
||||
- SessionCleanupChannelIDStore** session_cleanup_channel_id_store) {
|
||||
@@ -229,7 +229,7 @@ index 50b4f60a47c046796f2452a7454e2ed821113d3c..ec799409ac3597c2437d38a8686efcb8
|
||||
URLRequestContextBuilderMojo builder;
|
||||
const base::CommandLine* command_line =
|
||||
base::CommandLine::ForCurrentProcess();
|
||||
|
||||
|
||||
- // The cookie configuration is in this method, which is only used by the
|
||||
- // network process, and not ApplyContextParamsToBuilder which is used by the
|
||||
- // browser as well. This is because this code path doesn't handle encryption
|
||||
@@ -305,7 +305,7 @@ index 83459ab0f23ea0190bae410921391ca9d11c5aa9..4b25717b4be3a21249d177f0c7caca61
|
||||
#include "services/network/public/mojom/network_context.mojom.h"
|
||||
@@ -51,6 +50,7 @@ class TreeStateTracker;
|
||||
} // namespace certificate_transparency
|
||||
|
||||
|
||||
namespace network {
|
||||
+class CookieManager;
|
||||
class ExpectCTReporter;
|
||||
@@ -314,14 +314,14 @@ index 83459ab0f23ea0190bae410921391ca9d11c5aa9..4b25717b4be3a21249d177f0c7caca61
|
||||
@@ -233,9 +233,7 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) NetworkContext
|
||||
// On connection errors the NetworkContext destroys itself.
|
||||
void OnConnectionError();
|
||||
|
||||
|
||||
- URLRequestContextOwner MakeURLRequestContext(
|
||||
- SessionCleanupCookieStore** session_cleanup_cookie_store,
|
||||
- SessionCleanupChannelIDStore** session_cleanup_channel_id_store);
|
||||
+ URLRequestContextOwner MakeURLRequestContext();
|
||||
|
||||
|
||||
NetworkService* const network_service_;
|
||||
|
||||
|
||||
diff --git a/services/network/network_context_unittest.cc b/services/network/network_context_unittest.cc
|
||||
index c756789a39f3d265c536a69d899512e816708344..88cdcc0b5433087c15edad4e6a977bb2a127f834 100644
|
||||
--- a/services/network/network_context_unittest.cc
|
||||
@@ -341,7 +341,7 @@ index c4df8eceaad173b580c8fa91aca6cfdced5f571b..a91a9f4b5866c11ae76e2d173a92579f
|
||||
@@ -169,6 +169,10 @@ NetworkService::~NetworkService() {
|
||||
DCHECK(network_contexts_.empty());
|
||||
}
|
||||
|
||||
|
||||
+void NetworkService::set_os_crypt_is_configured() {
|
||||
+ os_crypt_config_set_ = true;
|
||||
+}
|
||||
@@ -362,9 +362,9 @@ index 839a5da98be9adaa836a3881f5a42fde069c860c..a686fd84e0cf61219289d6f5ee9c700e
|
||||
--- a/services/network/network_service.h
|
||||
+++ b/services/network/network_service.h
|
||||
@@ -62,6 +62,11 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) NetworkService
|
||||
|
||||
|
||||
~NetworkService() override;
|
||||
|
||||
|
||||
+ // Call to inform the NetworkService that OSCrypt::SetConfig() has already
|
||||
+ // been invoked, so OSCrypt::SetConfig() does not need to be called before
|
||||
+ // encrypted storage can be used.
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Kent Tamura <tkent@chromium.org>
|
||||
Date: Thu, 20 Dec 2018 00:22:07 +0000
|
||||
Subject: Fix crashes in RenderFrameImpl::OnSelectPopupMenuItem(s)
|
||||
|
||||
ExternalPopupMenu::DidSelectItem(s) can delete the RenderFrameImpl.
|
||||
We need to reset external_popup_menu_ before calling it.
|
||||
|
||||
Bug: 912211
|
||||
Change-Id: Ia9a628e144464a2ebb14ab77d3a693fd5cead6fc
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/1381325
|
||||
Commit-Queue: Kent Tamura <tkent@chromium.org>
|
||||
Reviewed-by: Avi Drissman <avi@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/master@{#618026}
|
||||
|
||||
diff --git a/content/renderer/external_popup_menu_browsertest.cc b/content/renderer/external_popup_menu_browsertest.cc
|
||||
index d3cff681551c4961a4a47c48bac9155b22fd7524..0ea34d8809f1b191504d2cc833f74fef694230d3 100644
|
||||
--- a/content/renderer/external_popup_menu_browsertest.cc
|
||||
+++ b/content/renderer/external_popup_menu_browsertest.cc
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "content/renderer/render_view_impl.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
#include "third_party/blink/public/platform/web_size.h"
|
||||
+#include "third_party/blink/public/web/web_local_frame.h"
|
||||
#include "third_party/blink/public/web/web_view.h"
|
||||
|
||||
// Tests for the external select popup menu (Mac specific).
|
||||
@@ -153,6 +154,31 @@ TEST_F(ExternalPopupMenuRemoveTest, RemoveOnChange) {
|
||||
EXPECT_FALSE(SimulateElementClick(kSelectID));
|
||||
}
|
||||
|
||||
+// crbug.com/912211
|
||||
+TEST_F(ExternalPopupMenuRemoveTest, RemoveFrameOnChange) {
|
||||
+ LoadHTML(
|
||||
+ "<style>* { margin: 0; } iframe { border: 0; }</style>"
|
||||
+ "<body><iframe srcdoc=\""
|
||||
+ "<style>* { margin: 0; }</style><select><option>opt1<option>opt2"
|
||||
+ "\"></iframe>"
|
||||
+ "<script>"
|
||||
+ "onload = function() {"
|
||||
+ " const frame = document.querySelector('iframe');"
|
||||
+ " frame.contentDocument.querySelector('select').onchange = "
|
||||
+ " () => { frame.remove(); };"
|
||||
+ "};"
|
||||
+ "</script>");
|
||||
+ // Open a popup.
|
||||
+ SimulatePointClick(gfx::Point(8, 8));
|
||||
+ // Select something on the sub-frame, it causes the frame to be removed from
|
||||
+ // the page.
|
||||
+ auto* child_web_frame =
|
||||
+ static_cast<blink::WebLocalFrame*>(frame()->GetWebFrame()->FirstChild());
|
||||
+ static_cast<RenderFrameImpl*>(RenderFrame::FromWebFrame(child_web_frame))
|
||||
+ ->OnSelectPopupMenuItem(1);
|
||||
+ // The test passes if the test didn't crash and ASAN didn't complain.
|
||||
+}
|
||||
+
|
||||
class ExternalPopupMenuDisplayNoneTest : public ExternalPopupMenuTest {
|
||||
public:
|
||||
ExternalPopupMenuDisplayNoneTest() {}
|
||||
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
|
||||
index 9571ea0233e84e3ab2f2159018efd12f18adcea9..7db2fa3591040b73a55ac620cbf35816afbd715f 100644
|
||||
--- a/content/renderer/render_frame_impl.cc
|
||||
+++ b/content/renderer/render_frame_impl.cc
|
||||
@@ -6473,8 +6473,12 @@ void RenderFrameImpl::OnSelectPopupMenuItem(int selected_index) {
|
||||
return;
|
||||
|
||||
blink::WebScopedUserGesture gesture(frame_);
|
||||
- external_popup_menu_->DidSelectItem(selected_index);
|
||||
- external_popup_menu_.reset();
|
||||
+ // We need to reset |external_popup_menu_| before calling DidSelectItem(),
|
||||
+ // which might delete |this|.
|
||||
+ // See ExternalPopupMenuRemoveTest.RemoveFrameOnChange
|
||||
+ std::unique_ptr<ExternalPopupMenu> popup;
|
||||
+ popup.swap(external_popup_menu_);
|
||||
+ popup->DidSelectItem(selected_index);
|
||||
}
|
||||
#else
|
||||
void RenderFrameImpl::OnSelectPopupMenuItems(
|
||||
@@ -6488,8 +6492,12 @@ void RenderFrameImpl::OnSelectPopupMenuItems(
|
||||
return;
|
||||
|
||||
blink::WebScopedUserGesture gesture(frame_);
|
||||
- external_popup_menu_->DidSelectItems(canceled, selected_indices);
|
||||
- external_popup_menu_.reset();
|
||||
+ // We need to reset |external_popup_menu_| before calling DidSelectItems(),
|
||||
+ // which might delete |this|.
|
||||
+ // See ExternalPopupMenuRemoveTest.RemoveFrameOnChange
|
||||
+ std::unique_ptr<ExternalPopupMenu> popup;
|
||||
+ popup.swap(external_popup_menu_);
|
||||
+ popup->DidSelectItems(canceled, selected_indices);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h
|
||||
index cb5ffc56b005d8fb5492c1254bf533a370d42448..c9fea9da0cf2e24cd1c1581cbe939a736edd65bf 100644
|
||||
--- a/content/renderer/render_frame_impl.h
|
||||
+++ b/content/renderer/render_frame_impl.h
|
||||
@@ -900,6 +900,7 @@ class CONTENT_EXPORT RenderFrameImpl
|
||||
friend class RenderAccessibilityImplTest;
|
||||
friend class TestRenderFrame;
|
||||
FRIEND_TEST_ALL_PREFIXES(ExternalPopupMenuDisplayNoneTest, SelectItem);
|
||||
+ FRIEND_TEST_ALL_PREFIXES(ExternalPopupMenuRemoveTest, RemoveFrameOnChange);
|
||||
FRIEND_TEST_ALL_PREFIXES(ExternalPopupMenuRemoveTest, RemoveOnChange);
|
||||
FRIEND_TEST_ALL_PREFIXES(ExternalPopupMenuTest, NormalCase);
|
||||
FRIEND_TEST_ALL_PREFIXES(ExternalPopupMenuTest, ShowPopupThenNavigate);
|
||||
@@ -0,0 +1,126 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: kylechar <kylechar@chromium.org>
|
||||
Date: Mon, 3 Dec 2018 18:17:17 +0000
|
||||
Subject: Fix re-entracy problem with InvalidateFrameSinkId().
|
||||
|
||||
HostFrameSinkManager::InvalidateFrameSinkId() can make a synchronous IPC
|
||||
to ensure whatever is drawing the platform window is destroyed before
|
||||
the platform window gets destroyed. However, while waiting for the
|
||||
synchronous IPC response other synchronous IPCs continue to get
|
||||
processed. |frame_sink_data_map_| can get mutated in response to a
|
||||
different synchronous IPC and |data| may no longer point to a valid
|
||||
memory location when DestroyCompositorFrameSink() returns.
|
||||
|
||||
Change the order so that all modifications to |data| happen before the
|
||||
synchronous IPC. Also add a comment to clarify that FrameSinkIds
|
||||
shouldn't be reused after they are invalidated. We don't do this today
|
||||
and it would cause more re-entrancy problems.
|
||||
|
||||
Also switch |frame_sink_data_map_| to use std::unordered_map instead of
|
||||
base::flat_map. This map can get large (tens of elements per open tab)
|
||||
so std::unordered_map is probably a better choice.
|
||||
|
||||
Bug: 907211
|
||||
Change-Id: Iea42d1eca290f5b61f215c66da9b9021f671c1e0
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/1352525
|
||||
Reviewed-by: Sadrul Chowdhury <sadrul@chromium.org>
|
||||
Commit-Queue: Sadrul Chowdhury <sadrul@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/master@{#613160}
|
||||
|
||||
diff --git a/components/viz/host/host_frame_sink_manager.cc b/components/viz/host/host_frame_sink_manager.cc
|
||||
index 53ccb9f26f8ce6bb472487d4650c0b1a51b9a4c6..bceb1bd9d96e11080928014e2c30674690e28a06 100644
|
||||
--- a/components/viz/host/host_frame_sink_manager.cc
|
||||
+++ b/components/viz/host/host_frame_sink_manager.cc
|
||||
@@ -79,15 +79,9 @@ void HostFrameSinkManager::InvalidateFrameSinkId(
|
||||
FrameSinkData& data = frame_sink_data_map_[frame_sink_id];
|
||||
DCHECK(data.IsFrameSinkRegistered());
|
||||
|
||||
- if (data.has_created_compositor_frame_sink && data.is_root) {
|
||||
- // This synchronous call ensures that the GL context/surface that draw to
|
||||
- // the platform window (eg. XWindow or HWND) get destroyed before the
|
||||
- // platform window is destroyed.
|
||||
- mojo::SyncCallRestrictions::ScopedAllowSyncCall allow_sync_call;
|
||||
- frame_sink_manager_->DestroyCompositorFrameSink(frame_sink_id);
|
||||
- }
|
||||
+ const bool destroy_synchronously =
|
||||
+ data.has_created_compositor_frame_sink && data.is_root;
|
||||
|
||||
- frame_sink_manager_->InvalidateFrameSinkId(frame_sink_id);
|
||||
data.has_created_compositor_frame_sink = false;
|
||||
data.client = nullptr;
|
||||
|
||||
@@ -96,6 +90,21 @@ void HostFrameSinkManager::InvalidateFrameSinkId(
|
||||
frame_sink_data_map_.erase(frame_sink_id);
|
||||
|
||||
display_hit_test_query_.erase(frame_sink_id);
|
||||
+
|
||||
+ if (destroy_synchronously) {
|
||||
+ // This synchronous call ensures that the GL context/surface that draw to
|
||||
+ // the platform window (eg. XWindow or HWND) get destroyed before the
|
||||
+ // platform window is destroyed.
|
||||
+ mojo::SyncCallRestrictions::ScopedAllowSyncCall allow_sync_call;
|
||||
+ frame_sink_manager_->DestroyCompositorFrameSink(frame_sink_id);
|
||||
+
|
||||
+ // Other synchronous IPCs continue to get processed while
|
||||
+ // DestroyCompositorFrameSink() is happening, so it's possible
|
||||
+ // HostFrameSinkManager has been mutated. |data| might not be a valid
|
||||
+ // reference at this point.
|
||||
+ }
|
||||
+
|
||||
+ frame_sink_manager_->InvalidateFrameSinkId(frame_sink_id);
|
||||
}
|
||||
|
||||
void HostFrameSinkManager::EnableSynchronizationReporting(
|
||||
diff --git a/components/viz/host/host_frame_sink_manager.h b/components/viz/host/host_frame_sink_manager.h
|
||||
index 1b6a6aca6d5cd58400bd0dd6784085f9dfd77ddb..68d0a251b0b60aac77fe04e1e910b51364357ae7 100644
|
||||
--- a/components/viz/host/host_frame_sink_manager.h
|
||||
+++ b/components/viz/host/host_frame_sink_manager.h
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
+#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include "base/compiler_specific.h"
|
||||
@@ -72,15 +73,24 @@ class VIZ_HOST_EXPORT HostFrameSinkManager
|
||||
// Sets a callback to be notified after Viz sent bad message to Viz host.
|
||||
void SetBadMessageReceivedFromGpuCallback(base::RepeatingClosure callback);
|
||||
|
||||
- // Registers |frame_sink_id| will be used. This must be called before
|
||||
- // CreateCompositorFrameSink(Support) is called.
|
||||
+ // Registers |frame_sink_id| so that a client can submit CompositorFrames
|
||||
+ // using it. This must be called before creating a CompositorFrameSink or
|
||||
+ // registering FrameSinkId hierarchy.
|
||||
+ //
|
||||
+ // When the client is done submitting CompositorFrames to |frame_sink_id| then
|
||||
+ // InvalidateFrameSink() should be called.
|
||||
void RegisterFrameSinkId(const FrameSinkId& frame_sink_id,
|
||||
HostFrameSinkClient* client);
|
||||
|
||||
- // Invalidates |frame_sink_id| which cleans up any dangling temporary
|
||||
- // references assigned to it. If there is a CompositorFrameSink for
|
||||
- // |frame_sink_id| then it will be destroyed and the message pipe to the
|
||||
- // client will be closed.
|
||||
+ // Invalidates |frame_sink_id| when the client is done submitting
|
||||
+ // CompositorFrames. If there is a CompositorFrameSink for |frame_sink_id|
|
||||
+ // then it will be destroyed and the message pipe to the client will be
|
||||
+ // closed.
|
||||
+ //
|
||||
+ // It's expected, but not enforced, that RegisterFrameSinkId() will never be
|
||||
+ // called for |frame_sink_id| again. This is to avoid problems with re-entrant
|
||||
+ // code. If the same client wants to submit CompositorFrames later a new
|
||||
+ // FrameSinkId should be allocated.
|
||||
void InvalidateFrameSinkId(const FrameSinkId& frame_sink_id);
|
||||
|
||||
// Tells FrameSinkManger to report when a synchronization event completes via
|
||||
@@ -256,7 +266,8 @@ class VIZ_HOST_EXPORT HostFrameSinkManager
|
||||
FrameSinkManagerImpl* frame_sink_manager_impl_ = nullptr;
|
||||
|
||||
// Per CompositorFrameSink data.
|
||||
- base::flat_map<FrameSinkId, FrameSinkData> frame_sink_data_map_;
|
||||
+ std::unordered_map<FrameSinkId, FrameSinkData, FrameSinkIdHash>
|
||||
+ frame_sink_data_map_;
|
||||
|
||||
// If |frame_sink_manager_ptr_| connection was lost.
|
||||
bool connection_was_lost_ = false;
|
||||
@@ -0,0 +1,37 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Samuel Attard <sattard@slack-corp.com>
|
||||
Date: Wed, 20 Mar 2019 22:48:27 -0700
|
||||
Subject: Fix system tray icons being cropped under KDE
|
||||
|
||||
The code that adds padding to too small icons was breaking the larger
|
||||
ones by cutting the minimal size (22x22px) out of their center.
|
||||
|
||||
Backports: https://chromium-review.googlesource.com/c/chromium/src/+/1173235
|
||||
|
||||
diff --git a/chrome/browser/ui/libgtkui/app_indicator_icon.cc b/chrome/browser/ui/libgtkui/app_indicator_icon.cc
|
||||
index 5aeb9d4d115ccae7763872aaa50734ead5228ec6..96134270493893c27b1f903028097220a6dd6fcf 100644
|
||||
--- a/chrome/browser/ui/libgtkui/app_indicator_icon.cc
|
||||
+++ b/chrome/browser/ui/libgtkui/app_indicator_icon.cc
|
||||
@@ -285,15 +285,16 @@ AppIndicatorIcon::WriteKDE4TempImageOnWorkerThread(
|
||||
std::string icon_name = base::StringPrintf(
|
||||
"chrome_app_indicator2_%s", base::MD5DigestToBase16(digest).c_str());
|
||||
|
||||
- // If |bitmap| is not 22x22, KDE does some really ugly resizing. Pad |bitmap|
|
||||
- // with transparent pixels to make it 22x22.
|
||||
- const int kDesiredSize = 22;
|
||||
+ // If |bitmap| is smaller than 22x22, KDE does some really ugly resizing.
|
||||
+ // Pad |bitmap| with transparent pixels to make it 22x22.
|
||||
+ const int kMinimalSize = 22;
|
||||
SkBitmap scaled_bitmap;
|
||||
- scaled_bitmap.allocN32Pixels(kDesiredSize, kDesiredSize);
|
||||
+ scaled_bitmap.allocN32Pixels(std::max(bitmap.width(), kMinimalSize),
|
||||
+ std::max(bitmap.height(), kMinimalSize));
|
||||
scaled_bitmap.eraseARGB(0, 0, 0, 0);
|
||||
SkCanvas canvas(scaled_bitmap);
|
||||
- canvas.drawBitmap(bitmap, (kDesiredSize - bitmap.width()) / 2,
|
||||
- (kDesiredSize - bitmap.height()) / 2);
|
||||
+ canvas.drawBitmap(bitmap, (scaled_bitmap.width() - bitmap.width()) / 2,
|
||||
+ (scaled_bitmap.height() - bitmap.height()) / 2);
|
||||
|
||||
base::FilePath image_path = image_dir.Append(icon_name + ".png");
|
||||
if (!WriteFile(image_path, scaled_bitmap))
|
||||
@@ -1,6 +1,6 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Cheng Zhao <zcbenz@gmail.com>
|
||||
Date: Mon Nov 26 09:32:14 2018 +0900
|
||||
Date: Mon, 26 Nov 2018 09:32:14 +0900
|
||||
Subject: fix_trackpad_scrolling.patch
|
||||
|
||||
Backport https://chromium-review.googlesource.com/c/chromium/src/+/1299342.
|
||||
@@ -9,7 +9,7 @@ This patch fixes https://github.com/electron/electron/issues/8960, and can be
|
||||
removed after upgraded to Chrome 72.
|
||||
|
||||
diff --git a/gpu/ipc/service/child_window_win.cc b/gpu/ipc/service/child_window_win.cc
|
||||
index d531234..3cce23e 100644
|
||||
index d531234e480e8b67582f69105de9ec42d857d840..3cce23ef71563a8106b35dcbdf561acd33c22625 100644
|
||||
--- a/gpu/ipc/service/child_window_win.cc
|
||||
+++ b/gpu/ipc/service/child_window_win.cc
|
||||
@@ -9,7 +9,6 @@
|
||||
@@ -20,7 +20,7 @@ index d531234..3cce23e 100644
|
||||
#include "base/win/scoped_hdc.h"
|
||||
#include "base/win/wrapped_window_proc.h"
|
||||
#include "gpu/ipc/common/gpu_messages.h"
|
||||
@@ -21,49 +20,11 @@
|
||||
@@ -21,48 +20,10 @@
|
||||
|
||||
namespace gpu {
|
||||
|
||||
@@ -38,7 +38,7 @@ index d531234..3cce23e 100644
|
||||
|
||||
ATOM g_window_class;
|
||||
|
||||
// This runs on the window owner thread.
|
||||
-// This runs on the window owner thread.
|
||||
-LRESULT CALLBACK IntermediateWindowProc(HWND window,
|
||||
- UINT message,
|
||||
- WPARAM w_param,
|
||||
@@ -66,10 +66,9 @@ index d531234..3cce23e 100644
|
||||
- }
|
||||
-}
|
||||
-
|
||||
-// This runs on the window owner thread.
|
||||
// This runs on the window owner thread.
|
||||
void InitializeWindowClass() {
|
||||
if (g_window_class)
|
||||
return;
|
||||
@@ -71,9 +32,9 @@ void InitializeWindowClass() {
|
||||
WNDCLASSEX intermediate_class;
|
||||
base::win::InitializeWindowClass(
|
||||
@@ -189,7 +188,7 @@ index d531234..3cce23e 100644
|
||||
|
||||
} // namespace gpu
|
||||
diff --git a/gpu/ipc/service/child_window_win.h b/gpu/ipc/service/child_window_win.h
|
||||
index c11202b..2b29fc6 100644
|
||||
index c11202b12da8fc540a78c3b13f731fc33d2d63b3..2b29fc641a810d2b521fa14e40da5bffb42ad722 100644
|
||||
--- a/gpu/ipc/service/child_window_win.h
|
||||
+++ b/gpu/ipc/service/child_window_win.h
|
||||
@@ -7,14 +7,13 @@
|
||||
@@ -227,7 +226,7 @@ index c11202b..2b29fc6 100644
|
||||
HWND parent_window_;
|
||||
HWND window_;
|
||||
diff --git a/gpu/ipc/service/direct_composition_surface_win.cc b/gpu/ipc/service/direct_composition_surface_win.cc
|
||||
index e6ac830..2fc7cd93 100644
|
||||
index e6ac8301cffe14cc55445a89d2013b61739d7e1f..2fc7cd93d82acf377391fa727d3fdfbb31d304f6 100644
|
||||
--- a/gpu/ipc/service/direct_composition_surface_win.cc
|
||||
+++ b/gpu/ipc/service/direct_composition_surface_win.cc
|
||||
@@ -1541,8 +1541,6 @@ gfx::SwapResult DirectCompositionSurfaceWin::SwapBuffers(
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
From 0000000000000000000000000000000000000000 Web Oct 31 00:00:00 2001
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shelley Vohr <shelley.vohr@gmail.com>
|
||||
Date: Web, 31 Oct 2018 09:08:02 -0700
|
||||
Date: Wed, 31 Oct 2018 09:08:02 -0700
|
||||
Subject: fix_zoom_display.patch
|
||||
|
||||
Backport of https://chromium-review.googlesource.com/c/chromium/src/+/1157224.
|
||||
Backport of https://chromium-review.googlesource.com/c/chromium/src/+/1157224.
|
||||
This patch was released in 70.0.3512.0.
|
||||
|
||||
diff --git a/ui/base/accelerators/platform_accelerator_cocoa.mm b/ui/base/accelerators/platform_accelerator_cocoa.mm
|
||||
index 9786168be893..3c177060453a 100644
|
||||
index 9786168be893dc756bca02f962f4ef0806e63ff3..3c177060453a4c01cc00cf36784eb336bd901e5e 100644
|
||||
--- a/ui/base/accelerators/platform_accelerator_cocoa.mm
|
||||
+++ b/ui/base/accelerators/platform_accelerator_cocoa.mm
|
||||
@@ -25,9 +25,16 @@ void GetKeyEquivalentAndModifierMaskFromAccelerator(
|
||||
|
||||
@@ -6,7 +6,7 @@ Subject: gtk_visibility.patch
|
||||
Allow electron and brightray to depend on GTK in the GN build.
|
||||
|
||||
diff --git a/build/config/linux/gtk/BUILD.gn b/build/config/linux/gtk/BUILD.gn
|
||||
index deae4d3455a8..fd5d906b98b0 100644
|
||||
index deae4d3455a8b54292dd3abc0a316f9ca60b4104..fd5d906b98b047b245824a4b3d6f0c528c96ee1b 100644
|
||||
--- a/build/config/linux/gtk/BUILD.gn
|
||||
+++ b/build/config/linux/gtk/BUILD.gn
|
||||
@@ -18,6 +18,8 @@ group("gtk") {
|
||||
|
||||
@@ -7,7 +7,7 @@ Dont compare RC.exe and RC.py output.
|
||||
FIXME: It has to be reverted once the script is fixed.
|
||||
|
||||
diff --git a/build/toolchain/win/tool_wrapper.py b/build/toolchain/win/tool_wrapper.py
|
||||
index cb0393ecd507b865169e9d7c3037d7d5523ae30e..34eebb06295b38dfa0b567f66780ce144b6b5f34 100644
|
||||
index ee21eb4b194b35576883b31c94c9a1f56075e89b..ab98a033a61c7a7cb4d5f0968c7a6178c13e3117 100644
|
||||
--- a/build/toolchain/win/tool_wrapper.py
|
||||
+++ b/build/toolchain/win/tool_wrapper.py
|
||||
@@ -231,7 +231,11 @@ class WinTool(object):
|
||||
|
||||
146
patches/common/chromium/intersection-observer.patch
Normal file
146
patches/common/chromium/intersection-observer.patch
Normal file
@@ -0,0 +1,146 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Milan Burda <milan.burda@gmail.com>
|
||||
Date: Wed, 27 Mar 2019 23:27:40 +0100
|
||||
Subject: [IntersectionObserver] Report coordinates as CSS pixels.
|
||||
|
||||
Prior to this patch, IntersectionObserverEntry was reporting
|
||||
coordinates in device pixels.
|
||||
|
||||
Backports https://chromium-review.googlesource.com/c/chromium/src/+/1250121
|
||||
|
||||
diff --git a/third_party/WebKit/LayoutTests/external/wpt/intersection-observer/bounding-box.html b/third_party/WebKit/LayoutTests/external/wpt/intersection-observer/bounding-box.html
|
||||
index 69052b11ce6c40c6a56fe2b723c70c49ddc36dd9..50f33f0443bb70e64bec2e2fcc930fa2b4118ed6 100644
|
||||
--- a/third_party/WebKit/LayoutTests/external/wpt/intersection-observer/bounding-box.html
|
||||
+++ b/third_party/WebKit/LayoutTests/external/wpt/intersection-observer/bounding-box.html
|
||||
@@ -13,7 +13,7 @@ pre, #log {
|
||||
overflow: visible;
|
||||
height: 200px;
|
||||
width: 160px;
|
||||
- border: 7px solid black;
|
||||
+ border: 8px solid black;
|
||||
}
|
||||
#target {
|
||||
margin: 10px;
|
||||
@@ -50,12 +50,35 @@ function step0() {
|
||||
var targetBounds = clientBounds(target);
|
||||
target.style.transform = "translateY(195px)";
|
||||
runTestCycle(step1, "target.style.transform = 'translateY(195px)'");
|
||||
- checkLastEntry(entries, 0, targetBounds.concat(0, 0, 0, 0, 8, 182, 8, 222, false));
|
||||
+ checkLastEntry(entries, 0, targetBounds.concat(0, 0, 0, 0, 8, 184, 8, 224, false));
|
||||
}
|
||||
|
||||
function step1() {
|
||||
+ var targetBounds = clientBounds(target);
|
||||
+ target.style.transform = "translateY(300px)";
|
||||
+ runTestCycle(step2, "target.style.transform = 'translateY(300px)'");
|
||||
+ checkLastEntry(entries, 1, targetBounds.concat(26, 146, 221, 224, 8, 184, 8, 224, true));
|
||||
+}
|
||||
+
|
||||
+function step2() {
|
||||
var targetBounds = clientBounds(target);
|
||||
target.style.transform = "";
|
||||
- checkLastEntry(entries, 1, targetBounds.concat(25, 145, 220, 222, 8, 182, 8, 222, true));
|
||||
+ target.style.zoom = "2";
|
||||
+ runTestCycle(step3, "target.style.zoom = 2");
|
||||
+ checkLastEntry(entries, 2, targetBounds.concat(0, 0, 0, 0, 8, 184, 8, 224, false));
|
||||
}
|
||||
+
|
||||
+function step3() {
|
||||
+ var targetBounds = clientBounds(target);
|
||||
+ var intersectionWidth = (
|
||||
+ 176 // root width including border
|
||||
+ -8 // root left border
|
||||
+ -20 // target left margin * target zoom
|
||||
+ ) / 2; // convert to target's zoom factor.
|
||||
+ var intersectionHeight = (216 - 8 - 20) / 2;
|
||||
+ var intersectionRect = [targetBounds[0], targetBounds[0] + intersectionWidth,
|
||||
+ targetBounds[2], targetBounds[2] + intersectionHeight];
|
||||
+ checkLastEntry(entries, 3, targetBounds.concat(intersectionRect).concat(8, 184, 8, 224, true));
|
||||
+}
|
||||
+
|
||||
</script>
|
||||
diff --git a/third_party/blink/renderer/core/intersection_observer/intersection_observation.cc b/third_party/blink/renderer/core/intersection_observer/intersection_observation.cc
|
||||
index 8b355a9f0b1e567950f8b5e9525d3af3e56605c4..d44b8b4e50f2a9de0628ebfb1bfdeac0292f79b5 100644
|
||||
--- a/third_party/blink/renderer/core/intersection_observer/intersection_observation.cc
|
||||
+++ b/third_party/blink/renderer/core/intersection_observer/intersection_observation.cc
|
||||
@@ -100,12 +100,12 @@ void IntersectionObservation::ComputeIntersectionObservations(
|
||||
|
||||
if (last_threshold_index_ != new_threshold_index ||
|
||||
last_is_visible_ != is_visible) {
|
||||
- FloatRect snapped_root_bounds(geometry.RootRect());
|
||||
+ FloatRect root_bounds(geometry.UnZoomedRootRect());
|
||||
FloatRect* root_bounds_pointer =
|
||||
- should_report_root_bounds_ ? &snapped_root_bounds : nullptr;
|
||||
+ should_report_root_bounds_ ? &root_bounds : nullptr;
|
||||
IntersectionObserverEntry* new_entry = new IntersectionObserverEntry(
|
||||
- timestamp, new_visible_ratio, FloatRect(geometry.TargetRect()),
|
||||
- root_bounds_pointer, FloatRect(geometry.IntersectionRect()),
|
||||
+ timestamp, new_visible_ratio, FloatRect(geometry.UnZoomedTargetRect()),
|
||||
+ root_bounds_pointer, FloatRect(geometry.UnZoomedIntersectionRect()),
|
||||
geometry.DoesIntersect(), is_visible, Target());
|
||||
Observer()->EnqueueIntersectionObserverEntry(*new_entry);
|
||||
SetLastThresholdIndex(new_threshold_index);
|
||||
diff --git a/third_party/blink/renderer/core/layout/intersection_geometry.cc b/third_party/blink/renderer/core/layout/intersection_geometry.cc
|
||||
index 2efb1a9cfef2c8372c98986f6a168979cafcd6df..1102b72814941faacf36ce486a46535565ea11e8 100644
|
||||
--- a/third_party/blink/renderer/core/layout/intersection_geometry.cc
|
||||
+++ b/third_party/blink/renderer/core/layout/intersection_geometry.cc
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
|
||||
#include "third_party/blink/renderer/core/frame/settings.h"
|
||||
#include "third_party/blink/renderer/core/html/html_frame_owner_element.h"
|
||||
+#include "third_party/blink/renderer/core/layout/adjust_for_absolute_zoom.h"
|
||||
#include "third_party/blink/renderer/core/layout/layout_box.h"
|
||||
#include "third_party/blink/renderer/core/layout/layout_view.h"
|
||||
#include "third_party/blink/renderer/core/page/page.h"
|
||||
@@ -230,4 +231,28 @@ void IntersectionGeometry::ComputeGeometry() {
|
||||
MapRootRectToRootFrameCoordinates();
|
||||
}
|
||||
|
||||
+LayoutRect IntersectionGeometry::UnZoomedTargetRect() const {
|
||||
+ if (!target_)
|
||||
+ return target_rect_;
|
||||
+ FloatRect rect(target_rect_);
|
||||
+ AdjustForAbsoluteZoom::AdjustFloatRect(rect, *target_);
|
||||
+ return LayoutRect(rect);
|
||||
+}
|
||||
+
|
||||
+LayoutRect IntersectionGeometry::UnZoomedIntersectionRect() const {
|
||||
+ if (!target_)
|
||||
+ return intersection_rect_;
|
||||
+ FloatRect rect(intersection_rect_);
|
||||
+ AdjustForAbsoluteZoom::AdjustFloatRect(rect, *target_);
|
||||
+ return LayoutRect(rect);
|
||||
+}
|
||||
+
|
||||
+LayoutRect IntersectionGeometry::UnZoomedRootRect() const {
|
||||
+ if (!root_)
|
||||
+ return root_rect_;
|
||||
+ FloatRect rect(root_rect_);
|
||||
+ AdjustForAbsoluteZoom::AdjustFloatRect(rect, *root_);
|
||||
+ return LayoutRect(rect);
|
||||
+}
|
||||
+
|
||||
} // namespace blink
|
||||
diff --git a/third_party/blink/renderer/core/layout/intersection_geometry.h b/third_party/blink/renderer/core/layout/intersection_geometry.h
|
||||
index cd264792a894bb2d25cb3df80a60cd667dcba36e..f08cfdbcc0778900558816eaaeee14dc662c3f9c 100644
|
||||
--- a/third_party/blink/renderer/core/layout/intersection_geometry.h
|
||||
+++ b/third_party/blink/renderer/core/layout/intersection_geometry.h
|
||||
@@ -38,12 +38,18 @@ class IntersectionGeometry {
|
||||
|
||||
// Client rect in the coordinate system of the frame containing target.
|
||||
LayoutRect TargetRect() const { return target_rect_; }
|
||||
+ // Target rect in CSS pixels
|
||||
+ LayoutRect UnZoomedTargetRect() const;
|
||||
|
||||
// Client rect in the coordinate system of the frame containing target.
|
||||
LayoutRect IntersectionRect() const { return intersection_rect_; }
|
||||
+ // Intersection rect in CSS pixels
|
||||
+ LayoutRect UnZoomedIntersectionRect() const;
|
||||
|
||||
// Client rect in the coordinate system of the frame containing root.
|
||||
LayoutRect RootRect() const { return root_rect_; }
|
||||
+ // Root rect in CSS pixels
|
||||
+ LayoutRect UnZoomedRootRect() const;
|
||||
|
||||
bool DoesIntersect() const { return does_intersect_; }
|
||||
|
||||
96
patches/common/chromium/keyboard-lock-service-impl.patch
Normal file
96
patches/common/chromium/keyboard-lock-service-impl.patch
Normal file
@@ -0,0 +1,96 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Joe Downing <joedow@chromium.org>
|
||||
Date: Thu, 27 Sep 2018 00:24:13 +0000
|
||||
Subject: Destroy KeyboardLockServiceImpl instance when RenderFrameHost goes
|
||||
away
|
||||
|
||||
This CL updates KeyboardLockServiceImpl to release its mojo binding if
|
||||
the RenderFrameHost instance it is linked to is destroyed.
|
||||
|
||||
Bug: 888678
|
||||
Change-Id: Icea5fe1a5c76df4d71fa4e78c423e49828664637
|
||||
Reviewed-on: https://chromium-review.googlesource.com/1246290
|
||||
Commit-Queue: Joe Downing <joedow@chromium.org>
|
||||
Reviewed-by: Daniel Cheng <dcheng@chromium.org>
|
||||
Reviewed-by: Scott Violet <sky@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/master@{#594534}
|
||||
|
||||
diff --git a/content/browser/keyboard_lock/keyboard_lock_service_impl.cc b/content/browser/keyboard_lock/keyboard_lock_service_impl.cc
|
||||
index f783d5356c8c81137ad99b366062aea1c76616a4..b0aa16010bbc602b0a854cd777221221164a49e3 100644
|
||||
--- a/content/browser/keyboard_lock/keyboard_lock_service_impl.cc
|
||||
+++ b/content/browser/keyboard_lock/keyboard_lock_service_impl.cc
|
||||
@@ -38,20 +38,22 @@ void LogKeyboardLockMethodCalled(KeyboardLockMethods method) {
|
||||
} // namespace
|
||||
|
||||
KeyboardLockServiceImpl::KeyboardLockServiceImpl(
|
||||
- RenderFrameHost* render_frame_host)
|
||||
- : render_frame_host_(static_cast<RenderFrameHostImpl*>(render_frame_host)) {
|
||||
+ RenderFrameHost* render_frame_host,
|
||||
+ blink::mojom::KeyboardLockServiceRequest request)
|
||||
+ : FrameServiceBase(render_frame_host, std::move(request)),
|
||||
+ render_frame_host_(static_cast<RenderFrameHostImpl*>(render_frame_host)) {
|
||||
DCHECK(render_frame_host_);
|
||||
}
|
||||
|
||||
-KeyboardLockServiceImpl::~KeyboardLockServiceImpl() = default;
|
||||
-
|
||||
// static
|
||||
void KeyboardLockServiceImpl::CreateMojoService(
|
||||
RenderFrameHost* render_frame_host,
|
||||
blink::mojom::KeyboardLockServiceRequest request) {
|
||||
- mojo::MakeStrongBinding(
|
||||
- std::make_unique<KeyboardLockServiceImpl>(render_frame_host),
|
||||
- std::move(request));
|
||||
+ DCHECK(render_frame_host);
|
||||
+
|
||||
+ // The object is bound to the lifetime of |render_frame_host| and the mojo
|
||||
+ // connection. See FrameServiceBase for details.
|
||||
+ new KeyboardLockServiceImpl(render_frame_host, std::move(request));
|
||||
}
|
||||
|
||||
void KeyboardLockServiceImpl::RequestKeyboardLock(
|
||||
@@ -131,4 +133,6 @@ void KeyboardLockServiceImpl::GetKeyboardLayoutMap(
|
||||
std::move(callback).Run(std::move(response));
|
||||
}
|
||||
|
||||
+KeyboardLockServiceImpl::~KeyboardLockServiceImpl() = default;
|
||||
+
|
||||
} // namespace content
|
||||
diff --git a/content/browser/keyboard_lock/keyboard_lock_service_impl.h b/content/browser/keyboard_lock/keyboard_lock_service_impl.h
|
||||
index 19c2f994758801e7d21d5256ec762eab84e7dd15..eecefd26e448befcb9c12b7203271c04d728751f 100644
|
||||
--- a/content/browser/keyboard_lock/keyboard_lock_service_impl.h
|
||||
+++ b/content/browser/keyboard_lock/keyboard_lock_service_impl.h
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "content/common/content_export.h"
|
||||
+#include "content/public/browser/frame_service_base.h"
|
||||
#include "mojo/public/cpp/bindings/strong_binding.h"
|
||||
#include "third_party/blink/public/platform/modules/keyboard_lock/keyboard_lock.mojom.h"
|
||||
|
||||
@@ -17,11 +18,11 @@ namespace content {
|
||||
class RenderFrameHost;
|
||||
class RenderFrameHostImpl;
|
||||
|
||||
-class CONTENT_EXPORT KeyboardLockServiceImpl
|
||||
- : public blink::mojom::KeyboardLockService {
|
||||
+class CONTENT_EXPORT KeyboardLockServiceImpl final
|
||||
+ : public FrameServiceBase<blink::mojom::KeyboardLockService> {
|
||||
public:
|
||||
- explicit KeyboardLockServiceImpl(RenderFrameHost* render_frame_host);
|
||||
- ~KeyboardLockServiceImpl() override;
|
||||
+ KeyboardLockServiceImpl(RenderFrameHost* render_frame_host,
|
||||
+ blink::mojom::KeyboardLockServiceRequest request);
|
||||
|
||||
static void CreateMojoService(
|
||||
RenderFrameHost* render_frame_host,
|
||||
@@ -34,6 +35,9 @@ class CONTENT_EXPORT KeyboardLockServiceImpl
|
||||
void GetKeyboardLayoutMap(GetKeyboardLayoutMapCallback callback) override;
|
||||
|
||||
private:
|
||||
+ // |this| can only be destroyed by FrameServiceBase.
|
||||
+ ~KeyboardLockServiceImpl() override;
|
||||
+
|
||||
RenderFrameHostImpl* const render_frame_host_;
|
||||
};
|
||||
|
||||
@@ -48,7 +48,7 @@ index e4e0da40981ca58964dfdcbd3fc0f730c9c09ec1..af028715ada9b8023f0ff7cf60e0f7e7
|
||||
Gtk2StatusIcon(const gfx::ImageSkia& image, const base::string16& tool_tip);
|
||||
~Gtk2StatusIcon() override;
|
||||
diff --git a/chrome/browser/ui/libgtkui/gtk_util.h b/chrome/browser/ui/libgtkui/gtk_util.h
|
||||
index d9f245070249f5f153bd8fe11e0a5e718c7d3629..a0f033c3e3f7f3996897f5f969b2a209d7d5cf3f 100644
|
||||
index d9f245070249f5f153bd8fe11e0a5e718c7d3629..05875b9ca744b6bf7e0891bca3b193f36a98b19d 100644
|
||||
--- a/chrome/browser/ui/libgtkui/gtk_util.h
|
||||
+++ b/chrome/browser/ui/libgtkui/gtk_util.h
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: deepak1556 <hop2deep@gmail.com>
|
||||
Date: Tue, 27 Nov 2018 04:32:18 +0530
|
||||
Subject: [Mac] Fix form control rendering on 10.14 Mojave.
|
||||
Subject: Fix form control rendering on 10.14 Mojave.
|
||||
|
||||
Backports https://crrev.com/c/1106298/ and https://crrev.com/c/1130163/
|
||||
with changes required for v1 sandbox on macOS.
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user