Compare commits

...

94 Commits

Author SHA1 Message Date
Electron Bot
b763d81d79 Bump v4.2.2 2019-05-16 14:21:46 -07:00
Cheng Zhao
7521454161 fix: lagging when using tabbed window (#18314) 2019-05-16 14:20:09 -07:00
Electron Bot
36f0583077 Bump v4.2.1 2019-05-14 11:52:55 -07:00
Jeremy Apthorp
96391dbb3b fix: default enable_negotiate_port to false (4-2-x) (#18287)
* fix: default enable_negotiate_port to false (#18251)

* chore: command_line is not a pointer
2019-05-14 11:16:00 -07:00
Electron Bot
d5cf2e1244 Bump v4.2.0 2019-05-02 14:34:52 -07:00
Samuel Attard
9a665eb5fb feat: allow setting of global fallback user agent (#18110) 2019-05-02 13:06:01 -07:00
Samuel Attard
6b16695ba3 build: reset version to 4.2.0-beta.0 in prep for 4.2.0 2019-05-01 16:55:28 -07:00
Milan Burda
ac714a1d02 fix: allow stream protocols to return headers with multiple values (#14887) (#18094)
* fix: allow stream protocols to return headers with multiple values

This allows stream protocols to return headers with multiple values as
an array of values.

Fixes https://github.com/electron/electron/issues/14778

* Prefer ConvertFromV8

* Cleanup header conversion

1. Deduplicate the code by using a lambda
2. Remove duplicate calls to headers->Get(key)

* Fix broken test

Headers with multiple values are now being converted correctly, this
test asserted the wrong behavior.
2019-05-01 16:36:42 -07:00
trop[bot]
e5e94fce02 docs: fix webContents 'new-window' event handler sample (#18096) 2019-05-01 13:43:39 -07:00
trop[bot]
f65a7983c6 chore: disable Vulkan validation layers (#18060) 2019-05-01 10:46:08 -07:00
trop[bot]
d1f5d20098 fix: explicitly focus window on win.show() (#18079) 2019-05-01 10:44:37 -07:00
Milan Burda
2f67cd5b35 Revert "build: disable Vulkan support by default (#17789)" (#17987)
This reverts commit ccad8ec125.
2019-04-30 06:43:12 -07:00
Milan Burda
3fd0ac6d44 fix: remove non-existent gpu-crashed event on <webview> (#17317) (#18003) 2019-04-29 15:22:01 -07:00
Electron Bot
4a6cad7ba5 Bump v4.1.5 2019-04-24 14:35:12 -07:00
Taiki Akita
eccede0c0d fix: add a compatibility EVP_CIPH_OCB_MODE value (#16214). (#17873)
* fix: add a compatibility EVP_CIPH_OCB_MODE value (#16214).

Backported google/boringssl@4b9683 to 4.1.x branch. This patch
replaces 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.

This patch fixed issue #16214.

* revert: "fix: add a compatibility EVP_CIPH_OCB_MODE value (#16214)."

This reverts commit f1156a8ee4.

* fix: (recommit) add a compatibility EVP_CIPH_OCB_MODE value (#16214).

Recommited change @f1156a with patches generated by
"git-export-patches".
2019-04-23 09:10:42 -07:00
Jeff Genovy
9ed83e7512 fix: Add support for the new Japanese Era (Reiwa) to ICU (#17833)
This change backports changes from the upstream ICU project's
maintenance release for ICU 62.2 in order to enable support for the new
Japanese Era "Reiwa" in Chromium 69 (which uses ICU version 62.1).

Upstream release: http://site.icu-project.org/download/62

Additionally, this change also includes the following fixes/updates:
 - Update IANA time zone tzdata to 2019a.
 - Japanese calendar era calculation should use local time, not UTC.
 - Japanese calendar: use all valid eras for calendar calculations.
 - Fix LocalMemory move constructor delete issue.

This change requires re-generating the checked-in Chromium ICU data
files (ex: icudtl.dat) in order for them to have the updated data for
the new era name. However, that will be done with a separate commit in
order to make the ".patch" files cleaner.

Note: All of the checked-in files are be regenerated, even though
the Electron project only uses the "common" one.

Also included in this change are some minor changes to the scripts used
by Chromium for building the data files so that they actually work on
Ubuntu.
2019-04-19 14:41:21 -07:00
Milan Burda
b3ed83055c fix: execute session preload scripts in sandboxed renderers (#17875) 2019-04-19 12:50:29 -07:00
Milan Burda
2360f3eb11 fix: copy pixels in AddImageSkiaRepFromBuffer (#17843) (#17862) 2019-04-18 08:53:32 -07:00
trop[bot]
4175e947bb doc: document occasional mismatch between NSImageName and string (#17848) 2019-04-17 21:01:17 -04:00
trop[bot]
1cbcd05ab7 fix: correct crash reporter for Windows on Arm (#17793)
ARM64 cleans up and moves around RUNTIME_FUNCTION structure fields.
With this patch applied, electron should build cleanly for Windows on Arm.
2019-04-16 19:42:01 -04:00
trop[bot]
40c7e767ef fix: reset the NSUserNotication handle on dismiss (#17821) 2019-04-16 16:24:16 -07:00
Milan Burda
66c5a8362a fix: emit process 'loaded' event in sandboxed renderers (#17807) 2019-04-16 16:23:53 -07:00
Shelley Vohr
d6ba1421fa docs: note desktop audio limitation on macOS (#17815) 2019-04-16 18:52:37 -04:00
Alexey Kuzmin
ccad8ec125 build: disable Vulkan support by default (#17789)
Is was enabled in
327326656f
which landed in 69.0.3460.0

Vulkan support would require a command line parameter "--enable-vulkan"
to be passes to a binary to be enabled anyway,
so this change doesn't actual alter the current behaviour of Electron.

(cherry picked from commit e05e45d62d)
2019-04-16 11:30:15 -04:00
Milan Burda
d2bff97199 fix: update fix_font_thickness.patch (#17737) 2019-04-15 19:53:10 -04:00
Milan Burda
46a1ce8117 fix: report module name when require fails in sandboxed renderers (#17704) 2019-04-09 21:00:45 -04:00
Electron Bot
042f24c5b6 Bump v4.1.4 2019-04-04 11:36:42 -07:00
Milan Burda
c3624116ae fix: Issue 907211: Heap-use-after-free in viz::HostFrameSinkManager::InvalidateFrameSinkId (#17658) 2019-04-04 11:33:48 -07:00
Milan Burda
492397b815 fix: Issue 912211: Security: a use-after-free in RenderFrameImple can lead to an RCE (#17659) 2019-04-04 09:11:45 -07:00
Shelley Vohr
3a0b72e5dc fix: expose process.getProcessMemoryInfo to sandbox (#17669) 2019-04-04 09:09:00 -07:00
trop[bot]
914939c793 build: optionally exclude some parts of patches from being applied (#17684) 2019-04-04 09:08:46 -07:00
trop[bot]
b8874913f2 docs: clarify cookie domain normalization (#17662) 2019-04-02 18:26:42 -07:00
Alexey Kuzmin
dc959414a3 fix: Make --explicitly-allowed-ports work with NetworkService. (#17642)
https://chromium-review.googlesource.com/c/1400042
2019-04-02 13:25:14 -07:00
Milan Burda
bcdc4435b4 fix: Issue 888678: Heap-use-after-free in content::KeyboardLockServiceImpl::GetKeyboardLayoutMap (#17632) 2019-04-01 18:55:51 -07:00
Electron Bot
303da32dd3 Bump v4.1.3 2019-03-29 10:19:35 -07:00
Robo
8fd91cc35b fix: make StreamSubscriber ref counted (#17267)
It is owned by URLRequestStreamJob on the IO thread once request starts,
but if the ownership was abondoned while transfering it to IO thread
which is possible when a request is aborted, then we need to make sure
its destroyed on the right thread to avoid lock in v8.
2019-03-29 12:28:55 -04:00
Milan Burda
3001c76483 fix: backport [IntersectionObserver] Report coordinates as CSS pixels. (#17583) 2019-03-29 17:18:39 +01:00
Electron Bot
28a9963ca7 Bump v4.1.2 2019-03-28 13:04:12 -07:00
Samuel Attard
b5f290d8d2 fix: add patch for framework file permissions (#17582) 2019-03-28 13:01:05 -07:00
trop[bot]
4574a21ed3 fix: handle a race condition between preload scripts executing and navigations (#17596)
There is a race condition between DidCreateScriptContext and another
navigation occuring in the main process. If the navigation occurs while
the preload script is running, the same process is re-used.  This
ensures that any pending navigations are completely removed / ignored
when we trigger a new navigation.

Fixes #17576
2019-03-28 12:56:23 -07:00
Samuel Attard
7aaaa24da7 Revert "Bump v4.1.2"
This reverts commit ded4a94a92.
2019-03-28 12:53:49 -07:00
Electron Bot
ded4a94a92 Bump v4.1.2 2019-03-28 08:57:59 -07:00
trop[bot]
c6fd15e641 fix: correctly return properties on the netLog module (#17544) 2019-03-27 15:38:16 -07:00
Electron Bot
36965a6b4e Revert "Bump v4.1.2"
This reverts commit 53c3e01af6.
2019-03-27 14:22:01 -07:00
Electron Bot
53c3e01af6 Bump v4.1.2 2019-03-27 13:58:56 -07:00
Jeff Genovy
d2571f3a9e fix: backport ICU changes for Japanese Era placeholder name (#17518)
This change backports changes from the upstream ICU 62.1 maintenance
branch into the Chromium copy of ICU, in order to enable the
"placeholder era" for the upcoming new Japanese Era.

Upstream change: https://github.com/unicode-org/icu/pull/514
Upstream ticket: https://unicode-org.atlassian.net/browse/ICU-20482

With this change you can set/define an Environment Variable
`ICU_ENABLE_TENTATIVE_ERA` to `true which will enable the placeholder
era name.

Note: This change requires re-generating the checked-in Chromium ICU
data files (icudtl.dat) in order for them to have the updated data
for the placeholder era name.

Also included in this change are some minor changes to the scripts
used by Chromium for building the data files so that they actually
work on Ubuntu.
2019-03-27 10:22:45 -04:00
trop[bot]
e1a8050eab fix: add missing buffer size check in nativeImage (#17567) 2019-03-27 09:37:13 -04:00
Samuel Attard
7b1f5a9cea fix: backport KDE icon size fix (#17497) 2019-03-21 14:19:11 -05:00
trop[bot]
5b9393c173 docs: clarify documentation for getLastCrashReport (backport: 4-1-x) (#17494)
* docs: clarify documentation for getLastCrashReport

* address feedback
2019-03-20 22:04:15 -07:00
trop[bot]
98180568f2 fix: take foreground visibility into account for isVisible on macOS (#17492) 2019-03-20 20:40:52 -07:00
Electron Bot
f005ac8d8b Bump v4.1.1 2019-03-20 13:49:36 -07:00
trop[bot]
a0d824ccf5 fix: use a more unique identifier for NSUserNotification instances (#17483)
So although apple has it documented that notifications with duplicate identifiers in the same session won't be presented.  They apparently forgot to mention that macOS also non-deterministically and without any errors, logs or warnings will also not present some notifications in future sessions if they have a previously used identifier.

As such, we're going to truly randomize these identifiers so they are
unique between apps and sessions.  The identifier now consists of a
randomly generated UUID and the app bundle id.
2019-03-20 11:19:08 -07:00
trop[bot]
ee1529587c fix: throw error when inserting menu items out-of-range (#17461)
* fix: throw error when inserting menu items out-of-range

* also check pos < 0
2019-03-19 12:59:11 -07:00
trop[bot]
5e665c1d38 fix: don't crash when nativeImage.createFromBuffer() called with invalid buffer (#17373) 2019-03-19 12:14:11 -07:00
Milan Burda
61d1df2b43 fix: remove crashReporterRenderer.sendSync() workaround for init() (#17409) 2019-03-19 11:56:39 -07:00
Electron Bot
6c4ee66165 Bump v4.1.0 2019-03-13 16:12:16 -07:00
Samuel Attard
84b014577f build: reset version to 4.1.0-beta.0 in preparation for 4.1.0 stable release 2019-03-13 15:18:05 -07:00
trop[bot]
84ec42463b fix: remove label/image from segment if they are mutated to undefined/null (#17335) 2019-03-11 17:19:53 -07:00
Jeremy Apthorp
01c8f698ee fix: crash in ECDH.setPrivateKey (#17297) 2019-03-08 14:06:57 -08:00
trop[bot]
f53a9c1268 test: fix incorrect reference to skip (#17280) 2019-03-08 16:12:23 -05:00
Electron Bot
56c545f679 Bump v4.0.8 2019-03-07 11:31:03 -08:00
Jeremy Apthorp
34c1a53441 fix: FileReader: Make a copy of the ArrayBuffer when returning partial results (#17256)
backports https://chromium-review.googlesource.com/c/chromium/src/+/1495209
2019-03-07 11:26:01 -08:00
Electron Bot
8d330f7dde Bump v4.0.7 2019-03-04 14:50:36 -08:00
Jeremy Apthorp
3c0d90eca8 fix: correct chrome version in chrome_version.h (#17218) 2019-03-04 13:42:08 -08:00
trop[bot]
9d30245fb4 fix: access of out-of-scope reference in ShowOpenDialog and ShowSaveDialog (#17176)
In the mac file dialog implementation of show*OpenDialog, a settings
object is passed down to the dialog completion handler.
However at the time the completion handler is invoked, the settings
object is already out-of-scope, resulting in an invalid access to
the security_scoped_bookmarks flag.
The fix is to capture the value of the flag and passing that directly
to the completion handler.

fixes issue #16664
2019-03-01 08:18:50 +00:00
Alexey Kuzmin
0efccf45bc chore: remove an unused header (#17158) 2019-02-28 17:32:49 +01:00
trop[bot]
4e0d4c4785 fix: set cancelId to 1 when defaultId == 0 and no 'cancel' button (#17151) 2019-02-27 13:01:34 +00:00
trop[bot]
6d313b48f2 Fix webContents.print() (#17116) 2019-02-27 08:25:15 +00:00
Electron Bot
330e8abd16 Bump v4.0.6 2019-02-26 15:01:41 -08:00
Roller Bot
ffd8c36f4f chore: bump chromium in DEPS to 69.0.3497.128 (#16636) 2019-02-25 18:00:06 -08:00
trop[bot]
efa12608e0 fix: pass result to chrome.tabs.executeScript callback (backport: 4-0-x) (#16948)
* fix: pass result to chrome.tabs.executeScript callback

Additionally, remove `nextId` counter in favor of `originResultID` counter which is more widely used in this file.

* fix: remove need for eslint override and better match style
2019-02-15 10:21:46 -08:00
Jeremy Apthorp
969ac4ced1 fix: enable inputpane virtual keyboard by default (#16944)
backports e6c18518b from chromium, fixes #13832
2019-02-15 07:38:47 -10:00
trop[bot]
a2d77352e5 docs: update dialog documentation for "undefined" ret vals (#16976) 2019-02-14 17:33:44 -08:00
Electron Bot
55c48efb90 Bump v4.0.5 2019-02-14 14:09:13 -08:00
Jeremy Apthorp
7a285cd0ea fix: renderer hang in cc BeginMainFrame (#16946)
* chore: re-export chromium patches

this is just git-import-patches && git-export-patches

* fix: renderer hang in cc BeginMainFrame

backports https://chromium-review.googlesource.com/c/chromium/src/+/1419132
2019-02-14 05:50:22 -10:00
John Kleinschmidt
415fbfaf41 ci: Move MacOS builds to CircleCI (4-0-x) (#16933)
* ci: build mac on CircleCI (#16656)

* ci: make macOS CI faster (#16766)

* ci: cache brew update result

* ci: checkout and sync the macOS build on a linux machine for speed

* ci: set MAS_BUILD=true on mas builds (#16824)

* build: remove non-arm vstsJobs (#16793)

* ci: fix binaries for chromedriver build on macOS
2019-02-13 11:25:03 -10:00
trop[bot]
1a41e196e8 build: ensure that the uploaded symbol path is correct for our symbol server (#16916) 2019-02-13 07:08:50 -10:00
trop[bot]
4f63509ebd fix: backport patch to sync exposed crypto (backport: 4-0-x) (#16912) 2019-02-12 21:29:57 -08:00
Cheng Zhao
45a554f305 Fix memory leak when using webFrame and spell checker (4-0-x) (#16772)
* fix: do not create native api::WebFrame in webFrame

When reloading a page without restarting renderer process (for example
sandbox mode), the blink::WebFrame is not destroyed, but api::WebFrame
is always recreated for the new page context. This leaves a leak of
api::WebFrame.

* fix: remove spell checker when page context is released
2019-02-12 06:36:23 -10:00
trop[bot]
29a0bc23c4 fix: release-notes plays more nicely with clerk (#16901)
Explicitly look not just for Clerk's "notes persisted"
message but also its "no release notes" message.
2019-02-12 10:17:40 -06:00
trop[bot]
f7508f17c5 chore: fix "creates offscreen window with correct size" spec on Mac with Retina display (#16877) 2019-02-11 13:14:44 -08:00
trop[bot]
d2538cd3b1 fix: enable property having no effect on submenus (#16857) 2019-02-09 09:58:31 -08:00
trop[bot]
fae52d8e4a fix: don't forward IPC filtering events to app for dev-tools and extensions (#16716) 2019-02-08 15:35:18 -08:00
trop[bot]
064f198162 chore: make crash-reporter specs not use URL module (#16849) 2019-02-08 15:32:41 -08:00
trop[bot]
fd2a9cb056 chore: disable get/setLoginItemSettings specs (#16844) 2019-02-08 15:13:44 -08:00
trop[bot]
b4c27eeaa1 fix: don't construct submenu if it's invisible (#16845) 2019-02-08 15:13:07 -08:00
trop[bot]
93b4d20c59 fix: display empty menu item for non-visible submenus (backport: 4-0-x) (#16847)
* fix: display empty menu item for nonvisible submenus

* use Chromium UI string ID
2019-02-08 15:12:34 -08:00
trop[bot]
c647bf5d27 docs: added webContents.getType() method (backport: 4-0-x) (#16786)
* docs: added webContents.getType() method

* docs: add enumeration of return value for webContents.getType()

* docs: getType() in WebContents should be class method not module method
2019-02-07 08:51:54 -08:00
trop[bot]
cbca75d184 build: ensure index.json is actually valid JSON before uploading (backport: 4-0-x) (#16750)
* build: ensure index.json is actually valid JSON before uploading

* chore: fix py linting for validation of index.json
2019-02-05 15:01:09 -08:00
trop[bot]
8054fc83ac fix: crash when calling setProgressBar on macOS (backport: 4-0-x) (#16727)
* fix: correctly check whether dock has progress bar

* fix: do not leak memory when setting dockTile
2019-02-04 20:56:38 -08:00
Shelley Vohr
0b7680aa14 fix: correctly handle IPC for promise-based methods (#16433) (#16654) 2019-02-04 16:01:42 -08:00
Shelley Vohr
668e85dd7c fix: show proper clerk notes in release notes script (#16694)
* fix: show proper clerk notes in release notes script (backport: 4-0-x) (#16678)

* fix: Note detection in PR

* fix: 'BREAKING CHANGE' detection in PR body

* fix: when to include PRs that landed in other branches too

* fix: when available, use clerk's notes

* address throw edge case
2019-02-04 14:09:56 -08:00
Milan Burda
e253c9bfe6 feat: add additional remote APIs filtering (#16688) 2019-02-04 08:46:54 -08:00
Birunthan Mohanathas
c00d3536d1 fix: use async save dialog for anchor download attribute (4-0-x) (#16647)
Backport of #16612 and #16646

Notes: Fix broken save dialog on macOS for `<a>` downloads
2019-02-03 23:55:18 -08:00
139 changed files with 133199 additions and 1508 deletions

File diff suppressed because it is too large Load Diff

2
DEPS
View File

@@ -10,7 +10,7 @@ gclient_gn_args = [
vars = {
'chromium_version':
'69.0.3497.106',
'69.0.3497.128',
'node_version':
'8bc5d171a0873c0ba49f9433798bc8b67399788c',

View File

@@ -1 +1 @@
4.0.4
4.2.2

View File

@@ -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 {

View File

@@ -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);
};

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -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;

View File

@@ -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_);

View File

@@ -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);

View File

@@ -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();

View File

@@ -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() {

View File

@@ -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_;

View File

@@ -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;
}

View File

@@ -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) {

View File

@@ -349,6 +349,9 @@ void NativeWindowViews::Show() {
widget()->native_widget_private()->ShowWithWindowState(GetRestoredState());
// explicitly focus the window
widget()->Activate();
NotifyWindowShow();
#if defined(USE_X11)

View File

@@ -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();
}

View File

@@ -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_;

View File

@@ -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>

View File

@@ -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

View File

@@ -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];

View File

@@ -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];
}

View File

@@ -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);
}];
}
}

View File

@@ -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);

View File

@@ -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));
}

View File

@@ -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

View File

@@ -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_

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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_

View File

@@ -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(

View File

@@ -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() {

View File

@@ -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);
}

View File

@@ -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;

View File

@@ -12,5 +12,6 @@ proprietary_codecs = true
ffmpeg_branding = "Chrome"
enable_basic_printing = true
angle_enable_vulkan_validation_layers = false
is_cfi = false

View File

@@ -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.

View File

@@ -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.

View File

@@ -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()`

View File

@@ -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`.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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`

View File

@@ -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:

View File

@@ -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",

View File

@@ -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)
}
}

View File

@@ -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') {

View File

@@ -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)

View File

@@ -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)
},

View File

@@ -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')

View 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()
}
}

View File

@@ -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) {

View File

@@ -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,

View File

@@ -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
})

View File

@@ -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'
])

View File

@@ -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)
}
}

View File

@@ -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)

View File

@@ -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) {

View File

@@ -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'],

View File

@@ -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')

View File

@@ -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
View File

@@ -1,6 +1,6 @@
{
"name": "electron",
"version": "4.0.4",
"version": "4.2.2",
"lockfileVersion": 1,
"requires": true,
"dependencies": {

View File

@@ -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": {

View File

@@ -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

View File

@@ -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.

View File

@@ -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);

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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;
}

View 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);

View File

@@ -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

View File

@@ -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 {

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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") {

View File

@@ -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):

View File

@@ -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.

View File

@@ -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];

View File

@@ -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(

View File

@@ -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);

View File

@@ -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") {

View File

@@ -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(

View File

@@ -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) {

View File

@@ -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;

View File

@@ -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",

View File

@@ -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.

View File

@@ -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);

View File

@@ -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;

View File

@@ -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))

View File

@@ -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(

View File

@@ -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(

View File

@@ -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") {

View File

@@ -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):

View 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_; }

View 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_;
};

View File

@@ -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 @@

View File

@@ -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